本文主要是介绍f2fs mkfs格式化系列3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前面讲了f2fs格式化主要进行了哪些操作,本篇看一下,mount过程中是如何读取格式化写到磁盘的那些内容的。
主要说一下如果读取f2fs meta data这些信息,mount过程还有一些比较重要的步骤,像build node management, build sit management后面会分开仔细再说。
static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
{struct f2fs_sb_info *sbi;struct f2fs_super_block *raw_super;struct buffer_head *raw_super_buf;struct inode *root;long err;bool retry = true, need_fsck = false;char *options = NULL;int recovery, i;try_onemore:err = -EINVAL;raw_super = NULL;raw_super_buf = NULL;recovery = 0;/* allocate memory for f2fs-specific super block info */sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL);if (!sbi)return -ENOMEM;/* set a block size */if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) {f2fs_msg(sb, KERN_ERR, "unable to set blocksize");goto free_sbi;}//读取磁盘中的super block,其中raw_super是f2fs superblock//f2fs super block有效数据并不是在一个物理block 0地址开始的,所以有一个head偏移,//raw_super_buff是包含head偏移的物理blockerr = read_raw_super_block(sb, &raw_super, &raw_super_buf, &recovery);if (err)goto free_sbi;//将vfs super block private info设置成f2fs super blocksb->s_fs_info = sbi;default_options(sbi);/* parse mount options */options = kstrdup((const char *)data, GFP_KERNEL);if (data && !options) {err = -ENOMEM;goto free_sb_buf;}err = parse_options(sb, options);if (err)goto free_options;//下面设置filesystem物理属性sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize));sb->s_max_links = F2FS_LINK_MAX;get_random_bytes(&sbi->s_next_generation, sizeof(u32));sb->s_op = &f2fs_sops;//super block相关的一些操作sb->s_xattr = f2fs_xattr_handlers;sb->s_export_op = &f2fs_export_ops;sb->s_magic = F2FS_SUPER_MAGIC;sb->s_time_gran = 1;sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |(test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);memcpy(sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));/* init f2fs-specific super block info */sbi->sb = sb;//f2fs super block指向vfs super blocksbi->raw_super = raw_super;sbi->raw_super_buf = raw_super_buf;mutex_init(&sbi->gc_mutex);mutex_init(&sbi->writepages);mutex_init(&sbi->cp_mutex);init_rwsem(&sbi->node_write);/* disallow all the data/node/meta page writes */set_sbi_flag(sbi, SBI_POR_DOING);spin_lock_init(&sbi->stat_lock);init_rwsem(&sbi->read_io.io_rwsem);sbi->read_io.sbi = sbi;sbi->read_io.bio = NULL;for (i = 0; i < NR_PAGE_TYPE; i++) {init_rwsem(&sbi->write_io[i].io_rwsem);sbi->write_io[i].sbi = sbi;sbi->write_io[i].bio = NULL;}init_rwsem(&sbi->cp_rwsem);init_waitqueue_head(&sbi->cp_wait);//设置super block物理特性,如块大小,segment, section大小,ino,meta ino等init_sb_info(sbi);/* get an inode for meta space *///初始化meta inodesbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi));if (IS_ERR(sbi->meta_inode)) {f2fs_msg(sb, KERN_ERR, "Failed to read F2FS meta data inode");err = PTR_ERR(sbi->meta_inode);goto free_options;}//读取check pointerr = get_valid_checkpoint(sbi);if (err) {f2fs_msg(sb, KERN_ERR, "Failed to get valid F2FS checkpoint");goto free_meta_inode;}/* sanity checking of checkpoint */err = -EINVAL;if (sanity_check_ckpt(sbi)) {f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint");goto free_cp;}//设置f2fs super block相关信息sbi->total_valid_node_count =le32_to_cpu(sbi->ckpt->valid_node_count);sbi->total_valid_inode_count =le32_to_cpu(sbi->ckpt->valid_inode_count);sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);sbi->total_valid_block_count =le64_to_cpu(sbi->ckpt->valid_block_count);sbi->last_valid_block_count = sbi->total_valid_block_count;sbi->alloc_valid_block_count = 0;INIT_LIST_HEAD(&sbi->dir_inode_list);spin_lock_init(&sbi->dir_inode_lock);init_extent_cache_info(sbi);init_ino_entry_info(sbi);/* setup f2fs internal modules */err = build_segment_manager(sbi);//初始化segmen infoif (err) {f2fs_msg(sb, KERN_ERR,"Failed to initialize F2FS segment manager");goto free_sm;}err = build_node_manager(sbi);//初始化node infoif (err) {f2fs_msg(sb, KERN_ERR,"Failed to initialize F2FS node manager");goto free_nm;}build_gc_manager(sbi);//初始化gc操作/* get an inode for node space *///初始化node inode,分配一个新的inode,并cachesbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi));if (IS_ERR(sbi->node_inode)) {f2fs_msg(sb, KERN_ERR, "Failed to read node inode");err = PTR_ERR(sbi->node_inode);goto free_nm;}f2fs_join_shrinker(sbi);/* if there are nt orphan nodes free them */err = recover_orphan_inodes(sbi);if (err)goto free_node_inode;/* read root inode and dentry *///从磁盘读取root inoderoot = f2fs_iget(sb, F2FS_ROOT_INO(sbi));if (IS_ERR(root)) {f2fs_msg(sb, KERN_ERR, "Failed to read root inode");err = PTR_ERR(root);goto free_node_inode;}if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {iput(root);err = -EINVAL;goto free_node_inode;}//申请root dentrysb->s_root = d_make_root(root); /* allocate root dentry */if (!sb->s_root) {err = -ENOMEM;goto free_root_inode;}err = f2fs_build_stats(sbi);if (err)goto free_root_inode;if (f2fs_proc_root)sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);if (sbi->s_proc)proc_create_data("segment_info", S_IRUGO, sbi->s_proc,&f2fs_seq_segment_info_fops, sb);sbi->s_kobj.kset = f2fs_kset;init_completion(&sbi->s_kobj_unregister);err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,"%s", sb->s_id);if (err)goto free_proc;/* recover fsynced data */if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {/** mount should be failed, when device has readonly mode, and* previous checkpoint was not done by clean system shutdown.*/if (bdev_read_only(sb->s_bdev) &&!is_set_ckpt_flags(sbi->ckpt, CP_UMOUNT_FLAG)) {err = -EROFS;goto free_kobj;}if (need_fsck)set_sbi_flag(sbi, SBI_NEED_FSCK);err = recover_fsync_data(sbi);if (err) {need_fsck = true;f2fs_msg(sb, KERN_ERR,"Cannot recover all fsync data errno=%ld", err);goto free_kobj;}}/* recover_fsync_data() cleared this already */clear_sbi_flag(sbi, SBI_POR_DOING);/** If filesystem is not mounted as read-only then* do start the gc_thread.*/if (test_opt(sbi, BG_GC) && !f2fs_readonly(sb)) {/* After POR, we can run background GC thread.*/err = start_gc_thread(sbi);if (err)goto free_kobj;}kfree(options);/* recover broken superblock */if (recovery && !f2fs_readonly(sb) && !bdev_read_only(sb->s_bdev)) {f2fs_msg(sb, KERN_INFO, "Recover invalid superblock");f2fs_commit_super(sbi, true);}sbi->cp_expires = round_jiffies_up(jiffies);return 0;free_kobj:kobject_del(&sbi->s_kobj);
free_proc:if (sbi->s_proc) {remove_proc_entry("segment_info", sbi->s_proc);remove_proc_entry(sb->s_id, f2fs_proc_root);}f2fs_destroy_stats(sbi);
free_root_inode:dput(sb->s_root);sb->s_root = NULL;
free_node_inode:mutex_lock(&sbi->umount_mutex);f2fs_leave_shrinker(sbi);iput(sbi->node_inode);mutex_unlock(&sbi->umount_mutex);
free_nm:destroy_node_manager(sbi);
free_sm:destroy_segment_manager(sbi);
free_cp:kfree(sbi->ckpt);
free_meta_inode:make_bad_inode(sbi->meta_inode);iput(sbi->meta_inode);
free_options:kfree(options);
free_sb_buf:brelse(raw_super_buf);
free_sbi:kfree(sbi);/* give only one another chance */if (retry) {retry = false;shrink_dcache_sb(sb);goto try_onemore;}return err;
}
这篇关于f2fs mkfs格式化系列3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!