diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-07-17 12:54:40 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:04 -0400 |
commit | ee6e6504e147a59a9f4d582662c105e9d72ae638 (patch) | |
tree | be932cc04abb860ed76ab8d4c4c28353ed50bebb /fs/btrfs/inode.c | |
parent | ba1da2f442ec91a1534afa893f9bef7e33056ace (diff) |
Add a per-inode lock around btrfs_drop_extents
btrfs_drop_extents is always called with a range lock held on the inode.
But, it may operate on extents outside that range as it drops and splits
them.
This patch adds a per-inode mutex that is held while calling
btrfs_drop_extents and while inserting new extents into the tree. It
prevents races from two procs working against adjacent ranges in the tree.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 293355c92a4f..0d1e2ba47a9c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -516,6 +516,8 @@ int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, | |||
516 | trans->transid, inode->i_ino, | 516 | trans->transid, inode->i_ino, |
517 | ordered_extent->file_offset, &ins); | 517 | ordered_extent->file_offset, &ins); |
518 | BUG_ON(ret); | 518 | BUG_ON(ret); |
519 | |||
520 | mutex_lock(&BTRFS_I(inode)->extent_mutex); | ||
519 | ret = btrfs_drop_extents(trans, root, inode, | 521 | ret = btrfs_drop_extents(trans, root, inode, |
520 | ordered_extent->file_offset, | 522 | ordered_extent->file_offset, |
521 | ordered_extent->file_offset + | 523 | ordered_extent->file_offset + |
@@ -531,6 +533,8 @@ int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, | |||
531 | btrfs_drop_extent_cache(inode, ordered_extent->file_offset, | 533 | btrfs_drop_extent_cache(inode, ordered_extent->file_offset, |
532 | ordered_extent->file_offset + | 534 | ordered_extent->file_offset + |
533 | ordered_extent->len - 1); | 535 | ordered_extent->len - 1); |
536 | mutex_unlock(&BTRFS_I(inode)->extent_mutex); | ||
537 | |||
534 | inode->i_blocks += ordered_extent->len >> 9; | 538 | inode->i_blocks += ordered_extent->len >> 9; |
535 | unlock_extent(io_tree, ordered_extent->file_offset, | 539 | unlock_extent(io_tree, ordered_extent->file_offset, |
536 | ordered_extent->file_offset + ordered_extent->len - 1, | 540 | ordered_extent->file_offset + ordered_extent->len - 1, |
@@ -1399,6 +1403,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
1399 | 1403 | ||
1400 | trans = btrfs_start_transaction(root, 1); | 1404 | trans = btrfs_start_transaction(root, 1); |
1401 | btrfs_set_trans_block_group(trans, inode); | 1405 | btrfs_set_trans_block_group(trans, inode); |
1406 | mutex_lock(&BTRFS_I(inode)->extent_mutex); | ||
1402 | err = btrfs_drop_extents(trans, root, inode, | 1407 | err = btrfs_drop_extents(trans, root, inode, |
1403 | hole_start, block_end, hole_start, | 1408 | hole_start, block_end, hole_start, |
1404 | &alloc_hint); | 1409 | &alloc_hint); |
@@ -1412,6 +1417,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
1412 | (u64)-1); | 1417 | (u64)-1); |
1413 | btrfs_check_file(root, inode); | 1418 | btrfs_check_file(root, inode); |
1414 | } | 1419 | } |
1420 | mutex_unlock(&BTRFS_I(inode)->extent_mutex); | ||
1415 | btrfs_end_transaction(trans, root); | 1421 | btrfs_end_transaction(trans, root); |
1416 | unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); | 1422 | unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); |
1417 | if (err) | 1423 | if (err) |
@@ -1578,6 +1584,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
1578 | inode->i_mapping, GFP_NOFS); | 1584 | inode->i_mapping, GFP_NOFS); |
1579 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | 1585 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); |
1580 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 1586 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
1587 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
1581 | return 0; | 1588 | return 0; |
1582 | } | 1589 | } |
1583 | 1590 | ||
@@ -1880,6 +1887,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
1880 | inode->i_mapping, GFP_NOFS); | 1887 | inode->i_mapping, GFP_NOFS); |
1881 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | 1888 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); |
1882 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 1889 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
1890 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
1883 | BTRFS_I(inode)->delalloc_bytes = 0; | 1891 | BTRFS_I(inode)->delalloc_bytes = 0; |
1884 | BTRFS_I(inode)->disk_i_size = 0; | 1892 | BTRFS_I(inode)->disk_i_size = 0; |
1885 | BTRFS_I(inode)->root = root; | 1893 | BTRFS_I(inode)->root = root; |
@@ -2105,6 +2113,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
2105 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 2113 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
2106 | inode->i_mapping, GFP_NOFS); | 2114 | inode->i_mapping, GFP_NOFS); |
2107 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 2115 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
2116 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
2108 | BTRFS_I(inode)->delalloc_bytes = 0; | 2117 | BTRFS_I(inode)->delalloc_bytes = 0; |
2109 | BTRFS_I(inode)->disk_i_size = 0; | 2118 | BTRFS_I(inode)->disk_i_size = 0; |
2110 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 2119 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
@@ -3079,6 +3088,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
3079 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 3088 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
3080 | inode->i_mapping, GFP_NOFS); | 3089 | inode->i_mapping, GFP_NOFS); |
3081 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 3090 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
3091 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
3082 | BTRFS_I(inode)->delalloc_bytes = 0; | 3092 | BTRFS_I(inode)->delalloc_bytes = 0; |
3083 | BTRFS_I(inode)->disk_i_size = 0; | 3093 | BTRFS_I(inode)->disk_i_size = 0; |
3084 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 3094 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |