diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2008-04-29 22:00:47 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-04-29 22:00:47 -0400 |
commit | c83617db76353ff30e825874be2c15c185b95759 (patch) | |
tree | 630ec09cb577589238e3ca02ad9978a830422d43 /fs | |
parent | 3dcf54515aa4981a647ad74859199032965193a5 (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')
-rw-r--r-- | fs/ext4/mballoc.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index f87471de3af..d2f0b9661fb 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 | */ |
3731 | static noinline_for_stack int | 3731 | static noinline_for_stack int |
3732 | ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, | 3732 | ext4_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 | ||
3803 | static noinline_for_stack int | 3799 | static noinline_for_stack int |
3804 | ext4_mb_release_group_pa(struct ext4_buddy *e4b, | 3800 | ext4_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); | ||
3880 | repeat: | 3875 | repeat: |
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 | ||
3942 | out: | 3937 | out: |
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); | ||
3978 | repeat: | 3977 | repeat: |
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 | /* |