f2fs系列文章fill_super(二)

本文详细介绍了f2fs文件系统在fill_super函数中的操作,包括设置块大小、读取和检查super block、验证超级块的合理性、获取有效检查点的过程。通过对set_blocksize、read_raw_super_block、sanity_check_raw_super、get_valid_checkpoint和validate_checkpoint等步骤的解析,揭示了f2fs初始化的重要细节。

    sb_set_blocksize通过函数set_blocksize对size进行检查并设置块设备的块大小。然后将super block的s_blocksize,s_blocksize_bits设置F2FS_BLKSIZE和F2FS_BLKSIZE相应的bit位数。

int sb_set_blocksize(struct super_block *sb, int size)
{
	if (set_blocksize(sb->s_bdev, size))
		return 0;
	sb->s_blocksize = size;
	sb->s_blocksize_bits = blksize_bits(size);
	return sb->s_blocksize;
}

    set_blocksize对size进行检查,[512,page_size]是文件系统的size范围,并且必须是2的幂,并且不能比设备的块大小小。并把super block的设备的块大小s_bdev设置成F2FS_BLKSIZE。

int set_blocksize(struct block_device *bdev, int size)
{
	if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
		return -EINVAL;

	if (size < bdev_logical_block_size(bdev))
		return -EINVAL;

	if (bdev->bd_block_size != size) {
		sync_blockdev(bdev);
		bdev->bd_block_size = size;
		bdev->bd_inode->i_blkbits = blksize_bits(size);
		kill_bdev(bdev);
	}
	return 0;
}

    read_raw_super_block:首先分配一个f2fs_super_block的空间。f2fs文件系统有着两个f2fs_super_block,调用sb_bread对其进行依次读取,直到读取到的f2fs_super_block是没有问题的。读取之后调用sanity_check_raw_super对f2fs_super_block进行一些基本的检查。如果没有问题并且raw_super是NULL(第一次肯定是NULL的,第二次读取如果第一次读取或者检查失败就会是NULL的),那么就将读取的f2fs_super_block赋值给raw_super,并且用valid_super_block记录下有效的block号(假如没有一个是有效的,那么这个是NULL,如果只有一个是有效的,那么记录的就是有效的那个,如果两个都是有效的那么记录的就是第一个)。如果读取或者检查失败过那么用recovery来标记需要对f2fs_super_block进行修复。如果两个都失败了,那么就将分配的f2fs_super_block的空间释放掉。

static int read_raw_super_block(struct f2fs_sb_info *sbi, struct f2fs_super_block **raw_super,
			int *valid_super_block, int *recovery)
{
	struct super_block *sb = sbi->sb;
	int block;
	struct buffer_head *bh;
	struct f2fs_super_block *super;
	int err = 0;

	super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL);
	if (!super)
		return -ENOMEM;

	for (block = 0; block < 2; block++) {
		bh = sb_bread(sb, block);
		if (!bh) {
			f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock", block + 1);
			err = -EIO;
			continue;
4463 static int f2fs_fill_super(struct super_block *sb, void *data, int silent) 4464 { 4465 struct f2fs_sb_info *sbi; 4466 struct f2fs_super_block *raw_super; 4467 struct inode *root; 4468 int err; 4469 bool skip_recovery = false, need_fsck = false; 4470 char *options = NULL; 4471 int recovery, i, valid_super_block; 4472 struct curseg_info *seg_i; 4473 int retry_cnt = 1; 4474 #ifdef CONFIG_QUOTA 4475 bool quota_enabled = false; 4476 #endif 4477 4478 try_onemore: 4479 err = -EINVAL; 4480 raw_super = NULL; 4481 valid_super_block = -1; 4482 recovery = 0; 4483 4484 /* allocate memory for f2fs-specific super block info */ 4485 sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); 4486 if (!sbi) 4487 return -ENOMEM; 4488 4489 sbi->sb = sb; 4490 4491 /* initialize locks within allocated memory */ 4492 init_f2fs_rwsem(&sbi->gc_lock); 4493 mutex_init(&sbi->writepages); 4494 init_f2fs_rwsem(&sbi->cp_global_sem); 4495 init_f2fs_rwsem(&sbi->node_write); 4496 init_f2fs_rwsem(&sbi->node_change); 4497 spin_lock_init(&sbi->stat_lock); 4498 init_f2fs_rwsem(&sbi->cp_rwsem); 4499 init_f2fs_rwsem(&sbi->quota_sem); 4500 init_waitqueue_head(&sbi->cp_wait); 4501 spin_lock_init(&sbi->error_lock); 4502 4503 for (i = 0; i < NR_INODE_TYPE; i++) { 4504 INIT_LIST_HEAD(&sbi->inode_list[i]); 4505 spin_lock_init(&sbi->inode_lock[i]); 4506 } 4507 mutex_init(&sbi->flush_lock); 4508 4509 /* Load the checksum driver */ 4510 sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0); 4511 if (IS_ERR(sbi->s_chksum_driver)) { 4512 f2fs_err(sbi, "Cannot load crc32 driver."); 4513 err = PTR_ERR(sbi->s_chksum_driver); 4514 sbi->s_chksum_driver = NULL; 4515 goto free_sbi; 4516 } 4517 4518 /* set a block size */ 4519 if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) { 4520 f2fs_err(sbi, "unable to set blocksize"); 4521 goto free_sbi; 4522 } 4523 4524 err = read_raw_super_block(sbi, &raw_super, &valid_super_block, 4525 &recovery); 4526 if (err) 4527 goto free_sbi; 4528 4529 sb->s_fs_info = sbi; 4530 sbi->raw_super = raw_super; 4531 4532 INIT_WORK(&sbi->s_error_work, f2fs_record_error_work); 4533 memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS); 4534 memcpy(sbi->stop_reason, raw_super->s_stop_reason, MAX_STOP_REASON); 4535 4536 /* precompute checksum seed for metadata */ 4537 if (f2fs_sb_has_inode_chksum(sbi)) 4538 sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, 4539 sizeof(raw_super->uuid)); 4540 4541 default_options(sbi, false); 4542 /* parse mount options */ 4543 options = kstrdup((const char *)data, GFP_KERNEL); 4544 if (data && !options) { 4545 err = -ENOMEM; 4546 goto free_sb_buf; 4547 } 4548 4549 err = parse_options(sb, options, false); 4550 if (err) 4551 goto free_options; 4552 4553 sb->s_maxbytes = max_file_blocks(NULL) << 4554 le32_to_cpu(raw_super->log_blocksize); 4555 sb->s_max_links = F2FS_LINK_MAX; 4556 4557 err = f2fs_setup_casefold(sbi); 4558 if (err) 4559 goto free_options; 4560 4561 #ifdef CONFIG_QUOTA 4562 sb->dq_op = &f2fs_quota_operations; 4563 sb->s_qcop = &f2fs_quotactl_ops; 4564 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; 4565 4566 if (f2fs_sb_has_quota_ino(sbi)) { 4567 for (i = 0; i < MAXQUOTAS; i++) { 4568 if (f2fs_qf_ino(sbi->sb, i)) 4569 sbi->nquota_files++; 4570 } 4571 } 4572 #endif 4573 4574 sb->s_op = &f2fs_sops; 4575 #ifdef CONFIG_FS_ENCRYPTION 4576 sb->s_cop = &f2fs_cryptops; 4577 #endif 4578 #ifdef CONFIG_FS_VERITY 4579 sb->s_vop = &f2fs_verityops; 4580 #endif 4581 sb->s_xattr = f2fs_xattr_handlers; 4582 sb->s_export_op = &f2fs_export_ops; 4583 sb->s_magic = F2FS_SUPER_MAGIC; 4584 sb->s_time_gran = 1; 4585 sb->s_flags = (sb->s_flags & ~SB_POSIXACL) | 4586 (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0); 4587 memcpy(&sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid)); 4588 sb->s_iflags |= SB_I_CGROUPWB; 4589 4590 /* init f2fs-specific super block info */ 4591 sbi->valid_super_block = valid_super_block; 4592 4593 /* disallow all the data/node/meta page writes */ 4594 set_sbi_flag(sbi, SBI_POR_DOING); 4595 4596 err = f2fs_init_write_merge_io(sbi); 4597 if (err) 4598 goto free_bio_info; 4599 4600 init_sb_info(sbi); 4601 4602 err = f2fs_init_iostat(sbi); 4603 if (err) 4604 goto free_bio_info; 4605 4606 err = init_percpu_info(sbi); 4607 if (err) 4608 goto free_iostat; 4609 4610 /* init per sbi slab cache */ 4611 err = f2fs_init_xattr_caches(sbi); 4612 if (err) 4613 goto free_percpu; 4614 err = f2fs_init_page_array_cache(sbi); 4615 if (err) 4616 goto free_xattr_cache; 4617 4618 /* get an inode for meta space */ 4619 sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); 4620 if (IS_ERR(sbi->meta_inode)) { 4621 f2fs_err(sbi, "Failed to read F2FS meta data inode"); 4622 err = PTR_ERR(sbi->meta_inode); 4623 goto free_page_array_cache; 4624 } 4625 4626 err = f2fs_get_valid_checkpoint(sbi); 4627 if (err) { 4628 f2fs_err(sbi, "Failed to get valid F2FS checkpoint"); 4629 goto free_meta_inode; 4630 } 4631 4632 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_QUOTA_NEED_FSCK_FLAG)) 4633 set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); 4634 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_DISABLED_QUICK_FLAG)) { 4635 set_sbi_flag(sbi, SBI_CP_DISABLED_QUICK); 4636 sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_QUICK_INTERVAL; 4637 } 4638 4639 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_FSCK_FLAG)) 4640 set_sbi_flag(sbi, SBI_NEED_FSCK); 4641 4642 /* Initialize device list */ 4643 err = f2fs_scan_devices(sbi); 4644 if (err) { 4645 f2fs_err(sbi, "Failed to find devices"); 4646 goto free_devices; 4647 } 4648 4649 err = f2fs_init_post_read_wq(sbi); 4650 if (err) { 4651 f2fs_err(sbi, "Failed to initialize post read workqueue"); 4652 goto free_devices; 4653 } 4654 4655 sbi->total_valid_node_count = 4656 le32_to_cpu(sbi->ckpt->valid_node_count); 4657 percpu_counter_set(&sbi->total_valid_inode_count, 4658 le32_to_cpu(sbi->ckpt->valid_inode_count)); 4659 sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count); 4660 sbi->total_valid_block_count = 4661 le64_to_cpu(sbi->ckpt->valid_block_count); 4662 sbi->last_valid_block_count = sbi->total_valid_block_count; 4663 sbi->reserved_blocks = 0; 4664 sbi->current_reserved_blocks = 0; 4665 limit_reserve_root(sbi); 4666 adjust_unusable_cap_perc(sbi); 4667 4668 f2fs_init_extent_cache_info(sbi); 4669 4670 f2fs_init_ino_entry_info(sbi); 4671 4672 f2fs_init_fsync_node_info(sbi); 4673 4674 /* setup checkpoint request control and start checkpoint issue thread */ 4675 f2fs_init_ckpt_req_control(sbi); 4676 if (!f2fs_readonly(sb) && !test_opt(sbi, DISABLE_CHECKPOINT) && 4677 test_opt(sbi, MERGE_CHECKPOINT)) { 4678 err = f2fs_start_ckpt_thread(sbi); 4679 if (err) { 4680 f2fs_err(sbi, 4681 "Failed to start F2FS issue_checkpoint_thread (%d)", 4682 err); 4683 goto stop_ckpt_thread; 4684 } 4685 } 4686 4687 /* setup f2fs internal modules */ 4688 err = f2fs_build_segment_manager(sbi); 4689 if (err) { 4690 f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)", 4691 err); 4692 goto free_sm; 4693 } 4694 err = f2fs_build_node_manager(sbi); 4695 if (err) { 4696 f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)", 4697 err); 4698 goto free_nm; 4699 } 4700 4701 /* For write statistics */ 4702 sbi->sectors_written_start = f2fs_get_sectors_written(sbi); 4703 4704 /* Read accumulated write IO statistics if exists */ 4705 seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE); 4706 if (__exist_node_summaries(sbi)) 4707 sbi->kbytes_written = 4708 le64_to_cpu(seg_i->journal->info.kbytes_written); 4709 4710 f2fs_build_gc_manager(sbi); 4711 4712 err = f2fs_build_stats(sbi); 4713 if (err) 4714 goto free_nm; 4715 4716 /* get an inode for node space */ 4717 sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi)); 4718 if (IS_ERR(sbi->node_inode)) { 4719 f2fs_err(sbi, "Failed to read node inode"); 4720 err = PTR_ERR(sbi->node_inode); 4721 goto free_stats; 4722 } 4723 4724 /* read root inode and dentry */ 4725 root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); 4726 if (IS_ERR(root)) { 4727 f2fs_err(sbi, "Failed to read root inode"); 4728 err = PTR_ERR(root); 4729 goto free_node_inode; 4730 } 4731 if (!S_ISDIR(root->i_mode) || !root->i_blocks || 4732 !root->i_size || !root->i_nlink) { 4733 iput(root); 4734 err = -EINVAL; 4735 goto free_node_inode; 4736 } 4737 4738 sb->s_root = d_make_root(root); /* allocate root dentry */ 4739 if (!sb->s_root) { 4740 err = -ENOMEM; 4741 goto free_node_inode; 4742 } 4743 4744 err = f2fs_init_compress_inode(sbi); 4745 if (err) 4746 goto free_root_inode; 4747 4748 err = f2fs_register_sysfs(sbi); 4749 if (err) 4750 goto free_compress_inode; 4751 4752 #ifdef CONFIG_QUOTA 4753 /* Enable quota usage during mount */ 4754 if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) { 4755 err = f2fs_enable_quotas(sb); 4756 if (err) 4757 f2fs_err(sbi, "Cannot turn on quotas: error %d", err); 4758 } 4759 4760 quota_enabled = f2fs_recover_quota_begin(sbi); 4761 #endif 4762 /* if there are any orphan inodes, free them */ 4763 err = f2fs_recover_orphan_inodes(sbi); 4764 if (err) 4765 goto free_meta; 4766 4767 if (unlikely(is_set_ckpt_flags(sbi, CP_DISABLED_FLAG))) 4768 goto reset_checkpoint; 4769 4770 /* recover fsynced data */ 4771 if (!test_opt(sbi, DISABLE_ROLL_FORWARD) && 4772 !test_opt(sbi, NORECOVERY)) { 4773 /* 4774 * mount should be failed, when device has readonly mode, and 4775 * previous checkpoint was not done by clean system shutdown. 4776 */ 4777 if (f2fs_hw_is_readonly(sbi)) { 4778 if (!is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { 4779 err = f2fs_recover_fsync_data(sbi, true); 4780 if (err > 0) { 4781 err = -EROFS; 4782 f2fs_err(sbi, "Need to recover fsync data, but " 4783 "write access unavailable, please try " 4784 "mount w/ disable_roll_forward or norecovery"); 4785 } 4786 if (err < 0) 4787 goto free_meta; 4788 } 4789 f2fs_info(sbi, "write access unavailable, skipping recovery"); 4790 goto reset_checkpoint; 4791 } 4792 4793 if (need_fsck) 4794 set_sbi_flag(sbi, SBI_NEED_FSCK); 4795 4796 if (skip_recovery) 4797 goto reset_checkpoint; 4798 4799 err = f2fs_recover_fsync_data(sbi, false); 4800 if (err < 0) { 4801 if (err != -ENOMEM) 4802 skip_recovery = true; 4803 need_fsck = true; 4804 f2fs_err(sbi, "Cannot recover all fsync data errno=%d", 4805 err); 4806 goto free_meta; 4807 } 4808 } else { 4809 err = f2fs_recover_fsync_data(sbi, true); 4810 4811 if (!f2fs_readonly(sb) && err > 0) { 4812 err = -EINVAL; 4813 f2fs_err(sbi, "Need to recover fsync data"); 4814 goto free_meta; 4815 } 4816 } 4817 4818 #ifdef CONFIG_QUOTA 4819 f2fs_recover_quota_end(sbi, quota_enabled); 4820 #endif 4821 reset_checkpoint: 4822 /* 4823 * If the f2fs is not readonly and fsync data recovery succeeds, 4824 * check zoned block devices' write pointer consistency. 4825 */ 4826 if (f2fs_sb_has_blkzoned(sbi) && !f2fs_readonly(sb)) { 4827 int err2; 4828 4829 f2fs_notice(sbi, "Checking entire write pointers"); 4830 err2 = f2fs_check_write_pointer(sbi); 4831 if (err2) 4832 err = err2; 4833 } 4834 if (err) 4835 goto free_meta; 4836 4837 err = f2fs_init_inmem_curseg(sbi); 4838 if (err) 4839 goto sync_free_meta; 4840 4841 /* f2fs_recover_fsync_data() cleared this already */ 4842 clear_sbi_flag(sbi, SBI_POR_DOING); 4843 4844 if (test_opt(sbi, DISABLE_CHECKPOINT)) { 4845 err = f2fs_disable_checkpoint(sbi); 4846 if (err) 4847 goto sync_free_meta; 4848 } else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) { 4849 f2fs_enable_checkpoint(sbi); 4850 } 4851 4852 /* 4853 * If filesystem is not mounted as read-only then 4854 * do start the gc_thread. 4855 */ 4856 if ((F2FS_OPTION(sbi).bggc_mode != BGGC_MODE_OFF || 4857 test_opt(sbi, GC_MERGE)) && !f2fs_readonly(sb)) { 4858 /* After POR, we can run background GC thread.*/ 4859 err = f2fs_start_gc_thread(sbi); 4860 if (err) 4861 goto sync_free_meta; 4862 } 4863 kvfree(options); 4864 4865 /* recover broken superblock */ 4866 if (recovery) { 4867 err = f2fs_commit_super(sbi, true); 4868 f2fs_info(sbi, "Try to recover %dth superblock, ret: %d", 4869 sbi->valid_super_block ? 1 : 2, err); 4870 } 4871 4872 f2fs_join_shrinker(sbi); 4873 4874 f2fs_tuning_parameters(sbi); 4875 4876 f2fs_notice(sbi, "Mounted with checkpoint version = %llx", 4877 cur_cp_version(F2FS_CKPT(sbi))); 4878 f2fs_update_time(sbi, CP_TIME); 4879 f2fs_update_time(sbi, REQ_TIME); 4880 clear_sbi_flag(sbi, SBI_CP_DISABLED_QUICK); 4881 4882 cleancache_init_fs(sb); 4883 return 0; 4884 4885 sync_free_meta: 4886 /* safe to flush all the data */ 4887 sync_filesystem(sbi->sb); 4888 retry_cnt = 0; 4889 4890 free_meta: 4891 #ifdef CONFIG_QUOTA 4892 f2fs_truncate_quota_inode_pages(sb); 4893 if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) 4894 f2fs_quota_off_umount(sbi->sb); 4895 #endif 4896 /* 4897 * Some dirty meta pages can be produced by f2fs_recover_orphan_inodes() 4898 * failed by EIO. Then, iput(node_inode) can trigger balance_fs_bg() 4899 * followed by f2fs_write_checkpoint() through f2fs_write_node_pages(), which 4900 * falls into an infinite loop in f2fs_sync_meta_pages(). 4901 */ 4902 truncate_inode_pages_final(META_MAPPING(sbi)); 4903 /* evict some inodes being cached by GC */ 4904 evict_inodes(sb); 4905 f2fs_unregister_sysfs(sbi); 4906 free_compress_inode: 4907 f2fs_destroy_compress_inode(sbi); 4908 free_root_inode: 4909 dput(sb->s_root); 4910 sb->s_root = NULL; 4911 free_node_inode: 4912 f2fs_release_ino_entry(sbi, true); 4913 truncate_inode_pages_final(NODE_MAPPING(sbi)); 4914 iput(sbi->node_inode); 4915 sbi->node_inode = NULL; 4916 free_stats: 4917 f2fs_destroy_stats(sbi); 4918 free_nm: 4919 /* stop discard thread before destroying node manager */ 4920 f2fs_stop_discard_thread(sbi); 4921 f2fs_destroy_node_manager(sbi); 4922 free_sm: 4923 f2fs_destroy_segment_manager(sbi); 4924 stop_ckpt_thread: 4925 f2fs_stop_ckpt_thread(sbi); 4926 /* flush s_error_work before sbi destroy */ 4927 flush_work(&sbi->s_error_work); 4928 f2fs_destroy_post_read_wq(sbi); 4929 free_devices: 4930 destroy_device_list(sbi); 4931 kvfree(sbi->ckpt); 4932 free_meta_inode: 4933 make_bad_inode(sbi->meta_inode); 4934 iput(sbi->meta_inode); 4935 sbi->meta_inode = NULL; 4936 free_page_array_cache: 4937 f2fs_destroy_page_array_cache(sbi); 4938 free_xattr_cache: 4939 f2fs_destroy_xattr_caches(sbi); 4940 free_percpu: 4941 destroy_percpu_info(sbi); 4942 free_iostat: 4943 f2fs_destroy_iostat(sbi); 4944 free_bio_info: 4945 for (i = 0; i < NR_PAGE_TYPE; i++) 4946 kvfree(sbi->write_io[i]); 4947 4948 #if IS_ENABLED(CONFIG_UNICODE) 4949 utf8_unload(sb->s_encoding); 4950 sb->s_encoding = NULL; 4951 #endif 4952 free_options: 4953 #ifdef CONFIG_QUOTA 4954 for (i = 0; i < MAXQUOTAS; i++) 4955 kfree(F2FS_OPTION(sbi).s_qf_names[i]); 4956 #endif 4957 fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy); 4958 kvfree(options); 4959 free_sb_buf: 4960 kfree(raw_super); 4961 free_sbi: 4962 if (sbi->s_chksum_driver) 4963 crypto_free_shash(sbi->s_chksum_driver); 4964 kfree(sbi); 4965 sb->s_fs_info = NULL; 4966 4967 /* give only one another chance */ 4968 if (retry_cnt > 0 && skip_recovery) { 4969 retry_cnt--; 4970 shrink_dcache_sb(sb); 4971 goto try_onemore; 4972 } 4973 return err; 4974 } 4975
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值