리눅스 커널 파일 시스템 [4] 정리 - Read

리눅스 커널 파일 시스템 Read [1]

리눅스 커널 파일 시스템 Read [2]

리눅스 커널 파일 시스템 Read [3]


1. 시스템콜이 vfs를 거쳐 각 파일시스템으로 간다.

2. 각 파일시스템에서 read를 어떻게 처리할지 결정 (Storage에서 바로 읽을지, Page cache에서 읽을지)

3. (Page cache에서 읽을 경우) mm/filemap.c의 generic_file_read_iter()로 간다. 디렉토리 명 (mm == memory management)에서 볼수 있듯이 이제 메인 메모리의 영역이다. Page cache는 메인 메모리에 저장되어 있다.

4. Storage의 해당 데이터가 메인 메모리에 있는지 살펴본다 (즉, 해당 데이터에 대한 page cache 가 존재하는지 살펴본다.) (이 단계는 filemap_get_pages()의 filemap_get_read_batch()에 의해 수행된다. page cache가 struct address_space *mapping에 존재하는지 살펴본다. 이때 xarray가 사용되는데 (xas_load, xas_next 같은 함수들), xarray는 매우 큰 인덱스 공간을 빠르게 탐색하는 동적 인덱싱 자료구조이다. 기존 radix tree를 대체한다.).

5. 해당 데이터에 대한 Page cache가 없다면 Storage로부터 Page cache에 데이터를 읽어온다 (filemap_read()를 통해 ext_readahead 까지 가게 된다.).

6. Page cache의 데이터를 사용자 공간으로 복사한다 (copy_folio_to_iter()). iocb->ki_pos에 업데이트된 file offset (파일 내에 I/O가 읽거나 쓸 위치)이 저장된다.



아래 함수 흐름을 살펴보자.
read system call --> ksys_read() --> vfs_read() --> new_sync_read() --> ext4_file_read_iter() --> generic_file_read_iter() (page cache가 없다면) --> filemap_read() --> filemap_get_pages() --> page_cache_sync_readahead() --> page_cache_sync_ra() --> do_page_cache_ra() --> page_cache_ra_unbounded() --> read_pages() --> .readahead = ext4_readahead

댓글