美文网首页
Linux Virtual FileSystem

Linux Virtual FileSystem

作者: zh_harry | 来源:发表于2018-10-27 12:36 被阅读0次

    Linux 成功的关键因素之一主是具有与其他操作系统和谐共存的能力。你能够透明地安装具有其他操作系统文件格式的磁盘文件或分区。这些操作包括windows unix mac等等。通过这虚拟文件系统的概念,Linux 使用与其他Unix 变体相同的方式设法支持多种系统类型。

    虚拟文件系统所隐含的思想是把很多不同种类的文件系统和共同信息放入内核;其中有一个字段或者函数来支持Linux 所支持的所有实际文件系统提供的任何操作。地所调用的每个读,写或其他函数。内核能把它们替换成支持本地Linux 文件系统,ntfs文件系统,或者文件所在的任何其他文件系统的实际函数。

    虚拟文件系统的作用

    虚拟文件系统(Virtual FileSystem) 也可以称为虚拟文件系统转换(Virtual FileSystem Switch VFS),是一个内核软件层,用来处理与unix标准文凭系统相关的所有操作系统调用。其健壮性表现在能为各种文件系统提供一个通用的接口。
    例如


    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)

    • 索引节点(inode object)
      存放关于具体文件的一般信息(对文件的描述信息)。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件控制块(file control block)。每个索引节点都一个索引节点号,这个节点号唯一地标识文件系统中的文件。

    • 文件对象
      存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间存在于内存中。

    • 目录项对象(dentry object)
      存放目录项(也就是文件的特定名称)与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。

    进程与vfs之间的交互

    vfs.jpeg

    三个不同的进程打开同一个文件,其中两个进程(1,2)使用同一个硬链接。在这种情况下其中每个进程都使用自己的文件对象,但只需要两个目录项对象,每个硬链接对应一个目录项对象。这两个目录项指向同一个索引节点对象该索引节点对象标识超级块对象,以及随后的普通磁盘文件。

    vfs 除了能为所有文件系统的实现提供一个通用的接口外,还具有另一个与系统性能相关的重要作用。最近最常使用的目录项对象被放入所谓目录项高速缓存(dentry cache)磁盘高速缓存中,以加速从文件路径名到最后一个路径分量的索引节点转换过程。

    vfs的数据结构

    • 超级块对象征(super block)
    struct super_block {
            struct list_head        s_list;            /* list of all superblocks */
            dev_t                   s_dev;             /* identifier */
            unsigned long           s_blocksize;       /* block size in bytes */
            unsigned long           s_old_blocksize;   /* old block size in bytes */
            unsigned char           s_blocksize_bits;  /* block size in bits */
            unsigned char           s_dirt;            /* dirty flag */
            unsigned long long      s_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 long            s_flags;          /* mount flags */
            unsigned long            s_magic;          /* filesystem's magic number */
            struct dentry            *s_root;          /* directory mount point */
            struct rw_semaphore      s_umount;         /* unmount semaphore */
            struct semaphore         s_lock;           /* superblock semaphore */
            int                      s_count;          /* superblock ref count */
            int                      s_syncing;        /* filesystem syncing flag */
            int                      s_need_sync_fs;   /* not-yet-synced flag */
            atomic_t                 s_active;         /* active reference count */
            void                     *s_security;      /* security module */
            struct list_head         s_dirty;          /* list of dirty inodes */
            struct list_head         s_io;             /* list of writebacks */
            struct hlist_head        s_anon;           /* anonymous dentries */
            struct list_head         s_files;          /* list of assigned files */
            struct block_device      *s_bdev;          /* associated block device */
            struct list_head         s_instances;      /* instances of this fs */
            struct quota_info        s_dquot;          /* quota-specific options */
            char                     s_id[32];         /* text name */
            void                     *s_fs_info;       /* filesystem-specific info */
            struct semaphore         s_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_node       i_hash;              /* hash list */
            struct list_head        i_list;              /* list of inodes */
            struct list_head        i_dentry;            /* list of dentries */
            unsigned long           i_ino;               /* inode number */
            atomic_t                i_count;             /* reference counter */
            umode_t                 i_mode;              /* access permissions */
            unsigned int            i_nlink;             /* number of hard links */
            uid_t                   i_uid;               /* user id of owner */
            gid_t                   i_gid;               /* group id of owner */
            kdev_t                  i_rdev;              /* real device node */
            loff_t                  i_size;              /* file size in bytes */
            struct timespec         i_atime;             /* last access time */
            struct timespec         i_mtime;             /* last modify time */
            struct timespec         i_ctime;             /* last change time */
            unsigned int            i_blkbits;           /* block size in bits */
            unsigned long           i_blksize;           /* block size in bytes */
            unsigned long           i_version;           /* version number */
            unsigned long           i_blocks;            /* file size in blocks */
            unsigned short          i_bytes;             /* bytes consumed */
            spinlock_t              i_lock;              /* spinlock */
            struct rw_semaphore     i_alloc_sem;         /* nests inside of i_sem */
            struct semaphore        i_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_space    i_data;              /* mapping for device */
            struct dquot            *i_dquot[MAXQUOTAS]; /* disk quotas for inode */
            struct list_head        i_devices;           /* list of block devices */
            struct pipe_inode_info  *i_pipe;             /* pipe information */
            struct block_device     *i_bdev;             /* block device driver */
            unsigned long           i_dnotify_mask;      /* directory notify mask */
            struct dnotify_struct   *i_dnotify;          /* dnotify */
            unsigned long           i_state;             /* state flags */
            unsigned long           dirtied_when;        /* first dirtying time */
            unsigned int            i_flags;             /* filesystem flags */
            unsigned char           i_sock;              /* is this a socket? */
            atomic_t                i_writecount;        /* count of writers */
            void                    *i_security;         /* security module */
            __u32                   i_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_head       f_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_t               f_count;       /* file object's usage count */
            unsigned int           f_flags;       /* flags specified on open */
            mode_t                 f_mode;        /* file access mode */
            loff_t                 f_pos;         /* file offset (file pointer) */
            struct fown_struct     f_owner;       /* owner data for signals */
            unsigned int           f_uid;         /* user's UID */
            unsigned int           f_gid;         /* user's GID */
            int                    f_error;       /* error code */
            struct file_ra_state   f_ra;          /* read-ahead state */
            unsigned long          f_version;     /* version number */
            void                   *f_security;   /* security module */
            void                   *private_data; /* tty driver hook */
            struct list_head       f_ep_links;    /* list of eventpoll links */
            spinlock_t             f_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_t                 d_count;      /* usage count */
            unsigned long            d_vfs_flags;  /* dentry cache flags */
            spinlock_t               d_lock;       /* per-dentry lock */
            struct inode             *d_inode;     /* associated inode */
            struct list_head         d_lru;        /* unused list */
            struct list_head         d_child;      /* list of dentries within */
            struct list_head         d_subdirs;    /* subdirectories */
            struct list_head         d_alias;      /* list of alias inodes */
            unsigned long            d_time;       /* revalidate time */
            struct dentry_operations *d_op;        /* dentry operations table */
            struct super_block       *d_sb;        /* superblock of file */
            unsigned int             d_flags;      /* dentry flags */
            int                      d_mounted;    /* is this a mount point? */
            void                     *d_fsdata;    /* filesystem-specific data */
            struct rcu_head          d_rcu;        /* RCU locking */
            struct dcookie_struct    *d_cookie;    /* cookie */
            struct dentry            *d_parent;    /* dentry object of parent */
            struct qstr              d_name;       /* dentry name */
            struct hlist_node        d_hash;       /* list of hash table entries */
            struct hlist_head        *d_bucket;    /* hash bucket */
            unsigned char            d_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

    相关文章

      网友评论

          本文标题:Linux Virtual FileSystem

          本文链接:https://www.haomeiwen.com/subject/xgqdtqtx.html