linux文件打开过程分析

本文介绍了Linux文件系统的基本概念,重点分析了Linux虚拟文件系统(VFS)的作用和设计,包括VFS支持的文件系统类型,通用文件系统模型中的主要数据结构如超级块、索引节点、文件对象和目录项对象。还详细讨论了文件打开过程,以及VFS如何处理文件系统安装和系统调用的实现。
摘要由CSDN通过智能技术生成

文件系统概念:

文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中。
磁盘组成示意图
· 文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。
文件系统是一种用于向用户提供底层数据访问的机制。它将设备中的空间划分为特定大小的块(扇区),一般每块512字节。数据存储在这些块中,大小被修正为占用整数个块。由文件系统软件来负责将这些块组织为文件和目录(即用户可以直接通过文件路径和文件名来访问磁盘数据,而不需要知道数据存储的扇区位置等信息),并记录哪些块被分配给了哪个文件,以及哪些块没有被使用。

linux虚拟文件(VFS)系统

VFS可以理解为 虚拟文件系统virtual filesystem 也可以理解为 虚拟文件系统转换virtual filesystem switch,是一个内核软件层,用来处理与unix标准文件系统相关的所有系统调用。其主要作用是为各种文件系统提供了统一接口。例如:使用同一个read函数可以读取U盘数据(FAT),也可以读取硬盘数据(Ext2),以及光盘数据(CD-ROM)。
linux虚拟文件系统

VFS支持的文件系统主要分为三类

磁盘文件系统:这些文件系统管理在本地磁盘分区中可用的存储空间或者其他可以起到磁盘作用的设备(如U盘)。Ext2/3 System V,MINIX,MS-DOS,VFAT,NTFS,CD-ROM等。
网络文件系统:这些文件可以轻易访问属于其他网络计算机的文件系统所包含的文件。虚拟文件系统所支持的一些网络文件系统有:NFS, Coda, NCP
特殊文件系统:这些文件系统不管理本地或远程磁盘空间。例如基于内存的/proc文件系统。

通用文件系统模型

在通用文件系统中目录被看做文件,每个文件操作都是通过指针实现,不同的文件系统所使用的操作指针不同。

通用系统模型由下列对象类型组成(主要数据结构):
超级块结构(struct super_block {…} ) 超级块对象
该结构保存了一个被安装在linux系统上的文件系统的信息。对于基于磁盘的文件系统,该结构一般和保存在磁盘上的”文件系统控制块”对应。也就是说如果是磁盘文件系统,该结构保存的磁盘文件系统的控制信息。
inode结构( struct inode {…} ) 索引节点对象
该结构中存储的是一个具体文件的一般信息,对于一个基于磁盘的文件系统,该结构对应磁盘上的”文件数据控制块”。每一个inode结构都对应一个inode节点号,这个节点号是唯一的,它也唯一标识一个文件系统中的文件。
file结构( struct file {…} ) 文件对象
该结构中存储的是一个打开的文件和打开这个文件的进程间的交互信息。该结构保存在kernel的内存区,在打开文件时被创建,关闭文件时被释放。
dentry结构( struct dentry {…} ) 目录项对象
该结构存储的是目录实体和对应的文件的关联信息。
下图是一个简单示例,说明进程是怎样与文件进行交互。三个不同进程打开同一个文件,其中两个进程使用同一个硬链接(每个硬链接对应一个目录对象),其中每个进程都使用自己的文件对象。
进程和VFS对象之间的关系

与VFS有关的系统调用:
与文件系统相关的系统调用
这里写图片描述

VFS是应用程序和具体文件系统之间的一层。不过,在某些情况下,一个文件操作可能由VFS本身去执行,无需调用底层函数。例如,当某个进程关闭一个打开的文件时,并不涉及磁盘上的相应文件,因此VFS只需释放相应的文件对象。类似的,当系统调用lseek()修改一个文件指针,而这个文件指针是打开文件与进程交互所涉及的一个属性时,VFS就只需修改相应的文件对象,而不必访问磁盘上的文件。因此,无需调用具体文件系统函数。从某种意义上说,可以把VFS看成“通用”文件系统,它在必要时依赖某种具体的文件系统。

VFS的数据结构

每个VFS对象都存放在一个适当的数据结构中,其中包括对象的属性和指向对象方法表的指针。内核可以动态的修改对象的方法,因此可以为对象建立专用的行为。

struct super_block {
    struct list_head    s_list;     /* 指向超级块链表的指针 */
    dev_t           s_dev;      /* 设备标示符t */
    unsigned long       s_blocksize;        块大小(以字节为单位)
    unsigned char       s_blocksize_bits;   以位为单位的块大小
    unsigned char       s_dirt;         修改(脏)标志
    loff_t          s_maxbytes;     /* 文件的最长长度 */
    struct file_system_type *s_type;   文件系统类型
    const struct super_operations   *s_op;  /*超级块方法。*/
    const struct dquot_operations   *dq_op;     磁盘限额处理方法
    const struct quotactl_ops   *s_qcop;    磁盘限额管理方法
    const struct export_operations *s_export_op; 
    unsigned long       s_flags;     安装标志
    unsigned long       s_magic;    文件系统魔数
    struct dentry       *s_root;        文件系统根目录的目录项对象
    struct rw_semaphore s_umount;
    struct mutex        s_lock;     超级块信号量
    int         s_count;        引用计数
    int         s_need_sync;
    atomic_t        s_active;
#ifdef CONFIG_SECURITY
    void                    *s_security;
#endif
    struct xattr_handler    **s_xattr;  指向超级块扩展属性结构的指针 

    struct list_head    s_inodes;   /* 所有索引节点链表 */
    struct hlist_head   s_anon;     /* anonymous dentries for (nfs) exporting */
    struct list_head    s_files;        文件对象链表
    /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
    struct list_head    s_dentry_lru;   /* unused dentry lru */
    int         s_nr_dentry_unused; /* # of dentry on lru */

    struct block_device *s_bdev;
    struct backing_dev_info *s_bdi;
    struct mtd_info     *s_mtd;
    struct list_head    s_instances;
    struct quota_info   s_dquot;    /* Diskquota specific options */

    int         s_frozen;
    wait_queue_head_t   s_wait_unfrozen;

    char s_id[32];              /* Informational name */

    void            *s_fs_info; /* 指向具体文件系统的超级块信息。比如,当超级块指向的是Ext2文件系统,该字段就指向ext2_sb_info数据结构。通常为了效率起见,由s_fs_info指向的数据结构被复制到内存,当对其进行操作时就无需实际访问磁盘,同时为了解决VFS与实际磁盘同步问题,而引入一个s_dirty标志来表示该超级块是否脏。linux定期性的将“脏”数据同步到磁盘上 */
    fmode_t         s_mode;

    /*
     * The next field is for VFS *only*. No filesystems have any business
     * even looking at it. You had been warned.
     */
    struct mutex s_vfs_rename_mutex;    /* Kludge */

    /* Granularity of c/m/atime in ns.
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值