diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 21 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 2 |
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 | ||
1751 | struct btrfs_ioctl_defrag_range_args { | 1752 | struct 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 | ||
3423 | void btrfs_free_fs_root(struct btrfs_root *root) | 3424 | void 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); | |||
76 | void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, | 76 | void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, |
77 | struct btrfs_root *root); | 77 | struct btrfs_root *root); |
78 | void btrfs_free_fs_root(struct btrfs_root *root); | 78 | void 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 | */ | ||
87 | static 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 | |||
94 | static inline void btrfs_put_fs_root(struct btrfs_root *root) | ||
95 | { | ||
96 | if (atomic_dec_and_test(&root->refs)) | ||
97 | kfree(root); | ||
98 | } | ||
99 | |||
79 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf); | 100 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf); |
80 | int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, | 101 | int 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 | } |
7474 | out_end_trans: | 7474 | out_end_trans: |
7475 | btrfs_end_transaction_throttle(trans, tree_root); | 7475 | btrfs_end_transaction_throttle(trans, tree_root); |