Linux|Linux Virtual FileSystem

Linux 成功的关键因素之一主是具有与其他操作系统和谐共存的能力。你能够透明地安装具有其他操作系统文件格式的磁盘文件或分区。这些操作包括windows unix mac等等。通过这虚拟文件系统的概念,Linux 使用与其他Unix 变体相同的方式设法支持多种系统类型。
虚拟文件系统所隐含的思想是把很多不同种类的文件系统和共同信息放入内核;其中有一个字段或者函数来支持Linux 所支持的所有实际文件系统提供的任何操作。地所调用的每个读,写或其他函数。内核能把它们替换成支持本地Linux 文件系统,ntfs文件系统,或者文件所在的任何其他文件系统的实际函数。
虚拟文件系统的作用 虚拟文件系统(Virtual FileSystem) 也可以称为虚拟文件系统转换(Virtual FileSystem Switch VFS),是一个内核软件层,用来处理与unix标准文凭系统相关的所有操作系统调用。其健壮性表现在能为各种文件系统提供一个通用的接口。
例如

Linux|Linux Virtual FileSystem
文章图片
copy.jpeg

cp /floppy/test /tmp/test

其中floppy 是ms-doc磁盘的一个安装点,而/tmp 是一个标准的ext2 文件系统的目录。vfs是用户的应用程序与文件系统之间的抽象层。因此cp程序不需要知道/floppy/test 和/tmp/test 具体是什么文件系统。相反,cp程序直接与vfs交互,这是通过unix程序设计人员都熟悉的普通系统调用来完成的。
vfs支持的文件系统可分为三种
  • 磁盘文件系统
    包括linux unix windows等操作系统支持的文件系统.
  • 网络文件系统
  • 特殊文件系统
通过文件模型 VFS 所隐含的主要思想是引入一个通过用的文件系统模型(common file system),这个模型能够表示所有支持的文件系统。该模型严格反映传统unix 文件系统提供的文件模型。这并不奇怪,因为linux 希望以最小的额外开销运动它本地的文件系统。不过,要实现每个具体的系统,必须将其物理组织转换为虚拟文件系统的通用文件模型。
通用文件模型由下列对象类型组成:
  • 超级块对象(Super block)
    存放已安装文件系统的有关信息。对基于磁盘的文件系统,这类对象通常对应于放在磁盘上的文件系统的控制块(file system control block)
  • 【Linux|Linux Virtual FileSystem】索引节点(inode object)
    存放关于具体文件的一般信息(对文件的描述信息)。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件控制块(file control block)。每个索引节点都一个索引节点号,这个节点号唯一地标识文件系统中的文件。
  • 文件对象
    存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间存在于内存中。
  • 目录项对象(dentry object)
    存放目录项(也就是文件的特定名称)与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。
进程与vfs之间的交互 Linux|Linux Virtual FileSystem
文章图片
vfs.jpeg 三个不同的进程打开同一个文件,其中两个进程(1,2)使用同一个硬链接。在这种情况下其中每个进程都使用自己的文件对象,但只需要两个目录项对象,每个硬链接对应一个目录项对象。这两个目录项指向同一个索引节点对象该索引节点对象标识超级块对象,以及随后的普通磁盘文件。
vfs 除了能为所有文件系统的实现提供一个通用的接口外,还具有另一个与系统性能相关的重要作用。最近最常使用的目录项对象被放入所谓目录项高速缓存(dentry cache)磁盘高速缓存中,以加速从文件路径名到最后一个路径分量的索引节点转换过程。
vfs的数据结构
  • 超级块对象征(super block)
struct super_block { struct list_heads_list; /* list of all superblocks */ dev_ts_dev; /* identifier */ unsigned longs_blocksize; /* block size in bytes */ unsigned longs_old_blocksize; /* old block size in bytes */ unsigned chars_blocksize_bits; /* block size in bits */ unsigned chars_dirt; /* dirty flag */ unsigned long longs_maxbytes; /* max file size */ struct file_system_type s_type; /* filesystem type */ struct super_operations s_op; /* superblock methods */ struct dquot_operations *dq_op; /* quota methods */ struct quotactl_ops*s_qcop; /* quota control methods */ struct export_operations *s_export_op; /* export methods */ unsigned longs_flags; /* mount flags */ unsigned longs_magic; /* filesystem's magic number */ struct dentry*s_root; /* directory mount point */ struct rw_semaphores_umount; /* unmount semaphore */ struct semaphores_lock; /* superblock semaphore */ ints_count; /* superblock ref count */ ints_syncing; /* filesystem syncing flag */ ints_need_sync_fs; /* not-yet-synced flag */ atomic_ts_active; /* active reference count */ void*s_security; /* security module */ struct list_heads_dirty; /* list of dirty inodes */ struct list_heads_io; /* list of writebacks */ struct hlist_heads_anon; /* anonymous dentries */ struct list_heads_files; /* list of assigned files */ struct block_device*s_bdev; /* associated block device */ struct list_heads_instances; /* instances of this fs */ struct quota_infos_dquot; /* quota-specific options */ chars_id[32]; /* text name */ void*s_fs_info; /* filesystem-specific info */ struct semaphores_vfs_rename_sem; /* rename semaphore */ };

struct super_operations { struct inode *(*alloc_inode) (struct super_block *sb); void (*destroy_inode) (struct inode *); void (*read_inode) (struct inode *); void (*dirty_inode) (struct inode *); void (*write_inode) (struct inode *, int); void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); void (*write_super) (struct super_block *); int (*sync_fs) (struct super_block *, int); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); int (*statfs) (struct super_block *, struct statfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); int (*show_options) (struct seq_file *, struct vfsmount *); };

  • 索引节点对象
struct inode { struct hlist_nodei_hash; /* hash list */ struct list_headi_list; /* list of inodes */ struct list_headi_dentry; /* list of dentries */ unsigned longi_ino; /* inode number */ atomic_ti_count; /* reference counter */ umode_ti_mode; /* access permissions */ unsigned inti_nlink; /* number of hard links */ uid_ti_uid; /* user id of owner */ gid_ti_gid; /* group id of owner */ kdev_ti_rdev; /* real device node */ loff_ti_size; /* file size in bytes */ struct timespeci_atime; /* last access time */ struct timespeci_mtime; /* last modify time */ struct timespeci_ctime; /* last change time */ unsigned inti_blkbits; /* block size in bits */ unsigned longi_blksize; /* block size in bytes */ unsigned longi_version; /* version number */ unsigned longi_blocks; /* file size in blocks */ unsigned shorti_bytes; /* bytes consumed */ spinlock_ti_lock; /* spinlock */ struct rw_semaphorei_alloc_sem; /* nests inside of i_sem */ struct semaphorei_sem; /* inode semaphore */ struct inode_operations *i_op; /* inode ops table */ struct file_operations*i_fop; /* default inode ops */ struct super_block*i_sb; /* associated superblock */ struct file_lock*i_flock; /* file lock list */ struct address_space*i_mapping; /* associated mapping */ struct address_spacei_data; /* mapping for device */ struct dquot*i_dquot[MAXQUOTAS]; /* disk quotas for inode */ struct list_headi_devices; /* list of block devices */ struct pipe_inode_info*i_pipe; /* pipe information */ struct block_device*i_bdev; /* block device driver */ unsigned longi_dnotify_mask; /* directory notify mask */ struct dnotify_struct*i_dnotify; /* dnotify */ unsigned longi_state; /* state flags */ unsigned longdirtied_when; /* first dirtying time */ unsigned inti_flags; /* filesystem flags */ unsigned chari_sock; /* is this a socket? */ atomic_ti_writecount; /* count of writers */ void*i_security; /* security module */ __u32i_generation; /* inode version number */ union { void*generic_ip; /* filesystem-specific info */ } u; };

struct inode_operations { int (*create) (struct inode *, struct dentry *,int); struct dentry * (*lookup) (struct inode *, struct dentry *); int (*link) (struct dentry *, struct inode *, struct dentry *); int (*unlink) (struct inode *, struct dentry *); int (*symlink) (struct inode *, struct dentry *, const char *); int (*mkdir) (struct inode *, struct dentry *, int); int (*rmdir) (struct inode *, struct dentry *); int (*mknod) (struct inode *, struct dentry *, int, dev_t); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char *, int); int (*follow_link) (struct dentry *, struct nameidata *); int (*put_link) (struct dentry *, struct nameidata *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *, size_t, int); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); };

  • 文件对象
struct file { struct list_headf_list; /* list of file objects */ struct dentry*f_dentry; /* associated dentry object */ struct vfsmount*f_vfsmnt; /* associated mounted fs */ struct file_operations *f_op; /* file operations table */ atomic_tf_count; /* file object's usage count */ unsigned intf_flags; /* flags specified on open */ mode_tf_mode; /* file access mode */ loff_tf_pos; /* file offset (file pointer) */ struct fown_structf_owner; /* owner data for signals */ unsigned intf_uid; /* user's UID */ unsigned intf_gid; /* user's GID */ intf_error; /* error code */ struct file_ra_statef_ra; /* read-ahead state */ unsigned longf_version; /* version number */ void*f_security; /* security module */ void*private_data; /* tty driver hook */ struct list_headf_ep_links; /* list of eventpoll links */ spinlock_tf_ep_lock; /* eventpoll lock */ struct address_space*f_mapping; /* page cache mapping */ };

struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int); int (*aio_fsync) (struct kiocb *, int); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags) (int flags); int (*dir_notify) (struct file *filp, unsigned long arg); int (*flock) (struct file *filp, int cmd, struct file_lock *fl); };

  • 目录项对象
struct dentry { atomic_td_count; /* usage count */ unsigned longd_vfs_flags; /* dentry cache flags */ spinlock_td_lock; /* per-dentry lock */ struct inode*d_inode; /* associated inode */ struct list_headd_lru; /* unused list */ struct list_headd_child; /* list of dentries within */ struct list_headd_subdirs; /* subdirectories */ struct list_headd_alias; /* list of alias inodes */ unsigned longd_time; /* revalidate time */ struct dentry_operations *d_op; /* dentry operations table */ struct super_block*d_sb; /* superblock of file */ unsigned intd_flags; /* dentry flags */ intd_mounted; /* is this a mount point? */ void*d_fsdata; /* filesystem-specific data */ struct rcu_headd_rcu; /* RCU locking */ struct dcookie_struct*d_cookie; /* cookie */ struct dentry*d_parent; /* dentry object of parent */ struct qstrd_name; /* dentry name */ struct hlist_noded_hash; /* list of hash table entries */ struct hlist_head*d_bucket; /* hash bucket */ unsigned chard_iname[DNAME_INLINE_LEN_MIN]; /* short name */ };

struct dentry_operations { int (*d_revalidate) (struct dentry *, int); int (*d_hash) (struct dentry *, struct qstr *); int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); int (*d_delete) (struct dentry *); void (*d_release) (struct dentry *); void (*d_iput) (struct dentry *, struct inode *); };

参考文献<<深入理解Linux 内核>>
https://www.jianshu.com/p/dd3f751407f0

    推荐阅读