aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDongsheng Yang <yangds.fnst@cn.fujitsu.com>2014-12-29 06:23:05 -0500
committerChris Mason <clm@fb.com>2015-04-13 10:52:48 -0400
commit237c0e9f1fbfdca7287f3539f1fa73e5063156b5 (patch)
tree6a5091ad33fc0da2f7bc4086de8f731877dfd754
parent31193213f1f9c13f6485007ef1e233b119e46910 (diff)
Btrfs: qgroup, Account data space in more proper timings.
Currenly, in data writing, ->reserved is accounted in fill_delalloc(), but ->may_use is released in clear_bit_hook() which is called by btrfs_finish_ordered_io(). That's too late, that said, between fill_delalloc() and btrfs_finish_ordered_io(), the data is doublely accounted by qgroup. It will cause some unexpected -EDQUOT. Example: # btrfs quota enable /root/btrfs-auto-test/ # btrfs subvolume create /root/btrfs-auto-test//sub Create subvolume '/root/btrfs-auto-test/sub' # btrfs qgroup limit 1G /root/btrfs-auto-test//sub dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=1500000 dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded 681353+0 records in 681352+0 records out 697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s It's (698 MB) when we got an -EDQUOT, but we limit it by 1G. This patch move the btrfs_qgroup_reserve/free() for data from btrfs_delalloc_reserve/release_metadata() to btrfs_check_data_free_space() and btrfs_free_reserved_data_space(). Then the accounter in qgroup will be updated at the same time with the accounter in space_info updated. In this way, the unexpected -EDQUOT will be killed. Reported-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com> Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/extent-tree.c16
-rw-r--r--fs/btrfs/file.c10
2 files changed, 10 insertions, 16 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3113e0b79b99..4d3774605a85 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3969,12 +3969,16 @@ commit_trans:
3969 data_sinfo->flags, bytes, 1); 3969 data_sinfo->flags, bytes, 1);
3970 return -ENOSPC; 3970 return -ENOSPC;
3971 } 3971 }
3972 ret = btrfs_qgroup_reserve(root, bytes);
3973 if (ret)
3974 goto out;
3972 data_sinfo->bytes_may_use += bytes; 3975 data_sinfo->bytes_may_use += bytes;
3973 trace_btrfs_space_reservation(root->fs_info, "space_info", 3976 trace_btrfs_space_reservation(root->fs_info, "space_info",
3974 data_sinfo->flags, bytes, 1); 3977 data_sinfo->flags, bytes, 1);
3978out:
3975 spin_unlock(&data_sinfo->lock); 3979 spin_unlock(&data_sinfo->lock);
3976 3980
3977 return 0; 3981 return ret;
3978} 3982}
3979 3983
3980/* 3984/*
@@ -3991,6 +3995,7 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
3991 data_sinfo = root->fs_info->data_sinfo; 3995 data_sinfo = root->fs_info->data_sinfo;
3992 spin_lock(&data_sinfo->lock); 3996 spin_lock(&data_sinfo->lock);
3993 WARN_ON(data_sinfo->bytes_may_use < bytes); 3997 WARN_ON(data_sinfo->bytes_may_use < bytes);
3998 btrfs_qgroup_free(root, bytes);
3994 data_sinfo->bytes_may_use -= bytes; 3999 data_sinfo->bytes_may_use -= bytes;
3995 trace_btrfs_space_reservation(root->fs_info, "space_info", 4000 trace_btrfs_space_reservation(root->fs_info, "space_info",
3996 data_sinfo->flags, bytes, 0); 4001 data_sinfo->flags, bytes, 0);
@@ -5391,8 +5396,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
5391 spin_unlock(&BTRFS_I(inode)->lock); 5396 spin_unlock(&BTRFS_I(inode)->lock);
5392 5397
5393 if (root->fs_info->quota_enabled) { 5398 if (root->fs_info->quota_enabled) {
5394 ret = btrfs_qgroup_reserve(root, num_bytes + 5399 ret = btrfs_qgroup_reserve(root, nr_extents * root->nodesize);
5395 nr_extents * root->nodesize);
5396 if (ret) 5400 if (ret)
5397 goto out_fail; 5401 goto out_fail;
5398 } 5402 }
@@ -5400,8 +5404,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
5400 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); 5404 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
5401 if (unlikely(ret)) { 5405 if (unlikely(ret)) {
5402 if (root->fs_info->quota_enabled) 5406 if (root->fs_info->quota_enabled)
5403 btrfs_qgroup_free(root, num_bytes + 5407 btrfs_qgroup_free(root, nr_extents * root->nodesize);
5404 nr_extents * root->nodesize);
5405 goto out_fail; 5408 goto out_fail;
5406 } 5409 }
5407 5410
@@ -5522,8 +5525,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
5522 trace_btrfs_space_reservation(root->fs_info, "delalloc", 5525 trace_btrfs_space_reservation(root->fs_info, "delalloc",
5523 btrfs_ino(inode), to_free, 0); 5526 btrfs_ino(inode), to_free, 0);
5524 if (root->fs_info->quota_enabled) { 5527 if (root->fs_info->quota_enabled) {
5525 btrfs_qgroup_free(root, num_bytes + 5528 btrfs_qgroup_free(root, dropped * root->nodesize);
5526 dropped * root->nodesize);
5527 } 5529 }
5528 5530
5529 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, 5531 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv,
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index fd105c172c8b..faef1d64394d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2549,7 +2549,6 @@ static long btrfs_fallocate(struct file *file, int mode,
2549{ 2549{
2550 struct inode *inode = file_inode(file); 2550 struct inode *inode = file_inode(file);
2551 struct extent_state *cached_state = NULL; 2551 struct extent_state *cached_state = NULL;
2552 struct btrfs_root *root = BTRFS_I(inode)->root;
2553 u64 cur_offset; 2552 u64 cur_offset;
2554 u64 last_byte; 2553 u64 last_byte;
2555 u64 alloc_start; 2554 u64 alloc_start;
@@ -2577,11 +2576,6 @@ static long btrfs_fallocate(struct file *file, int mode,
2577 ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start); 2576 ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
2578 if (ret) 2577 if (ret)
2579 return ret; 2578 return ret;
2580 if (root->fs_info->quota_enabled) {
2581 ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start);
2582 if (ret)
2583 goto out_reserve_fail;
2584 }
2585 2579
2586 mutex_lock(&inode->i_mutex); 2580 mutex_lock(&inode->i_mutex);
2587 ret = inode_newsize_ok(inode, alloc_end); 2581 ret = inode_newsize_ok(inode, alloc_end);
@@ -2674,6 +2668,7 @@ static long btrfs_fallocate(struct file *file, int mode,
2674 } else if (actual_end > inode->i_size && 2668 } else if (actual_end > inode->i_size &&
2675 !(mode & FALLOC_FL_KEEP_SIZE)) { 2669 !(mode & FALLOC_FL_KEEP_SIZE)) {
2676 struct btrfs_trans_handle *trans; 2670 struct btrfs_trans_handle *trans;
2671 struct btrfs_root *root = BTRFS_I(inode)->root;
2677 2672
2678 /* 2673 /*
2679 * We didn't need to allocate any more space, but we 2674 * We didn't need to allocate any more space, but we
@@ -2710,9 +2705,6 @@ static long btrfs_fallocate(struct file *file, int mode,
2710 &cached_state, GFP_NOFS); 2705 &cached_state, GFP_NOFS);
2711out: 2706out:
2712 mutex_unlock(&inode->i_mutex); 2707 mutex_unlock(&inode->i_mutex);
2713 if (root->fs_info->quota_enabled)
2714 btrfs_qgroup_free(root, alloc_end - alloc_start);
2715out_reserve_fail:
2716 /* Let go of our reservation. */ 2708 /* Let go of our reservation. */
2717 btrfs_free_reserved_data_space(inode, alloc_end - alloc_start); 2709 btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
2718 return ret; 2710 return ret;