2012年02月28日 情報科学類 オペレーティングシステム II 筑波大学 システム情報工学研究科 コンピュータサイエンス専攻, 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2011/2012-02-28
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
試験について
解決策:
図? ファイル・システム実現に置ける層構造
ディスク・キャッシュの層もある。解決策
$ ls -l /bin/{gunzip,gzip,zcat}
-rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/gunzip
-rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/gzip
-rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/zcat
$ ls -li /bin/{gunzip,gzip,zcat}
5636134 -rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/gunzip
5636134 -rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/gzip
5636134 -rwxr-xr-x 3 root root 62872 Jan 21 2010 /bin/zcat
$
$ cat /etc/fstab
LABEL=/ / ext3 defaults 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda3 swap swap defaults 0 0
130.158.86.2:/vol/vol1/home /home nfs rw,hard,bg,nfsvers=3,intr 0 0
130.158.86.2:/vol/vol5/local3 /usr/local3 nfs rw,hard,bg,nfsvers=3,intr 0 0
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 222G 13G 198G 6% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
130.158.86.2:/vol/vol1/home
4.0T 1.5T 2.5T 38% /home
130.158.86.2:/vol/vol5/local3
80G 4.9G 76G 7% /usr/local3
$
図? スーパーブロック、inode、dentry、file
linux-3.1.3/include/linux/fs.h 953: struct file { ... 962: struct path f_path; 963: #define f_dentry f_path.dentry 965: const struct file_operations *f_op; ... 970: atomic_long_t f_count; 972: fmode_t f_mode; 973: loff_t f_pos; ... 983: void *private_data; ... 993: };
struct fileの操作は、たとえば次のような形で行われる。 第1引数は、struct file *。
struct file *file; file->f_op->read(file, buf, count, pos);f_op には、次のような手続きがある。各ファイルシステム (ext4,nfs,tmpfs,...) ごとに、手続きの実体は異なるが、インタフェースは同じ。
linux-3.1.3/include/linux/fs.h 1563: struct file_operations { 1564: struct module *owner; 1565: loff_t (*llseek) (struct file *, loff_t, int); 1566: ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 1567: ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 1568: ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 1569: ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 1570: int (*readdir) (struct file *, void *, filldir_t); 1571: unsigned int (*poll) (struct file *, struct poll_table_struct *); 1572: long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 1573: long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 1574: int (*mmap) (struct file *, struct vm_area_struct *); 1575: int (*open) (struct inode *, struct file *); 1576: int (*flush) (struct file *, fl_owner_t id); 1577: int (*release) (struct inode *, struct file *); 1578: int (*fsync) (struct file *, loff_t, loff_t, int datasync); 1579: int (*aio_fsync) (struct kiocb *, int datasync); 1580: int (*fasync) (int, struct file *, int); 1581: int (*lock) (struct file *, int, struct file_lock *); 1582: ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1583: unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1584: int (*check_flags)(int); 1585: int (*flock) (struct file *, int, struct file_lock *); 1586: ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 1587: ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 1588: int (*setlease)(struct file *, long, struct file_lock **); 1589: long (*fallocate)(struct file *file, int mode, loff_t offset, 1590: loff_t len); 1591: };主な手続きの意味
linux-3.1.3/include/linux/dcache.h 116: struct dentry { ... 121: struct dentry *d_parent; /* parent directory */ 122: struct qstr d_name; 123: struct inode *d_inode; /* Where the name belongs to - NULL is 124: * negative */ 125: unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ ... 128: unsigned int d_count; /* protected by d_lock */ 130: const struct dentry_operations *d_op; 131: struct super_block *d_sb; /* The root of the dentry tree */ 133: void *d_fsdata; /* fs-specific data */ ... 143: struct list_head d_subdirs; /* our children */ ... 145: }; ... 35: struct qstr { 36: unsigned int hash; 37: unsigned int len; 38: const unsigned char *name; 39: }; ... 112: # define DNAME_INLINE_LEN 40 /* 128 bytes */
linux-3.1.3/include/linux/fs.h 748: struct inode { 749: umode_t i_mode; 750: unsigned short i_opflags; 751: uid_t i_uid; 752: gid_t i_gid; ... 760: const struct inode_operations *i_op; 761: struct super_block *i_sb; ... 769: unsigned long i_ino; 770: unsigned int i_nlink; 771: dev_t i_rdev; 772: loff_t i_size; 773: struct timespec i_atime; 774: struct timespec i_mtime; 775: struct timespec i_ctime; 776: unsigned int i_blkbits; 777: blkcnt_t i_blocks; ... 784: unsigned long i_state; 790: struct hlist_node i_hash; 795: struct list_head i_dentry; 798: atomic_t i_count; ... 826: void *i_private; /* fs or device private pointer */ 827: };
struct inode *inode; ... inode->i_op->truncate(inode);i_op には、次のような手続きがある。各ファイルシステム (ext3,nfs,tmpfs,...) ごとに、手続きの実体は異なるが、インタフェースは同じ。
linux-3.1.3/include/linux/fs.h 1593: struct inode_operations { 1594: struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); 1595: void * (*follow_link) (struct dentry *, struct nameidata *); 1596: int (*permission) (struct inode *, int); 1597: struct posix_acl * (*get_acl)(struct inode *, int); 1598: 1599: int (*readlink) (struct dentry *, char __user *,int); 1600: void (*put_link) (struct dentry *, struct nameidata *, void *); 1601: 1602: int (*create) (struct inode *,struct dentry *,int, struct nameidata *); 1603: int (*link) (struct dentry *,struct inode *,struct dentry *); 1604: int (*unlink) (struct inode *,struct dentry *); 1605: int (*symlink) (struct inode *,struct dentry *,const char *); 1606: int (*mkdir) (struct inode *,struct dentry *,int); 1607: int (*rmdir) (struct inode *,struct dentry *); 1608: int (*mknod) (struct inode *,struct dentry *,int,dev_t); 1609: int (*rename) (struct inode *, struct dentry *, 1610: struct inode *, struct dentry *); 1611: void (*truncate) (struct inode *); 1612: int (*setattr) (struct dentry *, struct iattr *); 1613: int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); 1614: int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); 1615: ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); 1616: ssize_t (*listxattr) (struct dentry *, char *, size_t); 1617: int (*removexattr) (struct dentry *, const char *); 1618: void (*truncate_range)(struct inode *, loff_t, loff_t); 1619: int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 1620: u64 len); 1621: } ____cacheline_aligned;
p->files->fd_array[fd]
の struct file を表
す。
linux-3.1.3/include/linux/sched.h 1220: struct task_struct { ... 1386: struct files_struct *files; ... 1572: }; linux-3.1.3/include/linux/fdtable.h 44: struct files_struct { ... 58: struct file __rcu * fd_array[NR_OPEN_DEFAULT]; 59: };
図? task_struct、ファイル記述子、file構造体
linux-3.1.3/fs/read_write.c 444: SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 445: { 446: struct file *file; 447: ssize_t ret = -EBADF; 448: int fput_needed; 449: 450: file = fget_light(fd, &fput_needed); 451: if (file) { 452: loff_t pos = file_pos_read(file); 453: ret = vfs_read(file, buf, count, &pos); 454: file_pos_write(file, pos); 455: fput_light(file, fput_needed); 456: } 457: 458: return ret; 459: }
348: ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 349: { 350: ssize_t ret; 351: 352: if (!(file->f_mode & FMODE_READ)) 353: return -EBADF; 354: if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) 355: return -EINVAL; 356: if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) 357: return -EFAULT; 358: 359: ret = rw_verify_area(READ, file, pos, count); 360: if (ret >= 0) { 361: count = ret; 362: if (file->f_op->read) 363: ret = file->f_op->read(file, buf, count, pos); 364: else 365: ret = do_sync_read(file, buf, count, pos); 366: if (ret > 0) { 367: fsnotify_access(file); 368: add_rchar(current, ret); 369: } 370: inc_syscr(current); 371: } 372: 373: return ret; 374: }
linux-3.1.3/fs/ext4/file.c 276: const struct file_operations ext4_file_operations = { 277: .llseek = ext4_llseek, 278: .read = do_sync_read, 279: .write = do_sync_write, 280: .aio_read = generic_file_aio_read, 281: .aio_write = ext4_file_write, 282: .unlocked_ioctl = ext4_ioctl, 283: #ifdef CONFIG_COMPAT 284: .compat_ioctl = ext4_compat_ioctl, 285: #endif 286: .mmap = ext4_file_mmap, 287: .open = ext4_file_open, 288: .release = ext4_release_file, 289: .fsync = ext4_sync_file, 290: .splice_read = generic_file_splice_read, 291: .splice_write = generic_file_splice_write, 292: .fallocate = ext4_fallocate, 293: }; 295: const struct inode_operations ext4_file_inode_operations = { ... 306: }; linux-3.1.3/fs/ext4/super.c 1256: static const struct super_operations ext4_sops = { ... 1275: };
linux-3.1.3/fs/ext4/ext4.h 761: struct ext4_inode_info { 762: __le32 i_data[15]; /* unconverted */ 763: __u32 i_dtime; 764: ext4_fsblk_t i_file_acl; ... 821: struct inode vfs_inode; ... 869: }; 1230: static inline struct ext4_inode_info *EXT4_I(struct inode *inode) 1231: { 1232: return container_of(inode, struct ext4_inode_info, vfs_inode); 1233: } linux-3.1.3/include/linux/kernel.h 653: #define container_of(ptr, type, member) ({ \ 654: const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 655: (type *)( (char *)__mptr - offsetof(type,member) );} )
図? Ext4 ファイルシステムで使う構造体 ext4_inode_info での struct inode の保持
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ... ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->/*空欄(a)*/) ret = /*空欄(b)*/(/*空欄(c)*/, buf, count, pos); ... } return ret; }