| From a508d6aa722ae358cf885dd33be7f02d18ba9e39 Mon Sep 17 00:00:00 2001 |
| From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> |
| Date: Wed, 9 Sep 2009 23:34:50 -0400 |
| Subject: [PATCH 26/85] ext4: check for need init flag in ext4_mb_load_buddy |
| |
| (cherry picked from commit f41c0750538667b87a19c93952e5d42fcc069bd7) |
| |
| We should check for need init flag with the group's alloc_sem held, to |
| make sure while we are loading the buddy cache and holding a reference |
| to it, a file system resize can't add new blocks to same group. |
| |
| The patch also drops the need init flag check in |
| ext4_mb_regular_allocator() because doing the check without holding |
| alloc_sem is racy. |
| |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| fs/ext4/mballoc.c | 39 ++++++++++++++++++--------------------- |
| 1 file changed, 18 insertions(+), 21 deletions(-) |
| |
| --- a/fs/ext4/mballoc.c |
| +++ b/fs/ext4/mballoc.c |
| @@ -1032,8 +1032,26 @@ ext4_mb_load_buddy(struct super_block *s |
| * groups mapped by the page is blocked |
| * till we are done with allocation |
| */ |
| +repeat_load_buddy: |
| down_read(e4b->alloc_semp); |
| |
| + if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) { |
| + /* we need to check for group need init flag |
| + * with alloc_semp held so that we can be sure |
| + * that new blocks didn't get added to the group |
| + * when we are loading the buddy cache |
| + */ |
| + up_read(e4b->alloc_semp); |
| + /* |
| + * we need full data about the group |
| + * to make a good selection |
| + */ |
| + ret = ext4_mb_init_group(sb, group); |
| + if (ret) |
| + return ret; |
| + goto repeat_load_buddy; |
| + } |
| + |
| /* |
| * the buddy cache inode stores the block bitmap |
| * and buddy information in consecutive blocks. |
| @@ -2010,27 +2028,6 @@ repeat: |
| if (grp->bb_free == 0) |
| continue; |
| |
| - /* |
| - * if the group is already init we check whether it is |
| - * a good group and if not we don't load the buddy |
| - */ |
| - if (EXT4_MB_GRP_NEED_INIT(grp)) { |
| - /* |
| - * we need full data about the group |
| - * to make a good selection |
| - */ |
| - err = ext4_mb_init_group(sb, group); |
| - if (err) |
| - goto out; |
| - } |
| - |
| - /* |
| - * If the particular group doesn't satisfy our |
| - * criteria we continue with the next group |
| - */ |
| - if (!ext4_mb_good_group(ac, group, cr)) |
| - continue; |
| - |
| err = ext4_mb_load_buddy(sb, group, &e4b); |
| if (err) |
| goto out; |