diff options
-rw-r--r-- | fs/btrfs/ctree.h | 7 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 3 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 97 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.h | 11 | ||||
-rw-r--r-- | fs/btrfs/inode-map.c | 87 | ||||
-rw-r--r-- | fs/btrfs/inode-map.h | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 45 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 2 |
9 files changed, 236 insertions, 19 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index c96a4e4c5566..b20082e27a9f 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -105,6 +105,12 @@ struct btrfs_ordered_sum; | |||
105 | /* For storing free space cache */ | 105 | /* For storing free space cache */ |
106 | #define BTRFS_FREE_SPACE_OBJECTID -11ULL | 106 | #define BTRFS_FREE_SPACE_OBJECTID -11ULL |
107 | 107 | ||
108 | /* | ||
109 | * The inode number assigned to the special inode for sotring | ||
110 | * free ino cache | ||
111 | */ | ||
112 | #define BTRFS_FREE_INO_OBJECTID -12ULL | ||
113 | |||
108 | /* dummy objectid represents multiple objectids */ | 114 | /* dummy objectid represents multiple objectids */ |
109 | #define BTRFS_MULTIPLE_OBJECTIDS -255ULL | 115 | #define BTRFS_MULTIPLE_OBJECTIDS -255ULL |
110 | 116 | ||
@@ -1110,6 +1116,7 @@ struct btrfs_root { | |||
1110 | wait_queue_head_t cache_wait; | 1116 | wait_queue_head_t cache_wait; |
1111 | struct btrfs_free_space_ctl *free_ino_pinned; | 1117 | struct btrfs_free_space_ctl *free_ino_pinned; |
1112 | u64 cache_progress; | 1118 | u64 cache_progress; |
1119 | struct inode *cache_inode; | ||
1113 | 1120 | ||
1114 | struct mutex log_mutex; | 1121 | struct mutex log_mutex; |
1115 | wait_queue_head_t log_writer_wait; | 1122 | wait_queue_head_t log_writer_wait; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d02683b1ee16..4f12c30a5470 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2505,6 +2505,7 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | |||
2505 | 2505 | ||
2506 | static void free_fs_root(struct btrfs_root *root) | 2506 | static void free_fs_root(struct btrfs_root *root) |
2507 | { | 2507 | { |
2508 | iput(root->cache_inode); | ||
2508 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); | 2509 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); |
2509 | if (root->anon_super.s_dev) { | 2510 | if (root->anon_super.s_dev) { |
2510 | down_write(&root->anon_super.s_umount); | 2511 | down_write(&root->anon_super.s_umount); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a0e818cb0401..95ce8da63b28 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3145,7 +3145,8 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) | |||
3145 | /* make sure bytes are sectorsize aligned */ | 3145 | /* make sure bytes are sectorsize aligned */ |
3146 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 3146 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
3147 | 3147 | ||
3148 | if (root == root->fs_info->tree_root) { | 3148 | if (root == root->fs_info->tree_root || |
3149 | BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID) { | ||
3149 | alloc_chunk = 0; | 3150 | alloc_chunk = 0; |
3150 | committed = 1; | 3151 | committed = 1; |
3151 | } | 3152 | } |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index fcbdcef6ca28..7d8b6b643403 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -209,7 +209,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, | |||
209 | return ret; | 209 | return ret; |
210 | } | 210 | } |
211 | 211 | ||
212 | return btrfs_update_inode(trans, root, inode); | 212 | ret = btrfs_update_inode(trans, root, inode); |
213 | return ret; | ||
213 | } | 214 | } |
214 | 215 | ||
215 | static int readahead_cache(struct inode *inode) | 216 | static int readahead_cache(struct inode *inode) |
@@ -525,6 +526,7 @@ out: | |||
525 | spin_lock(&block_group->lock); | 526 | spin_lock(&block_group->lock); |
526 | block_group->disk_cache_state = BTRFS_DC_CLEAR; | 527 | block_group->disk_cache_state = BTRFS_DC_CLEAR; |
527 | spin_unlock(&block_group->lock); | 528 | spin_unlock(&block_group->lock); |
529 | ret = 0; | ||
528 | 530 | ||
529 | printk(KERN_ERR "btrfs: failed to load free space cache " | 531 | printk(KERN_ERR "btrfs: failed to load free space cache " |
530 | "for block group %llu\n", block_group->key.objectid); | 532 | "for block group %llu\n", block_group->key.objectid); |
@@ -893,6 +895,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
893 | spin_lock(&block_group->lock); | 895 | spin_lock(&block_group->lock); |
894 | block_group->disk_cache_state = BTRFS_DC_ERROR; | 896 | block_group->disk_cache_state = BTRFS_DC_ERROR; |
895 | spin_unlock(&block_group->lock); | 897 | spin_unlock(&block_group->lock); |
898 | ret = 0; | ||
896 | 899 | ||
897 | printk(KERN_ERR "btrfs: failed to write free space cace " | 900 | printk(KERN_ERR "btrfs: failed to write free space cace " |
898 | "for block group %llu\n", block_group->key.objectid); | 901 | "for block group %llu\n", block_group->key.objectid); |
@@ -2458,3 +2461,95 @@ out: | |||
2458 | 2461 | ||
2459 | return ino; | 2462 | return ino; |
2460 | } | 2463 | } |
2464 | |||
2465 | struct inode *lookup_free_ino_inode(struct btrfs_root *root, | ||
2466 | struct btrfs_path *path) | ||
2467 | { | ||
2468 | struct inode *inode = NULL; | ||
2469 | |||
2470 | spin_lock(&root->cache_lock); | ||
2471 | if (root->cache_inode) | ||
2472 | inode = igrab(root->cache_inode); | ||
2473 | spin_unlock(&root->cache_lock); | ||
2474 | if (inode) | ||
2475 | return inode; | ||
2476 | |||
2477 | inode = __lookup_free_space_inode(root, path, 0); | ||
2478 | if (IS_ERR(inode)) | ||
2479 | return inode; | ||
2480 | |||
2481 | spin_lock(&root->cache_lock); | ||
2482 | if (!root->fs_info->closing) | ||
2483 | root->cache_inode = igrab(inode); | ||
2484 | spin_unlock(&root->cache_lock); | ||
2485 | |||
2486 | return inode; | ||
2487 | } | ||
2488 | |||
2489 | int create_free_ino_inode(struct btrfs_root *root, | ||
2490 | struct btrfs_trans_handle *trans, | ||
2491 | struct btrfs_path *path) | ||
2492 | { | ||
2493 | return __create_free_space_inode(root, trans, path, | ||
2494 | BTRFS_FREE_INO_OBJECTID, 0); | ||
2495 | } | ||
2496 | |||
2497 | int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | ||
2498 | { | ||
2499 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | ||
2500 | struct btrfs_path *path; | ||
2501 | struct inode *inode; | ||
2502 | int ret = 0; | ||
2503 | u64 root_gen = btrfs_root_generation(&root->root_item); | ||
2504 | |||
2505 | /* | ||
2506 | * If we're unmounting then just return, since this does a search on the | ||
2507 | * normal root and not the commit root and we could deadlock. | ||
2508 | */ | ||
2509 | smp_mb(); | ||
2510 | if (fs_info->closing) | ||
2511 | return 0; | ||
2512 | |||
2513 | path = btrfs_alloc_path(); | ||
2514 | if (!path) | ||
2515 | return 0; | ||
2516 | |||
2517 | inode = lookup_free_ino_inode(root, path); | ||
2518 | if (IS_ERR(inode)) | ||
2519 | goto out; | ||
2520 | |||
2521 | if (root_gen != BTRFS_I(inode)->generation) | ||
2522 | goto out_put; | ||
2523 | |||
2524 | ret = __load_free_space_cache(root, inode, ctl, path, 0); | ||
2525 | |||
2526 | if (ret < 0) | ||
2527 | printk(KERN_ERR "btrfs: failed to load free ino cache for " | ||
2528 | "root %llu\n", root->root_key.objectid); | ||
2529 | out_put: | ||
2530 | iput(inode); | ||
2531 | out: | ||
2532 | btrfs_free_path(path); | ||
2533 | return ret; | ||
2534 | } | ||
2535 | |||
2536 | int btrfs_write_out_ino_cache(struct btrfs_root *root, | ||
2537 | struct btrfs_trans_handle *trans, | ||
2538 | struct btrfs_path *path) | ||
2539 | { | ||
2540 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | ||
2541 | struct inode *inode; | ||
2542 | int ret; | ||
2543 | |||
2544 | inode = lookup_free_ino_inode(root, path); | ||
2545 | if (IS_ERR(inode)) | ||
2546 | return 0; | ||
2547 | |||
2548 | ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0); | ||
2549 | if (ret < 0) | ||
2550 | printk(KERN_ERR "btrfs: failed to write free ino cache " | ||
2551 | "for root %llu\n", root->root_key.objectid); | ||
2552 | |||
2553 | iput(inode); | ||
2554 | return ret; | ||
2555 | } | ||
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h index af06e6b6ceaa..8f2613f779ed 100644 --- a/fs/btrfs/free-space-cache.h +++ b/fs/btrfs/free-space-cache.h | |||
@@ -65,6 +65,17 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
65 | struct btrfs_block_group_cache *block_group, | 65 | struct btrfs_block_group_cache *block_group, |
66 | struct btrfs_path *path); | 66 | struct btrfs_path *path); |
67 | 67 | ||
68 | struct inode *lookup_free_ino_inode(struct btrfs_root *root, | ||
69 | struct btrfs_path *path); | ||
70 | int create_free_ino_inode(struct btrfs_root *root, | ||
71 | struct btrfs_trans_handle *trans, | ||
72 | struct btrfs_path *path); | ||
73 | int load_free_ino_cache(struct btrfs_fs_info *fs_info, | ||
74 | struct btrfs_root *root); | ||
75 | int btrfs_write_out_ino_cache(struct btrfs_root *root, | ||
76 | struct btrfs_trans_handle *trans, | ||
77 | struct btrfs_path *path); | ||
78 | |||
68 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group); | 79 | void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group); |
69 | int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl, | 80 | int __btrfs_add_free_space(struct btrfs_free_space_ctl *ctl, |
70 | u64 bytenr, u64 size); | 81 | u64 bytenr, u64 size); |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 5be62df90c4f..7967e85c72f5 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -137,6 +137,7 @@ out: | |||
137 | static void start_caching(struct btrfs_root *root) | 137 | static void start_caching(struct btrfs_root *root) |
138 | { | 138 | { |
139 | struct task_struct *tsk; | 139 | struct task_struct *tsk; |
140 | int ret; | ||
140 | 141 | ||
141 | spin_lock(&root->cache_lock); | 142 | spin_lock(&root->cache_lock); |
142 | if (root->cached != BTRFS_CACHE_NO) { | 143 | if (root->cached != BTRFS_CACHE_NO) { |
@@ -147,6 +148,14 @@ static void start_caching(struct btrfs_root *root) | |||
147 | root->cached = BTRFS_CACHE_STARTED; | 148 | root->cached = BTRFS_CACHE_STARTED; |
148 | spin_unlock(&root->cache_lock); | 149 | spin_unlock(&root->cache_lock); |
149 | 150 | ||
151 | ret = load_free_ino_cache(root->fs_info, root); | ||
152 | if (ret == 1) { | ||
153 | spin_lock(&root->cache_lock); | ||
154 | root->cached = BTRFS_CACHE_FINISHED; | ||
155 | spin_unlock(&root->cache_lock); | ||
156 | return; | ||
157 | } | ||
158 | |||
150 | tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", | 159 | tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", |
151 | root->root_key.objectid); | 160 | root->root_key.objectid); |
152 | BUG_ON(IS_ERR(tsk)); | 161 | BUG_ON(IS_ERR(tsk)); |
@@ -352,6 +361,84 @@ void btrfs_init_free_ino_ctl(struct btrfs_root *root) | |||
352 | pinned->op = &pinned_free_ino_op; | 361 | pinned->op = &pinned_free_ino_op; |
353 | } | 362 | } |
354 | 363 | ||
364 | int btrfs_save_ino_cache(struct btrfs_root *root, | ||
365 | struct btrfs_trans_handle *trans) | ||
366 | { | ||
367 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | ||
368 | struct btrfs_path *path; | ||
369 | struct inode *inode; | ||
370 | u64 alloc_hint = 0; | ||
371 | int ret; | ||
372 | int prealloc; | ||
373 | bool retry = false; | ||
374 | |||
375 | path = btrfs_alloc_path(); | ||
376 | if (!path) | ||
377 | return -ENOMEM; | ||
378 | again: | ||
379 | inode = lookup_free_ino_inode(root, path); | ||
380 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { | ||
381 | ret = PTR_ERR(inode); | ||
382 | goto out; | ||
383 | } | ||
384 | |||
385 | if (IS_ERR(inode)) { | ||
386 | BUG_ON(retry); | ||
387 | retry = true; | ||
388 | |||
389 | ret = create_free_ino_inode(root, trans, path); | ||
390 | if (ret) | ||
391 | goto out; | ||
392 | goto again; | ||
393 | } | ||
394 | |||
395 | BTRFS_I(inode)->generation = 0; | ||
396 | ret = btrfs_update_inode(trans, root, inode); | ||
397 | WARN_ON(ret); | ||
398 | |||
399 | if (i_size_read(inode) > 0) { | ||
400 | ret = btrfs_truncate_free_space_cache(root, trans, path, inode); | ||
401 | if (ret) | ||
402 | goto out_put; | ||
403 | } | ||
404 | |||
405 | spin_lock(&root->cache_lock); | ||
406 | if (root->cached != BTRFS_CACHE_FINISHED) { | ||
407 | ret = -1; | ||
408 | spin_unlock(&root->cache_lock); | ||
409 | goto out_put; | ||
410 | } | ||
411 | spin_unlock(&root->cache_lock); | ||
412 | |||
413 | spin_lock(&ctl->tree_lock); | ||
414 | prealloc = sizeof(struct btrfs_free_space) * ctl->free_extents; | ||
415 | prealloc = ALIGN(prealloc, PAGE_CACHE_SIZE); | ||
416 | prealloc += ctl->total_bitmaps * PAGE_CACHE_SIZE; | ||
417 | spin_unlock(&ctl->tree_lock); | ||
418 | |||
419 | /* Just to make sure we have enough space */ | ||
420 | prealloc += 8 * PAGE_CACHE_SIZE; | ||
421 | |||
422 | ret = btrfs_check_data_free_space(inode, prealloc); | ||
423 | if (ret) | ||
424 | goto out_put; | ||
425 | |||
426 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, | ||
427 | prealloc, prealloc, &alloc_hint); | ||
428 | if (ret) | ||
429 | goto out_put; | ||
430 | btrfs_free_reserved_data_space(inode, prealloc); | ||
431 | |||
432 | out_put: | ||
433 | iput(inode); | ||
434 | out: | ||
435 | if (ret == 0) | ||
436 | ret = btrfs_write_out_ino_cache(root, trans, path); | ||
437 | |||
438 | btrfs_free_path(path); | ||
439 | return ret; | ||
440 | } | ||
441 | |||
355 | static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) | 442 | static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) |
356 | { | 443 | { |
357 | struct btrfs_path *path; | 444 | struct btrfs_path *path; |
diff --git a/fs/btrfs/inode-map.h b/fs/btrfs/inode-map.h index eb918451b492..ddb347bfee23 100644 --- a/fs/btrfs/inode-map.h +++ b/fs/btrfs/inode-map.h | |||
@@ -5,6 +5,8 @@ void btrfs_init_free_ino_ctl(struct btrfs_root *root); | |||
5 | void btrfs_unpin_free_ino(struct btrfs_root *root); | 5 | void btrfs_unpin_free_ino(struct btrfs_root *root); |
6 | void btrfs_return_ino(struct btrfs_root *root, u64 objectid); | 6 | void btrfs_return_ino(struct btrfs_root *root, u64 objectid); |
7 | int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid); | 7 | int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid); |
8 | int btrfs_save_ino_cache(struct btrfs_root *root, | ||
9 | struct btrfs_trans_handle *trans); | ||
8 | 10 | ||
9 | int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid); | 11 | int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid); |
10 | 12 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index adec22884a3e..b78d3ab789ca 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -745,6 +745,15 @@ static u64 get_extent_allocation_hint(struct inode *inode, u64 start, | |||
745 | return alloc_hint; | 745 | return alloc_hint; |
746 | } | 746 | } |
747 | 747 | ||
748 | static inline bool is_free_space_inode(struct btrfs_root *root, | ||
749 | struct inode *inode) | ||
750 | { | ||
751 | if (root == root->fs_info->tree_root || | ||
752 | BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID) | ||
753 | return true; | ||
754 | return false; | ||
755 | } | ||
756 | |||
748 | /* | 757 | /* |
749 | * when extent_io.c finds a delayed allocation range in the file, | 758 | * when extent_io.c finds a delayed allocation range in the file, |
750 | * the call backs end up in this code. The basic idea is to | 759 | * the call backs end up in this code. The basic idea is to |
@@ -777,7 +786,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
777 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 786 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
778 | int ret = 0; | 787 | int ret = 0; |
779 | 788 | ||
780 | BUG_ON(root == root->fs_info->tree_root); | 789 | BUG_ON(is_free_space_inode(root, inode)); |
781 | trans = btrfs_join_transaction(root, 1); | 790 | trans = btrfs_join_transaction(root, 1); |
782 | BUG_ON(IS_ERR(trans)); | 791 | BUG_ON(IS_ERR(trans)); |
783 | btrfs_set_trans_block_group(trans, inode); | 792 | btrfs_set_trans_block_group(trans, inode); |
@@ -1048,17 +1057,18 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
1048 | int type; | 1057 | int type; |
1049 | int nocow; | 1058 | int nocow; |
1050 | int check_prev = 1; | 1059 | int check_prev = 1; |
1051 | bool nolock = false; | 1060 | bool nolock; |
1052 | u64 ino = btrfs_ino(inode); | 1061 | u64 ino = btrfs_ino(inode); |
1053 | 1062 | ||
1054 | path = btrfs_alloc_path(); | 1063 | path = btrfs_alloc_path(); |
1055 | BUG_ON(!path); | 1064 | BUG_ON(!path); |
1056 | if (root == root->fs_info->tree_root) { | 1065 | |
1057 | nolock = true; | 1066 | nolock = is_free_space_inode(root, inode); |
1067 | |||
1068 | if (nolock) | ||
1058 | trans = btrfs_join_transaction_nolock(root, 1); | 1069 | trans = btrfs_join_transaction_nolock(root, 1); |
1059 | } else { | 1070 | else |
1060 | trans = btrfs_join_transaction(root, 1); | 1071 | trans = btrfs_join_transaction(root, 1); |
1061 | } | ||
1062 | BUG_ON(IS_ERR(trans)); | 1072 | BUG_ON(IS_ERR(trans)); |
1063 | 1073 | ||
1064 | cow_start = (u64)-1; | 1074 | cow_start = (u64)-1; |
@@ -1316,8 +1326,7 @@ static int btrfs_set_bit_hook(struct inode *inode, | |||
1316 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1326 | if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
1317 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1327 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1318 | u64 len = state->end + 1 - state->start; | 1328 | u64 len = state->end + 1 - state->start; |
1319 | int do_list = (root->root_key.objectid != | 1329 | bool do_list = !is_free_space_inode(root, inode); |
1320 | BTRFS_ROOT_TREE_OBJECTID); | ||
1321 | 1330 | ||
1322 | if (*bits & EXTENT_FIRST_DELALLOC) | 1331 | if (*bits & EXTENT_FIRST_DELALLOC) |
1323 | *bits &= ~EXTENT_FIRST_DELALLOC; | 1332 | *bits &= ~EXTENT_FIRST_DELALLOC; |
@@ -1350,8 +1359,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, | |||
1350 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { | 1359 | if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) { |
1351 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1360 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1352 | u64 len = state->end + 1 - state->start; | 1361 | u64 len = state->end + 1 - state->start; |
1353 | int do_list = (root->root_key.objectid != | 1362 | bool do_list = !is_free_space_inode(root, inode); |
1354 | BTRFS_ROOT_TREE_OBJECTID); | ||
1355 | 1363 | ||
1356 | if (*bits & EXTENT_FIRST_DELALLOC) | 1364 | if (*bits & EXTENT_FIRST_DELALLOC) |
1357 | *bits &= ~EXTENT_FIRST_DELALLOC; | 1365 | *bits &= ~EXTENT_FIRST_DELALLOC; |
@@ -1458,7 +1466,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
1458 | 1466 | ||
1459 | skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; | 1467 | skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; |
1460 | 1468 | ||
1461 | if (root == root->fs_info->tree_root) | 1469 | if (is_free_space_inode(root, inode)) |
1462 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); | 1470 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); |
1463 | else | 1471 | else |
1464 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | 1472 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); |
@@ -1701,7 +1709,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1701 | struct extent_state *cached_state = NULL; | 1709 | struct extent_state *cached_state = NULL; |
1702 | int compress_type = 0; | 1710 | int compress_type = 0; |
1703 | int ret; | 1711 | int ret; |
1704 | bool nolock = false; | 1712 | bool nolock; |
1705 | 1713 | ||
1706 | ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, | 1714 | ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, |
1707 | end - start + 1); | 1715 | end - start + 1); |
@@ -1709,7 +1717,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1709 | return 0; | 1717 | return 0; |
1710 | BUG_ON(!ordered_extent); | 1718 | BUG_ON(!ordered_extent); |
1711 | 1719 | ||
1712 | nolock = (root == root->fs_info->tree_root); | 1720 | nolock = is_free_space_inode(root, inode); |
1713 | 1721 | ||
1714 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { | 1722 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { |
1715 | BUG_ON(!list_empty(&ordered_extent->list)); | 1723 | BUG_ON(!list_empty(&ordered_extent->list)); |
@@ -3473,7 +3481,9 @@ delete: | |||
3473 | 3481 | ||
3474 | if (path->slots[0] == 0 || | 3482 | if (path->slots[0] == 0 || |
3475 | path->slots[0] != pending_del_slot) { | 3483 | path->slots[0] != pending_del_slot) { |
3476 | if (root->ref_cows) { | 3484 | if (root->ref_cows && |
3485 | BTRFS_I(inode)->location.objectid != | ||
3486 | BTRFS_FREE_INO_OBJECTID) { | ||
3477 | err = -EAGAIN; | 3487 | err = -EAGAIN; |
3478 | goto out; | 3488 | goto out; |
3479 | } | 3489 | } |
@@ -3765,7 +3775,7 @@ void btrfs_evict_inode(struct inode *inode) | |||
3765 | 3775 | ||
3766 | truncate_inode_pages(&inode->i_data, 0); | 3776 | truncate_inode_pages(&inode->i_data, 0); |
3767 | if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || | 3777 | if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || |
3768 | root == root->fs_info->tree_root)) | 3778 | is_free_space_inode(root, inode))) |
3769 | goto no_delete; | 3779 | goto no_delete; |
3770 | 3780 | ||
3771 | if (is_bad_inode(inode)) { | 3781 | if (is_bad_inode(inode)) { |
@@ -4382,7 +4392,8 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4382 | return 0; | 4392 | return 0; |
4383 | 4393 | ||
4384 | smp_mb(); | 4394 | smp_mb(); |
4385 | nolock = (root->fs_info->closing && root == root->fs_info->tree_root); | 4395 | if (root->fs_info->closing && is_free_space_inode(root, inode)) |
4396 | nolock = true; | ||
4386 | 4397 | ||
4387 | if (wbc->sync_mode == WB_SYNC_ALL) { | 4398 | if (wbc->sync_mode == WB_SYNC_ALL) { |
4388 | if (nolock) | 4399 | if (nolock) |
@@ -6900,7 +6911,7 @@ int btrfs_drop_inode(struct inode *inode) | |||
6900 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6911 | struct btrfs_root *root = BTRFS_I(inode)->root; |
6901 | 6912 | ||
6902 | if (btrfs_root_refs(&root->root_item) == 0 && | 6913 | if (btrfs_root_refs(&root->root_item) == 0 && |
6903 | root != root->fs_info->tree_root) | 6914 | !is_free_space_inode(root, inode)) |
6904 | return 1; | 6915 | return 1; |
6905 | else | 6916 | else |
6906 | return generic_drop_inode(inode); | 6917 | return generic_drop_inode(inode); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f4c1184b7f1a..4d1dbcbbaf41 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -761,6 +761,8 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
761 | btrfs_update_reloc_root(trans, root); | 761 | btrfs_update_reloc_root(trans, root); |
762 | btrfs_orphan_commit_root(trans, root); | 762 | btrfs_orphan_commit_root(trans, root); |
763 | 763 | ||
764 | btrfs_save_ino_cache(root, trans); | ||
765 | |||
764 | if (root->commit_root != root->node) { | 766 | if (root->commit_root != root->node) { |
765 | mutex_lock(&root->fs_commit_mutex); | 767 | mutex_lock(&root->fs_commit_mutex); |
766 | switch_commit_root(root); | 768 | switch_commit_root(root); |