ext4: factor out ext4_group_desc_init() and ext4_group_desc_free()
Factor out ext4_group_desc_init() and ext4_group_desc_free(). No functional change. Signed-off-by: Jason Yan <yanaijie@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Link: https://lore.kernel.org/r/20220916141527.1012715-12-yanaijie@huawei.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
bc62dbf914
commit
a4e6a511d7
143
fs/ext4/super.c
143
fs/ext4/super.c
@ -4720,9 +4720,89 @@ static int ext4_geometry_check(struct super_block *sb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ext4_group_desc_free(struct ext4_sb_info *sbi)
|
||||||
|
{
|
||||||
|
struct buffer_head **group_desc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
group_desc = rcu_dereference(sbi->s_group_desc);
|
||||||
|
for (i = 0; i < sbi->s_gdb_count; i++)
|
||||||
|
brelse(group_desc[i]);
|
||||||
|
kvfree(group_desc);
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ext4_group_desc_init(struct super_block *sb,
|
||||||
|
struct ext4_super_block *es,
|
||||||
|
ext4_fsblk_t logical_sb_block,
|
||||||
|
ext4_group_t *first_not_zeroed)
|
||||||
|
{
|
||||||
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
||||||
|
unsigned int db_count;
|
||||||
|
ext4_fsblk_t block;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
|
||||||
|
EXT4_DESC_PER_BLOCK(sb);
|
||||||
|
if (ext4_has_feature_meta_bg(sb)) {
|
||||||
|
if (le32_to_cpu(es->s_first_meta_bg) > db_count) {
|
||||||
|
ext4_msg(sb, KERN_WARNING,
|
||||||
|
"first meta block group too large: %u "
|
||||||
|
"(group descriptor block count %u)",
|
||||||
|
le32_to_cpu(es->s_first_meta_bg), db_count);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rcu_assign_pointer(sbi->s_group_desc,
|
||||||
|
kvmalloc_array(db_count,
|
||||||
|
sizeof(struct buffer_head *),
|
||||||
|
GFP_KERNEL));
|
||||||
|
if (sbi->s_group_desc == NULL) {
|
||||||
|
ext4_msg(sb, KERN_ERR, "not enough memory");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgl_lock_init(sbi->s_blockgroup_lock);
|
||||||
|
|
||||||
|
/* Pre-read the descriptors into the buffer cache */
|
||||||
|
for (i = 0; i < db_count; i++) {
|
||||||
|
block = descriptor_loc(sb, logical_sb_block, i);
|
||||||
|
ext4_sb_breadahead_unmovable(sb, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < db_count; i++) {
|
||||||
|
struct buffer_head *bh;
|
||||||
|
|
||||||
|
block = descriptor_loc(sb, logical_sb_block, i);
|
||||||
|
bh = ext4_sb_bread_unmovable(sb, block);
|
||||||
|
if (IS_ERR(bh)) {
|
||||||
|
ext4_msg(sb, KERN_ERR,
|
||||||
|
"can't read group descriptor %d", i);
|
||||||
|
sbi->s_gdb_count = i;
|
||||||
|
ret = PTR_ERR(bh);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rcu_read_lock();
|
||||||
|
rcu_dereference(sbi->s_group_desc)[i] = bh;
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
sbi->s_gdb_count = db_count;
|
||||||
|
if (!ext4_check_descriptors(sb, logical_sb_block, first_not_zeroed)) {
|
||||||
|
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
|
||||||
|
ret = -EFSCORRUPTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
out:
|
||||||
|
ext4_group_desc_free(sbi);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh, **group_desc;
|
struct buffer_head *bh;
|
||||||
struct ext4_super_block *es = NULL;
|
struct ext4_super_block *es = NULL;
|
||||||
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
||||||
struct flex_groups **flex_groups;
|
struct flex_groups **flex_groups;
|
||||||
@ -4732,7 +4812,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
|||||||
struct inode *root;
|
struct inode *root;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
int blocksize;
|
int blocksize;
|
||||||
unsigned int db_count;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int needs_recovery, has_huge_files;
|
int needs_recovery, has_huge_files;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@ -5026,57 +5105,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
|
|||||||
if (ext4_geometry_check(sb, es))
|
if (ext4_geometry_check(sb, es))
|
||||||
goto failed_mount;
|
goto failed_mount;
|
||||||
|
|
||||||
db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
|
err = ext4_group_desc_init(sb, es, logical_sb_block, &first_not_zeroed);
|
||||||
EXT4_DESC_PER_BLOCK(sb);
|
if (err)
|
||||||
if (ext4_has_feature_meta_bg(sb)) {
|
|
||||||
if (le32_to_cpu(es->s_first_meta_bg) > db_count) {
|
|
||||||
ext4_msg(sb, KERN_WARNING,
|
|
||||||
"first meta block group too large: %u "
|
|
||||||
"(group descriptor block count %u)",
|
|
||||||
le32_to_cpu(es->s_first_meta_bg), db_count);
|
|
||||||
goto failed_mount;
|
goto failed_mount;
|
||||||
}
|
|
||||||
}
|
|
||||||
rcu_assign_pointer(sbi->s_group_desc,
|
|
||||||
kvmalloc_array(db_count,
|
|
||||||
sizeof(struct buffer_head *),
|
|
||||||
GFP_KERNEL));
|
|
||||||
if (sbi->s_group_desc == NULL) {
|
|
||||||
ext4_msg(sb, KERN_ERR, "not enough memory");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto failed_mount;
|
|
||||||
}
|
|
||||||
|
|
||||||
bgl_lock_init(sbi->s_blockgroup_lock);
|
|
||||||
|
|
||||||
/* Pre-read the descriptors into the buffer cache */
|
|
||||||
for (i = 0; i < db_count; i++) {
|
|
||||||
block = descriptor_loc(sb, logical_sb_block, i);
|
|
||||||
ext4_sb_breadahead_unmovable(sb, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < db_count; i++) {
|
|
||||||
struct buffer_head *bh;
|
|
||||||
|
|
||||||
block = descriptor_loc(sb, logical_sb_block, i);
|
|
||||||
bh = ext4_sb_bread_unmovable(sb, block);
|
|
||||||
if (IS_ERR(bh)) {
|
|
||||||
ext4_msg(sb, KERN_ERR,
|
|
||||||
"can't read group descriptor %d", i);
|
|
||||||
db_count = i;
|
|
||||||
ret = PTR_ERR(bh);
|
|
||||||
goto failed_mount2;
|
|
||||||
}
|
|
||||||
rcu_read_lock();
|
|
||||||
rcu_dereference(sbi->s_group_desc)[i] = bh;
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
|
||||||
sbi->s_gdb_count = db_count;
|
|
||||||
if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
|
|
||||||
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
|
|
||||||
ret = -EFSCORRUPTED;
|
|
||||||
goto failed_mount2;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
|
timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
|
||||||
spin_lock_init(&sbi->s_error_lock);
|
spin_lock_init(&sbi->s_error_lock);
|
||||||
@ -5520,13 +5551,7 @@ failed_mount3:
|
|||||||
flush_work(&sbi->s_error_work);
|
flush_work(&sbi->s_error_work);
|
||||||
del_timer_sync(&sbi->s_err_report);
|
del_timer_sync(&sbi->s_err_report);
|
||||||
ext4_stop_mmpd(sbi);
|
ext4_stop_mmpd(sbi);
|
||||||
failed_mount2:
|
ext4_group_desc_free(sbi);
|
||||||
rcu_read_lock();
|
|
||||||
group_desc = rcu_dereference(sbi->s_group_desc);
|
|
||||||
for (i = 0; i < db_count; i++)
|
|
||||||
brelse(group_desc[i]);
|
|
||||||
kvfree(group_desc);
|
|
||||||
rcu_read_unlock();
|
|
||||||
failed_mount:
|
failed_mount:
|
||||||
if (sbi->s_chksum_driver)
|
if (sbi->s_chksum_driver)
|
||||||
crypto_free_shash(sbi->s_chksum_driver);
|
crypto_free_shash(sbi->s_chksum_driver);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user