diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2011-05-26 02:38:30 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-05-26 17:53:04 -0400 |
commit | a47d6b70e280401d553e7cac6f5750870de1ad21 (patch) | |
tree | 2874064c08ecc65cdfda9b2a9fd9895eb73a011e /fs | |
parent | 00d01bc17cc2807292303961519d9c005794eb1d (diff) |
Btrfs: setup free ino caching in a more asynchronous way
For a filesystem that has lots of files in it, the first time we mount
it with free ino caching support, it can take quite a long time to
setup the caching before we can create new files.
Here we fill the cache with [highest_ino, BTRFS_LAST_FREE_OBJECTID]
before we start the caching thread to search through the extent tree.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/inode-map.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 000970512624..3262cd17a12f 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -60,12 +60,12 @@ again: | |||
60 | 60 | ||
61 | while (1) { | 61 | while (1) { |
62 | smp_mb(); | 62 | smp_mb(); |
63 | if (fs_info->closing > 1) | 63 | if (fs_info->closing) |
64 | goto out; | 64 | goto out; |
65 | 65 | ||
66 | leaf = path->nodes[0]; | 66 | leaf = path->nodes[0]; |
67 | slot = path->slots[0]; | 67 | slot = path->slots[0]; |
68 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | 68 | if (slot >= btrfs_header_nritems(leaf)) { |
69 | ret = btrfs_next_leaf(root, path); | 69 | ret = btrfs_next_leaf(root, path); |
70 | if (ret < 0) | 70 | if (ret < 0) |
71 | goto out; | 71 | goto out; |
@@ -100,7 +100,7 @@ again: | |||
100 | if (key.type != BTRFS_INODE_ITEM_KEY) | 100 | if (key.type != BTRFS_INODE_ITEM_KEY) |
101 | goto next; | 101 | goto next; |
102 | 102 | ||
103 | if (key.objectid >= BTRFS_LAST_FREE_OBJECTID) | 103 | if (key.objectid >= root->highest_objectid) |
104 | break; | 104 | break; |
105 | 105 | ||
106 | if (last != (u64)-1 && last + 1 != key.objectid) { | 106 | if (last != (u64)-1 && last + 1 != key.objectid) { |
@@ -114,9 +114,9 @@ next: | |||
114 | path->slots[0]++; | 114 | path->slots[0]++; |
115 | } | 115 | } |
116 | 116 | ||
117 | if (last < BTRFS_LAST_FREE_OBJECTID - 1) { | 117 | if (last < root->highest_objectid - 1) { |
118 | __btrfs_add_free_space(ctl, last + 1, | 118 | __btrfs_add_free_space(ctl, last + 1, |
119 | BTRFS_LAST_FREE_OBJECTID - last - 1); | 119 | root->highest_objectid - last - 1); |
120 | } | 120 | } |
121 | 121 | ||
122 | spin_lock(&root->cache_lock); | 122 | spin_lock(&root->cache_lock); |
@@ -136,8 +136,10 @@ out: | |||
136 | 136 | ||
137 | static void start_caching(struct btrfs_root *root) | 137 | static void start_caching(struct btrfs_root *root) |
138 | { | 138 | { |
139 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | ||
139 | struct task_struct *tsk; | 140 | struct task_struct *tsk; |
140 | int ret; | 141 | int ret; |
142 | u64 objectid; | ||
141 | 143 | ||
142 | spin_lock(&root->cache_lock); | 144 | spin_lock(&root->cache_lock); |
143 | if (root->cached != BTRFS_CACHE_NO) { | 145 | if (root->cached != BTRFS_CACHE_NO) { |
@@ -156,6 +158,19 @@ static void start_caching(struct btrfs_root *root) | |||
156 | return; | 158 | return; |
157 | } | 159 | } |
158 | 160 | ||
161 | /* | ||
162 | * It can be quite time-consuming to fill the cache by searching | ||
163 | * through the extent tree, and this can keep ino allocation path | ||
164 | * waiting. Therefore at start we quickly find out the highest | ||
165 | * inode number and we know we can use inode numbers which fall in | ||
166 | * [highest_ino + 1, BTRFS_LAST_FREE_OBJECTID]. | ||
167 | */ | ||
168 | ret = btrfs_find_free_objectid(root, &objectid); | ||
169 | if (!ret && objectid <= BTRFS_LAST_FREE_OBJECTID) { | ||
170 | __btrfs_add_free_space(ctl, objectid, | ||
171 | BTRFS_LAST_FREE_OBJECTID - objectid + 1); | ||
172 | } | ||
173 | |||
159 | tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", | 174 | tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", |
160 | root->root_key.objectid); | 175 | root->root_key.objectid); |
161 | BUG_ON(IS_ERR(tsk)); | 176 | BUG_ON(IS_ERR(tsk)); |
@@ -209,7 +224,8 @@ again: | |||
209 | 224 | ||
210 | start_caching(root); | 225 | start_caching(root); |
211 | 226 | ||
212 | if (objectid <= root->cache_progress) | 227 | if (objectid <= root->cache_progress || |
228 | objectid > root->highest_objectid) | ||
213 | __btrfs_add_free_space(ctl, objectid, 1); | 229 | __btrfs_add_free_space(ctl, objectid, 1); |
214 | else | 230 | else |
215 | __btrfs_add_free_space(pinned, objectid, 1); | 231 | __btrfs_add_free_space(pinned, objectid, 1); |