Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

80258
1323
114582


[리눅스커널][가상파일시스템] 파일 객체: close() 함수 연산 세부 동작 분석 13. Virtual Filesystem

파일 객체: close() 함수 연산 세부 동작 분석

다음 파일을 닫을 때 호출하는 sys_close() 함수 코드를 볼 차례입니다.
1 SYSCALL_DEFINE1(close, unsigned int, fd)
2 {
3 int retval = __close_fd(current->files, fd);
4
5 /* can't restart close syscall because file table entry was cleared */
6 if (unlikely(retval == -ERESTARTSYS ||
7      retval == -ERESTARTNOINTR ||
8      retval == -ERESTARTNOHAND ||
9      retval == -ERESTART_RESTARTBLOCK))
10 retval = -EINTR;
11
12 return retval;
13}
14 EXPORT_SYMBOL(sys_close);

3번째 줄 코드를 보겠습니다.
3 int retval = __close_fd(current->files, fd);

__close_fd() 함수 코드를 잠깐 살펴보겠습니다.
[https://elixir.bootlin.com/linux/v4.14.70/source/fs/file.c]
1 int __close_fd(struct files_struct *files, unsigned fd)
2 {
3 struct file *file;
4 struct fdtable *fdt;
5
6 spin_lock(&files->file_lock);
7 fdt = files_fdtable(files);
8 if (fd >= fdt->max_fds)
9 goto out_unlock;
10 file = fdt->fd[fd];
11 if (!file)
12 goto out_unlock;
13 rcu_assign_pointer(fdt->fd[fd], NULL);

7번째 줄 코드에서 파일 객체로 파일 디스크립터 테이블을 로딩합니다.
7 fdt = files_fdtable(files);

이번에 13번째 줄 코드를 봅시다.
13 rcu_assign_pointer(fdt->fd[fd], NULL);

fd 배열에 해당하는 파일 디스크립터 테이블 멤버를 NULL로 초기화합니다.

이렇게 close() 함수를 호출하면 파일 객체를 관리하는 프로세스 태스크 디스크립터 자료구조에 접근한 후 파일 디스크립터에 해당하는 파일 객체를 해제합니다.

6~10번 코드는 예외 처리를 위한 코드 블록입니다.
6 if (unlikely(retval == -ERESTARTSYS ||
7      retval == -ERESTARTNOINTR ||
8      retval == -ERESTARTNOHAND ||
9      retval == -ERESTART_RESTARTBLOCK))
10 retval = -EINTR;

sys_close 시스템 핸들링 도중 시그널이 발생했을 때 ERESTARTSYS와 ERESTARTNOHAND 매크로를 도중 반환합니다. 그런데 3번째 줄 코드에서 파일 디스크립터를 해제했으므로 시그널 핸들러를 실행한 다음에 sys_close() 함수로 복귀할 수 없다는 의미입니다.


"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)


Reference(가상 파일시스템)

가상 파일시스템 소개
파일 객체
파일 객체 함수 오퍼레이션 동작
프로세스는 파일객체 자료구조를 어떻게 관리할까?
슈퍼블록 객체
아이노드 객체
덴트리 객체
가상 파일시스템 디버깅

핑백

덧글

댓글 입력 영역