VFS主要数据结构与sys_read浅析

文件系统即对文件存储器空间进行组织和分配。
linux采用树状结构,最上层为根目录,而其他所有目录都从根目录出发,即只有一棵树,而DOS和Windows则不同,其也是树状结构但最上层为磁盘分区的盘符,即有多少分区则有多少棵树。linux这样设计有助于对其多用户下的系统文件及用户文件进行管理

为了linux的开放性,设计人员必须将不同文件系统的操作和管理纳入统一的框架,于是虚拟文件系统(VFS)就为此而生,其实际上是一组系统调用,但是能够对各种不同的文件系统及文件进行操作

linux VFS核心数据结构:

linux中实现文件系统的核心就是其所用到的各种数据结构,主要有4种:索引节点、超级块、目录项及文件对象

1、索引节点(inode):

索引节点包含了一个文件的所有信息,当文件系统要对一个文件进行操作时,主要依靠inode数据结构来提供信息
我们可以通过stat 文件名来查看某一个文件的inode信息

struct inode {      /*文件索引节点*/
    struct hlist_node   i_hash;     /*哈希表*/
    struct list_head    i_list;     /* backing dev IO list */   /*索引节点的链表*/
    struct list_head    i_sb_list;          /*超级块链表*/
    struct list_head    i_dentry;       /*目录项链表*/
    unsigned long       i_ino;      /*文件节点号,唯一表示一个文件系统中的一个文件*/
    atomic_t        i_count;        /*引用计数*/
    unsigned int        i_nlink;        /*文件的硬链接数*/
    uid_t           i_uid;      /*拥有者id*/
    gid_t           i_gid;      /*拥有组id*/
    dev_t           i_rdev;     /*设备标识符*/
    u64         i_version;      /*版本号*/
    loff_t          i_size;     /*文件大小,以字节为单位*/
#ifdef __NEED_I_SIZE_ORDERED
    seqcount_t      i_size_seqcount;        /*对i_size进行串行计数*/
#endif
    struct timespec     i_atime;        /*文件最后一次被访问的时间*/
    struct timespec     i_mtime;        /*文件最后一次被修改的时间*/
    struct timespec     i_ctime;        /*文件的inode被修改的时间*/
    blkcnt_t        i_blocks;       /*文件所占的块数*/
    unsigned int        i_blkbits;      /*块的大小,单位是位*/
    unsigned short          i_bytes;        /*用的字节数*/
    umode_t         i_mode;         /*访问的权限*/
    spinlock_t      i_lock; /* i_blocks, i_bytes, maybe i_size */
    struct mutex        i_mutex;
    struct rw_semaphore i_alloc_sem;
    const struct inode_operations   *i_op;      /*索引节点的操作表*/
    const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
    struct super_block  *i_sb;      /*与此索引节点相关的超级块*/
    struct file_lock    *i_flock;
    struct address_space    *i_mapping;     /*地址映射*/
    struct address_space    i_data;         /*设备地址映射*/
        ...

    struct list_head    i_devices;
    union {
        struct pipe_inode_info  *i_pipe;        /*如果此文件是一个管道,记录管道信息*/
        struct block_device *i_bdev;        /*指向块设备驱动程序*/
        struct cdev     *i_cdev;        /*指向字符设备驱动程序*/
    };
        ...

    unsigned long       i_state;        /*inde的状态标识符*/
    unsigned long       dirtied_when;   /* jiffies of first dirtying */

    unsigned int        i_flags;        /*文件系统标志*/

    atomic_t        i_writecount;       /*写者计数*/
        ...
};

可以看到里面基本包含了所有关于文件的信息,不过却没有文件名,这是跟linux中的符号链接有关,在后面进行解释,不过正是因为这种索引节点号与文件名分离的设计,导致一些Linux中的特殊情况:
 1. 文件名包含特殊字符,无法正常删除时,直接删除inode节点,就能起到删除文件的作用。
 2. 移动文件或重命名文件,只是改变文件名,不影响inode号码。
 3. 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。

inode会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令df -i
由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

当我们通过文件名来打开文件时,基本分为3步:1、根据文件名找到对应的索引节点号;2、根据索引节点号找到对应的inode结构;3、根据inode中的信息找到对应的block,读出数据。
我们可以通过ls -i 文件名来查看一个文件的inode号

2、超级块(super_block)

超级块是用来描述文件系统的信息,对于每个文件系统都有其自己的超级块,其在文件系统安装时建立,在文件系统卸载时自动删除


                
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值