aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-02-12 14:09:45 -0500
committerChris Mason <chris.mason@oracle.com>2009-02-12 14:09:45 -0500
commit4008c04a07c73ec3cb1be4c1391d2159a8f75d6d (patch)
treec0b10a7287ac810bfc406541e32b850ad4580248 /fs/btrfs/extent-tree.c
parent3f3420df505e47751ef76a652b5cb660e5360d6f (diff)
Btrfs: make a lockdep class for the extent buffer locks
Btrfs is currently using spin_lock_nested with a nested value based on the tree depth of the block. But, this doesn't quite work because the max tree depth is bigger than what spin_lock_nested can deal with, and because locks are sometimes taken before the level field is filled in. The solution here is to use lockdep_set_class_and_name instead, and to set the class before unlocking the pages when the block is read from the disk and just after init of a freshly allocated tree block. btrfs_clear_path_blocking is also changed to take the locks in the proper order, and it also makes sure all the locks currently held are properly set to blocking before it tries to retake the spinlocks. Otherwise, lockdep gets upset about bad lock orderin. The lockdep magic cam from Peter Zijlstra <peterz@infradead.org> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c59e12036e20..cd86bffbdc9f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3416,7 +3416,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
3416 3416
3417struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, 3417struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
3418 struct btrfs_root *root, 3418 struct btrfs_root *root,
3419 u64 bytenr, u32 blocksize) 3419 u64 bytenr, u32 blocksize,
3420 int level)
3420{ 3421{
3421 struct extent_buffer *buf; 3422 struct extent_buffer *buf;
3422 3423
@@ -3424,6 +3425,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
3424 if (!buf) 3425 if (!buf)
3425 return ERR_PTR(-ENOMEM); 3426 return ERR_PTR(-ENOMEM);
3426 btrfs_set_header_generation(buf, trans->transid); 3427 btrfs_set_header_generation(buf, trans->transid);
3428 btrfs_set_buffer_lockdep_class(buf, level);
3427 btrfs_tree_lock(buf); 3429 btrfs_tree_lock(buf);
3428 clean_tree_block(trans, root, buf); 3430 clean_tree_block(trans, root, buf);
3429 3431
@@ -3467,7 +3469,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
3467 return ERR_PTR(ret); 3469 return ERR_PTR(ret);
3468 } 3470 }
3469 3471
3470 buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); 3472 buf = btrfs_init_new_buffer(trans, root, ins.objectid,
3473 blocksize, level);
3471 return buf; 3474 return buf;
3472} 3475}
3473 3476