一、挂载文件系统的命令
mount -t ext4 /dev/sdb1 /mnt/sdb1
把设备节点/dev/sdb1,即插入的硬盘设备,cat /dev/sdb1可以直接访问硬盘的二进制数据,以ext4文件系统格式挂载到/mnt/sdb1目录下。挂载结束后,就可以访问/mnt/sdb1目录的方式访问磁盘空间的数据了。
二、如何挂载
1、mount命令会去执行mount系统调用
fs/namespace.c
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
int ret;
char *kernel_type;
char *kernel_dev;
void *options;
kernel_type = copy_mount_string(type);
kernel_dev = copy_mount_string(dev_name);
options = copy_mount_options(data);
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
}
准备好应用层传递下来的参数,详见第一部分描述。而后继续往下执行
do_mount
path_mount
do_new_mount
vfs_kern_mount
mount_fs
其中mount_fs的源码
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
root = type->mount(type, flags, name, data);
此时就需要依赖于struct file_system_type结构体
2、系统初始化的时候,会初始化各种类型的文件系统。以ext4为例,通过
module_init(ext4_init_fs)
初始化注册文件系统
register_filesystem(&ext4_fs_type)
其中ext4_fs_type的定义
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext4");
3、在do_new_mount中,通过get_fs_type函数加上fstype参数,即mount -t type的type值,找到对应的file_system_type结构体
static int do_new_mount(struct path *path, const char *fstype, int flags,
int mnt_flags, const char *name, void *data)
{
type = get_fs_type(fstype);
if (!type)
return -ENODEV;
mnt = vfs_kern_mount(type, flags, name, data);
最终mount_fs函数中type->mount对应着ext4_mount函数的具体实现。
ext4_mount
mount_bdev
mount_bdev的源码
struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{
struct block_device *bdev;
struct super_block *s;
bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
bdev);
return dget(s->s_root);
3.1、通过blkdev_get_by_path的参数dev_name,即/dev/sdb1打开设备
3.2、通过sget函数获取打开设备super_block内容。super_block内容是什么?参考: