Skip to content

Commit

Permalink
ext4: Don't allow new groups to be added during block allocation
Browse files Browse the repository at this point in the history
After we mark the blocks in the buddy cache as allocated,
we need to ensure that we don't reinit the buddy cache until
the block bitmap is updated.  This commit achieves this by holding
the group_info alloc_semaphore till ext4_mb_release_context

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@kernel.org
  • Loading branch information
Aneesh Kumar K.V authored and Theodore Ts'o committed Jan 6, 2009
1 parent 648f587 commit 8556e8f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
16 changes: 13 additions & 3 deletions fs/ext4/mballoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,8 @@ static void ext4_mb_release_desc(struct ext4_buddy *e4b)
if (e4b->bd_buddy_page)
page_cache_release(e4b->bd_buddy_page);
/* Done with the buddy cache */
up_read(e4b->alloc_semp);
if (e4b->alloc_semp)
up_read(e4b->alloc_semp);
}


Expand Down Expand Up @@ -1371,7 +1372,9 @@ static void ext4_mb_use_best_found(struct ext4_allocation_context *ac,
get_page(ac->ac_bitmap_page);
ac->ac_buddy_page = e4b->bd_buddy_page;
get_page(ac->ac_buddy_page);

/* on allocation we use ac to track the held semaphore */
ac->alloc_semp = e4b->alloc_semp;
e4b->alloc_semp = NULL;
/* store last allocated for subsequent stream allocation */
if ((ac->ac_flags & EXT4_MB_HINT_DATA)) {
spin_lock(&sbi->s_md_lock);
Expand Down Expand Up @@ -4289,6 +4292,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
ac->ac_pa = NULL;
ac->ac_bitmap_page = NULL;
ac->ac_buddy_page = NULL;
ac->alloc_semp = NULL;
ac->ac_lg = NULL;

/* we have to define context: we'll we work with a file or
Expand Down Expand Up @@ -4469,6 +4473,8 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
}
ext4_mb_put_pa(ac, ac->ac_sb, pa);
}
if (ac->alloc_semp)
up_read(ac->alloc_semp);
if (ac->ac_bitmap_page)
page_cache_release(ac->ac_bitmap_page);
if (ac->ac_buddy_page)
Expand Down Expand Up @@ -4569,10 +4575,14 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
ac->ac_o_ex.fe_len < ac->ac_b_ex.fe_len)
ext4_mb_new_preallocation(ac);
}

if (likely(ac->ac_status == AC_STATUS_FOUND)) {
*errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks);
if (*errp == -EAGAIN) {
/*
* drop the reference that we took
* in ext4_mb_use_best_found
*/
ext4_mb_release_context(ac);
ac->ac_b_ex.fe_group = 0;
ac->ac_b_ex.fe_start = 0;
ac->ac_b_ex.fe_len = 0;
Expand Down
5 changes: 5 additions & 0 deletions fs/ext4/mballoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ struct ext4_allocation_context {
__u8 ac_op; /* operation, for history only */
struct page *ac_bitmap_page;
struct page *ac_buddy_page;
/*
* pointer to the held semaphore upon successful
* block allocation
*/
struct rw_semaphore *alloc_semp;
struct ext4_prealloc_space *ac_pa;
struct ext4_locality_group *ac_lg;
};
Expand Down

0 comments on commit 8556e8f

Please sign in to comment.