当前位置: 首页 > news >正文

Linux: 关于 mount 的一些细节

文章目录

  • 1. 前言
  • 2. mount 的主要细节

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. mount 的主要细节

mount 从系统调用 sys_mount() 发起,如 mount -t tmpfs cgroup /sys/fs/cgroup

sys_mount() /* fs/namespace.c */do_mount()do_new_mount()struct vfsmount *mnt;...type = get_fs_type(fstype); /* 查找 @fstype 字串对应的文件系统类型 */...mnt = vfs_kern_mount(type, sb_flags, name, data);struct mount *mnt;struct dentry *root; /* @type 文件系统 的 根目录 */...mnt = alloc_vfsmnt(name);...root = mount_fs(type, flags, name, data);struct dentry *root; /* @type 文件系统 的 根目录 */struct super_block *sb; /* @type 文件系统 super block */...root = type->mount(type, flags, name, data);shmem_mount() /* tmpfs 的 挂载接口 */...sb = root->d_sb;.../* mm/shmem.c */
static struct dentry *shmem_mount(struct file_system_type *fs_type,int flags, const char *dev_name, void *data)
{return mount_nodev(fs_type, flags, data, shmem_fill_super);
}struct dentry *mount_nodev(struct file_system_type *fs_type,int flags, void *data,int (*fill_super)(struct super_block *, void *, int))
{.../* 分配 super block 对象 */struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL);...error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); /* shmem_fill_super(), ... */...
}int shmem_fill_super(struct super_block *sb, void *data, int silent)
{struct inode *inode; /* tmpfs 根目录的 inode */struct shmem_sb_info *sbinfo; /* 特定于 tmpfs 的 super block 信息 */.../* Round up to L1_CACHE_BYTES to resist false sharing */sbinfo = kzalloc(max((int)sizeof(struct shmem_sb_info),L1_CACHE_BYTES), GFP_KERNEL);...sb->s_fs_info = sbinfo;...sb->s_magic = TMPFS_MAGIC;sb->s_op = &shmem_ops;.../* 创建 tmpfs 根目录的 inode */inode = shmem_get_inode(sb, NULL, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE);if (!inode)goto failed;inode->i_uid = sbinfo->uid;inode->i_gid = sbinfo->gid;/* 创建 tmpfs 根目录对象 */sb->s_root = d_make_root(inode);...
}static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,umode_t mode, dev_t dev, unsigned long flags)
{struct inode *inode;...inode = new_inode(sb);if (inode) {inode->i_ino = get_next_ino(); /* 分配 inode 编号 */...inode->i_blocks = 0;inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);inode->i_generation = get_seconds();.../* 根据 inode 的类型,设置对应的接口 */switch (mode & S_IFMT) {...case S_IFDIR: /* 这里的上下文是为 tmpfs 建立的 根目录 的 inode */inc_nlink(inode);/* Some things misbehave if size == 0 on a directory */inode->i_size = 2 * BOGO_DIRENT_SIZE;inode->i_op = &shmem_dir_inode_operations;inode->i_fop = &simple_dir_operations;break;...}}  else...return inode;
}

看下来,mount 的重点工作是:

1. 建立文件系统的 super block 。
2. 建立根目录,同时绑定根目录的接口。在例子中的上下文,是绑定 shmem_dir_inode_operations、simple_dir_operations 接口。

建立文件系统 super block,以及文件系统根目录和其接口设定,自然都是为了管理文件系统。super block 包含文件系统的很多信息,譬如关联的设备,最大 block 尺寸,等等,这里不详细展开。而文件系统根目录,首先是建立了文件系统起始路径再就是根目录接口的设定,其主要目的是用来创建目录和文件。先看文件创建的过程:

sys_open()do_sys_open()do_filp_open()path_openat()struct file *file;...file = get_empty_filp(); /* 新建 file 对象 */...do_last(nd, file, op, &opened).../* 创建文件 inode,设置文件 file 对象 */lookup_open(nd, &path, file, op, got_write, opened).../* Negative dentry, just create the file */if (!dentry->d_inode && (open_flag & O_CREAT)) {error = dir_inode->i_op->create(dir_inode, dentry, mode, open_flag & O_EXCL);shmem_create() /* 创建文件 inode 和 接口 */}...vfs_open(&nd->path, file, current_cred());do_dentry_open(file, d_backing_inode(dentry), NULL, cred)...f->f_inode = inode; /* 绑定文件 file 的 inode */.../* 绑定文件 file 对象的接口 &simple_dir_operations */f->f_op = fops_get(inode->i_fop); ...	static int shmem_create(struct inode *dir, struct dentry *dentry, umode_t mode,bool excl)
{return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
}static int
shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{struct inode *inode;...inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);if (inode) {...d_instantiate(dentry, inode);...}return error;...
}static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,umode_t mode, dev_t dev, unsigned long flags)
{struct inode *inode;...inode = new_inode(sb);if (inode) {inode->i_ino = get_next_ino(); /* 分配 inode 编号 */...switch (mode & S_IFMT) {...case S_IFREG: /* 文件类型 inode 接口设定 */inode->i_mapping->a_ops = &shmem_aops;inode->i_op = &shmem_inode_operations;inode->i_fop = &shmem_file_operations;mpol_shared_policy_init(&info->policy,shmem_get_sbmpol(sbinfo));break;...}}...
}

再看目录创建的过程:

sys_mkdir()sys_mkdirat()vfs_mkdir(path.dentry->d_inode, dentry, mode)dir->i_op->mkdir(dir, dentry, mode)shmem_mkdir()shmem_mknod(dir, dentry, mode | S_IFDIR, 0)struct inode *inode;.../* 创建 目录 的 inode ,过程参考前面 tmpfs 的 挂载过程 */inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);if (inode) {...dir->i_size += BOGO_DIRENT_SIZE;dir->i_ctime = dir->i_mtime = current_time(dir);d_instantiate(dentry, inode);dget(dentry); /* Extra count - pin the dentry in core */}

到此,mount 的主要过程及相关细节已经分析完毕。

简单小结一下,mount 的主要目的就是 建立 super block根目录,然后绑定的根目录接口又可以进行目录和文件的创建和接口绑定,目录下的目录的接口又可以创建目录和文件,如此层层递推。


http://www.mrgr.cn/news/82768.html

相关文章:

  • STM32 I2C通信外设
  • FreeSWITCH 呼出之我见
  • java常见面试题
  • [备忘.OFD]OFD是什么、OFD与PDF格式文件的互转换
  • 起重机检测数据集VOC+YOLO格式2316张1类别
  • Spring 复习笔记
  • Vue笔记-001-声明式渲染
  • 【简博士统计学习方法】3. 统计学习方法的三要素
  • 自定义字典转换器用于easyExcel 导入导出
  • 51单片机(二)中断系统与外部中断实验
  • INT305 Machine Learning
  • Linux 35.6 + JetPack v5.1.4之 pytorch升级
  • 【LC】2469. 温度转换
  • Haskell语言的面向对象编程
  • 【python如何使用随机模块】
  • 智能工厂的设计软件 应用场景的一个例子: 为AI聊天工具添加一个知识系统 之23 “单子”职业能力原型:PIN语言/AI操作系统/robot扮演的actor
  • DX12 快速教程(3) —— 画矩形
  • easyx空洞武士项目总结
  • 基于springboot+vue的餐饮连锁店管理系统的设计与实现
  • 3272 小蓝的漆房