aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2011-04-19 22:33:24 -0400
committerLi Zefan <lizf@cn.fujitsu.com>2011-04-25 04:46:11 -0400
commit82d5902d9c681be37ffa9d70482907f9f0b7ec1f (patch)
treec9c99f0b60004ac14d09d277d3216667df09c32d /fs/btrfs/inode.c
parent33345d01522f8152f99dc84a3e7a1a45707f387f (diff)
Btrfs: Support reading/writing on disk free ino cache
This is similar to block group caching. We dedicate a special inode in fs tree to save free ino cache. At the very first time we create/delete a file after mount, the free ino cache will be loaded from disk into memory. When the fs tree is commited, the cache will be written back to disk. To keep compatibility, we check the root generation against the generation of the special inode when loading the cache, so the loading will fail if the btrfs filesystem was mounted in an older kernel before. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index adec22884a3e..b78d3ab789ca 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -745,6 +745,15 @@ static u64 get_extent_allocation_hint(struct inode *inode, u64 start,
745 return alloc_hint; 745 return alloc_hint;
746} 746}
747 747
748static inline bool is_free_space_inode(struct btrfs_root *root,
749 struct inode *inode)
750{
751 if (root == root->fs_info->tree_root ||
752 BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
753 return true;
754 return false;
755}
756
748/* 757/*
749 * when extent_io.c finds a delayed allocation range in the file, 758 * when extent_io.c finds a delayed allocation range in the file,
750 * the call backs end up in this code. The basic idea is to 759 * the call backs end up in this code. The basic idea is to
@@ -777,7 +786,7 @@ static noinline int cow_file_range(struct inode *inode,
777 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; 786 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
778 int ret = 0; 787 int ret = 0;
779 788
780 BUG_ON(root == root->fs_info->tree_root); 789 BUG_ON(is_free_space_inode(root, inode));
781 trans = btrfs_join_transaction(root, 1); 790 trans = btrfs_join_transaction(root, 1);
782 BUG_ON(IS_ERR(trans)); 791 BUG_ON(IS_ERR(trans));
783 btrfs_set_trans_block_group(trans, inode); 792 btrfs_set_trans_block_group(trans, inode);
@@ -1048,17 +1057,18 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1048 int type; 1057 int type;
1049 int nocow; 1058 int nocow;
1050 int check_prev = 1; 1059 int check_prev = 1;
1051 bool nolock = false; 1060 bool nolock;
1052 u64 ino = btrfs_ino(inode); 1061 u64 ino = btrfs_ino(inode);
1053 1062
1054 path = btrfs_alloc_path(); 1063 path = btrfs_alloc_path();
1055 BUG_ON(!path); 1064 BUG_ON(!path);
1056 if (root == root->fs_info->tree_root) { 1065
1057 nolock = true; 1066 nolock = is_free_space_inode(root, inode);
1067
1068 if (nolock)
1058 trans = btrfs_join_transaction_nolock(root, 1); 1069 trans = btrfs_join_transaction_nolock(root, 1);
1059 } else { 1070 else
1060 trans = btrfs_join_transaction(root, 1); 1071 trans = btrfs_join_transaction(root, 1);
1061 }
1062 BUG_ON(IS_ERR(trans)); 1072 BUG_ON(IS_ERR(trans));
1063 1073
1064 cow_start = (u64)-1; 1074 cow_start = (u64)-1;
@@ -1316,8 +1326,7 @@ static int btrfs_set_bit_hook(struct inode *inode,
1316 if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { 1326 if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
1317 struct btrfs_root *root = BTRFS_I(inode)->root; 1327 struct btrfs_root *root = BTRFS_I(inode)->root;
1318 u64 len = state->end + 1 - state->start; 1328 u64 len = state->end + 1 - state->start;
1319 int do_list = (root->root_key.objectid != 1329 bool do_list = !is_free_space_inode(root, inode);
1320 BTRFS_ROOT_TREE_OBJECTID);
1321 1330
1322 if (*bits & EXTENT_FIRST_DELALLOC) 1331 if (*bits & EXTENT_FIRST_DELALLOC)
1323 *bits &= ~EXTENT_FIRST_DELALLOC; 1332 *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1350,8 +1359,7 @@ static int btrfs_clear_bit_hook(struct inode *inode,
1350 if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { 1359 if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
1351 struct btrfs_root *root = BTRFS_I(inode)->root; 1360 struct btrfs_root *root = BTRFS_I(inode)->root;
1352 u64 len = state->end + 1 - state->start; 1361 u64 len = state->end + 1 - state->start;
1353 int do_list = (root->root_key.objectid != 1362 bool do_list = !is_free_space_inode(root, inode);
1354 BTRFS_ROOT_TREE_OBJECTID);
1355 1363
1356 if (*bits & EXTENT_FIRST_DELALLOC) 1364 if (*bits & EXTENT_FIRST_DELALLOC)
1357 *bits &= ~EXTENT_FIRST_DELALLOC; 1365 *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1458,7 +1466,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1458 1466
1459 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 1467 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
1460 1468
1461 if (root == root->fs_info->tree_root) 1469 if (is_free_space_inode(root, inode))
1462 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); 1470 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2);
1463 else 1471 else
1464 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 1472 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
@@ -1701,7 +1709,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1701 struct extent_state *cached_state = NULL; 1709 struct extent_state *cached_state = NULL;
1702 int compress_type = 0; 1710 int compress_type = 0;
1703 int ret; 1711 int ret;
1704 bool nolock = false; 1712 bool nolock;
1705 1713
1706 ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, 1714 ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
1707 end - start + 1); 1715 end - start + 1);
@@ -1709,7 +1717,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1709 return 0; 1717 return 0;
1710 BUG_ON(!ordered_extent); 1718 BUG_ON(!ordered_extent);
1711 1719
1712 nolock = (root == root->fs_info->tree_root); 1720 nolock = is_free_space_inode(root, inode);
1713 1721
1714 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { 1722 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
1715 BUG_ON(!list_empty(&ordered_extent->list)); 1723 BUG_ON(!list_empty(&ordered_extent->list));
@@ -3473,7 +3481,9 @@ delete:
3473 3481
3474 if (path->slots[0] == 0 || 3482 if (path->slots[0] == 0 ||
3475 path->slots[0] != pending_del_slot) { 3483 path->slots[0] != pending_del_slot) {
3476 if (root->ref_cows) { 3484 if (root->ref_cows &&
3485 BTRFS_I(inode)->location.objectid !=
3486 BTRFS_FREE_INO_OBJECTID) {
3477 err = -EAGAIN; 3487 err = -EAGAIN;
3478 goto out; 3488 goto out;
3479 } 3489 }
@@ -3765,7 +3775,7 @@ void btrfs_evict_inode(struct inode *inode)
3765 3775
3766 truncate_inode_pages(&inode->i_data, 0); 3776 truncate_inode_pages(&inode->i_data, 0);
3767 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || 3777 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
3768 root == root->fs_info->tree_root)) 3778 is_free_space_inode(root, inode)))
3769 goto no_delete; 3779 goto no_delete;
3770 3780
3771 if (is_bad_inode(inode)) { 3781 if (is_bad_inode(inode)) {
@@ -4382,7 +4392,8 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
4382 return 0; 4392 return 0;
4383 4393
4384 smp_mb(); 4394 smp_mb();
4385 nolock = (root->fs_info->closing && root == root->fs_info->tree_root); 4395 if (root->fs_info->closing && is_free_space_inode(root, inode))
4396 nolock = true;
4386 4397
4387 if (wbc->sync_mode == WB_SYNC_ALL) { 4398 if (wbc->sync_mode == WB_SYNC_ALL) {
4388 if (nolock) 4399 if (nolock)
@@ -6900,7 +6911,7 @@ int btrfs_drop_inode(struct inode *inode)
6900 struct btrfs_root *root = BTRFS_I(inode)->root; 6911 struct btrfs_root *root = BTRFS_I(inode)->root;
6901 6912
6902 if (btrfs_root_refs(&root->root_item) == 0 && 6913 if (btrfs_root_refs(&root->root_item) == 0 &&
6903 root != root->fs_info->tree_root) 6914 !is_free_space_inode(root, inode))
6904 return 1; 6915 return 1;
6905 else 6916 else
6906 return generic_drop_inode(inode); 6917 return generic_drop_inode(inode);