Page cache와 관련된 코드를 함께 먼저 보기 위해 generic_file_read_iter() 부터 분석한다.
mm/filemap.c
먼저 이 함수 위 주석을 보자.
/**
* generic_file_read_iter - generic filesystem read routine
* @iocb: kernel I/O control block
* @iter: destination for the data read
*
* This is the "read_iter()" routine for all filesystems
* that can use the page cache directly.
*
* The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall
* be returned when no data can be read without waiting for I/O requests
* to complete; it doesn't prevent readahead.
* generic_file_read_iter - generic filesystem read routine
* @iocb: kernel I/O control block
* @iter: destination for the data read
*
* This is the "read_iter()" routine for all filesystems
* that can use the page cache directly.
*
* The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall
* be returned when no data can be read without waiting for I/O requests
* to complete; it doesn't prevent readahead.
--> IOCB_NOWAIT flag가 있으면 prefetch를 막지 않는다고 함.
--> "I/O requests가 complete 되는 것을 기다리지 않고" -EAGAIN이 리턴된다는 것임.
--> Prefetch (readahead) 던져 놓고 리턴될거야~ 라는 것인 듯.
*
* The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O
* requests shall be made for the read or for readahead. When no data
* can be read, -EAGAIN shall be returned. When readahead would be
* triggered, a partial, possibly empty read shall be returned.
* The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O
* requests shall be made for the read or for readahead. When no data
* can be read, -EAGAIN shall be returned. When readahead would be
* triggered, a partial, possibly empty read shall be returned.
--> IOCB_NOIO flag는 read/readahead를 위한 I/O request가 없을 거라는 것임.
--> 데이터를 읽을 수 없을 때 -EAGAIN이 return 됨.
--> readahead가 trigger될 수도 있지만 empty read가 return 되야함.
*
* Return:
* * number of bytes copied, even for partial reads
* * negative error code (or 0 if IOCB_NOIO) if nothing was read
*/
*
* Return:
* * number of bytes copied, even for partial reads
* * negative error code (or 0 if IOCB_NOIO) if nothing was read
*/
ssize_t
generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
size_t count = iov_iter_count(iter);
ssize_t retval = 0;
if (!count)
return 0; /* skip atime */
if (iocb->ki_flags & IOCB_DIRECT) {
generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
size_t count = iov_iter_count(iter);
ssize_t retval = 0;
if (!count)
return 0; /* skip atime */
if (iocb->ki_flags & IOCB_DIRECT) {
--> ext4에서 넘어왔다면 IOCB_DIRECT가 ext4_dio_read_iter() 를 불렀을 것이다.
--> 이쪽을 타지 않음.
...
}
return filemap_read(iocb, iter, retval);
}
...
}
return filemap_read(iocb, iter, retval);
}
역시 함수 위 주석을 먼저 보자.
/**
* filemap_read - Read data from the page cache.
* @iocb: The iocb to read.
* @iter: Destination for the data.
* @already_read: Number of bytes already read by the caller.
*
* Copies data from the page cache. If the data is not currently present,
* uses the readahead and read_folio address_space operations to fetch it.
*
* Return: Total number of bytes copied, including those already read by
* the caller. If an error happens before any bytes are copied, returns
* a negative error number.
*/
[작성 예정]