aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-04-29 22:00:47 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-04-29 22:00:47 -0400
commitc83617db76353ff30e825874be2c15c185b95759 (patch)
tree630ec09cb577589238e3ca02ad9978a830422d43 /fs/ext4
parent3dcf54515aa4981a647ad74859199032965193a5 (diff)
ext4: Don't do GFP_NOFS allocations after taking ext4_lock_group
We can't do GFP_NOFS allocation after taking ext4_lock_group BUG: sleeping function called from invalid context at mm/slab.c:3054 in_atomic():1, irqs_disabled():0 1 lock held by vi/2426: #0: (&ei->i_data_sem){----}, at: [<c01cf665>] ext4_release_file+0x23/0x66 Pid: 2426, comm: vi Not tainted 2.6.25-rc7 #24 [<c011a3dc>] __might_sleep+0xbe/0xc5 [<c01620c9>] kmem_cache_alloc+0x22/0xa6 [<c01e382a>] ext4_mb_release_inode_pa+0x73/0x1b3 [<c01e6adf>] ext4_mb_discard_inode_preallocations+0x22d/0x2d4 [<c013000a>] ? param_set_ushort+0x32/0x39 [<c01ceba1>] ext4_discard_reservation+0x27/0x6a [<c01cf66c>] ext4_release_file+0x2a/0x66 [<c0165bd6>] __fput+0xae/0x155 [<c0165e46>] fput+0x17/0x19 [<c0163756>] filp_close+0x50/0x5a [<c01647c0>] sys_close+0x71/0xad [<c0104aba>] sysenter_past_esp+0x5f/0xa5 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/mballoc.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index f87471de3af7..d2f0b9661fb9 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3730,9 +3730,9 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac)
3730 */ 3730 */
3731static noinline_for_stack int 3731static noinline_for_stack int
3732ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, 3732ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3733 struct ext4_prealloc_space *pa) 3733 struct ext4_prealloc_space *pa,
3734 struct ext4_allocation_context *ac)
3734{ 3735{
3735 struct ext4_allocation_context *ac;
3736 struct super_block *sb = e4b->bd_sb; 3736 struct super_block *sb = e4b->bd_sb;
3737 struct ext4_sb_info *sbi = EXT4_SB(sb); 3737 struct ext4_sb_info *sbi = EXT4_SB(sb);
3738 unsigned long end; 3738 unsigned long end;
@@ -3748,8 +3748,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3748 BUG_ON(group != e4b->bd_group && pa->pa_len != 0); 3748 BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
3749 end = bit + pa->pa_len; 3749 end = bit + pa->pa_len;
3750 3750
3751 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
3752
3753 if (ac) { 3751 if (ac) {
3754 ac->ac_sb = sb; 3752 ac->ac_sb = sb;
3755 ac->ac_inode = pa->pa_inode; 3753 ac->ac_inode = pa->pa_inode;
@@ -3794,23 +3792,19 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3794 */ 3792 */
3795 } 3793 }
3796 atomic_add(free, &sbi->s_mb_discarded); 3794 atomic_add(free, &sbi->s_mb_discarded);
3797 if (ac)
3798 kmem_cache_free(ext4_ac_cachep, ac);
3799 3795
3800 return err; 3796 return err;
3801} 3797}
3802 3798
3803static noinline_for_stack int 3799static noinline_for_stack int
3804ext4_mb_release_group_pa(struct ext4_buddy *e4b, 3800ext4_mb_release_group_pa(struct ext4_buddy *e4b,
3805 struct ext4_prealloc_space *pa) 3801 struct ext4_prealloc_space *pa,
3802 struct ext4_allocation_context *ac)
3806{ 3803{
3807 struct ext4_allocation_context *ac;
3808 struct super_block *sb = e4b->bd_sb; 3804 struct super_block *sb = e4b->bd_sb;
3809 ext4_group_t group; 3805 ext4_group_t group;
3810 ext4_grpblk_t bit; 3806 ext4_grpblk_t bit;
3811 3807
3812 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
3813
3814 if (ac) 3808 if (ac)
3815 ac->ac_op = EXT4_MB_HISTORY_DISCARD; 3809 ac->ac_op = EXT4_MB_HISTORY_DISCARD;
3816 3810
@@ -3828,7 +3822,6 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
3828 ac->ac_b_ex.fe_len = pa->pa_len; 3822 ac->ac_b_ex.fe_len = pa->pa_len;
3829 ac->ac_b_ex.fe_logical = 0; 3823 ac->ac_b_ex.fe_logical = 0;
3830 ext4_mb_store_history(ac); 3824 ext4_mb_store_history(ac);
3831 kmem_cache_free(ext4_ac_cachep, ac);
3832 } 3825 }
3833 3826
3834 return 0; 3827 return 0;
@@ -3850,6 +3843,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
3850 struct ext4_group_info *grp = ext4_get_group_info(sb, group); 3843 struct ext4_group_info *grp = ext4_get_group_info(sb, group);
3851 struct buffer_head *bitmap_bh = NULL; 3844 struct buffer_head *bitmap_bh = NULL;
3852 struct ext4_prealloc_space *pa, *tmp; 3845 struct ext4_prealloc_space *pa, *tmp;
3846 struct ext4_allocation_context *ac;
3853 struct list_head list; 3847 struct list_head list;
3854 struct ext4_buddy e4b; 3848 struct ext4_buddy e4b;
3855 int err; 3849 int err;
@@ -3877,6 +3871,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
3877 grp = ext4_get_group_info(sb, group); 3871 grp = ext4_get_group_info(sb, group);
3878 INIT_LIST_HEAD(&list); 3872 INIT_LIST_HEAD(&list);
3879 3873
3874 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
3880repeat: 3875repeat:
3881 ext4_lock_group(sb, group); 3876 ext4_lock_group(sb, group);
3882 list_for_each_entry_safe(pa, tmp, 3877 list_for_each_entry_safe(pa, tmp,
@@ -3931,9 +3926,9 @@ repeat:
3931 spin_unlock(pa->pa_obj_lock); 3926 spin_unlock(pa->pa_obj_lock);
3932 3927
3933 if (pa->pa_linear) 3928 if (pa->pa_linear)
3934 ext4_mb_release_group_pa(&e4b, pa); 3929 ext4_mb_release_group_pa(&e4b, pa, ac);
3935 else 3930 else
3936 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa); 3931 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac);
3937 3932
3938 list_del(&pa->u.pa_tmp_list); 3933 list_del(&pa->u.pa_tmp_list);
3939 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback); 3934 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
@@ -3941,6 +3936,8 @@ repeat:
3941 3936
3942out: 3937out:
3943 ext4_unlock_group(sb, group); 3938 ext4_unlock_group(sb, group);
3939 if (ac)
3940 kmem_cache_free(ext4_ac_cachep, ac);
3944 ext4_mb_release_desc(&e4b); 3941 ext4_mb_release_desc(&e4b);
3945 put_bh(bitmap_bh); 3942 put_bh(bitmap_bh);
3946 return free; 3943 return free;
@@ -3961,6 +3958,7 @@ void ext4_mb_discard_inode_preallocations(struct inode *inode)
3961 struct super_block *sb = inode->i_sb; 3958 struct super_block *sb = inode->i_sb;
3962 struct buffer_head *bitmap_bh = NULL; 3959 struct buffer_head *bitmap_bh = NULL;
3963 struct ext4_prealloc_space *pa, *tmp; 3960 struct ext4_prealloc_space *pa, *tmp;
3961 struct ext4_allocation_context *ac;
3964 ext4_group_t group = 0; 3962 ext4_group_t group = 0;
3965 struct list_head list; 3963 struct list_head list;
3966 struct ext4_buddy e4b; 3964 struct ext4_buddy e4b;
@@ -3975,6 +3973,7 @@ void ext4_mb_discard_inode_preallocations(struct inode *inode)
3975 3973
3976 INIT_LIST_HEAD(&list); 3974 INIT_LIST_HEAD(&list);
3977 3975
3976 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
3978repeat: 3977repeat:
3979 /* first, collect all pa's in the inode */ 3978 /* first, collect all pa's in the inode */
3980 spin_lock(&ei->i_prealloc_lock); 3979 spin_lock(&ei->i_prealloc_lock);
@@ -4039,7 +4038,7 @@ repeat:
4039 4038
4040 ext4_lock_group(sb, group); 4039 ext4_lock_group(sb, group);
4041 list_del(&pa->pa_group_list); 4040 list_del(&pa->pa_group_list);
4042 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa); 4041 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa, ac);
4043 ext4_unlock_group(sb, group); 4042 ext4_unlock_group(sb, group);
4044 4043
4045 ext4_mb_release_desc(&e4b); 4044 ext4_mb_release_desc(&e4b);
@@ -4048,6 +4047,8 @@ repeat:
4048 list_del(&pa->u.pa_tmp_list); 4047 list_del(&pa->u.pa_tmp_list);
4049 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback); 4048 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
4050 } 4049 }
4050 if (ac)
4051 kmem_cache_free(ext4_ac_cachep, ac);
4051} 4052}
4052 4053
4053/* 4054/*