aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c5
-rw-r--r--fs/btrfs/disk-io.h21
-rw-r--r--fs/btrfs/extent-tree.c2
4 files changed, 26 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a84e59b7b006..91a8ca7af77e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1746,6 +1746,7 @@ struct btrfs_root {
1746 int force_cow; 1746 int force_cow;
1747 1747
1748 spinlock_t root_item_lock; 1748 spinlock_t root_item_lock;
1749 atomic_t refs;
1749}; 1750};
1750 1751
1751struct btrfs_ioctl_defrag_range_args { 1752struct btrfs_ioctl_defrag_range_args {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c65a5aac1e45..90b643e07f3c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1216,6 +1216,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1216 atomic_set(&root->log_writers, 0); 1216 atomic_set(&root->log_writers, 0);
1217 atomic_set(&root->log_batch, 0); 1217 atomic_set(&root->log_batch, 0);
1218 atomic_set(&root->orphan_inodes, 0); 1218 atomic_set(&root->orphan_inodes, 0);
1219 atomic_set(&root->refs, 1);
1219 root->log_transid = 0; 1220 root->log_transid = 0;
1220 root->last_log_commit = 0; 1221 root->last_log_commit = 0;
1221 extent_io_tree_init(&root->dirty_log_pages, 1222 extent_io_tree_init(&root->dirty_log_pages,
@@ -2052,7 +2053,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
2052 } else { 2053 } else {
2053 free_extent_buffer(gang[0]->node); 2054 free_extent_buffer(gang[0]->node);
2054 free_extent_buffer(gang[0]->commit_root); 2055 free_extent_buffer(gang[0]->commit_root);
2055 kfree(gang[0]); 2056 btrfs_put_fs_root(gang[0]);
2056 } 2057 }
2057 } 2058 }
2058 2059
@@ -3417,7 +3418,7 @@ static void free_fs_root(struct btrfs_root *root)
3417 kfree(root->free_ino_ctl); 3418 kfree(root->free_ino_ctl);
3418 kfree(root->free_ino_pinned); 3419 kfree(root->free_ino_pinned);
3419 kfree(root->name); 3420 kfree(root->name);
3420 kfree(root); 3421 btrfs_put_fs_root(root);
3421} 3422}
3422 3423
3423void btrfs_free_fs_root(struct btrfs_root *root) 3424void btrfs_free_fs_root(struct btrfs_root *root)
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 534d583e609d..b71acd6e1e5b 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -76,6 +76,27 @@ void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root);
76void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, 76void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
77 struct btrfs_root *root); 77 struct btrfs_root *root);
78void btrfs_free_fs_root(struct btrfs_root *root); 78void btrfs_free_fs_root(struct btrfs_root *root);
79
80/*
81 * This function is used to grab the root, and avoid it is freed when we
82 * access it. But it doesn't ensure that the tree is not dropped.
83 *
84 * If you want to ensure the whole tree is safe, you should use
85 * fs_info->subvol_srcu
86 */
87static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
88{
89 if (atomic_inc_not_zero(&root->refs))
90 return root;
91 return NULL;
92}
93
94static inline void btrfs_put_fs_root(struct btrfs_root *root)
95{
96 if (atomic_dec_and_test(&root->refs))
97 kfree(root);
98}
99
79void btrfs_mark_buffer_dirty(struct extent_buffer *buf); 100void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
80int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, 101int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
81 int atomic); 102 int atomic);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c989fe602faf..04066c2cc711 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -7469,7 +7469,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
7469 } else { 7469 } else {
7470 free_extent_buffer(root->node); 7470 free_extent_buffer(root->node);
7471 free_extent_buffer(root->commit_root); 7471 free_extent_buffer(root->commit_root);
7472 kfree(root); 7472 btrfs_put_fs_root(root);
7473 } 7473 }
7474out_end_trans: 7474out_end_trans:
7475 btrfs_end_transaction_throttle(trans, tree_root); 7475 btrfs_end_transaction_throttle(trans, tree_root);