# ext4: 읽기 요청이 캐시·직접 I/O·DAX로 나뉘는 이유

v6.18.37 / fs/ext4/file.c

ext4 파일을 읽는다고 모든 호출이 같은 길로 디스크에 도달하지는 않습니다. 파일의 inode와 열기 옵션에 따라 페이지 캐시를 사용하는 읽기, 직접 I/O, DAX로 나뉩니다. ext4_file_read_iter를 입구로 삼아 어떤 조건을 먼저 확인하고 어느 계층에 실제 읽기를 맡기는지 설명합니다. extent와 저널은 이 함수가 직접 처리하는 대상이 아니라 후속 경로와 파일시스템 구조를 이해할 때 연결할 개념입니다.

## ext4_file_read_iter

```c

static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
	struct inode *inode = file_inode(iocb->ki_filp);

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))
		return -EIO;

	if (!iov_iter_count(to))
		return 0; /* skip atime */

#ifdef CONFIG_FS_DAX
	if (IS_DAX(inode))
		return ext4_dax_read_iter(iocb, to);
#endif
	if (iocb->ki_flags & IOCB_DIRECT)
		return ext4_dio_read_iter(iocb, to);

	return generic_file_read_iter(iocb, to);
}

```

### 130행

```c

static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to)

```

비동기 I/O 제어 정보 iocb와 데이터를 받을 반복자 to를 받습니다. 반환값은 읽은 바이트 수 또는 음수 오류입니다.

### 132행

```c

	struct inode *inode = file_inode(iocb->ki_filp);

```

열린 파일에서 inode를 얻어 파일시스템 상태와 DAX 여부를 확인할 준비를 합니다.

### 134행

```c

	if (unlikely(ext4_forced_shutdown(inode->i_sb)))

```

파일시스템이 강제 종료 상태인지 검사합니다. unlikely는 분기 빈도에 대한 힌트이며 오류 판단 자체를 바꾸지 않습니다.

### 135행

```c

		return -EIO;

```

더 읽기를 진행하지 않고 I/O 오류를 반환합니다.

### 137행

```c

	if (!iov_iter_count(to))

```

목적지 반복자에 남은 요청 길이가 0인지 검사합니다.

### 138행

```c

		return 0; /* skip atime */

```

0바이트 읽기는 바로 성공값 0을 반환해 접근 시각 갱신도 생략합니다.

### 140행

```c

#ifdef CONFIG_FS_DAX

```

DAX는 지원 저장장치와 파일 시스템에서 페이지 캐시를 거치지 않고 메모리처럼 직접 접근하는 기능입니다. 이 설정은 DAX 분기를 빌드에 포함할지 정하고, 실제 파일이 DAX인지 여부는 다음 IS_DAX(inode)가 별도로 검사합니다. 이 선택은 전처리 단계에서 이루어지며, CPU가 실행 중 이 줄의 조건을 검사하지 않습니다.

### 141행

```c

	if (IS_DAX(inode))

```

이 inode가 실제 DAX 방식으로 동작하는지 확인합니다. 빌드 지원만으로 모든 파일이 DAX가 되는 것은 아닙니다.

### 142행

```c

		return ext4_dax_read_iter(iocb, to);

```

DAX 전용 읽기에 동일한 요청과 목적지를 전달하고 그 결과를 반환합니다.

### 143행

```c

#endif

```

DAX 조건부 코드는 여기서 끝납니다.

### 144행

```c

	if (iocb->ki_flags & IOCB_DIRECT)

```

이 I/O 요청에 직접 I/O 플래그가 있는지 확인합니다.

### 145행

```c

		return ext4_dio_read_iter(iocb, to);

```

ext4의 직접 I/O 읽기로 전달합니다. 정렬 및 후속 처리는 그 경로에서 확인해야 합니다.

### 147행

```c

	return generic_file_read_iter(iocb, to);

```

특별 경로가 아니면 공통 파일 읽기 구현으로 넘겨 페이지 캐시를 사용하는 읽기를 진행합니다.

