ext4: Clarify the locking details in mballoc
We don't need to take the alloc_sem lock when we are adding new groups, since mballoc won't see the new group added until we bump sbi->s_groups_count. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
parent
f41c075053
commit
08c3a81338
@ -928,8 +928,11 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
|
|||||||
blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
|
blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
|
||||||
this_grp = ext4_get_group_info(sb, group);
|
this_grp = ext4_get_group_info(sb, group);
|
||||||
/*
|
/*
|
||||||
* This ensures we don't add group
|
* This ensures that we don't reinit the buddy cache
|
||||||
* to this buddy cache via resize
|
* page which map to the group from which we are already
|
||||||
|
* allocating. If we are looking at the buddy cache we would
|
||||||
|
* have taken a reference using ext4_mb_load_buddy and that
|
||||||
|
* would have taken the alloc_sem lock.
|
||||||
*/
|
*/
|
||||||
num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, group);
|
num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, group);
|
||||||
if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
|
if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
|
||||||
|
@ -746,7 +746,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
|||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
int gdb_off, gdb_num;
|
int gdb_off, gdb_num;
|
||||||
int num_grp_locked = 0;
|
|
||||||
int err, err2;
|
int err, err2;
|
||||||
|
|
||||||
gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
|
gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
|
||||||
@ -856,7 +855,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
|||||||
* using the new disk blocks.
|
* using the new disk blocks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, input->group);
|
|
||||||
/* Update group descriptor block for new group */
|
/* Update group descriptor block for new group */
|
||||||
gdp = (struct ext4_group_desc *)((char *)primary->b_data +
|
gdp = (struct ext4_group_desc *)((char *)primary->b_data +
|
||||||
gdb_off * EXT4_DESC_SIZE(sb));
|
gdb_off * EXT4_DESC_SIZE(sb));
|
||||||
@ -875,10 +873,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
|||||||
* descriptor
|
* descriptor
|
||||||
*/
|
*/
|
||||||
err = ext4_mb_add_groupinfo(sb, input->group, gdp);
|
err = ext4_mb_add_groupinfo(sb, input->group, gdp);
|
||||||
if (err) {
|
if (err)
|
||||||
ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked);
|
|
||||||
goto exit_journal;
|
goto exit_journal;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the new blocks and inodes valid next. We do this before
|
* Make the new blocks and inodes valid next. We do this before
|
||||||
@ -920,7 +916,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
|
|||||||
|
|
||||||
/* Update the global fs size fields */
|
/* Update the global fs size fields */
|
||||||
sbi->s_groups_count++;
|
sbi->s_groups_count++;
|
||||||
ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked);
|
|
||||||
|
|
||||||
ext4_handle_dirty_metadata(handle, NULL, primary);
|
ext4_handle_dirty_metadata(handle, NULL, primary);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user