diff options
Diffstat (limited to 'fs/btrfs/inode-map.c')
-rw-r--r-- | fs/btrfs/inode-map.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index f6a596d5a637..d4a582ac3f73 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -246,6 +246,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) | |||
246 | { | 246 | { |
247 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | 247 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
248 | struct rb_root *rbroot = &root->free_ino_pinned->free_space_offset; | 248 | struct rb_root *rbroot = &root->free_ino_pinned->free_space_offset; |
249 | spinlock_t *rbroot_lock = &root->free_ino_pinned->tree_lock; | ||
249 | struct btrfs_free_space *info; | 250 | struct btrfs_free_space *info; |
250 | struct rb_node *n; | 251 | struct rb_node *n; |
251 | u64 count; | 252 | u64 count; |
@@ -254,24 +255,30 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) | |||
254 | return; | 255 | return; |
255 | 256 | ||
256 | while (1) { | 257 | while (1) { |
258 | bool add_to_ctl = true; | ||
259 | |||
260 | spin_lock(rbroot_lock); | ||
257 | n = rb_first(rbroot); | 261 | n = rb_first(rbroot); |
258 | if (!n) | 262 | if (!n) { |
263 | spin_unlock(rbroot_lock); | ||
259 | break; | 264 | break; |
265 | } | ||
260 | 266 | ||
261 | info = rb_entry(n, struct btrfs_free_space, offset_index); | 267 | info = rb_entry(n, struct btrfs_free_space, offset_index); |
262 | BUG_ON(info->bitmap); /* Logic error */ | 268 | BUG_ON(info->bitmap); /* Logic error */ |
263 | 269 | ||
264 | if (info->offset > root->ino_cache_progress) | 270 | if (info->offset > root->ino_cache_progress) |
265 | goto free; | 271 | add_to_ctl = false; |
266 | else if (info->offset + info->bytes > root->ino_cache_progress) | 272 | else if (info->offset + info->bytes > root->ino_cache_progress) |
267 | count = root->ino_cache_progress - info->offset + 1; | 273 | count = root->ino_cache_progress - info->offset + 1; |
268 | else | 274 | else |
269 | count = info->bytes; | 275 | count = info->bytes; |
270 | 276 | ||
271 | __btrfs_add_free_space(ctl, info->offset, count); | ||
272 | free: | ||
273 | rb_erase(&info->offset_index, rbroot); | 277 | rb_erase(&info->offset_index, rbroot); |
274 | kfree(info); | 278 | spin_unlock(rbroot_lock); |
279 | if (add_to_ctl) | ||
280 | __btrfs_add_free_space(ctl, info->offset, count); | ||
281 | kmem_cache_free(btrfs_free_space_cachep, info); | ||
275 | } | 282 | } |
276 | } | 283 | } |
277 | 284 | ||