diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2015-04-16 02:34:17 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-06-10 12:25:32 -0400 |
commit | 3368d001ba5df44930d986e82b1b497d4da285ba (patch) | |
tree | 62797b833909d45d2e8b6244c4007d6661154f67 /fs/btrfs/delayed-ref.c | |
parent | 823ae5b8e340003dacbe7cd08a355efe018c9f1b (diff) |
btrfs: qgroup: Record possible quota-related extent for qgroup.
Add hook in add_delayed_ref_head() to record quota-related extent record
into delayed_ref_root->dirty_extent_record rb-tree for later qgroup
accounting.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/delayed-ref.c')
-rw-r--r-- | fs/btrfs/delayed-ref.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index fc9563d42693..fd64fd0f011a 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "ctree.h" | 22 | #include "ctree.h" |
23 | #include "delayed-ref.h" | 23 | #include "delayed-ref.h" |
24 | #include "transaction.h" | 24 | #include "transaction.h" |
25 | #include "qgroup.h" | ||
25 | 26 | ||
26 | struct kmem_cache *btrfs_delayed_ref_head_cachep; | 27 | struct kmem_cache *btrfs_delayed_ref_head_cachep; |
27 | struct kmem_cache *btrfs_delayed_tree_ref_cachep; | 28 | struct kmem_cache *btrfs_delayed_tree_ref_cachep; |
@@ -420,12 +421,14 @@ update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs, | |||
420 | static noinline struct btrfs_delayed_ref_head * | 421 | static noinline struct btrfs_delayed_ref_head * |
421 | add_delayed_ref_head(struct btrfs_fs_info *fs_info, | 422 | add_delayed_ref_head(struct btrfs_fs_info *fs_info, |
422 | struct btrfs_trans_handle *trans, | 423 | struct btrfs_trans_handle *trans, |
423 | struct btrfs_delayed_ref_node *ref, u64 bytenr, | 424 | struct btrfs_delayed_ref_node *ref, |
424 | u64 num_bytes, int action, int is_data) | 425 | struct btrfs_qgroup_extent_record *qrecord, |
426 | u64 bytenr, u64 num_bytes, int action, int is_data) | ||
425 | { | 427 | { |
426 | struct btrfs_delayed_ref_head *existing; | 428 | struct btrfs_delayed_ref_head *existing; |
427 | struct btrfs_delayed_ref_head *head_ref = NULL; | 429 | struct btrfs_delayed_ref_head *head_ref = NULL; |
428 | struct btrfs_delayed_ref_root *delayed_refs; | 430 | struct btrfs_delayed_ref_root *delayed_refs; |
431 | struct btrfs_qgroup_extent_record *qexisting; | ||
429 | int count_mod = 1; | 432 | int count_mod = 1; |
430 | int must_insert_reserved = 0; | 433 | int must_insert_reserved = 0; |
431 | 434 | ||
@@ -474,6 +477,18 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
474 | head_ref->processing = 0; | 477 | head_ref->processing = 0; |
475 | head_ref->total_ref_mod = count_mod; | 478 | head_ref->total_ref_mod = count_mod; |
476 | 479 | ||
480 | /* Record qgroup extent info if provided */ | ||
481 | if (qrecord) { | ||
482 | qrecord->bytenr = bytenr; | ||
483 | qrecord->num_bytes = num_bytes; | ||
484 | qrecord->old_roots = NULL; | ||
485 | |||
486 | qexisting = btrfs_qgroup_insert_dirty_extent(delayed_refs, | ||
487 | qrecord); | ||
488 | if (qexisting) | ||
489 | kfree(qrecord); | ||
490 | } | ||
491 | |||
477 | spin_lock_init(&head_ref->lock); | 492 | spin_lock_init(&head_ref->lock); |
478 | mutex_init(&head_ref->mutex); | 493 | mutex_init(&head_ref->mutex); |
479 | 494 | ||
@@ -624,6 +639,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
624 | struct btrfs_delayed_tree_ref *ref; | 639 | struct btrfs_delayed_tree_ref *ref; |
625 | struct btrfs_delayed_ref_head *head_ref; | 640 | struct btrfs_delayed_ref_head *head_ref; |
626 | struct btrfs_delayed_ref_root *delayed_refs; | 641 | struct btrfs_delayed_ref_root *delayed_refs; |
642 | struct btrfs_qgroup_extent_record *record = NULL; | ||
627 | 643 | ||
628 | if (!is_fstree(ref_root) || !fs_info->quota_enabled) | 644 | if (!is_fstree(ref_root) || !fs_info->quota_enabled) |
629 | no_quota = 0; | 645 | no_quota = 0; |
@@ -639,6 +655,15 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
639 | return -ENOMEM; | 655 | return -ENOMEM; |
640 | } | 656 | } |
641 | 657 | ||
658 | if (fs_info->quota_enabled && is_fstree(ref_root)) { | ||
659 | record = kmalloc(sizeof(*record), GFP_NOFS); | ||
660 | if (!record) { | ||
661 | kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref); | ||
662 | kmem_cache_free(btrfs_delayed_ref_head_cachep, ref); | ||
663 | return -ENOMEM; | ||
664 | } | ||
665 | } | ||
666 | |||
642 | head_ref->extent_op = extent_op; | 667 | head_ref->extent_op = extent_op; |
643 | 668 | ||
644 | delayed_refs = &trans->transaction->delayed_refs; | 669 | delayed_refs = &trans->transaction->delayed_refs; |
@@ -648,7 +673,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
648 | * insert both the head node and the new ref without dropping | 673 | * insert both the head node and the new ref without dropping |
649 | * the spin lock | 674 | * the spin lock |
650 | */ | 675 | */ |
651 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, | 676 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, |
652 | bytenr, num_bytes, action, 0); | 677 | bytenr, num_bytes, action, 0); |
653 | 678 | ||
654 | add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, | 679 | add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, |
@@ -673,6 +698,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
673 | struct btrfs_delayed_data_ref *ref; | 698 | struct btrfs_delayed_data_ref *ref; |
674 | struct btrfs_delayed_ref_head *head_ref; | 699 | struct btrfs_delayed_ref_head *head_ref; |
675 | struct btrfs_delayed_ref_root *delayed_refs; | 700 | struct btrfs_delayed_ref_root *delayed_refs; |
701 | struct btrfs_qgroup_extent_record *record = NULL; | ||
676 | 702 | ||
677 | if (!is_fstree(ref_root) || !fs_info->quota_enabled) | 703 | if (!is_fstree(ref_root) || !fs_info->quota_enabled) |
678 | no_quota = 0; | 704 | no_quota = 0; |
@@ -688,6 +714,16 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
688 | return -ENOMEM; | 714 | return -ENOMEM; |
689 | } | 715 | } |
690 | 716 | ||
717 | if (fs_info->quota_enabled && is_fstree(ref_root)) { | ||
718 | record = kmalloc(sizeof(*record), GFP_NOFS); | ||
719 | if (!record) { | ||
720 | kmem_cache_free(btrfs_delayed_data_ref_cachep, ref); | ||
721 | kmem_cache_free(btrfs_delayed_ref_head_cachep, | ||
722 | head_ref); | ||
723 | return -ENOMEM; | ||
724 | } | ||
725 | } | ||
726 | |||
691 | head_ref->extent_op = extent_op; | 727 | head_ref->extent_op = extent_op; |
692 | 728 | ||
693 | delayed_refs = &trans->transaction->delayed_refs; | 729 | delayed_refs = &trans->transaction->delayed_refs; |
@@ -697,7 +733,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
697 | * insert both the head node and the new ref without dropping | 733 | * insert both the head node and the new ref without dropping |
698 | * the spin lock | 734 | * the spin lock |
699 | */ | 735 | */ |
700 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, | 736 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, |
701 | bytenr, num_bytes, action, 1); | 737 | bytenr, num_bytes, action, 1); |
702 | 738 | ||
703 | add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, | 739 | add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, |
@@ -725,9 +761,9 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | |||
725 | delayed_refs = &trans->transaction->delayed_refs; | 761 | delayed_refs = &trans->transaction->delayed_refs; |
726 | spin_lock(&delayed_refs->lock); | 762 | spin_lock(&delayed_refs->lock); |
727 | 763 | ||
728 | add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, | 764 | add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr, |
729 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 765 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, |
730 | extent_op->is_data); | 766 | extent_op->is_data); |
731 | 767 | ||
732 | spin_unlock(&delayed_refs->lock); | 768 | spin_unlock(&delayed_refs->lock); |
733 | return 0; | 769 | return 0; |