aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-07-26 15:35:09 -0400
committerChris Mason <chris.mason@oracle.com>2011-07-27 12:46:48 -0400
commit2cf8572dac62cc2ff7e995173e95b6c694401b3f (patch)
treeae37f2f4a2f4a797ee971a94ee2c29c55a8048dc /fs
parent19b6caf4acbf065dc96b47741d99f1b87243c468 (diff)
Btrfs: use the commit_root for reading free_space_inode crcs
Now that we are using regular file crcs for the free space cache, we can deadlock if we try to read the free_space_inode while we are updating the crc tree. This commit fixes things by using the commit_root to read the crcs. This is safe because we the free space cache file would already be loaded if that block group had been changed in the current transaction. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/btrfs_inode.h9
-rw-r--r--fs/btrfs/file-item.c9
-rw-r--r--fs/btrfs/inode.c29
3 files changed, 28 insertions, 19 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 03dce3f40ce0..502b9e988679 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -187,4 +187,13 @@ static inline void btrfs_i_size_write(struct inode *inode, u64 size)
187 BTRFS_I(inode)->disk_i_size = size; 187 BTRFS_I(inode)->disk_i_size = size;
188} 188}
189 189
190static inline bool btrfs_is_free_space_inode(struct btrfs_root *root,
191 struct inode *inode)
192{
193 if (root == root->fs_info->tree_root ||
194 BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
195 return true;
196 return false;
197}
198
190#endif 199#endif
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index bb22a4435b2d..08bcfa92a222 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -177,6 +177,15 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
177 177
178 WARN_ON(bio->bi_vcnt <= 0); 178 WARN_ON(bio->bi_vcnt <= 0);
179 179
180 /*
181 * the free space stuff is only read when it hasn't been
182 * updated in the current transaction. So, we can safely
183 * read from the commit root and sidestep a nasty deadlock
184 * between reading the free space cache and updating the csum tree.
185 */
186 if (btrfs_is_free_space_inode(root, inode))
187 path->search_commit_root = 1;
188
180 disk_bytenr = (u64)bio->bi_sector << 9; 189 disk_bytenr = (u64)bio->bi_sector << 9;
181 if (dio) 190 if (dio)
182 offset = logical_offset; 191 offset = logical_offset;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3b5763a2b7f9..4b9be2883a8d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -750,15 +750,6 @@ static u64 get_extent_allocation_hint(struct inode *inode, u64 start,
750 return alloc_hint; 750 return alloc_hint;
751} 751}
752 752
753static inline bool is_free_space_inode(struct btrfs_root *root,
754 struct inode *inode)
755{
756 if (root == root->fs_info->tree_root ||
757 BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
758 return true;
759 return false;
760}
761
762/* 753/*
763 * when extent_io.c finds a delayed allocation range in the file, 754 * when extent_io.c finds a delayed allocation range in the file,
764 * the call backs end up in this code. The basic idea is to 755 * the call backs end up in this code. The basic idea is to
@@ -791,7 +782,7 @@ static noinline int cow_file_range(struct inode *inode,
791 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; 782 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
792 int ret = 0; 783 int ret = 0;
793 784
794 BUG_ON(is_free_space_inode(root, inode)); 785 BUG_ON(btrfs_is_free_space_inode(root, inode));
795 trans = btrfs_join_transaction(root); 786 trans = btrfs_join_transaction(root);
796 BUG_ON(IS_ERR(trans)); 787 BUG_ON(IS_ERR(trans));
797 trans->block_rsv = &root->fs_info->delalloc_block_rsv; 788 trans->block_rsv = &root->fs_info->delalloc_block_rsv;
@@ -1072,7 +1063,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1072 path = btrfs_alloc_path(); 1063 path = btrfs_alloc_path();
1073 BUG_ON(!path); 1064 BUG_ON(!path);
1074 1065
1075 nolock = is_free_space_inode(root, inode); 1066 nolock = btrfs_is_free_space_inode(root, inode);
1076 1067
1077 if (nolock) 1068 if (nolock)
1078 trans = btrfs_join_transaction_nolock(root); 1069 trans = btrfs_join_transaction_nolock(root);
@@ -1341,7 +1332,7 @@ static int btrfs_set_bit_hook(struct inode *inode,
1341 if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { 1332 if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
1342 struct btrfs_root *root = BTRFS_I(inode)->root; 1333 struct btrfs_root *root = BTRFS_I(inode)->root;
1343 u64 len = state->end + 1 - state->start; 1334 u64 len = state->end + 1 - state->start;
1344 bool do_list = !is_free_space_inode(root, inode); 1335 bool do_list = !btrfs_is_free_space_inode(root, inode);
1345 1336
1346 if (*bits & EXTENT_FIRST_DELALLOC) { 1337 if (*bits & EXTENT_FIRST_DELALLOC) {
1347 *bits &= ~EXTENT_FIRST_DELALLOC; 1338 *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1377,7 +1368,7 @@ static int btrfs_clear_bit_hook(struct inode *inode,
1377 if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { 1368 if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
1378 struct btrfs_root *root = BTRFS_I(inode)->root; 1369 struct btrfs_root *root = BTRFS_I(inode)->root;
1379 u64 len = state->end + 1 - state->start; 1370 u64 len = state->end + 1 - state->start;
1380 bool do_list = !is_free_space_inode(root, inode); 1371 bool do_list = !btrfs_is_free_space_inode(root, inode);
1381 1372
1382 if (*bits & EXTENT_FIRST_DELALLOC) { 1373 if (*bits & EXTENT_FIRST_DELALLOC) {
1383 *bits &= ~EXTENT_FIRST_DELALLOC; 1374 *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1487,7 +1478,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1487 1478
1488 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 1479 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
1489 1480
1490 if (is_free_space_inode(root, inode)) 1481 if (btrfs_is_free_space_inode(root, inode))
1491 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); 1482 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2);
1492 else 1483 else
1493 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 1484 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
@@ -1736,7 +1727,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1736 return 0; 1727 return 0;
1737 BUG_ON(!ordered_extent); 1728 BUG_ON(!ordered_extent);
1738 1729
1739 nolock = is_free_space_inode(root, inode); 1730 nolock = btrfs_is_free_space_inode(root, inode);
1740 1731
1741 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { 1732 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
1742 BUG_ON(!list_empty(&ordered_extent->list)); 1733 BUG_ON(!list_empty(&ordered_extent->list));
@@ -2670,7 +2661,7 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
2670 * The data relocation inode should also be directly updated 2661 * The data relocation inode should also be directly updated
2671 * without delay 2662 * without delay
2672 */ 2663 */
2673 if (!is_free_space_inode(root, inode) 2664 if (!btrfs_is_free_space_inode(root, inode)
2674 && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { 2665 && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
2675 ret = btrfs_delayed_update_inode(trans, root, inode); 2666 ret = btrfs_delayed_update_inode(trans, root, inode);
2676 if (!ret) 2667 if (!ret)
@@ -3620,7 +3611,7 @@ void btrfs_evict_inode(struct inode *inode)
3620 3611
3621 truncate_inode_pages(&inode->i_data, 0); 3612 truncate_inode_pages(&inode->i_data, 0);
3622 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || 3613 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
3623 is_free_space_inode(root, inode))) 3614 btrfs_is_free_space_inode(root, inode)))
3624 goto no_delete; 3615 goto no_delete;
3625 3616
3626 if (is_bad_inode(inode)) { 3617 if (is_bad_inode(inode)) {
@@ -4263,7 +4254,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
4263 if (BTRFS_I(inode)->dummy_inode) 4254 if (BTRFS_I(inode)->dummy_inode)
4264 return 0; 4255 return 0;
4265 4256
4266 if (btrfs_fs_closing(root->fs_info) && is_free_space_inode(root, inode)) 4257 if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(root, inode))
4267 nolock = true; 4258 nolock = true;
4268 4259
4269 if (wbc->sync_mode == WB_SYNC_ALL) { 4260 if (wbc->sync_mode == WB_SYNC_ALL) {
@@ -6817,7 +6808,7 @@ int btrfs_drop_inode(struct inode *inode)
6817 struct btrfs_root *root = BTRFS_I(inode)->root; 6808 struct btrfs_root *root = BTRFS_I(inode)->root;
6818 6809
6819 if (btrfs_root_refs(&root->root_item) == 0 && 6810 if (btrfs_root_refs(&root->root_item) == 0 &&
6820 !is_free_space_inode(root, inode)) 6811 !btrfs_is_free_space_inode(root, inode))
6821 return 1; 6812 return 1;
6822 else 6813 else
6823 return generic_drop_inode(inode); 6814 return generic_drop_inode(inode);