diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 7 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 12 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 21 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 5 |
4 files changed, 35 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0a68cf7032f5..7a2a2621f0d9 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | struct btrfs_trans_handle; | 35 | struct btrfs_trans_handle; |
| 36 | struct btrfs_transaction; | 36 | struct btrfs_transaction; |
| 37 | struct btrfs_pending_snapshot; | 37 | struct btrfs_pending_snapshot; |
| 38 | struct btrfs_delayed_ref_root; | ||
| 38 | extern struct kmem_cache *btrfs_trans_handle_cachep; | 39 | extern struct kmem_cache *btrfs_trans_handle_cachep; |
| 39 | extern struct kmem_cache *btrfs_bit_radix_cachep; | 40 | extern struct kmem_cache *btrfs_bit_radix_cachep; |
| 40 | extern struct kmem_cache *btrfs_path_cachep; | 41 | extern struct kmem_cache *btrfs_path_cachep; |
| @@ -786,6 +787,9 @@ enum { | |||
| 786 | * main phase. The fs_info::balance_ctl is initialized. | 787 | * main phase. The fs_info::balance_ctl is initialized. |
| 787 | */ | 788 | */ |
| 788 | BTRFS_FS_BALANCE_RUNNING, | 789 | BTRFS_FS_BALANCE_RUNNING, |
| 790 | |||
| 791 | /* Indicate that the cleaner thread is awake and doing something. */ | ||
| 792 | BTRFS_FS_CLEANER_RUNNING, | ||
| 789 | }; | 793 | }; |
| 790 | 794 | ||
| 791 | struct btrfs_fs_info { | 795 | struct btrfs_fs_info { |
| @@ -2661,6 +2665,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
| 2661 | unsigned long count); | 2665 | unsigned long count); |
| 2662 | int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info, | 2666 | int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info, |
| 2663 | unsigned long count, u64 transid, int wait); | 2667 | unsigned long count, u64 transid, int wait); |
| 2668 | void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info, | ||
| 2669 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 2670 | struct btrfs_delayed_ref_head *head); | ||
| 2664 | int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len); | 2671 | int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len); |
| 2665 | int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, | 2672 | int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, |
| 2666 | struct btrfs_fs_info *fs_info, u64 bytenr, | 2673 | struct btrfs_fs_info *fs_info, u64 bytenr, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8da2f380d3c0..6a2a2a951705 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg) | |||
| 1682 | while (1) { | 1682 | while (1) { |
| 1683 | again = 0; | 1683 | again = 0; |
| 1684 | 1684 | ||
| 1685 | set_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags); | ||
| 1686 | |||
| 1685 | /* Make the cleaner go to sleep early. */ | 1687 | /* Make the cleaner go to sleep early. */ |
| 1686 | if (btrfs_need_cleaner_sleep(fs_info)) | 1688 | if (btrfs_need_cleaner_sleep(fs_info)) |
| 1687 | goto sleep; | 1689 | goto sleep; |
| @@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg) | |||
| 1728 | */ | 1730 | */ |
| 1729 | btrfs_delete_unused_bgs(fs_info); | 1731 | btrfs_delete_unused_bgs(fs_info); |
| 1730 | sleep: | 1732 | sleep: |
| 1733 | clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags); | ||
| 1731 | if (kthread_should_park()) | 1734 | if (kthread_should_park()) |
| 1732 | kthread_parkme(); | 1735 | kthread_parkme(); |
| 1733 | if (kthread_should_stop()) | 1736 | if (kthread_should_stop()) |
| @@ -4201,6 +4204,14 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info) | |||
| 4201 | spin_lock(&fs_info->ordered_root_lock); | 4204 | spin_lock(&fs_info->ordered_root_lock); |
| 4202 | } | 4205 | } |
| 4203 | spin_unlock(&fs_info->ordered_root_lock); | 4206 | spin_unlock(&fs_info->ordered_root_lock); |
| 4207 | |||
| 4208 | /* | ||
| 4209 | * We need this here because if we've been flipped read-only we won't | ||
| 4210 | * get sync() from the umount, so we need to make sure any ordered | ||
| 4211 | * extents that haven't had their dirty pages IO start writeout yet | ||
| 4212 | * actually get run and error out properly. | ||
| 4213 | */ | ||
| 4214 | btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1); | ||
| 4204 | } | 4215 | } |
| 4205 | 4216 | ||
| 4206 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | 4217 | static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, |
| @@ -4265,6 +4276,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
| 4265 | if (pin_bytes) | 4276 | if (pin_bytes) |
| 4266 | btrfs_pin_extent(fs_info, head->bytenr, | 4277 | btrfs_pin_extent(fs_info, head->bytenr, |
| 4267 | head->num_bytes, 1); | 4278 | head->num_bytes, 1); |
| 4279 | btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head); | ||
| 4268 | btrfs_put_delayed_ref_head(head); | 4280 | btrfs_put_delayed_ref_head(head); |
| 4269 | cond_resched(); | 4281 | cond_resched(); |
| 4270 | spin_lock(&delayed_refs->lock); | 4282 | spin_lock(&delayed_refs->lock); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b15afeae16df..d81035b7ea7d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -2456,12 +2456,10 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans, | |||
| 2456 | return ret ? ret : 1; | 2456 | return ret ? ret : 1; |
| 2457 | } | 2457 | } |
| 2458 | 2458 | ||
| 2459 | static void cleanup_ref_head_accounting(struct btrfs_trans_handle *trans, | 2459 | void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info, |
| 2460 | struct btrfs_delayed_ref_head *head) | 2460 | struct btrfs_delayed_ref_root *delayed_refs, |
| 2461 | struct btrfs_delayed_ref_head *head) | ||
| 2461 | { | 2462 | { |
| 2462 | struct btrfs_fs_info *fs_info = trans->fs_info; | ||
| 2463 | struct btrfs_delayed_ref_root *delayed_refs = | ||
| 2464 | &trans->transaction->delayed_refs; | ||
| 2465 | int nr_items = 1; /* Dropping this ref head update. */ | 2463 | int nr_items = 1; /* Dropping this ref head update. */ |
| 2466 | 2464 | ||
| 2467 | if (head->total_ref_mod < 0) { | 2465 | if (head->total_ref_mod < 0) { |
| @@ -2544,7 +2542,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans, | |||
| 2544 | } | 2542 | } |
| 2545 | } | 2543 | } |
| 2546 | 2544 | ||
| 2547 | cleanup_ref_head_accounting(trans, head); | 2545 | btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head); |
| 2548 | 2546 | ||
| 2549 | trace_run_delayed_ref_head(fs_info, head, 0); | 2547 | trace_run_delayed_ref_head(fs_info, head, 0); |
| 2550 | btrfs_delayed_ref_unlock(head); | 2548 | btrfs_delayed_ref_unlock(head); |
| @@ -4954,6 +4952,15 @@ static void flush_space(struct btrfs_fs_info *fs_info, | |||
| 4954 | ret = 0; | 4952 | ret = 0; |
| 4955 | break; | 4953 | break; |
| 4956 | case COMMIT_TRANS: | 4954 | case COMMIT_TRANS: |
| 4955 | /* | ||
| 4956 | * If we have pending delayed iputs then we could free up a | ||
| 4957 | * bunch of pinned space, so make sure we run the iputs before | ||
| 4958 | * we do our pinned bytes check below. | ||
| 4959 | */ | ||
| 4960 | mutex_lock(&fs_info->cleaner_delayed_iput_mutex); | ||
| 4961 | btrfs_run_delayed_iputs(fs_info); | ||
| 4962 | mutex_unlock(&fs_info->cleaner_delayed_iput_mutex); | ||
| 4963 | |||
| 4957 | ret = may_commit_transaction(fs_info, space_info); | 4964 | ret = may_commit_transaction(fs_info, space_info); |
| 4958 | break; | 4965 | break; |
| 4959 | default: | 4966 | default: |
| @@ -7188,7 +7195,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, | |||
| 7188 | if (head->must_insert_reserved) | 7195 | if (head->must_insert_reserved) |
| 7189 | ret = 1; | 7196 | ret = 1; |
| 7190 | 7197 | ||
| 7191 | cleanup_ref_head_accounting(trans, head); | 7198 | btrfs_cleanup_ref_head_accounting(trans->fs_info, delayed_refs, head); |
| 7192 | mutex_unlock(&head->mutex); | 7199 | mutex_unlock(&head->mutex); |
| 7193 | btrfs_put_delayed_ref_head(head); | 7200 | btrfs_put_delayed_ref_head(head); |
| 7194 | return ret; | 7201 | return ret; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 43eb4535319d..5c349667c761 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3129,9 +3129,6 @@ out: | |||
| 3129 | /* once for the tree */ | 3129 | /* once for the tree */ |
| 3130 | btrfs_put_ordered_extent(ordered_extent); | 3130 | btrfs_put_ordered_extent(ordered_extent); |
| 3131 | 3131 | ||
| 3132 | /* Try to release some metadata so we don't get an OOM but don't wait */ | ||
| 3133 | btrfs_btree_balance_dirty_nodelay(fs_info); | ||
| 3134 | |||
| 3135 | return ret; | 3132 | return ret; |
| 3136 | } | 3133 | } |
| 3137 | 3134 | ||
| @@ -3254,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode) | |||
| 3254 | ASSERT(list_empty(&binode->delayed_iput)); | 3251 | ASSERT(list_empty(&binode->delayed_iput)); |
| 3255 | list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs); | 3252 | list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs); |
| 3256 | spin_unlock(&fs_info->delayed_iput_lock); | 3253 | spin_unlock(&fs_info->delayed_iput_lock); |
| 3254 | if (!test_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags)) | ||
| 3255 | wake_up_process(fs_info->cleaner_kthread); | ||
| 3257 | } | 3256 | } |
| 3258 | 3257 | ||
| 3259 | void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info) | 3258 | void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info) |
