aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-05-15 03:48:20 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:29:38 -0400
commitb0feb9d96e71a88d7eec56f41b8f23e92af889b0 (patch)
treee808deeb4f3b33636d6481ff1bc88ae269880fa3 /fs
parentcb517eabba4f109810dba2e5f37b0dcf22103065 (diff)
Btrfs: introduce grab/put functions for the root of the fs/file tree
The grab/put funtions will be used in the next patch, which need grab the root object and ensure it is not freed. We use reference counter instead of the srcu lock is to aovid blocking the memory reclaim task, which invokes synchronize_srcu(). Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
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);