第 8 章 虚拟文件系统(5)

目录

8.4 处理VFS对象

8.4.1 文件系统操作


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

8.4 处理VFS对象

8.4.1 文件系统操作

文件系统可以编译为模块。

使用文件系统前需先注册。

1. 注册文件系统

int    register_filesystem( struct file_system_type *fs )

        注册文件系统,将加入全局文件系统链表。

通过遍历全局链表,查找文件系统名称字符串,可确定是否已注册。

struct    file_system_type   {

        const char         *name;           //如"ext3","nfs","ubifs"。

        int                      fs_flags;         //是否只读、禁止setuid、禁止setgid。

        struct module    *owner;          //当文件系统编译为模块时有效。

        struct dentry   *(*mount) (struct file_system_type *,   int,  const char *,  void *);

                //挂载文件系统时调用。

        void         (*kill_sb) (struct super_block *);

                //卸载文件系统时调用。

        struct hlist_head        fs_supers;

                //不同目录可装载了相同文件系统。

                //所有相同文件系统连接到fs_supers为表头的链表。

        struct file_system_type      *next; //连接其他文件系统

};

成员介绍:

fs_supers:

        不同目录可装载了相同文件系统。

        所有相同文件系统连接同一链表,fs_supers就是表头。

        使用举例:

                hlist_add_head( &s->s_instances,   &type->fs_supers );

                hlist_for_each_entry( old,   &type->fs_supers,   s_instances ) {

                }

2. 装载卸载

mount命令:查看系统装载的文件系统。

vfsmount 结构

每一个装载的文件系统都有一个 vfsmount 实例。

struct    vfsmount {

        struct dentry                 *mnt_root;         //文件系统装载的根目录的dentry。

        struct super_block         *mnt_sb;         //对应超级块。

        int                                  mnt_flags;

};

setuid:执行程序时,可将进程有效用户ID设置为文件所有者ID,但有安全隐患。

mnt_flags 有:

        #define MNT_NOSUID 0x01         // 禁止setuid执行。

        #define MNT_NODEV 0x02           // 虚拟文件系统。

        #define MNT_NOEXEC 0x04         // 禁止执行程序文件。

        #define MNT_READONLY 0x40     // 挂载为只读文件系统。

超级块管理

装载一个文件系统时,还将初始化一个 struct super_block 实例。

        其中包含文件系统信息,装载点信息。

struct    super_block   {

        struct list_head         s_list;          // 连接系统所有超级块。

        dev_t                        s_dev;         // 文件系统所在块设备标识符。

        struct block_device    *s_bdev;                // 文件系统所在块设备。

        unsigned char            s_blocksize_bits;   // 文件系统块大小,单位:bit。

        unsigned long            s_blocksize;          // 文件系统块大小,单位:字节。

        loff_t                           s_maxbytes;         // 文件系统中文件最大长度。

        struct file_system_type    *s_type;

        struct super_operations    *s_op;

        struct dentry                      *s_root;         // 根目录的dentry,用于检查文件系统是否装载。

        struct hlist_node                s_instances;  // 连接到file_system_type中fs_supers链表。

        void                                   *s_fs_info;      // 私有信息。

        u32                                    s_time_gran; // 支持的时间戳最大粒度,单位:ns。

        struct list_head                  s_inodes;       // 文件系统中所有inode。

        struct list_head                  s_files;           // 文件系统中所有打开的文件。

        struct list_head                  s_inodes_wb;    // 文件系统中正在回写的inode。

        unsigned char                    s_dirt;            // 文件系统是否脏。

};

struct    super_operations   { //管理 inode

        struct inode    *(*alloc_inode)(struct super_block    *sb);

                //分配一个 inode 结构体。

        void    (*destroy_inode)(struct inode   *);

                // 释放 inode 结构体。

        void    (*free_inode)(struct inode    *);

        void    (*dirty_inode) (struct inode    *,    int    flags);

                // 将一个 inode 标记为脏。

        int    (*write_inode) (struct inode    *,    struct writeback_control    *wbc);

                //将 inode 结构体写回磁盘。

        int    (*drop_inode) (struct inode    *);

                //引用计数为 0 时释放 inode 结构体。

        void    (*put_super) (struct super_block    *);

                //释放超级块占用的资源。

        int    (*sync_fs)(struct super_block    *sb,    int    wait);

                //将文件系统中未写入磁盘的数据都写回磁盘。

        int    (*statfs) (struct dentry    *,    struct kstatfs    *);

                //返回统计信息。包括:使用和未使用数据块数目等。

        int    (*remount_fs) (struct super_block    *,    int    *,    char    *);

                // 重新挂载文件系统。

};

mount 系统调用

根据不同选项,do_mount调用不同函数:

        MS_REMOUNT 选项:

                do_remount ()                 //修改一个已装载的文件系统。

        MS_MOVE 选项:

                do_move_mount ()         //移动一个已装载文件系统。

        默认选项:

                do_new_mount ()           //普通装载,使用最多。

do_new_mount 流程:

共享子树

Linux 扩展的装载选项:

        1. MS_SHARED,共享装载:

                对挂载点的更改,将传播给所有共享的的其他挂载点。

        2. MS_PRIVATE,私有装载:

                私有挂载点的更改,不会传播给其他挂载点。

        3. MS_SLAVE,从属装载:

                跟随其上级挂载点的共享或私有状态。

        4. MS_UNBINDABLE,不可绑定的装载:

                不可将其绑定或移动到其他挂载点。

do_mount 中:

if (  flags    &    (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))

        do_change_type( &path,    flags );         //改变装载类型。

umount 系统调用

卸载文件系统。

装载的自动过期

使用场景:网络文件系统会使用。

将该装载从vfsmount树中移除。

伪文件系统

一个文件系统不一定需要底层块设备,如。

        内存为后备存储器:ramfs,tmpfs。

        无后备存储器:procfs,sysfs。

伪文件系统:应用层不可见,不能卸载。主要为了组织 inode,如:

        bdev:管理块设备inode。

        pipefs:处理管道。

        sockfs:处理套接字。

cat    /proc/filesystem:

        可查看所有文件系统,包括伪文件系统。

标志 MS_NOUSER:

        表示为伪文件系统,可防止被装载, 其余操作和普通文件系统一致。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山下小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值