diff options
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 26 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 24 |
3 files changed, 38 insertions, 15 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 014fd52c01bf..f32404db2c5d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2376,7 +2376,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
2376 | u32 min_type); | 2376 | u32 min_type); |
2377 | 2377 | ||
2378 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | 2378 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); |
2379 | int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput); | 2379 | int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput, |
2380 | int sync); | ||
2380 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 2381 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
2381 | struct extent_state **cached_state); | 2382 | struct extent_state **cached_state); |
2382 | int btrfs_writepages(struct address_space *mapping, | 2383 | int btrfs_writepages(struct address_space *mapping, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0f27f7b48804..2846cebc9427 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3111,9 +3111,10 @@ static int maybe_allocate_chunk(struct btrfs_trans_handle *trans, | |||
3111 | * shrink metadata reservation for delalloc | 3111 | * shrink metadata reservation for delalloc |
3112 | */ | 3112 | */ |
3113 | static int shrink_delalloc(struct btrfs_trans_handle *trans, | 3113 | static int shrink_delalloc(struct btrfs_trans_handle *trans, |
3114 | struct btrfs_root *root, u64 to_reclaim) | 3114 | struct btrfs_root *root, u64 to_reclaim, int sync) |
3115 | { | 3115 | { |
3116 | struct btrfs_block_rsv *block_rsv; | 3116 | struct btrfs_block_rsv *block_rsv; |
3117 | struct btrfs_space_info *space_info; | ||
3117 | u64 reserved; | 3118 | u64 reserved; |
3118 | u64 max_reclaim; | 3119 | u64 max_reclaim; |
3119 | u64 reclaimed = 0; | 3120 | u64 reclaimed = 0; |
@@ -3122,9 +3123,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3122 | int ret; | 3123 | int ret; |
3123 | 3124 | ||
3124 | block_rsv = &root->fs_info->delalloc_block_rsv; | 3125 | block_rsv = &root->fs_info->delalloc_block_rsv; |
3125 | spin_lock(&block_rsv->lock); | 3126 | space_info = block_rsv->space_info; |
3126 | reserved = block_rsv->reserved; | 3127 | spin_lock(&space_info->lock); |
3127 | spin_unlock(&block_rsv->lock); | 3128 | reserved = space_info->bytes_reserved; |
3129 | spin_unlock(&space_info->lock); | ||
3128 | 3130 | ||
3129 | if (reserved == 0) | 3131 | if (reserved == 0) |
3130 | return 0; | 3132 | return 0; |
@@ -3132,7 +3134,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3132 | max_reclaim = min(reserved, to_reclaim); | 3134 | max_reclaim = min(reserved, to_reclaim); |
3133 | 3135 | ||
3134 | while (1) { | 3136 | while (1) { |
3135 | ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0); | 3137 | ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0, sync); |
3136 | if (!ret) { | 3138 | if (!ret) { |
3137 | if (no_reclaim > 2) | 3139 | if (no_reclaim > 2) |
3138 | break; | 3140 | break; |
@@ -3147,11 +3149,11 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3147 | pause = 1; | 3149 | pause = 1; |
3148 | } | 3150 | } |
3149 | 3151 | ||
3150 | spin_lock(&block_rsv->lock); | 3152 | spin_lock(&space_info->lock); |
3151 | if (reserved > block_rsv->reserved) | 3153 | if (reserved > space_info->bytes_reserved) |
3152 | reclaimed = reserved - block_rsv->reserved; | 3154 | reclaimed += reserved - space_info->bytes_reserved; |
3153 | reserved = block_rsv->reserved; | 3155 | reserved = space_info->bytes_reserved; |
3154 | spin_unlock(&block_rsv->lock); | 3156 | spin_unlock(&space_info->lock); |
3155 | 3157 | ||
3156 | if (reserved == 0 || reclaimed >= max_reclaim) | 3158 | if (reserved == 0 || reclaimed >= max_reclaim) |
3157 | break; | 3159 | break; |
@@ -3180,7 +3182,7 @@ static int should_retry_reserve(struct btrfs_trans_handle *trans, | |||
3180 | if (trans && trans->transaction->in_commit) | 3182 | if (trans && trans->transaction->in_commit) |
3181 | return -ENOSPC; | 3183 | return -ENOSPC; |
3182 | 3184 | ||
3183 | ret = shrink_delalloc(trans, root, num_bytes); | 3185 | ret = shrink_delalloc(trans, root, num_bytes, 0); |
3184 | if (ret) | 3186 | if (ret) |
3185 | return ret; | 3187 | return ret; |
3186 | 3188 | ||
@@ -3729,7 +3731,7 @@ again: | |||
3729 | block_rsv_add_bytes(block_rsv, to_reserve, 1); | 3731 | block_rsv_add_bytes(block_rsv, to_reserve, 1); |
3730 | 3732 | ||
3731 | if (block_rsv->size > 512 * 1024 * 1024) | 3733 | if (block_rsv->size > 512 * 1024 * 1024) |
3732 | shrink_delalloc(NULL, root, to_reserve); | 3734 | shrink_delalloc(NULL, root, to_reserve, 0); |
3733 | 3735 | ||
3734 | return 0; | 3736 | return 0; |
3735 | } | 3737 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1bff92ad4744..5f9e4fc20a73 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -6603,7 +6603,8 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | |||
6603 | return 0; | 6603 | return 0; |
6604 | } | 6604 | } |
6605 | 6605 | ||
6606 | int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput) | 6606 | int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput, |
6607 | int sync) | ||
6607 | { | 6608 | { |
6608 | struct btrfs_inode *binode; | 6609 | struct btrfs_inode *binode; |
6609 | struct inode *inode = NULL; | 6610 | struct inode *inode = NULL; |
@@ -6625,7 +6626,26 @@ int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput) | |||
6625 | spin_unlock(&root->fs_info->delalloc_lock); | 6626 | spin_unlock(&root->fs_info->delalloc_lock); |
6626 | 6627 | ||
6627 | if (inode) { | 6628 | if (inode) { |
6628 | write_inode_now(inode, 0); | 6629 | if (sync) { |
6630 | filemap_write_and_wait(inode->i_mapping); | ||
6631 | /* | ||
6632 | * We have to do this because compression doesn't | ||
6633 | * actually set PG_writeback until it submits the pages | ||
6634 | * for IO, which happens in an async thread, so we could | ||
6635 | * race and not actually wait for any writeback pages | ||
6636 | * because they've not been submitted yet. Technically | ||
6637 | * this could still be the case for the ordered stuff | ||
6638 | * since the async thread may not have started to do its | ||
6639 | * work yet. If this becomes the case then we need to | ||
6640 | * figure out a way to make sure that in writepage we | ||
6641 | * wait for any async pages to be submitted before | ||
6642 | * returning so that fdatawait does what its supposed to | ||
6643 | * do. | ||
6644 | */ | ||
6645 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
6646 | } else { | ||
6647 | filemap_flush(inode->i_mapping); | ||
6648 | } | ||
6629 | if (delay_iput) | 6649 | if (delay_iput) |
6630 | btrfs_add_delayed_iput(inode); | 6650 | btrfs_add_delayed_iput(inode); |
6631 | else | 6651 | else |