aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorDongsheng Yang <yangds.fnst@cn.fujitsu.com>2015-02-06 10:26:52 -0500
committerChris Mason <clm@fb.com>2015-04-13 10:52:50 -0400
commite2d1f92399afb6ec518b68867ed10db2585b283a (patch)
treea6964e3b445268bf5c67c4b482de6c98b03571c8 /fs/btrfs
parent237c0e9f1fbfdca7287f3539f1fa73e5063156b5 (diff)
btrfs: qgroup: do a reservation in a higher level.
There are two problems in qgroup: a). The PAGE_CACHE is 4K, even when we are writing a data of 1K, qgroup will reserve a 4K size. It will cause the last 3K in a qgroup is not available to user. b). When user is writing a inline data, qgroup will not reserve it, it means this is a window we can exceed the limit of a qgroup. The main idea of this patch is reserving the data size of write_bytes rather than the reserve_bytes. It means qgroup will not care about the data size btrfs will reserve for user, but only care about the data size user is going to write. Then reserve it when user want to write and release it in transaction committed. In this way, qgroup can be released from the complex procedure in btrfs and only do the reserve when user want to write and account when the data is written in commit_transaction(). Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/extent-tree.c38
-rw-r--r--fs/btrfs/file.c4
-rw-r--r--fs/btrfs/inode.c15
-rw-r--r--fs/btrfs/qgroup.c70
-rw-r--r--fs/btrfs/qgroup.h4
-rw-r--r--fs/btrfs/relocation.c2
7 files changed, 14 insertions, 121 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d48b22f31182..851f2355f3c8 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3448,7 +3448,7 @@ enum btrfs_reserve_flush_enum {
3448 BTRFS_RESERVE_FLUSH_ALL, 3448 BTRFS_RESERVE_FLUSH_ALL,
3449}; 3449};
3450 3450
3451int btrfs_check_data_free_space(struct inode *inode, u64 bytes); 3451int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes);
3452void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes); 3452void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
3453void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, 3453void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
3454 struct btrfs_root *root); 3454 struct btrfs_root *root);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 4d3774605a85..1eef4ee01d1a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3331,7 +3331,7 @@ again:
3331 num_pages *= 16; 3331 num_pages *= 16;
3332 num_pages *= PAGE_CACHE_SIZE; 3332 num_pages *= PAGE_CACHE_SIZE;
3333 3333
3334 ret = btrfs_check_data_free_space(inode, num_pages); 3334 ret = btrfs_check_data_free_space(inode, num_pages, num_pages);
3335 if (ret) 3335 if (ret)
3336 goto out_put; 3336 goto out_put;
3337 3337
@@ -3851,7 +3851,7 @@ u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data)
3851 * This will check the space that the inode allocates from to make sure we have 3851 * This will check the space that the inode allocates from to make sure we have
3852 * enough space for bytes. 3852 * enough space for bytes.
3853 */ 3853 */
3854int btrfs_check_data_free_space(struct inode *inode, u64 bytes) 3854int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes)
3855{ 3855{
3856 struct btrfs_space_info *data_sinfo; 3856 struct btrfs_space_info *data_sinfo;
3857 struct btrfs_root *root = BTRFS_I(inode)->root; 3857 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3969,7 +3969,7 @@ 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); 3972 ret = btrfs_qgroup_reserve(root, write_bytes);
3973 if (ret) 3973 if (ret)
3974 goto out; 3974 goto out;
3975 data_sinfo->bytes_may_use += bytes; 3975 data_sinfo->bytes_may_use += bytes;
@@ -3995,7 +3995,6 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
3995 data_sinfo = root->fs_info->data_sinfo; 3995 data_sinfo = root->fs_info->data_sinfo;
3996 spin_lock(&data_sinfo->lock); 3996 spin_lock(&data_sinfo->lock);
3997 WARN_ON(data_sinfo->bytes_may_use < bytes); 3997 WARN_ON(data_sinfo->bytes_may_use < bytes);
3998 btrfs_qgroup_free(root, bytes);
3999 data_sinfo->bytes_may_use -= bytes; 3998 data_sinfo->bytes_may_use -= bytes;
4000 trace_btrfs_space_reservation(root->fs_info, "space_info", 3999 trace_btrfs_space_reservation(root->fs_info, "space_info",
4001 data_sinfo->flags, bytes, 0); 4000 data_sinfo->flags, bytes, 0);
@@ -5243,8 +5242,6 @@ void btrfs_subvolume_release_metadata(struct btrfs_root *root,
5243 u64 qgroup_reserved) 5242 u64 qgroup_reserved)
5244{ 5243{
5245 btrfs_block_rsv_release(root, rsv, (u64)-1); 5244 btrfs_block_rsv_release(root, rsv, (u64)-1);
5246 if (qgroup_reserved)
5247 btrfs_qgroup_free(root, qgroup_reserved);
5248} 5245}
5249 5246
5250/** 5247/**
@@ -5478,11 +5475,8 @@ out_fail:
5478 to_free = 0; 5475 to_free = 0;
5479 } 5476 }
5480 spin_unlock(&BTRFS_I(inode)->lock); 5477 spin_unlock(&BTRFS_I(inode)->lock);
5481 if (dropped) { 5478 if (dropped)
5482 if (root->fs_info->quota_enabled)
5483 btrfs_qgroup_free(root, dropped * root->nodesize);
5484 to_free += btrfs_calc_trans_metadata_size(root, dropped); 5479 to_free += btrfs_calc_trans_metadata_size(root, dropped);
5485 }
5486 5480
5487 if (to_free) { 5481 if (to_free) {
5488 btrfs_block_rsv_release(root, block_rsv, to_free); 5482 btrfs_block_rsv_release(root, block_rsv, to_free);
@@ -5524,9 +5518,6 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
5524 5518
5525 trace_btrfs_space_reservation(root->fs_info, "delalloc", 5519 trace_btrfs_space_reservation(root->fs_info, "delalloc",
5526 btrfs_ino(inode), to_free, 0); 5520 btrfs_ino(inode), to_free, 0);
5527 if (root->fs_info->quota_enabled) {
5528 btrfs_qgroup_free(root, dropped * root->nodesize);
5529 }
5530 5521
5531 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, 5522 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv,
5532 to_free); 5523 to_free);
@@ -5551,7 +5542,7 @@ int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes)
5551{ 5542{
5552 int ret; 5543 int ret;
5553 5544
5554 ret = btrfs_check_data_free_space(inode, num_bytes); 5545 ret = btrfs_check_data_free_space(inode, num_bytes, num_bytes);
5555 if (ret) 5546 if (ret)
5556 return ret; 5547 return ret;
5557 5548
@@ -5727,12 +5718,8 @@ static int pin_down_extent(struct btrfs_root *root,
5727 5718
5728 set_extent_dirty(root->fs_info->pinned_extents, bytenr, 5719 set_extent_dirty(root->fs_info->pinned_extents, bytenr,
5729 bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL); 5720 bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL);
5730 if (reserved) { 5721 if (reserved)
5731 btrfs_qgroup_update_reserved_bytes(root->fs_info,
5732 root->root_key.objectid,
5733 num_bytes, -1);
5734 trace_btrfs_reserved_extent_free(root, bytenr, num_bytes); 5722 trace_btrfs_reserved_extent_free(root, bytenr, num_bytes);
5735 }
5736 return 0; 5723 return 0;
5737} 5724}
5738 5725
@@ -6470,9 +6457,6 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
6470 btrfs_put_block_group(cache); 6457 btrfs_put_block_group(cache);
6471 trace_btrfs_reserved_extent_free(root, buf->start, buf->len); 6458 trace_btrfs_reserved_extent_free(root, buf->start, buf->len);
6472 pin = 0; 6459 pin = 0;
6473 btrfs_qgroup_update_reserved_bytes(root->fs_info,
6474 root->root_key.objectid,
6475 buf->len, -1);
6476 } 6460 }
6477out: 6461out:
6478 if (pin) 6462 if (pin)
@@ -7205,9 +7189,6 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
7205 ret = btrfs_discard_extent(root, start, len, NULL); 7189 ret = btrfs_discard_extent(root, start, len, NULL);
7206 btrfs_add_free_space(cache, start, len); 7190 btrfs_add_free_space(cache, start, len);
7207 btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc); 7191 btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc);
7208 btrfs_qgroup_update_reserved_bytes(root->fs_info,
7209 root->root_key.objectid,
7210 len, -1);
7211 } 7192 }
7212 7193
7213 btrfs_put_block_group(cache); 7194 btrfs_put_block_group(cache);
@@ -7446,9 +7427,6 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
7446 BUG_ON(ret); /* logic error */ 7427 BUG_ON(ret); /* logic error */
7447 ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, 7428 ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
7448 0, owner, offset, ins, 1); 7429 0, owner, offset, ins, 1);
7449 btrfs_qgroup_update_reserved_bytes(root->fs_info,
7450 root->root_key.objectid,
7451 ins->offset, 1);
7452 btrfs_put_block_group(block_group); 7430 btrfs_put_block_group(block_group);
7453 return ret; 7431 return ret;
7454} 7432}
@@ -7595,10 +7573,6 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7595 return ERR_PTR(ret); 7573 return ERR_PTR(ret);
7596 } 7574 }
7597 7575
7598 btrfs_qgroup_update_reserved_bytes(root->fs_info,
7599 root_objectid,
7600 ins.offset, 1);
7601
7602 buf = btrfs_init_new_buffer(trans, root, ins.objectid, level); 7576 buf = btrfs_init_new_buffer(trans, root, ins.objectid, level);
7603 BUG_ON(IS_ERR(buf)); /* -ENOMEM */ 7577 BUG_ON(IS_ERR(buf)); /* -ENOMEM */
7604 7578
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index faef1d64394d..23b6e03f8465 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1510,7 +1510,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1510 } 1510 }
1511 1511
1512 reserve_bytes = num_pages << PAGE_CACHE_SHIFT; 1512 reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
1513 ret = btrfs_check_data_free_space(inode, reserve_bytes); 1513 ret = btrfs_check_data_free_space(inode, reserve_bytes, write_bytes);
1514 if (ret == -ENOSPC && 1514 if (ret == -ENOSPC &&
1515 (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | 1515 (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1516 BTRFS_INODE_PREALLOC))) { 1516 BTRFS_INODE_PREALLOC))) {
@@ -2573,7 +2573,7 @@ static long btrfs_fallocate(struct file *file, int mode,
2573 * Make sure we have enough space before we do the 2573 * Make sure we have enough space before we do the
2574 * allocation. 2574 * allocation.
2575 */ 2575 */
2576 ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start); 2576 ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start, alloc_end - alloc_start);
2577 if (ret) 2577 if (ret)
2578 return ret; 2578 return ret;
2579 2579
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a9f69a0d4b08..27b59b8362f9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -754,9 +754,6 @@ retry:
754 } 754 }
755 goto out_free; 755 goto out_free;
756 } 756 }
757 btrfs_qgroup_update_reserved_bytes(root->fs_info,
758 root->root_key.objectid,
759 ins.offset, 1);
760 /* 757 /*
761 * here we're doing allocation and writeback of the 758 * here we're doing allocation and writeback of the
762 * compressed pages 759 * compressed pages
@@ -981,10 +978,6 @@ static noinline int cow_file_range(struct inode *inode,
981 if (ret < 0) 978 if (ret < 0)
982 goto out_unlock; 979 goto out_unlock;
983 980
984 btrfs_qgroup_update_reserved_bytes(root->fs_info,
985 root->root_key.objectid,
986 ins.offset, 1);
987
988 em = alloc_extent_map(); 981 em = alloc_extent_map();
989 if (!em) { 982 if (!em) {
990 ret = -ENOMEM; 983 ret = -ENOMEM;
@@ -7037,10 +7030,6 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
7037 return ERR_PTR(ret); 7030 return ERR_PTR(ret);
7038 } 7031 }
7039 7032
7040 btrfs_qgroup_update_reserved_bytes(root->fs_info,
7041 root->root_key.objectid,
7042 ins.offset, 1);
7043
7044 return em; 7033 return em;
7045} 7034}
7046 7035
@@ -9595,10 +9584,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
9595 break; 9584 break;
9596 } 9585 }
9597 9586
9598 btrfs_qgroup_update_reserved_bytes(root->fs_info,
9599 root->root_key.objectid,
9600 ins.offset, 1);
9601
9602 btrfs_drop_extent_cache(inode, cur_offset, 9587 btrfs_drop_extent_cache(inode, cur_offset,
9603 cur_offset + ins.offset -1, 0); 9588 cur_offset + ins.offset -1, 0);
9604 9589
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index cd291733dc3e..17881ad8ed96 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -72,7 +72,6 @@ struct btrfs_qgroup {
72 /* 72 /*
73 * reservation tracking 73 * reservation tracking
74 */ 74 */
75 u64 may_use;
76 u64 reserved; 75 u64 reserved;
77 76
78 /* 77 /*
@@ -2383,67 +2382,6 @@ out:
2383 return ret; 2382 return ret;
2384} 2383}
2385 2384
2386int btrfs_qgroup_update_reserved_bytes(struct btrfs_fs_info *fs_info,
2387 u64 ref_root,
2388 u64 num_bytes,
2389 int sign)
2390{
2391 struct btrfs_root *quota_root;
2392 struct btrfs_qgroup *qgroup;
2393 int ret = 0;
2394 struct ulist_node *unode;
2395 struct ulist_iterator uiter;
2396
2397 if (!is_fstree(ref_root) || !fs_info->quota_enabled)
2398 return 0;
2399
2400 if (num_bytes == 0)
2401 return 0;
2402
2403 spin_lock(&fs_info->qgroup_lock);
2404 quota_root = fs_info->quota_root;
2405 if (!quota_root)
2406 goto out;
2407
2408 qgroup = find_qgroup_rb(fs_info, ref_root);
2409 if (!qgroup)
2410 goto out;
2411
2412 ulist_reinit(fs_info->qgroup_ulist);
2413 ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
2414 (uintptr_t)qgroup, GFP_ATOMIC);
2415 if (ret < 0)
2416 goto out;
2417
2418 ULIST_ITER_INIT(&uiter);
2419 while ((unode = ulist_next(fs_info->qgroup_ulist, &uiter))) {
2420 struct btrfs_qgroup *qg;
2421 struct btrfs_qgroup_list *glist;
2422
2423 qg = u64_to_ptr(unode->aux);
2424
2425 qg->reserved += sign * num_bytes;
2426
2427 list_for_each_entry(glist, &qg->groups, next_group) {
2428 ret = ulist_add(fs_info->qgroup_ulist,
2429 glist->group->qgroupid,
2430 (uintptr_t)glist->group, GFP_ATOMIC);
2431 if (ret < 0)
2432 goto out;
2433 }
2434 }
2435
2436out:
2437 spin_unlock(&fs_info->qgroup_lock);
2438 return ret;
2439}
2440
2441/*
2442 * reserve some space for a qgroup and all its parents. The reservation takes
2443 * place with start_transaction or dealloc_reserve, similar to ENOSPC
2444 * accounting. If not enough space is available, EDQUOT is returned.
2445 * We assume that the requested space is new for all qgroups.
2446 */
2447int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes) 2385int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
2448{ 2386{
2449 struct btrfs_root *quota_root; 2387 struct btrfs_root *quota_root;
@@ -2486,14 +2424,14 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
2486 qg = u64_to_ptr(unode->aux); 2424 qg = u64_to_ptr(unode->aux);
2487 2425
2488 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) && 2426 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
2489 qg->reserved + qg->may_use + (s64)qg->rfer + num_bytes > 2427 qg->reserved + (s64)qg->rfer + num_bytes >
2490 qg->max_rfer) { 2428 qg->max_rfer) {
2491 ret = -EDQUOT; 2429 ret = -EDQUOT;
2492 goto out; 2430 goto out;
2493 } 2431 }
2494 2432
2495 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) && 2433 if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
2496 qg->reserved + qg->may_use + (s64)qg->excl + num_bytes > 2434 qg->reserved + (s64)qg->excl + num_bytes >
2497 qg->max_excl) { 2435 qg->max_excl) {
2498 ret = -EDQUOT; 2436 ret = -EDQUOT;
2499 goto out; 2437 goto out;
@@ -2517,7 +2455,7 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
2517 2455
2518 qg = u64_to_ptr(unode->aux); 2456 qg = u64_to_ptr(unode->aux);
2519 2457
2520 qg->may_use += num_bytes; 2458 qg->reserved += num_bytes;
2521 } 2459 }
2522 2460
2523out: 2461out:
@@ -2563,7 +2501,7 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
2563 2501
2564 qg = u64_to_ptr(unode->aux); 2502 qg = u64_to_ptr(unode->aux);
2565 2503
2566 qg->may_use -= num_bytes; 2504 qg->reserved -= num_bytes;
2567 2505
2568 list_for_each_entry(glist, &qg->groups, next_group) { 2506 list_for_each_entry(glist, &qg->groups, next_group) {
2569 ret = ulist_add(fs_info->qgroup_ulist, 2507 ret = ulist_add(fs_info->qgroup_ulist,
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 64d49b8482b3..c5242aa9a4b2 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -94,10 +94,6 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
94int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, 94int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
95 struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, 95 struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
96 struct btrfs_qgroup_inherit *inherit); 96 struct btrfs_qgroup_inherit *inherit);
97int btrfs_qgroup_update_reserved_bytes(struct btrfs_fs_info *fs_info,
98 u64 ref_root,
99 u64 num_bytes,
100 int sign);
101int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes); 97int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes);
102void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes); 98void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes);
103 99
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 840a4eb0f396..74b24b01d574 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3027,7 +3027,7 @@ int prealloc_file_extent_cluster(struct inode *inode,
3027 mutex_lock(&inode->i_mutex); 3027 mutex_lock(&inode->i_mutex);
3028 3028
3029 ret = btrfs_check_data_free_space(inode, cluster->end + 3029 ret = btrfs_check_data_free_space(inode, cluster->end +
3030 1 - cluster->start); 3030 1 - cluster->start, 0);
3031 if (ret) 3031 if (ret)
3032 goto out; 3032 goto out;
3033 3033