目录
1.mount流程
2. ext4_file_super
ext4同步磁盘模式
jbd提交日志间隔
journal_inode日志索引节点
mount参数解析
ext4_load_journal
ext4_register_sysfs
1.mount流程
路径:fs\ext4\super.c
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super);
}
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");
static int __init ext4_init_fs(void)
{
int i, err;
ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64);
ext4_li_info = NULL;
mutex_init(&ext4_li_mtx);
/* Build-time check for flags consistency */
ext4_check_flag_values();
for (i = 0; i < EXT4_WQ_HASH_SZ; i++)
init_waitqueue_head(&ext4__ioend_wq[i]);
err = ext4_init_es();
if (err)
return err;
err = ext4_init_pending();
if (err)
goto out7;
err = ext4_init_post_read_processing();
if (err)
goto out6;
err = ext4_init_pageio();
if (err)
goto out5;
err = ext4_init_system_zone();
if (err)
goto out4;
err = ext4_init_sysfs();
if (err)
goto out3;
err = ext4_init_mballoc();
if (err)
goto out2;
err = init_inodecache();
if (err)
goto out1;
err = ext4_fc_init_dentry_cache();
if (err)
goto out05;
register_as_ext3();
register_as_ext2();
err = register_filesystem(&ext4_fs_type);
if (err)
goto out;
return 0;
out:
unregister_as_ext2();
unregister_as_ext3();
ext4_fc_destroy_dentry_cache();
out05:
destroy_inodecache();
out1:
ext4_exit_mballoc();
out2:
ext4_exit_sysfs();
out3:
ext4_exit_system_zone();
out4:
ext4_exit_pageio();
out5:
ext4_exit_post_read_processing();
out6:
ext4_exit_pending();
out7:
ext4_exit_es();
return err;
}
其中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");
2. ext4_file_super
ext4同步磁盘模式
if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
set_opt(sb, JOURNAL_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED)
set_opt(sb, ORDERED_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK)
set_opt(sb, WRITEBACK_DATA);
jbd提交日志间隔
sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; //5*HZ
sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
journal_inode日志索引节点
journal_inode = d_inode(path.dentry);
if (!S_ISBLK(journal_inode->i_mode)) {
ext4_msg(sb, KERN_ERR, "error: journal path %s "
"is not a block device", journal_path);
path_put(&path);
kfree(journal_path);
return -1;
}
mount参数解析
if (sbi->s_es->s_mount_opts[0]) {
char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts,
sizeof(sbi->s_es->s_mount_opts),
GFP_KERNEL);
if (!s_mount_opts)
goto failed_mount;
if (!parse_options(s_mount_opts, sb, &journal_devnum,
&journal_ioprio, 0)) {
ext4_msg(sb, KERN_WARNING,
"failed to parse options in superblock: %s",
s_mount_opts);
}
kfree(s_mount_opts);
}
sbi->s_def_mount_opt = sbi->s_mount_opt;
if (!parse_options((char *) data, sb, &journal_devnum,
&journal_ioprio, 0))
goto failed_mount;
ext4_load_journal
if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
err = ext4_load_journal(sb, es, journal_devnum);
if (err)
goto failed_mount3a;
} else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) &&
ext4_register_sysfs
err = ext4_register_sysfs(sb);
if (err)
goto failed_mount7;