1 File System and VFS May, 2016 Dept. of software Dankook University http://embedded.dankook.ac.kr/~baeksj
File system 2 MM (Buddy, Slab, ) +? = FS (FAT, ExtN, )
File system 3 MM (Buddy, Slab, ) + Naming = FS (FAT, ExtN, )
File system 4 MM (Buddy, Slab, ) + Naming = FS (FAT, ExtN, ) N/A Name Pointer File(fd) Page frame Block 4KB~ Continuous or noncontinuous allocation Paging(page table) 512B~ Continuous or noncontinuous allocation FAT(FAT table), block chanin, index block,
File system 5 MM (Buddy, Slab, ) + Naming = FS (FAT, ExtN, ) N/A Name Pointer File(fd) Page frame Block 4KB~ Continuous or noncontinuous allocation Paging(page table) 512B~ Continuous or noncontinuous allocation FAT(FAT table), block chanin, index block, Block size vs. performance, Cylinder group, Defragmentation, Layout policy,
디스크구조 6 물리적관점 plotter, arm, head cylinder, track, sector 탐색지간 (seek time), 회전지연시간 (rotational latency), 데이터전송시간 (transmission time) Cylinder group Block size vs Performance Fragments Layout policy 한 Dir내의파일한 file내의 block
디스크구조 논리적인관점 7 논리적관점 ( 커널이보는디스크구조 ) 디스크는디스크블록들의집합 (disk is a collection of disk blocks) 디스크블록의크기는보통페이지프레임의크기와같다 (4K, 8K) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14.
디스크블록할당 (1/5) 8 시나리오 새로운 14 K 크기의파일을디스크에게쓰려고함 디스크블록의크기는 4K로가정 ( 따라서 4개의디스크블록이필요 ) 아래그림에서빗금이있는디스크블록들은이미사용중인 ( 파일의데이터를갖고있는 ) 블록이라고가정 어떤디스크블록들을할당할것인가? (disk block allocation) 0 1 2 3 4 5 6 7 8 9 10 11.. 12 13 14 15 16 디스크블록할당방법 연속할당방법 (sequential allocation) 불연속할당방법 (non sequential allocation)
디스크블록할당 (2/5) 9 연속할당방법 new file name start size 0 1 2 3 4 5 6 7 8 9 10 11.. 12 13 14 15 16
디스크블록할당 (3/5) 10 불연속할당방법 : 블록체인 (block chain) 방법 new file name start size 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18.. 연속할당과불연속할당방법간에장단점을논해보자.
디스크블록할당 (4/5) 11 불연속할당방법 : 인덱스블록 (index block) 기법 index block new file name index size 0 1 2 3 4 5 6 7 8 9 10 11... 12 13 14 15 16 17 18.. 인덱스블록이가득차면?
디스크블록할당 (5/5) 12 불연속할당방법 : FAT (File Allocation Table) new file name start size FAT 2 5 FF 12 11 6 FF 34 21 9 0 FF 7 0 0 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18.. 11 블록체인, 인덱스블록, FAT 간에장단점을논해보자. Linux 는어떤방법을사용하고있는가?
FAT internal 13 FAT Blocks 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 FF FF FF FF FF FF 8 9 FF FF 12 13 14 15 FF FF 0 0 0 0 0 0 0 0 File1 File2 0 0 0 0 0 0 0 0 0 0 0 0 Master Boot Block Partition Boot Block Boot Block #2 Root Dir BLock Dir1 Dir2 Status File Name FirstAddr Size F File1 7 3 D Dir1 10 1 F File2 11 5 D Dir2 16 1 Status File Name FirstAddr Size D. 10? D.. 6? F x.hwp 17 5 F my.doc 22 1 (Source : Dr. dhlee)
디렉토리구조 14 파일계층구조 (hierarchical structure) / usr dev etc var mnt vmunix src include lib bin member local jim tom mark sooni mjc
디렉토리계층구조와메타데이터의예 (FAT 기준 ) 15 usr dev home var src include member / 6 11 Status File Name FirstAddr Size D usr 7 3 D dev 10 1 D home 11 5 D var 16 11 D member 20 2 choijm sjbaek 20 D choijm 39 3 D sjbaek 43 2 약속.txt 43 F 약속.txt 48 1
inode 구조 1 16 inode /* include/linux/fs.h, ext2_fs_i.h */ inode i_inode_number i_mode i_nlink, i_dev i_uid, gid i_op i_atime, ctime, mtime type (4bit) u g s r w x r w x r w x S_IFSOCK S_IFLNK S_IFREG S_IFBLK S_IFDIR S_IFCHR S_IFIFO 12 direct block. 3 indirect block
inode 구조 2 17 시나리오 디스크블록의크기가 4K 로가정 파일옵셋 (offset) 이 10000 이면어떤디스크블록에접근하게되는가? 또한파일옵셋이 58000 이라면? file f_pos direct. inode 24 7 18 33 12 169 4 41 indirect 165
디렉토리구조 1 18 디렉터리 파일이름과 inode를연결하는객체 (namei()) 디렉터리자체도파일임계층구조제공 Linux의디렉토리엔트리 inode number file name size file name inode for / i_mode time. 1 directory entry in DOS file name extension attributes time first block number inode 1 disk block 1 inode 3 disk block 7 inode 23 1.. 1. 3 usr 4 dev 5 etc 6 vmunix 7 var 9 mnt i_mode time. 7 1.. 3. 12 src 16 include 17 lib 20 bin 23 member 25 local i_mode time. 39 disk block 39 3.. 23. 32 jim 33 tom 37 mark 41 sooni 42 choijm
Ext2 의 inode 와파일의개념적구조 19 inode 2 i_mode time. 20 disk block 20 2.. 2. File1.c 11 mydir 12 File1.c / mydir inode 11 i_mode time. 21 22 23 inode 12 i_mode time. 24
Ext2 internal 20 i-node blocks Boot Block Super Block 0 1 2 3 4 5 6 20 21 22 23 24 25 26 27 28 29 30 Root Dir File1.c mydir myfile 34 35 36 37 38 39 myfile Root dir File1.c mydir myfile 상태 : dir 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 20 상태 : file 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 21 22 23 상태 : dir 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 24 상태 : file 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 25 26 27 29 30 31 32 33 28 file name i-node No.. 2.. 2 File1.c 3 mydir 4 myfile 5 mydir2 7 file name i-node No.. 4.. 2 a.hwp 10 b.c 11 Test.c 24 Note.doc 19 (Source : Dr. dhlee)
Ext2 파일시스템의디스크에서의레이아웃 21 Partition Boot block Block Group 0 Block Group 1 Block Group N Block size = X 라가정 Super Block Group Descriptor Datablock Bitmap Inode Bitmap Inode Table Data blocks(m 개 ) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 Root dir 상태 : dir 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 20 File1.c 상태 : file 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 21 22 23 (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 X / 128)*N file name i-node No.. 2.. X File1.c 11 mydir 12 mydir 상태 : dir 크기 :?? 생성날짜수정날짜접근날짜소유자, 그룹접근비트 : 111100100 데이터위치 : 24 file name i-node No.. 12.. 2 Root Dir File1.c mydir 20 21 22 23 24 25 26 27 28 29 30
Example(1/19)-FS 제작 22 만약여러분이 FS 제작자라면어떤구조로 FS 를제작할것인가? FAT Ext2 LFS
Example(2/19)-FS 제작만약여러분이 FS 제작자라면파일을관리하기위한메타데이터자료구조를어떻게정의할것인가? 이름, 크기, 사이즈, 생성시간, data 블록의위치, typedef struct { unsigned int blockno; unsigned short offset; } attribute ((packed)) ET_T; 23 typedef struct { unsigned char status; time_t date; unsigned long size; char name[file_name]; union{ ET_T index[5]; char data[30]; } attribute ((packed)) uarea; unsigned int next_blkno; char reserved[4]; char attr; } attribute ((packed)) DIRENTRY_T; typedef struct { unsigned char status; char reserved[5]; ET_T index[9]; unsigned int next_blkno; } attribute ((packed)) IDXDIRENTRY_T; nebfs
Example(3/19)-FS 제작 24 struct ext2_dir_entry { le32 inode; /* Inode number */ le16 rec_len; /* Directory entry length */ le16 name_len; /* Name length */ char name[]; /* File name, up to EXT2_NAME_LEN */ }; struct ext2_inode { u16 i_mode; /* File mode */ u16 i_uid; /* Low 16 bits of Owner Uid */ u32 i_size; /* Size in bytes */ u32 i_atime; /* Access time */ u32 i_ctime; /* Creation time */ u32 i_mtime; /* Modification time */ u32 i_dtime; /* Deletion Time */ u16 i_gid; /* Low 16 bits of Group Id */ u16 i_links_count; /* Links count */ u32 i_blocks; /* Blocks count */ u32 i_flags; /* File flags */ union { struct { u32 l_i_reserved1; } linux1; struct { u32 h_i_translator; } hurd1; struct { u32 m_i_reserved1; } masix1; } } osd1; /* OS dependent 1 */ u32 i_block[ext2_n_blocks]; /* Pointers to blocks */ u32 i_generation;/* File version (for NFS) */ u32 i_file_acl; /* File ACL */ u32 i_dir_acl; /* Directory ACL */ u32 i_faddr; /* Fragment address */.. ext2
Example(4/19)-FS 제작 25 struct msdos_dir_entry { s8 name[8],ext[3]; /* name and extension */ u8 attr; /* attribute bits */ u8 lcase; /* Case for base and extension */ u8 ctime_ms; /* Creation time, milliseconds */ u16 ctime; /* Creation time */ u16 cdate; /* Creation date */ u16 adate; /* Last access date */ u16 starthi; /* High 16 bits of cluster in FAT32 */ u16 time,date,start; /* time, date and first cluster */ u32 size; /* file size (in bytes) */ }; Msdos FS
Example(5/19)-FS 제작 26 typedef struct { yaffs_objecttype type; int parentobjectid; u16 sum NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies char name[yaffs_max_name_length + 1]; u32 st_mode; // protection // Thes following apply to directories, files, symlinks - not hard links #ifdef CONFIG_YAFFS_WINCE u32 notforwince[5]; #else u32 st_uid; // user ID of owner u32 st_gid; // group ID of owner u32 st_atime; // time of last access u32 st_mtime; // time of last modification u32 st_ctime; // time of last change #endif int filesize; // File size applies to files only int equivalentobjectid; // Equivalent object id applies to hard links only. char alias[yaffs_max_alias_length + 1]; // Alias is for symlinks only. u32 st_rdev; // device stuff for block and char devices (maj/min) #ifdef CONFIG_YAFFS_WINCE u32 win_ctime[2]; u32 win_atime[2]; u32 win_mtime[2]; u32 roomtogrow[6]; #else u32 roottogrow[12]; #endif } yaffs_objectheader; YAFFS
Example(6/19)-FS 제작 27 만약여러분이 FS 제작자라면파일시스템에어떤연산을구현할것인가? 즉, FS 외부로어떤 interface 를뽑아줄것인가? touch MYFS_file_create() rm MYFS_file_delete() cp MYFS_file_rename() cat MYFS_file_read() echo >> MYFS_file_write() mkdir MYFS_dir_create() rmdir MYFS_dir_delete() ls MYFS_dir_read()
Example(7/19)-FS 제작 28 다양한유형의파일지원 정규파일, 디렉토리, 특수장치파일, 링크, 파이프, 소켓,.. 파일시스템관련시스템호출 open, close read, write lseek dup link pipe, mkfifo mkdir, readdir mknod stat mount sync, fsck POSIX interface?
Example(8/19)-FS 제작 29 static struct file_operations neb_dir_operations = { readdir: neb_readdir, }; static struct inode_operations neb_dir_inode_operations = { create: neb_create, lookup: neb_lookup, unlink: neb_unlink, mkdir: neb_mkdir, rmdir: neb_rmdir, rename: neb_rename, permission: neb_permission, symlink: neb_symlink, mknod: neb_mknod, }; static struct file_operations neb_file_operations = { read: neb_file_read, write: neb_file_write, mmap: generic_file_mmap, }; static struct inode_operations neb_file_inode_operations = { lookup: neb_lookup, permission: neb_permission, truncate: neb_truncate, }; nebfs
Example(9/19)-FS 제작 30 struct file_operations ext2_dir_operations = { read: generic_read_dir, readdir: ext2_readdir, ioctl: ext2_ioctl, fsync: ext2_sync_file, }; struct file_operations ext2_file_operations = { llseek: generic_file_llseek, read: generic_file_read, write: generic_file_write, ioctl: ext2_ioctl, mmap: generic_file_mmap, open: generic_file_open, release: ext2_release_file, fsync: ext2_sync_file, }; static struct super_operations ext2_sops = { read_inode: ext2_read_inode, write_inode: ext2_write_inode, put_inode: ext2_put_inode, delete_inode: ext2_delete_inode, put_super: ext2_put_super, write_super: ext2_write_super, statfs: ext2_statfs, remount_fs: ext2_remount, }; ext2
Example(10/19)-FS 제작 31 struct inode_operations msdos_dir_inode_operations = { create: msdos_create, lookup: msdos_lookup, unlink: msdos_unlink, mkdir: msdos_mkdir, rmdir: msdos_rmdir, rename: msdos_rename, setattr: fat_notify_change, }; Msdos FS
Example(11/19)-FS 제작 32 static struct address_space_operations yaffs_file_address_operations = { readpage: yaffs_readpage, prepare_write: yaffs_prepare_write, commit_write: yaffs_commit_write }; static struct file_operations yaffs_file_operations = { #ifdef CONFIG_YAFFS_USE_GENERIC_RW read: generic_file_read, write: generic_file_write, #else read: yaffs_file_read, write: yaffs_file_write, #endif mmap: generic_file_mmap, flush: yaffs_file_flush, fsync: yaffs_sync_object, }; static struct inode_operations yaffs_file_inode_operations = { setattr: yaffs_setattr, }; struct inode_operations yaffs_symlink_inode_operations = { readlink: yaffs_readlink, follow_link:yaffs_follow_link, setattr: yaffs_setattr }; static struct inode_operations yaffs_dir_inode_operations = { create: yaffs_create, lookup: yaffs_lookup, link: yaffs_link, unlink: yaffs_unlink, symlink: yaffs_symlink, mkdir: yaffs_mkdir, rmdir: yaffs_unlink, mknod: yaffs_mknod, rename: yaffs_rename, setattr: yaffs_setattr, }; static struct file_operations yaffs_dir_operations = { read: generic_read_dir, readdir: yaffs_readdir, fsync: yaffs_sync_object, }; static struct super_operations yaffs_super_ops = { statfs: yaffs_statfs, read_inode: yaffs_read_inode, put_inode: yaffs_put_inode, put_super: yaffs_put_super, delete_inode: yaffs_delete_inode, clear_inode: yaffs_clear_inode, }; YAFFS
Example(12/19)-FS 제작 33 만약여러분이 FS 제작자라면만든 FS 가특정 device 위에서만돌도록만드시겠습니까? User File System Disk Emulator Disk Device Driver CD-ROM Device Driver SDRAM Access Interface Disk CD-ROM SDRAM
Example(13/19)-FS 제작 34 만약 Hard Disk 위에서돌리고싶다면? User # touch a File System file_create() Disk Emulator disk_write_block() Disk Device Driver XXXhdd_write_block() Disk
Example(14/19)-FS 제작 35 만약 RAM 상에서돌리고싶다면? User # touch a File System file_create() Disk Emulator disk_write_block() SDRAM Access Interface SDRAM RAM_write_block() Static char * ramdata[size]; RAM_write_block(){ //copy data to ramdata }
Example(15/19)-FS 제작 FS 함수구현의예 (ls) int MYFS_dir_read() { int i, sector, offset, files_in_dir; DIRENTRY_T *ep; 36 SM_P(); ep = (DIRENTRY_T *)buf; sector = cur_dir; offset = 0; disk_read_block(sector, buf); files_in_dir = ep->size; for (i = 0; i < files_in_dir; i++) { disk_read_block(sector, buf); ep = (DIRENTRY_T *) (buf+offset); if (ep->status == DIR) printk(" %14s/ %d", ep->name, ep->size); else printk(" %14s %d", ep->name, ep->size); /* ep->status == FILE */ offset += sizeof(direntry_t); if (offset == 512) { sector = FAT[sector]; offset = 0; } if (!((i+1) % 4)) printk(" n"); } printk(" n"); SM_V(); return(fs_success);
Example(16/19)-FS 제작 37 create, read, write. 의함수는? cp./a.txt /b.txt Int cp(.... ) { int a, b, rb; char buf[size_of_block]; a = MYFS_file_open(./a.txt); b = EXT2_file_open(/b.txt); rb = MYFS_file_read(a, buf); while( rb ){ EXT2_file_write(b, rb, buf); rb = MYFS_file_read(a, buf); } } 정말 cp 프로그램을이렇게만들어줘야할까? 이렇게 FS 종속적이지않도록하려면?
다양한파일시스템지원의문제점 38 User App fat_file_write(a.txt, ); ext2_truncate(b.txt, ); User level do_sync_read, do_sync_write, ext3_truncate, ext3_readdir, generic_file_read, generic_file_write, ext2_truncate, ext2_readdir, generic_file_read, fat_file_write, fat_truncat, generic_read_dir, Kernel level b.txt a.txt Ext3 Ext2 msdos /dev/hda1 /dev/hda2 /dev/hda3 /dev/hda Disk
가상적인 (Virtual) 계층의도입 39 User App open(a.txt, ); write(b.txt, ); User level b.txt a.txt Kernel level do_sync_read, do_sync_write, ext3_truncate, ext3_readdir, generic_file_read, generic_file_write, ext2_truncate, ext2_readdir, generic_file_read, fat_file_write, fat_truncat, generic_read_dir, Ext3 Ext2 msdos /dev/hda1 /dev/hda2 /dev/hda3 /dev/hda Disk
VFS 의동작원리 40 VFS read 요청 3 msdos 자체의관리방법을통해 요청된파일내용을읽음 사용자의 a.txt 요청 1 8 2 7 msdos 4 FAT, msdos_ 디렉토리엔트리 5 /dev/hda3 b.txt b.txt 6 읽어온내용을바탕으로 넘겨받은구조체를채워서리턴 /dev/hda Disk
Linux 파일시스템구조 41 task 1 task 2 task n System call interface User level Kernel level VFS Page Cache submit_bh() ll_rw_block() ext2 buffer page Virtualization Dentry cache buffer page msdos buffer page. Inode cache procfs Generic Block layer gendisk I/O Scheduler gendisk ext3 yaffs nfs device driver Queue device driver. Disk Disk
VFS 와네가지객체 42 VFS 의객체유형 슈퍼블록객체 마운트된 FS 을나타내는정보저장 ( 디스크의 ) 파일시스템제어블록 (filesystem control block) 에대응 아이노드객체 특정파일을나타내는정보저장 ( 디스크의 ) 파일제어블록 (file control block) 에대응 inode 번호로 FS 내에서유일하게식별됨 파일객체 프로세스와연관되어 Open 되어있는파일과관련된정보를저장 각 process 가 file 에접근하는동안커널메모리에만존재 디엔트리객체 디렉토리항목과이에대응하는파일의연결에대한정보를저장 독자적방법으로디스크에저장함 디엔트리캐시 가장최근에사용한디엔트리객체를캐시
VFS 자료구조 Super block 객체 슈퍼블록객체 (struct super_block, <linux/fs.>) 43
Super block 객체관리 44 모든 superblock object는 circular doubly linked list로연결 list field 처음과끝은 super_blocks 변수의 s_list 의 next 와 prev 에저장 슈퍼블록슈퍼블록슈퍼블록 s_list s_list s_list super_blocks next next next next prev prev prev prev
super_blocks list 확인 45
Super block 객체와 super operations 46
VFS mounted FS system structure 47 root d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount dentry d_subdirs d_child d_cover d_mount
Example 간단한 FS 실습 (1/2) 48
Example 간단한 FS 실습 (2/2) 49 Block Size 를 2048 혹은, 4096 으로만들수있는가?
Inode 객체 아이노드객체 (struct inode <linux/fs.h>) 50
Inode 객체 51
Inode 객체와 inode operatoins 52 inode 관련연산은 inode_operations 구조체에담아 i_op 필드에
File 객체 53 파일객체 (struct file <linux/fs.h>)
File 객체와 file operations 54 파일에대한연산을 file_operations 구조체에담아 f_op 에
Dentry 객체 55 디엔트리객체 (struct dentry <linux/dcache.h>) 디렉토리엔트리를메모리로읽은뒤, VFS가 dentry 구조체의디엔트리객체로변환 P가탐색하는경로명의모든구성요소에대해디엔트리객체생성
Dentry 객체와 dentry operations 56 dentry 객체에대한연산을 dentry_operations 구조체에담아 d_op 필드에, 대개 NULL 임
struct task_struct /* include/linux/sched.h */. struct files_struct *files;. Linux 의파일연산구현분석 (1/5) 파일연산 : file_operations inode 연산 : inode_operations 57 struct files_struct /* include/linux/sched.h */ atomic_t count; int max_fds; struct file *fd_array[] ; fd_set close_on_exec;.. struct file /* include/linux/fs.h*/ struct file *f_next, **f_pprev; struct dentry f_dentry; struct file_operations *f_op; mode_t f_mode; loff_t f_pos; unsigned int f_count, f_flags;. struct dentry /* include/linux/dcache.h */ int d_count, d_flags; struct inode *d_inode;. struct inode /* include/linux/fs.h */ int i_ino. struct inode_operations i_op.
task_struct 와 VFS 의객체 58 task_struct file_struct /* include/linux/fdtable.h */ files file /* include/linux/fs.h */ fs fd[0] fd[1] dentry /* include/linux/dcache.h */... fd[2] f_dentry fd[3] f_pos f_op d_inode... d_op... fs_struct /* include/linux/fs_struct.h */ inode /* include/linux/fs.h */ root pwd file dentry i_sb... f_dentry i_op d_inode f_pos d_op f_op task_struct file_struct...... files fs fd[0] super_block /* include/linux/fs.h */ fd[1]... fd[2] fd[3] s_bdev fd[4] ext2 s_op /dev/hda2
파일인터페이스 59 커널자료구조관계 fork open same file file_struct task_struct file inode task_struct file_struct file inode parent parent file_struct task_struct child file how about dup?
Linux 의파일연산구현분석 (2/5) 60 open 시스템호출분석 /* fs/open.c */ sys_open() System call layer /* fs/namei.c */ filp_open() - get_unused_fd_flags() - do_filp_open() - fd_install(fd, f) - struct file initialize - call file->f_op->open() VFS layer Specific File layer fifo_open() blkdev_open() chrdev_open() nfs_file_open() sock_no_open()
Linux 의파일연산구현분석 (3/5) 61 struct file_operations 구조 : 다양한파일유형을일관된인터페이스로지원 NFS /* fs/nfs/file.c */ NULL, nfs_file_read, nfs_file_write NULL, NULL, NULL, nfs_file_mmap nfs_file_open, ext2 file system /* fs/ext2/file.c */ ext2_file_lseek, generic_file_read, ext2_file_write NULL, NULL, ext2_file_ioctl generic_file_mmap NULL,. 파이프 pipe_lseek, pipe_read, pipe_write NULL, pipe_poll, pipe_ioctl, NULL, fifo_open,... struct file_operations /* include/linux/fs.h */ llseek() read() write() readdir() poll() ioctl() mmap() open() flush() release() fsync() fasync().. socket /* net/socket.c */ no_lseek sock_readv sock_writev NULL sock_poll sock_ioctl sock_mmap sock_no_op en. 블록장치파일 /* fs/block_dev.c */ /* fs/pipe.c */ blkdev_close, blkdev_llseek, block_ioctl, blkdev_open,. 문자장치파일 /* fs/char_dev.c */ noop_llseek, chrdev_open
Linux 의파일연산구현분석 (4/5) 62 open 시스템호출분석 sock_read() /* fs/read_write.c */ sys_read() - file->f_op->read System call handling layer block_read() VFS layer pipe_read() /* mm/filemap.c */ generic_file_read_iter() tty_read() - try to find page in cache, if (hit) OK. - inode->i_op->readpage() Specific File layer nfs_readpage() /* fs/buffer.c */ coda_readpage() Specific FS layer /* fs/ext2/inode.c */ ext2_bmap() /* fs/ufs/inode.c */ ufs_bmap() generic_readpage() /* driver/block/ll_rw_blk.c */ ll_rw_block() /* driver/block/hd.c */ Device Driver layer hd_request
Linux 의파일연산구현분석 (5/5) 63 struct inode_operations 구조 : 다양한파일시스템을일관된인터페이스로지원 fs/pipe.c rdwr_pipe_fops, NULL, NULL, NULL, NULL,... fs/ext2/file.c ext2_file_operations, NULL, NULL, NULL, NULL,... generic_readpage NULL ext2_bmap,. fs/device.c def_blk_fops, NULL, NULL, NULL, NULL,... include/linux/fs.h struct inode_operation { def_file_operation create(), lookup(), link(), unlink(), symlink(), mkdir(), rmdir(), mknod(), rename(), readlink(), followlink(), readpage(), writepage() bmap(), truncate(),. } fs/ufs/file.c ufs_file_operations, NULL, NULL, NULL, NULL,... generic_readpage NULL ufs_bmap,. fs/dos/files. c dos_file_operation s, NULL, NULL, NULL, NULL, dos_readpage, dos_writepage, NULL,. fs/nfs/file.c nfs_file_operations, NULL, NULL, NULL, NULL,... nfs_readpage nfs_writepage NULL.
파일시스템등록 64 register_filesystem() 간단하다. file_system_type 구조체하나채워주고호출하면끝
파일시스템등록 65 이때 file_system_type 구조체의내용은아래와같다. read_super 필드는슈퍼블록을읽는함수를지정해주는필드이다 앞장에서 find_filesystem() 함수는현재시스템에올라와있는모든 FS 를찾아봐서중복된놈을올리는게아닌지확인하는역할을한다
파일시스템등록 66 구조체는직접채워도되지만, 보통모두 DECLARE_FSTYPE() 매크로를사용한다. 쉽고간단하다.
Example(17/19)-FS 제작 67 FS 를 Module 형태로제작한다면? /* NEB_super.c */. static DECLARE_FSTYPE(neb_type, "neb", neb_read_super, FS_SINGLE); static int init init_neb(void) { return register_filesystem(&neb_type); } int init_module(void) { dprintk("<0>%s:%s(%d) n", FILE, FUNCTION, LINE ); return init_neb(); }..
Example(18/19)-FS 제작 68 User 가 mount 명령을내리면? static struct super_block *neb_read_super(struct super_block *sb, void *data, int silent) { dprintk("<0>%s:%s(%d) n", FILE, FUNCTION, LINE ); struct inode *root_inode; int vol, err; dev_t dev; neb_file_id_t fid; unsigned long tmp; vol = MINOR(sb->s_dev) & 0x7; dev = MKDEV(MAJOR(sb->s_dev), MINOR(sb->s_dev)-vol); if ((err = _neb_mount_vol(dev, vol-1)) < 0) { printk("<0> %s: _neb_mount_vol failed: %d n", FUNCTION, err); goto neb_sb_err1; } // read_super 의인자로넘어온 super block 포인터 sb 에 file system specific 한정보를기입 if ((err = _neb_read_super(dev, vol-1, &sb->u.neb_sb)) < 0) { printk("<0> %s: _neb_read_super failed: %d n", FUNCTION, err); goto neb_sb_err1; }
Example(19/19)-FS 제작 // 나머지 sb 의정보를채움 sb->s_blocksize = sb->u.neb_sb.cluster_size; User가 mount명령을내리면? sb->s_blocksize_bits = 0; tmp = sb->s_blocksize; while (tmp > 1) { sb->s_blocksize_bits++; tmp >>= 1; } sb->s_maxbytes = 0xFFFFFFFF; // maximum file size sb->s_magic = NEB_MAGIC; sb->s_op = &neb_ops; sb->s_dirt = 0; // 지역변수 fid에다가 root directory의 inode 정보를기입 fid.dev = dev; fid.vol = vol-1; fid.parent_first_block = sb->u.neb_sb.root_cluster; fid.dir_first_block = sb->u.neb_sb.root_cluster; strcpy(fid.filename, "."); if ((err = _neb_lookup(&fid)) < 0) { printk("<0>%s: _neb_lookup failed: %d n", FUNCTION, err); goto neb_sb_err1; } // root_inode 에 root dir 을위한inode 할당 root_inode = iget4(sb, sb->u.neb_sb.root_cluster, (find_inode_t) _neb_find_actor, (void *) &fid); 69 } if (!root_inode) goto neb_sb_err1; // root_inode 를위한dentry할당 if (!(sb->s_root = d_alloc_root(root_inode))) return sb; goto neb_sb_err2;
Example(1/3)- Lock 실험 70 Process A 에서 fcntl() 이나 flock() 함수를사용하여파일 a.txt 에 lock 을건다 Process A 가 fork() 하여 Process A 를생성한다 Process A 가파일 a.txt 에접근하려하면? Process A 가파일 a.txt 에 lock 을잡고있는동안, 창을하나더띄워서 vi 편집기로 a.txt 를편집하려고하면?
Example(2/3)- Lock 실험 71 Advisory lock(posix : fcntl(), BSD : flock()) OS 가특정프로세스에의해 Locking 된파일에대하여정확한자료를유지하되, 다른프로세스에의해 Locking 된파일에대하여쓰기를막지않는것을말함 프로세스는 advisory lock 을무시하고적절한권한이있다면 Lock 된파일에쓰기를할수있음 Mandatory lock(system V Release 3 : lockf()) 호출프로세스가접근하려는파일에대해 lock 을위반하지않는가를검사하기위해 kernel 로하여금 open, read, write 를검사하는방식