diff options
author | Chris Mason <chris.mason@oracle.com> | 2009-02-12 14:09:45 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-02-12 14:09:45 -0500 |
commit | 4008c04a07c73ec3cb1be4c1391d2159a8f75d6d (patch) | |
tree | c0b10a7287ac810bfc406541e32b850ad4580248 /fs/btrfs/extent-tree.c | |
parent | 3f3420df505e47751ef76a652b5cb660e5360d6f (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.c | 7 |
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 | ||
3417 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 3417 | struct 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 | ||