btrfs: make inodes hold a ref on their roots
authorJosef Bacik <josef@toxicpanda.com>
Fri, 14 Feb 2020 21:11:43 +0000 (16:11 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Mar 2020 16:01:59 +0000 (17:01 +0100)
If we make sure all the inodes have refs on their root we don't have to
worry about the root disappearing while we have open inodes.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/inode.c

index 242c072d69a74e5934e5086519da002c15864001..5db76264b07f8d9b353e9813e377a4a186894b2a 100644 (file)
@@ -2096,7 +2096,7 @@ static void btrfs_init_btree_inode(struct btrfs_fs_info *fs_info)
 
        BTRFS_I(inode)->io_tree.ops = &btree_extent_io_ops;
 
-       BTRFS_I(inode)->root = fs_info->tree_root;
+       BTRFS_I(inode)->root = btrfs_grab_root(fs_info->tree_root);
        memset(&BTRFS_I(inode)->location, 0, sizeof(struct btrfs_key));
        set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags);
        btrfs_insert_inode_hash(inode);
index d31543350799e4b2650f20774c8dade62c275dba..683bb20c1d0f1b8f4b87f71c875b3016d5d3db11 100644 (file)
@@ -5235,7 +5235,8 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p)
        inode->i_ino = args->location->objectid;
        memcpy(&BTRFS_I(inode)->location, args->location,
               sizeof(*args->location));
-       BTRFS_I(inode)->root = args->root;
+       BTRFS_I(inode)->root = btrfs_grab_root(args->root);
+       BUG_ON(args->root && !BTRFS_I(inode)->root);
        return 0;
 }
 
@@ -5316,7 +5317,7 @@ static struct inode *new_simple_dir(struct super_block *s,
        if (!inode)
                return ERR_PTR(-ENOMEM);
 
-       BTRFS_I(inode)->root = root;
+       BTRFS_I(inode)->root = btrfs_grab_root(root);
        memcpy(&BTRFS_I(inode)->location, key, sizeof(*key));
        set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags);
 
@@ -5884,7 +5885,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
         */
        BTRFS_I(inode)->index_cnt = 2;
        BTRFS_I(inode)->dir_index = *index;
-       BTRFS_I(inode)->root = root;
+       BTRFS_I(inode)->root = btrfs_grab_root(root);
        BTRFS_I(inode)->generation = trans->transid;
        inode->i_generation = BTRFS_I(inode)->generation;
 
@@ -8926,6 +8927,7 @@ void btrfs_destroy_inode(struct inode *inode)
        inode_tree_del(inode);
        btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
        btrfs_inode_clear_file_extent_range(BTRFS_I(inode), 0, (u64)-1);
+       btrfs_put_root(BTRFS_I(inode)->root);
 }
 
 int btrfs_drop_inode(struct inode *inode)