aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2012-05-31 08:00:15 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2012-05-31 13:56:18 -0400
commit926dd8a640da1bbf7478eebea1c23a842fc9c890 (patch)
tree92ca5d559964d910575de487fdb66372ad5caa60 /fs/btrfs/ctree.c
parent3301958b7c1dae8f0f5ded63aa881e0b71e78464 (diff)
Btrfs: add missing spin_lock for insertion into tree mod log
tree_mod_alloc calls __get_tree_mod_seq and must acquire a spinlock before doing so. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 0954f1770fd0..26e8dc1681b0 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -455,11 +455,11 @@ unlock:
455 return ret; 455 return ret;
456} 456}
457 457
458int tree_mod_alloc(struct btrfs_fs_info *fs_info, gfp_t flags, 458static inline int tree_mod_alloc(struct btrfs_fs_info *fs_info, gfp_t flags,
459 struct tree_mod_elem **tm_ret) 459 struct tree_mod_elem **tm_ret)
460{ 460{
461 struct tree_mod_elem *tm; 461 struct tree_mod_elem *tm;
462 u64 seq = 0; 462 int seq;
463 463
464 smp_mb(); 464 smp_mb();
465 if (list_empty(&fs_info->tree_mod_seq_list)) 465 if (list_empty(&fs_info->tree_mod_seq_list))
@@ -469,9 +469,22 @@ int tree_mod_alloc(struct btrfs_fs_info *fs_info, gfp_t flags,
469 if (!tm) 469 if (!tm)
470 return -ENOMEM; 470 return -ENOMEM;
471 471
472 __get_tree_mod_seq(fs_info, &tm->elem);
473 seq = tm->elem.seq;
474 tm->elem.flags = 0; 472 tm->elem.flags = 0;
473 spin_lock(&fs_info->tree_mod_seq_lock);
474 if (list_empty(&fs_info->tree_mod_seq_list)) {
475 /*
476 * someone emptied the list while we were waiting for the lock.
477 * we must not add to the list, because no blocker exists. items
478 * are removed from the list only when the existing blocker is
479 * removed from the list.
480 */
481 kfree(tm);
482 seq = 0;
483 } else {
484 __get_tree_mod_seq(fs_info, &tm->elem);
485 seq = tm->elem.seq;
486 }
487 spin_unlock(&fs_info->tree_mod_seq_lock);
475 488
476 return seq; 489 return seq;
477} 490}