340 likes | 568 Views
Virtual Filesystem. 924362 呂佳翰 926327 莊維哲 Oct. 29, 2004. Outline. VFS Common file model superblock, inode, file, dentry file_system_type, vfsmount Mount and unmount. Virtual Filesystem (VFS). $ cp /floppy/TEST /tmp/test. P.373, Understanding the Linux Kernel, 2nd Ed.
E N D
Virtual Filesystem 924362 呂佳翰 926327 莊維哲 Oct. 29, 2004
Outline • VFS • Common file model • superblock, inode, file, dentry • file_system_type, vfsmount • Mount and unmount
Virtual Filesystem (VFS) • $ cp /floppy/TEST /tmp/test P.373, Understanding the Linux Kernel, 2nd Ed.
Virtual Filesystem (VFS) (Cont’d) • Basics • Abstraction between application program and filesystem implementations • Common interface to kinds of filesystems • System calls related to a standard Unix filesystem • Disk-based filesystems • Second Extended Filesystem (Ext2), Third Extended Filesystem (Ext3) • SYSV filesystem, UFS filesystem • VFAT, NTFS • ISO9660 CD-ROM filesystem, UDF DVD filesystem • Network filesystems • NFS, SMB, and NCP • Special filesystems (virtual filesystems) • /proc
Common File Model • Common File Model • Key idea • Mirror the file model provided by the traditional Unix filesystem • Object-oriented • Each directory as a file • Point to proper function • read( ), write( ) • file->f_op->read(…) file->f_op->write(…) • Assigning right set pointers to the file variable
Common File Model (Cont’d) • Superblock object • Mounted filesystem • Filesystem control block on disk • Inode object • Specific file • File control block on disk • File object • Exists in kernel memory upon process existence • Interaction between an file and a process • Dentry object • Linking of a directory entry with corresponding file • /tmp/test
Common File Model (Cont’d) P.376, Understanding the Linux Kernel, 2nd Ed.
Common File Model (Cont’d) Wu Chia-Chih, “Linux Virtual File System”, Linux Kernel Trace Seminar, Jun. 3, 2002 (PowerPoint)
Superblock Object include/linux/fs.h
Superblock Object (Cont’d) • Circular doubly linked list • super_blocks, s_list • Specific filesystem information • s_fs_info (u in 2.4), s_dirt • Duplicated in memory from disk • Synchronization issue
Inode Object include/linux/fs.h
Inode Object (Cont’d) • i_count, s_dirty • Circular doubly linked lists • Valid unused inodes (inode_unused) • In-use inodes (inode_in_use) • Dirty inodes (s_dirty) • i_op as inode_operations • link(old_dentry, dir, new_dentry), unlink(dir, dentry) • symlink(dir, dentry, symname), follow_link(inode, dir) • mkdir(dir, dentry, mode), rmdir(dir, dentry) • etc. • i_fop as file_operations
File Object include/linux/fs.h
File Object • File pointer, the current position in the file from which the next operation will take place • Circular doubly linked lists (f_count) • “Unused” (free_list) • “In use” but not assigned to a superblock (anno_list) • “In use” and assigned to a superblock (s_list) • f_op as file_operations • read(file, buf, count, offset), write(file, buf , count, offset) • open(inode, file) • etc.
Dentry Object include/linux/d_dcache.h
Dentry Object (Cont’d) dentry-inode relationship(d_alias, d_inode, i_dentry) dentry tree relationship(d_parent, d_child, d_subdirs) i_dentry d_parent pointer d_inode pointer inode dentry Modified from Peter J. Braam, “Linux Virtual File System”, CMU(PowerPoint file)
Dentry Object (Cont’d) • Each directory as a file that contains a list of files and other directories • No image on disk and hence no field in the dentry structure to tell whether modified or not • Four states (d_count, d_inode) • Free • Unused • In use • Negative
Dentry Cache • Time consuming reading a directory entry from disk and constructing dentry object • Set of dentry objects in the in-use, unused, or negative state • Hash table do derive the dentry object associated with a given filename and a given directory • Inode cache • “unused” dentries • Doubly linked “Least Recently Used” list (d_lru, dentry_unused) • Remove elements from the tail when dentry cache has to shrink • “in use” dentries • Doubly linked list (i_dentry, d_alias)
Files Associated with a Process • fs_struct (include/linux/fs_struct.h) • Current working directory, root directory
Files Associated with a Process (Cont’d) • files_struct (include/linux/file.h) • Files opened • Array index in the fd array is the file descriptor
Files Associated with a Process (Cont’d) P.394, Understanding the Linux Kernel, 2nd Ed.
file_system_type • Simply linked list
vfsmount • The mount point, the mount flags, and the relationships between the filesystem to be mounted and the other mounted filesystems • vfsmount (include/linux/mount.h) as mounted filesystem descriptor
Mounting Root Filesystem • It’s a fairly complex procedure because the Linux kernel allows the root filesystem to be stored in many different places • While the system boots, the kernel finds the major number of the disk that contains the root filesystem in the ROOT_DEV variable • The root filesystem can be specified as a device file in the /dev • Mount flags of the root filesystem are stored in the root_mountflags variable • Specified them either by using the rdev external program on a compiled kernel image or by passing a suitable rootflags option to the initial bootstrap loader
Mounting Root Filesystem (Cont’d) • Two-stage procedure • The kernel mounts the special rootfs filesystem, which just provides an empty directory that serves as initial mount point (init_mount_tree( ), do_kern_mount( )) • The kernel mounts the real root filesystem over the empty directory (mount_root) • The rootfs filesystem allows the kernel to easily change the real root filesystem
do_kern_mount • type, flags, name, data • root_vfsmount = do_kern_mount(“rootfs”, 0, “rootfs”, NULL) • Check whether the current process has the privileges for the mount operation • Search in the list of filesystem and locate the name stored in the type parameter (get_fs_type( )) • Allocate a new mounted filesystem descriptor and stores its address in the mnt local variable (alloc_vfsmnt( )) • Initializes the mnt->mnt_devname field • Allocates a new superblock and initialized it (file_system_type) • FS_REQUIRES_DEV, FS_SINGLE • Initializes the mnt->mnt_sb, mnt->mnt_root, mnt->mnt_mountpoint, and mnt_parent • Return the address mnt of the mounted filesystem object
mount_root • Allocates a buffer and fills it with a list of filesystem type names • Check whether the ROOT_DEV root device exists and is properly working • Search for a superblock object associated with ROOT_DEV (get_super( )). Usually the root filesystem is mounted twice during the system boot • Scans the list of filesystem type names built in Step 1. Allocates a new superlock object and attemps to fill it, and creates an inode object and a dentry object for the root directory (get_fs_type( ), read_super( )) • Allocates a new mounted filesystem object and initializes its fields, and inserts it in the children list of root_vfsmnt, in the global list of mounted filesystem objects, and in the mount_hashtable hash table • Sets the root and pwd fields of the fs_struct table of current (the init process) to the dentry object of the root directory
Mounting a Generic Filesystem • Once the root filesystem is initialized, additional filesystems may be mounted. Each must have its own mount point, which is just an already existing directory in the system’s directory tree • sys_mount( ) in mount( ) copies the value of the parameters into temporary kernel buffers and invokes the do_mount( ) • Pathname of a device file containing the filesystem • Pathname of the directory on which the filesystem will be mounted (the mount point) • Filesystem type • Mount flags • Pointer to a filesystem-dependent data structure
do_mount( ) • Check if any of the MS_NOSUID, MS_NODEV, or MS_EXEC flags passed as a parameter • Looks up the pathname of the mount point (path_init( ), path_walk( )) • Examines the mount flags to determine what has to be done • The most case is to invoke do_add_mount( ) • User asks to mount either a special filesytem or a regular filesystem stored in a disk partition • Invokes do_kern_mount( ) passing, to it the filesystem type, the mount flags, and the block device name • Initialized the flags in the mnt_flags field of the new mounted filesystem object • Insert the new mounted filesystem object in the global list, in the hash table, and in the children list of the parent-mounted filesystem • Teminates the pathname lookup of the mount point (path_release( ))
Unmounting a Filesystem • umount( ) • A filename and a set of flags • Looks up the mount point pathname and check if the resulting directory is the mount point of a filesystem • Check if the filesystem has been mounted • Check the privileges required to unmount the filesystem • do_umount( ) • Retrives the address of the superblock object • Check if it’s required to force unmount operation • Check if the filesystem to be unmounted is the root filesystem and the user didn’t ask to actually detach it. • If the mounted filesystem does not include mount points for any child mounted filesystem, or if the user asked to forcibly detach the filesystem, invokes umount_tree( ) to unmount the filesystem (together with all children)
Appendix A: Symbolic Link in Ext2 • i_mode in Ext2 disk inode
Appendix B: u in super_block (2.4) union { struct minix_sb_info minix_sb; struct ext2_sb_info ext2_sb; struct ext3_sb_info ext3_sb; struct hpfs_sb_info hpfs_sb; struct ntfs_sb_info ntfs_sb; struct msdos_sb_info msdos_sb; struct isofs_sb_info isofs_sb; /*ommited*/ struct cramfs_sb_info cramfs_sb; void *generic_sbp; } u;
struct hlist_head { struct hlist_node *first; }; struct hlist_node { struct hlist_node *next, **pprev; }; struct list_head { struct list_head *next,*prev; }; Appendix C: hlist_head, h_listnode (include/linux/list.h)