|
@@ -745,6 +745,15 @@ static u64 get_extent_allocation_hint(struct inode *inode, u64 start,
|
|
|
return alloc_hint;
|
|
|
}
|
|
|
|
|
|
+static inline bool is_free_space_inode(struct btrfs_root *root,
|
|
|
+ struct inode *inode)
|
|
|
+{
|
|
|
+ if (root == root->fs_info->tree_root ||
|
|
|
+ BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* when extent_io.c finds a delayed allocation range in the file,
|
|
|
* 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,
|
|
|
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
|
|
int ret = 0;
|
|
|
|
|
|
- BUG_ON(root == root->fs_info->tree_root);
|
|
|
+ BUG_ON(is_free_space_inode(root, inode));
|
|
|
trans = btrfs_join_transaction(root, 1);
|
|
|
BUG_ON(IS_ERR(trans));
|
|
|
btrfs_set_trans_block_group(trans, inode);
|
|
@@ -1048,17 +1057,18 @@ static noinline int run_delalloc_nocow(struct inode *inode,
|
|
|
int type;
|
|
|
int nocow;
|
|
|
int check_prev = 1;
|
|
|
- bool nolock = false;
|
|
|
+ bool nolock;
|
|
|
u64 ino = btrfs_ino(inode);
|
|
|
|
|
|
path = btrfs_alloc_path();
|
|
|
BUG_ON(!path);
|
|
|
- if (root == root->fs_info->tree_root) {
|
|
|
- nolock = true;
|
|
|
+
|
|
|
+ nolock = is_free_space_inode(root, inode);
|
|
|
+
|
|
|
+ if (nolock)
|
|
|
trans = btrfs_join_transaction_nolock(root, 1);
|
|
|
- } else {
|
|
|
+ else
|
|
|
trans = btrfs_join_transaction(root, 1);
|
|
|
- }
|
|
|
BUG_ON(IS_ERR(trans));
|
|
|
|
|
|
cow_start = (u64)-1;
|
|
@@ -1316,8 +1326,7 @@ static int btrfs_set_bit_hook(struct inode *inode,
|
|
|
if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
|
|
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
|
|
u64 len = state->end + 1 - state->start;
|
|
|
- int do_list = (root->root_key.objectid !=
|
|
|
- BTRFS_ROOT_TREE_OBJECTID);
|
|
|
+ bool do_list = !is_free_space_inode(root, inode);
|
|
|
|
|
|
if (*bits & EXTENT_FIRST_DELALLOC)
|
|
|
*bits &= ~EXTENT_FIRST_DELALLOC;
|
|
@@ -1350,8 +1359,7 @@ static int btrfs_clear_bit_hook(struct inode *inode,
|
|
|
if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
|
|
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
|
|
u64 len = state->end + 1 - state->start;
|
|
|
- int do_list = (root->root_key.objectid !=
|
|
|
- BTRFS_ROOT_TREE_OBJECTID);
|
|
|
+ bool do_list = !is_free_space_inode(root, inode);
|
|
|
|
|
|
if (*bits & EXTENT_FIRST_DELALLOC)
|
|
|
*bits &= ~EXTENT_FIRST_DELALLOC;
|
|
@@ -1458,7 +1466,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
|
|
|
|
|
|
skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
|
|
|
|
|
|
- if (root == root->fs_info->tree_root)
|
|
|
+ if (is_free_space_inode(root, inode))
|
|
|
ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2);
|
|
|
else
|
|
|
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)
|
|
|
struct extent_state *cached_state = NULL;
|
|
|
int compress_type = 0;
|
|
|
int ret;
|
|
|
- bool nolock = false;
|
|
|
+ bool nolock;
|
|
|
|
|
|
ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
|
|
|
end - start + 1);
|
|
@@ -1709,7 +1717,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|
|
return 0;
|
|
|
BUG_ON(!ordered_extent);
|
|
|
|
|
|
- nolock = (root == root->fs_info->tree_root);
|
|
|
+ nolock = is_free_space_inode(root, inode);
|
|
|
|
|
|
if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
|
|
|
BUG_ON(!list_empty(&ordered_extent->list));
|
|
@@ -3473,7 +3481,9 @@ delete:
|
|
|
|
|
|
if (path->slots[0] == 0 ||
|
|
|
path->slots[0] != pending_del_slot) {
|
|
|
- if (root->ref_cows) {
|
|
|
+ if (root->ref_cows &&
|
|
|
+ BTRFS_I(inode)->location.objectid !=
|
|
|
+ BTRFS_FREE_INO_OBJECTID) {
|
|
|
err = -EAGAIN;
|
|
|
goto out;
|
|
|
}
|
|
@@ -3765,7 +3775,7 @@ void btrfs_evict_inode(struct inode *inode)
|
|
|
|
|
|
truncate_inode_pages(&inode->i_data, 0);
|
|
|
if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
|
|
|
- root == root->fs_info->tree_root))
|
|
|
+ is_free_space_inode(root, inode)))
|
|
|
goto no_delete;
|
|
|
|
|
|
if (is_bad_inode(inode)) {
|
|
@@ -4382,7 +4392,8 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
|
|
return 0;
|
|
|
|
|
|
smp_mb();
|
|
|
- nolock = (root->fs_info->closing && root == root->fs_info->tree_root);
|
|
|
+ if (root->fs_info->closing && is_free_space_inode(root, inode))
|
|
|
+ nolock = true;
|
|
|
|
|
|
if (wbc->sync_mode == WB_SYNC_ALL) {
|
|
|
if (nolock)
|
|
@@ -6900,7 +6911,7 @@ int btrfs_drop_inode(struct inode *inode)
|
|
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
|
|
|
|
|
if (btrfs_root_refs(&root->root_item) == 0 &&
|
|
|
- root != root->fs_info->tree_root)
|
|
|
+ !is_free_space_inode(root, inode))
|
|
|
return 1;
|
|
|
else
|
|
|
return generic_drop_inode(inode);
|