Presentation is loading. Please wait.

Presentation is loading. Please wait.

리눅스 커널의 이해 중에서 12장. 가상 파일 시스템 김석훈 시스템 소프트웨어 실험실.

Similar presentations


Presentation on theme: "리눅스 커널의 이해 중에서 12장. 가상 파일 시스템 김석훈 시스템 소프트웨어 실험실."— Presentation transcript:

1 리눅스 커널의 이해 중에서 12장. 가상 파일 시스템 김석훈 시스템 소프트웨어 실험실

2 목차 Part I : VFS의 역할 Part II : VFS 자료 구조 Part III : 파일 시스템 마운트하기
Part V : VFS 시스템 콜 구현 Part Ⅵ : 파일 락킹

3 Part I : VFS의 역할

4 $ cp /floppy /TEST / tmp /test
VFS의 역할 가상 파일 시스템(VFS:Virtual File System) 표준 유닉스 파일시스템과 관련한 모든 시스템 콜을 처리하는 kernel software layer 실제 파일 시스템의 구현과 사용자 프로세스 사이에 존재하는 추상화 계층 다른 여러 종류의 파일시스템에 일반적인 공통 인터페이스를 제공 cp VFS Ext2 MS-DOS /tmp/test /floppy/TEST int = open(“/floppy/TEST”, O_RDONLY, 0); outf = open(“/tmp/test”, O_WRONLY|O_CREATE|O_TRUNC, 0600); do { l = read(inf, buf, 4096); write(outf, buf, l); } while (l); close(outf); close(inf); $ cp /floppy /TEST / tmp /test MS_DOS 디스켓 마운트 포인트 일반 Ext2 디렉토리 P.468 단순한 파일 복사 작업을 위한 VFS의 역할 프로세스와 VFS 객체의 상호 작용

5 VFS의 역할 VFS 전체구조 System call interface Virture File system proc ext2
tasks System call interface Virture File system proc ext2 vfat proc Disk Driver machine

6 VFS의 역할 VFS에 지원되는 파일시스템 3가지 그룹 디스크 기반 파일시스템 네트워크 파일시스템 특수 파일시스템
로컬 디스크 파티션의 기억 장소를 관리 하드디스크, 플로피, 씨디롬 같은 블록 디바이스에 저장 리눅스는 /dev/loop0와 같은 가상 블록 장치도 핸들 할 수도 있다 ext, ext2, msdos, vfat, ntfs, iso9660, hpfs, hfs, fffs, adfs등의 filesystem 지원 네트워크 파일시스템 다른 네트워크의 컴퓨터에 속한 파일 시스템에 쉽게 접근할 수 있음 VFS 지원 네트워크 파일 시스템 : NFS, Coda, AFS, SMB, NCP 특수 파일시스템 /proc filesystem은 사용자가 커널 데이터 구조의 내용에 접근할 수 있는 간단한 interface를 제공 /dev/pts filesystem은 Open Group’s Unix98표준에 기술된 가상 터미널을 지원하는데 사용

7 VFS의 역할 공통 파일 모델(The common File Model) VFS의 핵심 개념으로서 모든 파일시스템 표현
전형적인 유닉스 파일 시스템에서 제공하는 파일 모델을 반영 Specific filesystem은 자신의 물리적인 구조를 VFS의 공통 파일 모델로 변환시켜 구현 공통 파일 모델에서 각 디렉토리는 파일 리스트와 기타 디렉토리를 포함한 일반 파일로 간주 몇몇 비 유닉스 계열의 디스크 기반 파일시스템 디렉토리 트리에 각 파일이 있는 파일 할당 테이블(FAT)를 사용 이 디렉토리들은 파일이 아닌데, 리눅스에서는 FAT-based filesystem을 필요할 때 디렉토리와 유사한 파일을 즉석으로 구현 이러한 파일은 커널 메모리에 객체로만 존재

8 VFS의 역할 공통 파일 모델 read () write()
어플리케이션 read() 호출  커널이 sys_read() 호출 MS DOS  file  f_op  read(…) write() 출력 파일에 대응하는 적당한 Ext2 쓰기 함수 실행 함수 포인터 할당f_op 필드가 가리키는 각 파일시스템별 호출 실행 File은 Object-oriented(data structure+method) 효율성 문제로 객체지향을 쓰지 않음 객체의 methods와 비슷한 function을 가리키는 Data structure로써 객체를 구현

9 VFS의 역할 공통 파일 모델 공통 파일 모델 구성하는 객체 유형
The superblock object : 마운트시킨 파일 시스템 정보를 저장 disk-based filesystem을 위해서 이 object는 보통 disk에 저장된 filesystem control block에 해당 The inode object : 특정 파일에 대한 일반 정보를 저장 각 object는 inode number를 가짐 The file object : 열린 파일과 프로세스 사이의 상호 작용과 관련한 정보 저장 이 정보는 단지 각 프로세스가 파일을 접근한 동안만 kernel memory에 존재 The dentry object : 디렉토리 항목과 대응하는 파일간 연결에 대한 정보 저장 각 디스크 기반 파일 시스템에서는 독특한 방법으로 정보를 디스크에 저장

10 VFS의 역할 파일 객체 수퍼블록 객체 아이노드 객체 디스크 파일 프로세스 1 디엔드리 객체 프로세스 2 프로세스 3
디스크 파일 fd 프로세스 2 프로세스 3 수퍼블록 객체 아이노드 객체 디엔드리 객체 f_dentry d_inode i_sb Dentry cache P.472 프로세스와 VFS 객체의 상호 작용

11 VFS의 역할 VFS가 처리하는 시스템 콜 파일 시스템, 일반 파일, 디렉토리, 심볼릭 링크를 대상 시스템 콜 이름 설 명
설 명 mount ( ) umount ( ) sysfs ( ) stafs ( ) fstatfs ( ) ustat ( ) chroot ( ) chdir ( ) fchdir ( ) getcwd ( ) mkdir ( ) rmdir ( ) getdents( ) readdir( ) link( ) unlink( ) rename ( ) readlink( ) symlink( ) chown ( ) fchown ( ) lchown ( ) chmod ( ) fchmod ( ) utime ( ) stat ( ) fstat ( ) lstat ( ) access ( ) open( ) close ( ) creat ( ) umask ( ) dup ( ) dup2 ( ) fcnt ( ) Select ( ) poll ( ) truncate ( ) fruncate ( ) lseek ( ) _llseek ( ) read ( ) write ( ) readv ( ) writev ( ) sendfile ( ) pread ( ) pwrite ( ) nmap ( ) munmap ( ) fdatasync( ) fsync ( ) sync ( ) msync ( ) flock ( ) 파일 시스템의 마운트/언마운트 파일 시스템 정보 얻음 파일 시스템 통계를 얻음 루트 디렉토리 변경 현재 디렉토리 변경 디렉토리 생성과 삭제 디렉토리 항목 처리 소프트 링크 처리 파일 소유자 변경 파일 속성 변경 파일 상태 읽음 파일을 열고 닫음 파일 디스크립터 처리 비동기적 입출력 알림 파일 크기 변경 파일 포인터 변경 파일 입출력 연산 파일 탐색과 접근 파일 메모리 매핑 파일 데이터 동기화 파일 락 처리 P.473 VFS가 처리하는 시스템 콜

12 Part II : VFS 자료구조

13 VFS 자료구조 수퍼블록 객체 수퍼블록 객체는 super_block 구조체 유형으로 구성 유 형 필 드 설 명
설 명 struct list_head kdev_t unsigned long unsigned char struct file_system_type * struct super_operations * struct dquot_operations * struct dentry * struct wait_queue * struct inode * short int union s_list s_dev s_blocksize s_blocksize_bits s_lock s_rd_only s_dirt s_type s_op dq_op s_flags s_magic s_time s_root s_wait s_ibasket s_ibasket_count s_ibasket_max s_dirty u 수퍼블록 리스트 포인터 장치 식별자 블록 크기 (바이트 단위) 블록 크기 (비트 단위) 락 플레그 읽기 전용 플래그 변경된 플래그 파일 시스템 유형 수퍼블록 메소드 디스크 할당 메소드 마운트 플래그 파일시스템 매직 넘버 마지막 수퍼블록 변경시간 마운트 디렉토리 디엔트리 객체 마운트 대기 큐 향후 개발 변경된 아이노드 리스트 특정 파일시스템 정보 P. 475 수퍼블록 객체 항목

14 VFS 자료구조 수퍼 블록 객체 마운트된 파일시스템마다 하나씩 superblock object가 존재
모든 superblock object는 circular doubly linked list로 연결 List field 처음과 끝은 super_blocks 변수의 s_list의 next와 prev에 저장 s_list next prev super_blocks 슈퍼 블록 P.476 수퍼블록 리스트

15 VFS 자료구조 U field 각 파일시스템에 포함된 superblock 정보를 포함
일반적으로 u field에 있는 data는 memory에 복사 VFS는 이들 파일시스템이 disk 접속 없이 바로 메모리에 있는 superblock의 u field에서 수행가능 하도록 함 문제점 disk의 superblock과 memory에 있는 superblock을 동기화 시켜야 하는 새로운 문제가 발생 이를 위해 superblock이 dirty한지를 나타내는 s_dirt flag가 필요

16 VFS 자료구조 수퍼블록 연산(superblock operations) superblock에 관련된 method
super_operations 구조체로 표현 구조체 주소를 s_op 필드에 저장 수퍼블록 연산 테이블 read_inode(inode) inode object의 field를 채움 write_inode(inode) parameter로 넘겨준 inode object의 내용을 가지고 filesystem inode를 갱신 inode object의 i_ino field는 관련된 disk에 있는 inode를 명시 put_inode(inode) inode object를 해제 delete_inode(inode) data block과 disk inode, VFS inode를 제거

17 VFS 자료구조 notify_change(dentry, iattr) put_super(super)
iattr 매개변수에 따라 inode의 속성 변경 put_super(super) 매개변수로 넘겨준 주소의 superblock object를 해제 write_super(super) 지정한 객체내용으로 superblock object를 갱신 statfs(super, buf, bufsize) buf buffer를 채우고 filesystem의 통계정보를 리턴 remount_fs(super, flags, data) 새로운 옵션을 가지고 filesystem을 다시 마운트 clear_inode(inode) put_inode과 같다. 또한 file에 관련된 data의 내용을 해제 umount_begin(super) mount operation을 interrupt한다. 이는 단지 network filesystem에서 사용

18 VFS 자료구조 인덱스노드 객체 파일을 처리하기 위해 filesystem에 필요한 모든 정보는 inode에 포함
memory에 있는 inode object는 inode 구조체로 구성 inode는 유일하며 파일이 존재하는 만큼 오래 남음 circular doubly linked list로 구성 unused inode의 list : 이 list의 처음과 마지막은 inode_unused변수의 next와 priv에 저장되고, 이 list는 memory cache처럼 수행 in-use inode의 list : 이 list의 처음과 마지막은 inode_in_use변수에 의해 참조 dirty inode의 list : 이 list의 처음과 끝은 superblock object의 s_dirty에 의해 참조 “in use”혹은 “dirty” list에 속하는 Inode 객체는 hash table에 포함 Hash table은 커널이 inode number와 superblock의 주소를 알때 inode 객체를 검색하는 속도가 향상

19 VFS 자료구조 인덱스노드 객체 유 형 필 드 설 명 유 형 필 드 설 명 P.479 인덱스노드 객체 필드
설 명 유 형 필 드 설 명 struct list_head unsigned long unsigned int kdev_t umode_t nlink_t uid_t gid_t off_t time_t struct semaphore i_hash i_list i_dentry i_ino i_count i_dev i_mode i_nlink i_uid i_gid i_rdev i_size i_atime i_mtime i_ctime i_blksize i_blocks i_version i_nrpages i_sem i_automic_write 해시 리스트 포인터 아이노드 리스트 포인터 디엔트리 리스트 포인터 아이노드 번호 사용 카운터 장치 식별자 파일 유형과 접근 권한 하드 링크 개수 소유자 식별자 그룹 식별자 실제 장치 식별자 파일 길이(바이트 단위) 최종 파일 접근 시간 최종 파일 기록 시간 최종 아이노드 변경 시간 블록 크기(바이트 단위) 파일 블록 수 버전 번호 파일 자료 포함하는 페이지수 아이노드 세마포어 struct inode_operations* struct super_block* struct wait_queue* struct file_lock* struct vm_area_struct* struct page* struct dquot** unsigned long unsigned int unsigned char int _ _u32 union i_op i_sb i_wait i_flock i_mmap i_pages i_dquot i_state i_flags i_pipe i_sock i_writecount i_attr_flags i_generation u 아이노드 연산 수퍼블록의 객체포인터 아이노드 대기 큐 파일 락 리스트 포인터 파일 맵을 위해 사용하는 메모리 영역 포인터 페이지 디스크립터 포인터 아이노드 디스크 할당량 아이노드 상태 플래그 파일시스템 마운트 플래그 파일이 파이프이면 참 쓰기 중인 프로세스 사용 카운터 파일 생성 플래그 향후 개발을 위해 예약 특정 파일시스템 정보 P.479 인덱스노드 객체 필드

20 VFS 자료구조 인덱스노드 연산(inode_operations) inode에 관련된 method 인덱스노드 연산 테이블
create(dir, dentry, mode) 새로운 disk inode를 생성 lookup(dir, dentry) dentry object에 포함된 filename에 대응하는 inode를 위해 directory를 탐색 link(old_dentry, dir, new_dentry) dir에서 old_dentry에 의해 지정된 file을 참조하는 새로운 hard link를 생성 새 hard link는 new_dentry라는 이름을 사용 unlink(dir, dentry) dir로부터 dentry object에 의해 지정된 file의 hard link를 삭제 symlink(dir, dentry, symname) 같은 directory에 있는 dentry object를 가지는 symbolic link를 위한 새로운 inode를 생성 mkdir(dir, dentry, moder) 새로운 inode를 생성 rmdir(dir, dentry) dentry object에 포함된 이름의 subdirectory를 삭제 mknod(dir, dentry, mode, rdev) 새로운 disk inode를 생성, mode와 rdev는 file type과 device의 major number 지정

21 VFS 자료구조 rename(old_dir, old_dentry, new_dir, new_dentry)
디렉토리 내부에서 디엔트리 객체가 나타내는 심볼릭 링크를 위해 새로운 아이노드 생성 readlink(dentry, buffer, buflen) buffer에 dentry에 명시된 symbolic link에 대응하는 file pathname을 복사 follow_link(inode, dir) inode object에 지정된 symbolic link를 변환 readpage(file, pg) 열린 파일에서 자료를 한 페이지 읽어온다. writepage(file, pg) 자료 한 페이지를 열린 파일에 기록한다. bmap(inode, block) inode와 관련된 파일의 file block number에 대응하는 logical block number를 return. truncate(inode) inode에 있는 file의 크기를 수정 permission(inode, mask) file에 특정 access mode가 허용되는지 check. smap(inode, sector) 디스크 섹터 번호 결정 updatepage(inode, pg, buf, offset, count, sync) 아이노드가 나타내는 파일 자료 한 페이지를 갱신 revalidate(dentry) dentry object에 의해 지정된 파일의 cache attribute를 갱신

22 VFS 자료구조 파일 객체(File object) process가 opened file과 어떻게 상호작용을 하는지를 나타냄
파일이 열릴 때 생성되고, file structure로 구성 disk의 image와 관련이 없기 때문에 dirty field가 없음 몇몇 프로세스들이 같은 파일을 동시에 access할 수 있음 각 file 객체는 다음의 Circular doubly linked list중 하나를 포함 “unused” 파일 객체의 리스트 파일 객체를 위한 메모리 캐쉬와 superuser를 위한 예약에 작용하는 list object가 unused이면 f_count는 null, 이 list의 처음은 free_filps 변수에 저장 superuser가 시스템에 있는 동적메모리를 모두 썼다 하더라도 파일을 오픈 하도록 해 준다. “in use” 파일 객체 리스트 리스트의 각 element는 프로세스에 의해 적어도 한번은 사용 f_count는 null이 아니다. list의 처음은 inuse_filps변수에 저장

23 VFS 자료구조 파일 객체 유 형 필 드 설 명 struct file* struct dentry*
설 명 struct file* struct dentry* struct file_operations* mode_t loff_t unsigned int unsigned long struct fown_struct int void* f_next f_pprev f_dentry f_op f_mode f_pos f_count f_flags f_reada f_ramax f_raend f_ralen f_rawin f_owner f_uid f_gid f_error f_version private_data 다음 파일 객체 포인터 이전 파일 객체 포인터 디엔트리 객체와 관련한 포인터 파일 연산 테이블의 포인터 프로세스 접근 모드 현재 파일 오프셋(파일 포인터) 파일 객체의 사용 카운터 파일을 열때 지정된 플래그 미리 읽기 플래그 미리 읽기 페이지의 최대 수 마지막 미리 읽기 후 파일 포인터 미리 읽기 바이트 수 미리 읽기 페이지 수 시그널을 통한 비동기적 입출력을 위한 데이터 사용자 UID 사용자 GID 네트워크 쓰기 연산을 위한 에러 코드 버전 번호, 매번 사용 후마다 자동 증가 tty 드라이버용으로 필요 P.483 파일 객체 필드

24 VFS 자료구조 파일 연산(file_operations) 파일에 관련된 method 파일 연산 테이블
llseek(file, offset, whence) file pointer를 갱신 read(file, buf, count, offset) file에서 *offset 위치부터 count 바이트만큼 읽는다. write(file, buf, count, offset) *offset 위치부터 count 바이트만큼 파일에 쓴다. readdir(dir, dirent, filldir) dirent의 다음 diretory를 리턴 poll(file, poll_table) 어떤 일이 발생할 때까지 file이 activity인지, sleep인지 검사 ioctl(inode, file, cmd, arg) 하드웨어 장치에 명령을 전송

25 VFS 자료구조 mmap(file, vma) open(inode, file) flush(file)
프로세스의 주소 공간에 파일 메모리 매핑을 수행 open(inode, file) 새로운 파일 객체를 생성하고 이를 대응하는 아이노드 객체에 연결하여 파일을 open flush(file) open file이 close될 때, f_count 필드 값이 감소할때 호출 release(inode, file) file object를 해제, open file의 마지막 참조를 닫을때, 파일 객체의 f_count가 0일때 호출 fsync(file, dentry) 모든 cached data를 disk에 기록하고 저장 fasync(file, on) 비동기 적인 입출력 공지 기능(asynchronous I/O notification)을 활성화 또는 비활성화 check_media_change(dev) media의 변화가 있는지 검사 revalidate(dev) device의 일관성(consistency)을 복구 lock(file, cmd, file_lock) file에 lock을 적용

26 VFS 자료구조 디렉토리 파일 객체에 대한 특수 처리 각 프로세스가 자신의 내용을 동시에 변경하려 할 때 문제 발생
일반적인 파일에서 자주 수행하는 명시적 locking은 locked된 디렉토리의 subtree 전체에 다른 프로세스들의 접근을 막기때문에 디렉토리에서는 적당하지 않다. 따라서 파일 객체의 f_version 필드는 각 디렉토리 파일을 일관성 있게 관리하기 위하여 inode객체의 i_version 필드와 함께 사용 readdir() system call 이것을 호출하면 디렉토리 요소가 리턴 디렉토리 파일 포인터를 갱신허여 다음 시스템 콜에 대한 디렉토리 엔트리를 반환 동시에 접근하려는 다른 프로세스에 의해 디렉토리는 수정 가능 무결성 검사를 하지 않으면 readdir() 시스템 call은 잘못된 디렉토리 entry 를 리턴 프로세스는 readdir()을 여러 번 호출, 긴시간 간격으로 호출 언제든지 프로세스가 호출을 멈출 수도 있으모로 디렉토리 잠금 불가

27 VFS 자료구조 readdir()를 변화에 적응하도록 수정
이 문제를 해결하기 위해서 version stamp역할을 하는 global_event 변수를 이용 디렉토리 파일의 inode객체가 변경될때마다, global_event는 1이 증가하고, 새로운 version stamp는 객체의 i_version field에 저장 파일 객체가 생성되거나 파일 포인터가 변경될 때마다 global_event는 1이 증가하고, new version stamp는 객체의 f_version field에 저장된다. Readdir() system call이 수행될때, VFS는 i_version과 f_version field에 포함된 version stamp가 일치하는지를 체크 만약 그렇지 않다면 디렉토리는 readdir()의 수행이전의 명령을 수행한 후에 다른 프로세스에 의해 변경되었을 수 있음

28 VFS 자료구조 readdir()의 지속적인 문제 발생 전체 디렉토리를 다시 읽음으로써 디렉토리의 파일 포인터를 재계산
system call은 프로세스의 마지막 readdir()에 의해 리턴된 entry의 다음 값으로 즉시 디렉토리 entry를 리턴 f_version은 readdir()이 실제 디렉토리 상태로 동기화된 것을 가리키기 위해 i_version으로 설정

29 VFS 자료구조 디엔트리 객체 디렉토리 entry를 메모리에서 읽으면, VFS에 의해서 dentry structure의 dentry 객체가 바뀜 프로세스가 찾은 경로의 각각의 component로 구성된 Dentry 객체는 커널에 의해 생성 Dentry 객체는 inode와 유사한 구성요소와 연결 /tmp/test 경로명을 찾을 때 커널은 /디렉토리를 위해 dentry 객체를 생성 두번째 /디렉토리의 tmp entry를 위한 dentry 객체를 생성 세번째 /tmp 디렉토리의 test entry를 위한 dentry 객체를 생성 Dentry 객체는 디스크에 대응하는 이미지가 없음 dentry구조체에는 변경된 객체를 나타내는 field가 없음 Dentry 객체는 dentry_cache라고 불리는 slab allocator cache에 저장 dentry 객체는 kmem_cache_alloc()와 kmem_cache_free()에 의해 생성과 소멸

30 VFS 자료구조 디엔트리 객체 유 형 필 드 설 명 int unsigned int struct inode*
설 명 int unsigned int struct inode* struct dentry* struct list_head struct qstr unsigned long structdentry_operations* struct super_block* void* unsigned char d_count d_flags d_inode d_parent d_mounts d_covers d_hash d_lru d_child d_subdirs d_alias d_name d_time d_op d_sb d_reftime d_fsdata d_iname[16] 디엔트리 객체 사용 카운터 디엔트리 플래그 파일명과 관련한 아이노드 부모 디렉토리의 디엔트리 객체 마운트 포인터의 경우, 마운트된 파일 시스템 루트의 디엔트리 파일시스템 루트의 경우, 마운트 포인트의 디엔트리 해시 테이블 엔트리 내 리스트 포인터 쓰지않는 리스트 포인터 부모 디렉토리에 포함된 디엔트리 디엔트리 객체 리스트의 포인터 디렉토리의 경우, 서브 디렉토리의 디엔트리 객체 포인터 관련 아이노드 리스트 파일명 d_revaliate 메소드에서 사용 디엔트리 메소드 파일의 수퍼블록 객체 디엔트리가 제거된 시간 파일시스템에 따른 데이터 짧은 파일명(영문 15자까지) 공간 P.488 디엔트리 객체

31 VFS 자료구조 Dentry object의 4가지 상태 해제(Free) 사용하지 않음(Unused) 사용중 (Inuse)
해당 메모리 역역은 슬랩 할당자(slab allocator)에 의해 처리 사용하지 않음(Unused) 현재 커널에서 사용되지 않음 d_count는 0이고, d_inode는 여전히 관련된 inode를 가리킴 유효한 정보를 유지하지만, 그 내용은 삭제될 수 있다. 사용중 (Inuse) 현재 커널에 의해 사용 d_count 사용 카운터는 양수, d_inode 필드는 연관된 아이노드 객체를 가리킴 유효한 정보를 유지하지만 이를 제거할 수 없다. 음수 (Negative) dentry와 관련된 inode가 더 이상 존재하지 않고 d_inode는 null로 설정 같은 file pathname에 대해 탐색 연산을 빨리 해결하기 위해 여전히 dentry cache에 남아있음

32 VFS 자료구조 디엔트리 캐시 disk로부터 directory entry를 읽고, 대응하는 dentry object를 구성
Dentry object의 사용이 끝났다 할지라도 나중에 또 필요(반복적인 접근)하게 되므로 메모리에 dentry object를 유지할 필요가 있음 Dentry Cache의 효율을 위한 데이터 구조 2가지 In-use, unused, negative state에 대한 dentry객체의 집합 Unused : double linked list – LRU (Least Recently Used) In use : double linked list – hard links도 포함됨 Negative : 마지막 hard link가 지워지면 unused의 LRU로 옮겨짐 Hash table 파일이름과 디렉토리가 주어지면 연관된 dentry객체를 빨리 찾아줌 만약 요구한 object가 cache에 없다면, 해시 함수는 null을 리턴

33 VFS 자료구조 디엔트리 연산 디엔트리 객체와 관련된 메소드 d_revalidate(dentry)
dentry object가 여전히 유효한지 결정 d_hash(dentry, hash) hash value 생성 d_compare(dir, name1, name2) 두 filename을 비교 d_delete(dentry) dentry object의 마지막 참조를 delete할 때 call, d_count는 0이 된다. d_release(dentry) dentry object가 free될 때 call d_input(dentry, ino) dentry object가 “negative”될 때 call. 즉, inode를 잃어버린다.

34 VFS 자료구조 프로세스와 관련한 파일 프로세스
자신의 현재 working directory와 root directory를 가짐 fs_struct 커널 구조에서 이 정보를 저장 프로세스 디스크립터의 fs 필드에 저장 struct fs_struct { atomic_t count; //fs_struct 테이블 공유하는 프로세스 개수 int umask; // 새로 만든 파일에 대한 초기 파일 접근 권한 설정 struct dentry * root, * pwd; };

35 VFS 자료구조 프로세스와 관련한 파일 유 형 필 드 설 명 int struct file** fd_set* fd_set
설 명 int struct file** fd_set* fd_set truct file* count next_fds max_fdset next_fd fd close_on_exec open_on_exec_init open_fds_init fd_array[32] 이 테이블을 공유하고 있는 프로세스 개수 현재 파일 객체의 최대 개수 현재 파일 디스크립터의 최대 개수 지금까지 할당된 파일 디스크립터의 최대값+1 파일 객체 포인터의 배열 포인터 exec( )에서 닫혀질 파일 디스크립터를 가리키는 포인터 열린 파일 디스크립터의 포인터 파일 디스크립터의 초기 집합 파일 객체 포인터의 초기 배열 P.493 files_struct 구조체 필드

36 VFS 자료구조 프로세스와 관련한 파일 파일 객체 fd stdin 0 파일 객체 stdout 1 파일 객체 stderr 2 3
4 . 인덱스 0 : 프로세스의 표준 입력과 관계 인덱스 1 : 표준 출력과 관계 인덱스 2 : 표준 에러와 관계 P.494 fd 배열

37 Part III : 파일 시스템 마운트하기

38 파일 시스템 마운트하기 파일시스템을 사용하기 전에 수행하는 2가지 작업 등록(Registration) 마운트(Mounting)
system boot 혹은 파일시스템을 구현하는 모듈을 load할때 이루어짐 파일 시스템이 등록되면, 여러 종류의 파일 시스템이 시스템 디렉토리 트리에 마운트 할 수 있게 됨 마운트(Mounting) 각 파일 시스템은 자신의 root directory가 있음 어떤 파일시스템의 루트 디렉토리가 시스템 디렉토리 트리의 root일때 root filesystem이라고 함 다른 파일 시스템을 시스템 루트 디렉토리에 속한 서브 트리에 마운트 마운트하여 삽입하는 디렉토리 : 마운트 포인트(mount point) 시스템이 boot할때 root filesystem의 major number를 찾는다. 커널 컴파일이나 boot strap loader가 초기화 될 때 /dev에 명시

39 파일 시스템 마운트하기 파일 시스템 등록 유저는 kernel을 컴파일할 때 필요한 모든 파일시스템을 인식하도록 설정
파일시스템을 위한 코드는 실제로 커널이미지에 포함되거나 모듈로 로드 VFS는 모든 파일시스템의 트랙을 유지 filesystem registration을 수행함으로써 이뤄짐 struct file_system_type { const char *name; int fs_flags; struct super_block *(*read_super) (struct super_block *, void *, int); struct file_system_type * next; file_system_type 객체

40 파일 시스템 마운트하기 파일 시스템 등록 system을 초기화
filesystem_setup()은 compile time시 지정된 파일시스템을 등록 각 파일시스템을 위해 register_filesystem()은 file_system_type object를 가리키는 매개변수를 가지고 호출하고 filesystem-type list에 들어가게 된다. register_filesytem()은 filesystem을 실행하는 모듈이 로드될 때도 호출 get_fs_type()은 filesystem name을 매개변수로 받아서 등록된 파일시스템을 탐색 대응하는 file_system_type object가 존재하는 경우 pointer를 리턴

41 파일 시스템 마운트하기 루트 파일시스템 마운트하기
시스템을 초기화하는 동안 filesystem_setup()후에 바로 mount_root() 함수를 실행 dummy(local file object filp)를 초기화, f_mode field는 root의 mount flag에 의해 설정되고, 나머지 field는 0으로 설정 dummy inode object를 생성, i_rdev를 ROOT_DEV에 설정하여 초기화 dummy inode와 file object를 넘겨주고 blkdev_open()을 호출 dummy inode object를 해제 filesystem-type list를 scan, 각 file_system_type object에 대해서 일치하는 superblock을 읽기 위해서 read_super()를 호출 read_super()는 root directory를 위한 inode object와 dentry object를 생성 current의 fs_struct table의 root와 pwd field를 root directory의 dentry object로 초기화 마운트시킨 filesystem list에 첫번째 요소를 삽입하기 위해 add_vfsmnt()를 호출

42 파일 시스템 마운트하기 일반 파일시스템 마운트하기 root filesystem을 초기화
추가적으로 다른 filesystem도 mount될 수 있고 이들 각각은 자신의 mount point를 가지고 있어야 함 모든 mount된 filesystem들은 list에 포함되고 list의 첫번째 element는 vfsmntlist변수에 의해 참조 각 element는 vfsmount 유형의 구조체 struct vfsmount { kdev_t mnt_dev; /* Device this applies to */ char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ char *mnt_dirname; /* Name of directory mounted on */ unsigned int mnt_flags; /* Flags of this device */ struct super_block *mnt_sb; /* pointer to superblock */ struct quota_mount_options mnt_dquot; /* Diskquota specific mount options */ struct vfsmount *mnt_next; /* pointer to next in linkedlist */ }; P.498 vfsmount 자료 구조

43 파일 시스템 마운트하기 일반 파일시스템 마운트하기 add_vfsmnt()와 remove_vfsmnt()
list에서 element를 추가하고 삭제하기 위해 사용 lookup_vfsmnt() mount된 filesystem을 찾고, 일치하는 vfsmount 자료구조 주소를 반환 sys_mount() 매개변수 파일시스템 포함하는 device file의 경로명 파일시스템 마운트할 directory의 경로명 filesystem type mount flags filesystem-dependent 자료구조 pointer

44 파일 시스템 마운트하기 일반 파일시스템 마운트하기 매크로 값 설 명 MS_MANDLOCK MS_NOATIME MS_NODEV
설 명 MS_MANDLOCK MS_NOATIME MS_NODEV MS_NODIRATIME MS_NOEXEC MS_NOSUID MS_RDONLY MS_REMOUNT MS_SYNCHRONOUS S_APPEND S_IMMUTABLE S_QUOTA 0x040 0x400 0x004 0x800 0x008 0x002 0x001 0x020 0x010 0x100 0x200 0x080 강제적 락 허용 파일 접근 시간을 갱신하지 않음 장치 파일에 대한 접근 금지 디렉토리 접근 시간을 갱신하지 않음 프로그램 실행 금지 setuid, setgid 플래그 금지 파일을 읽을 수만 있음 파일시스템을 다시 마운트 쓰기 연산을 즉시 실행함 파일 뒤에 추가만 허용 파일 변경 허용하지 않음 디스크 할당량 초기화 P.498 파일시스템 마운트 옵션

45 파일 시스템 마운트하기 일반 파일 시스템 마운트하기 sys_mount()
process가 filesystem을 mount하기위해 필요한 권한을 가지는지 검사 MS_REMOUNT이면, 종료하고 mount flag를 변경하기 위해 do_remount()를 수행 get_fs_type()을 호출하여 file_system_type object의 pointer를 얻음 filesystem이 /dev/hda1과 같은 device를 mount한다면, 그 device가 존재하고 운영가능한지를 검사 일치하는 device file의 dentry object를 얻기 위해 namei()를 호출 device와 관련된 inode가 유효한 block device를 참조하는지 검사 device file을 참조하는 dummy file object를 초기화 한후 device file을 open mount된 파일시스템이 hardware device를 참조하지 않는다면 get_unnamed_dev()를 호출해서 주 번호 0인 가상 블록 장치를 얻음

46 파일시스템 마운트하기 일반 파일 시스템 마운트하기 Sys_mount()
Do_mount()…필요한 파일시스템을 마운트 하기위해 실행 dir_name과 유사한 dir_d dentry object가 위치한 namei() 호출 (a) 연속된 마운트와 언마운트를 위한 mount_sem 세마포어가 실행 dir_dd_inode가 디렉토리의 inode인지 검사하고, 이미 마운트 된 디렉토리는 파일시스템의 루트가 아닌지 검사 새로운 파일시스템의 superblock object sb를 얻기 위해 read_super() 호출 superblock object의 s_root 필드는 마운트된 파일시스템의 루트 디렉토리의 dentry object를 가리킨다.(b) 다른 프로세스가 superblock를 사용하지 않는지, 프로세스가 이미 같은 파일시스템에 마운트 되지 않았는지 검사 마운트 파일시스템의 list에 새로운 element를 삽입하기 위해 Add_vfsmnt() 호출 root 디렉토리에 파일시스템을 마운트하기 위해, superblock의 s_root field에 dir_d의 d_mounts field를 설정 dir_d에 마운트된 파일시스템의 root디렉토리의 dentry 객체의 d_covers field를 설정(c) mount_sem 세마포어를 해제

47 파일시스템 마운트하기 s_root “/” d_mounts sb dir_d dir_name d_covers (a) (b) (c)
마운트 직전 시스템 디렉토리 트리 dir_d d_mounts d_covers dir_name “/” (a) sb s_root 마운트될 파일시스템 (b) 마운트 직후 시스템 디렉토리 트리 (c) 수퍼블록 객체 디엔드리 객체 디엔드리 서브트리 P.501 파일시스템 마운트하기

48 파일시스템 마운트하기 파일시스템 언마운트하기 sys_umount()
프로세스가 filesystem을 언마운트 할 수 있는지 검사 Dentry 객체에 연관된 dentry pointer를 얻기위해 filename에 Namei()를 호출 filename이 mount point를 참조하면, dentryd_inodei_sbs_dev에서부터 장치 식별자를 얻음 filename이 device file을 참조하면, dentryd_inodei_rdev에서부터 장치 식별자를 얻음 Dentry object를 해제하기 위해 dput()을 호출 장치의 버퍼를 flush한다. mount_sem 세마포어를 획득

49 파일시스템 마운트하기 파일시스템 언마운트하기 Sys_umount() Do_umount()
마운트 된 파일시스템 Superblock의 sb pointer를 얻기 위해 Get_super()를 호출 dev 장치를 참조한 Dentry object를 제거하기 위하여 Shrink_dcache_sb()를 호출 dev장치를 참조한 모든 “dirty” 버퍼를 Disk에 쓰기 위한 Fsync_dev()를 호출 만약 dev가 root device이면 unmount 할 수 없음 언마운트 된 파일시스템의 root 디렉토리와 일치하는 Dentry object의 counter가 1보다 큰지 아닌지 검사 sbs_rootd_covers의 카운터를 감소시킨다. sbs_rootd_coversd_mounts를 sbs_rootd_covers로 설정. 파일시스템의 root디렉토리 inode를 가리키는 inode link를 삭제 sbs_root point와 sbs_root를 NULL로 설정하기 위해, Dentry object를 해제 만약 superblock가 변경되었고 write_super superblock의 method가 정의 된다면 superblock의 put_super() method를 수행 sbs_dev를 0으로 설정 마운트된 파일시스템의 list로부터 해당 항목을제거시키는 remove_vfsmnt() 호출 dev장치에 참조하기 위해 모든 “dirty” buffer에 남아 있는 디스크에 쓰기 위해, F_fsync_dev() 호출 mount_sem세마포어를 해제

50 Part IV : 경로명 탐색

51 경로명 탐색 프로세스는 open(), mkdir(), rename(), stat()와 같은 VFS시스템 콜을 수행하려면 파일을 확인 만약 pathname이 절대경로인 /이면, currentfsroot로부터 디렉토리를 찾기 시작 상대경로이면 currentfspwd로부터 디렉토리를 찾기 시작 초기 디렉토리의 inode를 가지고 있으면 code는 일치하는 inode의 첫번째 이름과 맞는지 entry를 조사 디렉토리 파일은 inode를 disk로 부터 읽고, 일치하는 inode를 조사하여 두번째 이름과 일치하는 entry를 가짐 이 절차는 path에 포함된 각각의 이름에 대하여 반복 dentry cache는 최근에 사용한 dentry object 메모리에 보관되어 있기 때문에 수행 속도가 향상 Lookup_flags 비트열 LOOKUP_FOLLOW LOOKUP_DIRECTORY LOOKUP_SLASHOK LOOK_CONTINUE

52 Part V : VFS 시스템 콜 구현

53 VFS 시스템 콜 구현 open() System Call read() and write() System Call
Sys_open() Open할 Pathname : Filename 접근 flag : flags 퍼미션 bit mask : mode 성공 : 파일 discriptor, 실패 : -1 read() and write() System Call Read(), Write() File descriptor : fd 메모리 영역의 Address : buf 한번에 전송할 byte수 : number 성공 : byte의 number, 실패 : -1

54 Part VI : 파일 락킹

55 파일 락킹 동기화의 문제 - lock Advisory lock(POSIX : fcntl(), BSD : flock())
OS가 특정 프로세스에 의해 Locking된 파일에 대하여 정확한 자료를 유지하되, 다른 프로세스에 의해 Locking된 파일에 대하여 쓰기를 막지 않는 것을 말함 프로세스는 advisory lock을 무시하고 적절한 권한이 있다면 Lock된 파일에 쓰기를 할 수 있음 Mandatory lock(System V Release 3 : lockf()) 호출 프로세스가 접근하려는 파일에 대해 lock을 위반하지 않는가를 검사하기 위해 kernel로 하여금 open, read, write를 검사하는 방식

56 파일 락킹 Read lock, write lock
어떤 lock이든 read locks는 공유되고 여러 프로세스가 lock을 걸 수 있음 write locks는 exclusive이며 단지 하나의 프로세스만이 lock을 걸 수 있음 같은 file region에 다른 프로세스들이 read lock을 걸었을 때, write lock을 걸 수 없음 현재 락 요청한 락 읽기 쓰기 락이 없음 읽기 락 쓰기 락 yes no yes no P.516 락 허용 여부

57 파일 락킹 리눅스 파일 락킹 Linux에서 locking Advisory locks mandatory locks
fcntl() - FL_POSIX 타입 flock() - FL_LOCK 타입 mandatory locks Lockf() – System V mount() 시스템 콜의 MS_MANDLOCK flag를 사용하여 파일시스템 당 enable와 disable할 수 있음 디폴트 값은 mandatory locking switch off 두 가지 lock은 공존하며 서로에게 영향을 주지 않음 fcntl()이 file에 lock을 걸면 flock()는 나타나지 않음

58 파일 락킹 파일 락킹 자료구조 struct file_lock {
struct file_lock *fl_next; /* singly linked list for this inode */ struct file_lock *fl_nextlink; /* doubly linked list of all locks */ struct file_lock *fl_prevlink; /* used to simplify lock removal */ struct file_lock *fl_nextblock; /* circular list of blocked processes */ struct file_lock *fl_prevblock; fl_owner_t fl_owner; unsigned int fl_pid; struct wait_queue *fl_wait; struct file *fl_file; unsigned char fl_flags; unsigned char fl_type; off_t fl_start; off_t fl_end; void (*fl_notify)(struct file_lock *); /* unblock callback */ union { struct nfs_lock_info nfs_fl; } fl_u; };

59 파일 락킹 FL_LOCK lock(File object에 관련) sys_flock()
파일 객체가 fput()에 의해 free될때 파일객체를 참조하는 모든 FL_LOCK locks은 destoryed된다. 다른 FL_LOCK은 같은 파일(inode)의 다른 프로세스에 의해 설정된 locks를 읽고, 여전히 active상태로 남음 sys_flock() 주어진 fd가 유효한 file descriptor인지 검사. fl_flags에 의해서 file_lock 구조체를 초기화하기 위해 flock_make_lock()을 수행. lock이 요구된다면, open file에 대해서 read, write permission이 있는지 검사 flock_lock_file() 수행

60 파일 락킹 FL_POSIX lock(프로세스와 inode에 관련)
프로세서가 죽거나 파일 디스크립터가 closed될 때 Lock는 자동으로 release된다. 절대 fork()를 통해 child에게 상속되지 않음 sys_fcntl() user space로부터 flock 구조체를 읽음 fd와 관련된 file object를 얻음 lock이 mandatory인지 검사 새로운 file_lock을 초기화하기 위해서 posix_make_lock()을 수행 access mode를 허용하지 않으면 error return. file operation의 lock method를 수행 posix_lock_conflict() 수행 inode의 lock list에 있는 각 FL_POSIX lock을 위해 posix_locks_conflict() 수행 상반된 lock이 있고 fcnti()이 F_SETLK flag를 가지고 수행되었으면 error 리턴 inode의 lock list가 포함되면, 모든 현재 프로세스의 FL_POSIX lock를 검사 새로운 file_lock 구조체를 global lock list와 inode list에 넣는다 0을 리턴

61 Part VII : 리눅스 2.4 예상

62 리눅스 2.4 예상 리눅스 2.4 VFS 새로운 파일 시스템 8개 지원 Udf 최대 파일 크기 늘었음 DVD 장치 지원
Inode의 i_size 필드를 32bit에서 64bit로 확장


Download ppt "리눅스 커널의 이해 중에서 12장. 가상 파일 시스템 김석훈 시스템 소프트웨어 실험실."

Similar presentations


Ads by Google