aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-10-15 15:18:40 -0400
committerJosef Bacik <josef@redhat.com>2010-10-22 15:54:58 -0400
commit0019f10db6f596f3e14a19f9bd7059a1b85b0853 (patch)
tree9f295bc2e335a6890ea29bc0830bda43903671d9 /fs
parent6d48755d02b150de7f47e7b4753202f2fc9f990f (diff)
Btrfs: re-work delalloc flushing
Currently we try and flush delalloc, but we only do that in a sort of weak way, which works fine in most cases but if we're under heavy pressure we need to be able to wait for flushing to happen. Also instead of checking the bytes reserved in the block_rsv, check the space info since it is more accurate. The sync option will be used in a future patch. Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/extent-tree.c26
-rw-r--r--fs/btrfs/inode.c24
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
2378int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); 2378int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
2379int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput); 2379int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput,
2380 int sync);
2380int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, 2381int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
2381 struct extent_state **cached_state); 2382 struct extent_state **cached_state);
2382int btrfs_writepages(struct address_space *mapping, 2383int 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 */
3113static int shrink_delalloc(struct btrfs_trans_handle *trans, 3113static 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
6606int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput) 6606int 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