]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ext4: fix race in ext4_mb_add_n_trim()
authorNiu Yawei <yawei.niu@gmail.com>
Sat, 2 Feb 2013 02:31:27 +0000 (21:31 -0500)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 6 Mar 2013 03:23:47 +0000 (03:23 +0000)
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: Ben Hutchings <ben@decadent.org.uk>
fs/ext4/mballoc.c

index 1d07c1231b7feeb7f4e126a0c68358c4abca97af..553ff71bb151c82e38ff520a9564bae5c3f99332 100644 (file)
@@ -4178,7 +4178,7 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
                /* The max size of hash table is PREALLOC_TB_SIZE */
                order = PREALLOC_TB_SIZE - 1;
        /* Add the prealloc space to lg */
-       rcu_read_lock();
+       spin_lock(&lg->lg_prealloc_lock);
        list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order],
                                                pa_inode_list) {
                spin_lock(&tmp_pa->pa_lock);
@@ -4202,12 +4202,12 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
        if (!added)
                list_add_tail_rcu(&pa->pa_inode_list,
                                        &lg->lg_prealloc_list[order]);
-       rcu_read_unlock();
+       spin_unlock(&lg->lg_prealloc_lock);
 
        /* Now trim the list to be not more than 8 elements */
        if (lg_prealloc_count > 8) {
                ext4_mb_discard_lg_preallocations(sb, lg,
-                                               order, lg_prealloc_count);
+                                                 order, lg_prealloc_count);
                return;
        }
        return ;