aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiu Yawei2013-02-01 20:31:27 -0600
committerGreg Kroah-Hartman2013-03-03 16:09:05 -0600
commitfd80f53550720f200ca0469e9419c750f895ab50 (patch)
tree9f38972a5c4df24ae1e780df97f5c85cffdbbf0f
parent5dec43e3d688390256df3343bb444e7ed0022f44 (diff)
downloadkernel-common-fd80f53550720f200ca0469e9419c750f895ab50.tar.gz
kernel-common-fd80f53550720f200ca0469e9419c750f895ab50.tar.xz
kernel-common-fd80f53550720f200ca0469e9419c750f895ab50.zip
ext4: fix race in ext4_mb_add_n_trim()
commit f1167009711032b0d747ec89a632a626c901a1ad upstream. In ext4_mb_add_n_trim(), lg_prealloc_lock should be taken when changing the lg_prealloc_list. Signed-off-by: Niu Yawei <yawei.niu@intel.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/ext4/mballoc.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index b6adf68a5c0..31bbdb52b89 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4111,7 +4111,7 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
4111 /* The max size of hash table is PREALLOC_TB_SIZE */ 4111 /* The max size of hash table is PREALLOC_TB_SIZE */
4112 order = PREALLOC_TB_SIZE - 1; 4112 order = PREALLOC_TB_SIZE - 1;
4113 /* Add the prealloc space to lg */ 4113 /* Add the prealloc space to lg */
4114 rcu_read_lock(); 4114 spin_lock(&lg->lg_prealloc_lock);
4115 list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order], 4115 list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order],
4116 pa_inode_list) { 4116 pa_inode_list) {
4117 spin_lock(&tmp_pa->pa_lock); 4117 spin_lock(&tmp_pa->pa_lock);
@@ -4135,12 +4135,12 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
4135 if (!added) 4135 if (!added)
4136 list_add_tail_rcu(&pa->pa_inode_list, 4136 list_add_tail_rcu(&pa->pa_inode_list,
4137 &lg->lg_prealloc_list[order]); 4137 &lg->lg_prealloc_list[order]);
4138 rcu_read_unlock(); 4138 spin_unlock(&lg->lg_prealloc_lock);
4139 4139
4140 /* Now trim the list to be not more than 8 elements */ 4140 /* Now trim the list to be not more than 8 elements */
4141 if (lg_prealloc_count > 8) { 4141 if (lg_prealloc_count > 8) {
4142 ext4_mb_discard_lg_preallocations(sb, lg, 4142 ext4_mb_discard_lg_preallocations(sb, lg,
4143 order, lg_prealloc_count); 4143 order, lg_prealloc_count);
4144 return; 4144 return;
4145 } 4145 }
4146 return ; 4146 return ;