diff options
author | Omar Sandoval <osandov@fb.com> | 2017-06-06 19:45:30 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2017-06-29 14:17:01 -0400 |
commit | 7be07912b32d103d9789082f27dd54b47c89c744 (patch) | |
tree | 5e432366945651742de3b48e72b0884d70ddcb02 | |
parent | 0a16c7d7aecfae8987197e50116ebfc338cbe0a2 (diff) |
Btrfs: return old and new total ref mods when adding delayed refs
We need this to decide when to account pinned bytes.
Signed-off-by: Omar Sandoval <osandov@fb.com>
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/delayed-ref.c | 29 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.h | 6 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 51 |
3 files changed, 52 insertions, 34 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index be70d90dfee5..93ffa898df6d 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -470,7 +470,8 @@ add_tail: | |||
470 | static noinline void | 470 | static noinline void |
471 | update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs, | 471 | update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs, |
472 | struct btrfs_delayed_ref_node *existing, | 472 | struct btrfs_delayed_ref_node *existing, |
473 | struct btrfs_delayed_ref_node *update) | 473 | struct btrfs_delayed_ref_node *update, |
474 | int *old_ref_mod_ret) | ||
474 | { | 475 | { |
475 | struct btrfs_delayed_ref_head *existing_ref; | 476 | struct btrfs_delayed_ref_head *existing_ref; |
476 | struct btrfs_delayed_ref_head *ref; | 477 | struct btrfs_delayed_ref_head *ref; |
@@ -523,6 +524,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs, | |||
523 | * currently, for refs we just added we know we're a-ok. | 524 | * currently, for refs we just added we know we're a-ok. |
524 | */ | 525 | */ |
525 | old_ref_mod = existing_ref->total_ref_mod; | 526 | old_ref_mod = existing_ref->total_ref_mod; |
527 | if (old_ref_mod_ret) | ||
528 | *old_ref_mod_ret = old_ref_mod; | ||
526 | existing->ref_mod += update->ref_mod; | 529 | existing->ref_mod += update->ref_mod; |
527 | existing_ref->total_ref_mod += update->ref_mod; | 530 | existing_ref->total_ref_mod += update->ref_mod; |
528 | 531 | ||
@@ -550,7 +553,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
550 | struct btrfs_delayed_ref_node *ref, | 553 | struct btrfs_delayed_ref_node *ref, |
551 | struct btrfs_qgroup_extent_record *qrecord, | 554 | struct btrfs_qgroup_extent_record *qrecord, |
552 | u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved, | 555 | u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved, |
553 | int action, int is_data, int *qrecord_inserted_ret) | 556 | int action, int is_data, int *qrecord_inserted_ret, |
557 | int *old_ref_mod, int *new_ref_mod) | ||
554 | { | 558 | { |
555 | struct btrfs_delayed_ref_head *existing; | 559 | struct btrfs_delayed_ref_head *existing; |
556 | struct btrfs_delayed_ref_head *head_ref = NULL; | 560 | struct btrfs_delayed_ref_head *head_ref = NULL; |
@@ -638,7 +642,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
638 | if (existing) { | 642 | if (existing) { |
639 | WARN_ON(ref_root && reserved && existing->qgroup_ref_root | 643 | WARN_ON(ref_root && reserved && existing->qgroup_ref_root |
640 | && existing->qgroup_reserved); | 644 | && existing->qgroup_reserved); |
641 | update_existing_head_ref(delayed_refs, &existing->node, ref); | 645 | update_existing_head_ref(delayed_refs, &existing->node, ref, |
646 | old_ref_mod); | ||
642 | /* | 647 | /* |
643 | * we've updated the existing ref, free the newly | 648 | * we've updated the existing ref, free the newly |
644 | * allocated ref | 649 | * allocated ref |
@@ -646,6 +651,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
646 | kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref); | 651 | kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref); |
647 | head_ref = existing; | 652 | head_ref = existing; |
648 | } else { | 653 | } else { |
654 | if (old_ref_mod) | ||
655 | *old_ref_mod = 0; | ||
649 | if (is_data && count_mod < 0) | 656 | if (is_data && count_mod < 0) |
650 | delayed_refs->pending_csums += num_bytes; | 657 | delayed_refs->pending_csums += num_bytes; |
651 | delayed_refs->num_heads++; | 658 | delayed_refs->num_heads++; |
@@ -655,6 +662,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info, | |||
655 | } | 662 | } |
656 | if (qrecord_inserted_ret) | 663 | if (qrecord_inserted_ret) |
657 | *qrecord_inserted_ret = qrecord_inserted; | 664 | *qrecord_inserted_ret = qrecord_inserted; |
665 | if (new_ref_mod) | ||
666 | *new_ref_mod = head_ref->total_ref_mod; | ||
658 | return head_ref; | 667 | return head_ref; |
659 | } | 668 | } |
660 | 669 | ||
@@ -778,7 +787,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
778 | struct btrfs_trans_handle *trans, | 787 | struct btrfs_trans_handle *trans, |
779 | u64 bytenr, u64 num_bytes, u64 parent, | 788 | u64 bytenr, u64 num_bytes, u64 parent, |
780 | u64 ref_root, int level, int action, | 789 | u64 ref_root, int level, int action, |
781 | struct btrfs_delayed_extent_op *extent_op) | 790 | struct btrfs_delayed_extent_op *extent_op, |
791 | int *old_ref_mod, int *new_ref_mod) | ||
782 | { | 792 | { |
783 | struct btrfs_delayed_tree_ref *ref; | 793 | struct btrfs_delayed_tree_ref *ref; |
784 | struct btrfs_delayed_ref_head *head_ref; | 794 | struct btrfs_delayed_ref_head *head_ref; |
@@ -813,7 +823,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
813 | */ | 823 | */ |
814 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, | 824 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, |
815 | bytenr, num_bytes, 0, 0, action, 0, | 825 | bytenr, num_bytes, 0, 0, action, 0, |
816 | &qrecord_inserted); | 826 | &qrecord_inserted, old_ref_mod, |
827 | new_ref_mod); | ||
817 | 828 | ||
818 | add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, | 829 | add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, |
819 | num_bytes, parent, ref_root, level, action); | 830 | num_bytes, parent, ref_root, level, action); |
@@ -838,7 +849,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
838 | struct btrfs_trans_handle *trans, | 849 | struct btrfs_trans_handle *trans, |
839 | u64 bytenr, u64 num_bytes, | 850 | u64 bytenr, u64 num_bytes, |
840 | u64 parent, u64 ref_root, | 851 | u64 parent, u64 ref_root, |
841 | u64 owner, u64 offset, u64 reserved, int action) | 852 | u64 owner, u64 offset, u64 reserved, int action, |
853 | int *old_ref_mod, int *new_ref_mod) | ||
842 | { | 854 | { |
843 | struct btrfs_delayed_data_ref *ref; | 855 | struct btrfs_delayed_data_ref *ref; |
844 | struct btrfs_delayed_ref_head *head_ref; | 856 | struct btrfs_delayed_ref_head *head_ref; |
@@ -878,7 +890,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
878 | */ | 890 | */ |
879 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, | 891 | head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record, |
880 | bytenr, num_bytes, ref_root, reserved, | 892 | bytenr, num_bytes, ref_root, reserved, |
881 | action, 1, &qrecord_inserted); | 893 | action, 1, &qrecord_inserted, |
894 | old_ref_mod, new_ref_mod); | ||
882 | 895 | ||
883 | add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, | 896 | add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, |
884 | num_bytes, parent, ref_root, owner, offset, | 897 | num_bytes, parent, ref_root, owner, offset, |
@@ -909,7 +922,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | |||
909 | 922 | ||
910 | add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr, | 923 | add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr, |
911 | num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD, | 924 | num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD, |
912 | extent_op->is_data, NULL); | 925 | extent_op->is_data, NULL, NULL, NULL); |
913 | 926 | ||
914 | spin_unlock(&delayed_refs->lock); | 927 | spin_unlock(&delayed_refs->lock); |
915 | return 0; | 928 | return 0; |
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index c0264ff01b53..ce88e4ac5276 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
@@ -247,12 +247,14 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
247 | struct btrfs_trans_handle *trans, | 247 | struct btrfs_trans_handle *trans, |
248 | u64 bytenr, u64 num_bytes, u64 parent, | 248 | u64 bytenr, u64 num_bytes, u64 parent, |
249 | u64 ref_root, int level, int action, | 249 | u64 ref_root, int level, int action, |
250 | struct btrfs_delayed_extent_op *extent_op); | 250 | struct btrfs_delayed_extent_op *extent_op, |
251 | int *old_ref_mod, int *new_ref_mod); | ||
251 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | 252 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, |
252 | struct btrfs_trans_handle *trans, | 253 | struct btrfs_trans_handle *trans, |
253 | u64 bytenr, u64 num_bytes, | 254 | u64 bytenr, u64 num_bytes, |
254 | u64 parent, u64 ref_root, | 255 | u64 parent, u64 ref_root, |
255 | u64 owner, u64 offset, u64 reserved, int action); | 256 | u64 owner, u64 offset, u64 reserved, int action, |
257 | int *old_ref_mod, int *new_ref_mod); | ||
256 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | 258 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
257 | struct btrfs_trans_handle *trans, | 259 | struct btrfs_trans_handle *trans, |
258 | u64 bytenr, u64 num_bytes, | 260 | u64 bytenr, u64 num_bytes, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 40c80ed8d1f9..8121a78f6cbd 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2120,14 +2120,16 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
2120 | 2120 | ||
2121 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 2121 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { |
2122 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, | 2122 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
2123 | num_bytes, | 2123 | num_bytes, parent, |
2124 | parent, root_objectid, (int)owner, | 2124 | root_objectid, (int)owner, |
2125 | BTRFS_ADD_DELAYED_REF, NULL); | 2125 | BTRFS_ADD_DELAYED_REF, NULL, |
2126 | NULL, NULL); | ||
2126 | } else { | 2127 | } else { |
2127 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, | 2128 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
2128 | num_bytes, parent, root_objectid, | 2129 | num_bytes, parent, |
2129 | owner, offset, 0, | 2130 | root_objectid, owner, offset, |
2130 | BTRFS_ADD_DELAYED_REF); | 2131 | 0, BTRFS_ADD_DELAYED_REF, NULL, |
2132 | NULL); | ||
2131 | } | 2133 | } |
2132 | return ret; | 2134 | return ret; |
2133 | } | 2135 | } |
@@ -7184,12 +7186,12 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
7184 | int ret; | 7186 | int ret; |
7185 | 7187 | ||
7186 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { | 7188 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { |
7187 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, | 7189 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, buf->start, |
7188 | buf->start, buf->len, | 7190 | buf->len, parent, |
7189 | parent, | ||
7190 | root->root_key.objectid, | 7191 | root->root_key.objectid, |
7191 | btrfs_header_level(buf), | 7192 | btrfs_header_level(buf), |
7192 | BTRFS_DROP_DELAYED_REF, NULL); | 7193 | BTRFS_DROP_DELAYED_REF, NULL, |
7194 | NULL, NULL); | ||
7193 | BUG_ON(ret); /* -ENOMEM */ | 7195 | BUG_ON(ret); /* -ENOMEM */ |
7194 | } | 7196 | } |
7195 | 7197 | ||
@@ -7257,15 +7259,16 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
7257 | ret = 0; | 7259 | ret = 0; |
7258 | } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 7260 | } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { |
7259 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, | 7261 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
7260 | num_bytes, | 7262 | num_bytes, parent, |
7261 | parent, root_objectid, (int)owner, | 7263 | root_objectid, (int)owner, |
7262 | BTRFS_DROP_DELAYED_REF, NULL); | 7264 | BTRFS_DROP_DELAYED_REF, NULL, |
7265 | NULL, NULL); | ||
7263 | } else { | 7266 | } else { |
7264 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, | 7267 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
7265 | num_bytes, | 7268 | num_bytes, parent, |
7266 | parent, root_objectid, owner, | 7269 | root_objectid, owner, offset, |
7267 | offset, 0, | 7270 | 0, BTRFS_DROP_DELAYED_REF, |
7268 | BTRFS_DROP_DELAYED_REF); | 7271 | NULL, NULL); |
7269 | } | 7272 | } |
7270 | return ret; | 7273 | return ret; |
7271 | } | 7274 | } |
@@ -8213,9 +8216,9 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
8213 | BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); | 8216 | BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); |
8214 | 8217 | ||
8215 | ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid, | 8218 | ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid, |
8216 | ins->offset, 0, | 8219 | ins->offset, 0, root_objectid, owner, |
8217 | root_objectid, owner, offset, | 8220 | offset, ram_bytes, |
8218 | ram_bytes, BTRFS_ADD_DELAYED_EXTENT); | 8221 | BTRFS_ADD_DELAYED_EXTENT, NULL, NULL); |
8219 | return ret; | 8222 | return ret; |
8220 | } | 8223 | } |
8221 | 8224 | ||
@@ -8435,11 +8438,11 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, | |||
8435 | extent_op->is_data = false; | 8438 | extent_op->is_data = false; |
8436 | extent_op->level = level; | 8439 | extent_op->level = level; |
8437 | 8440 | ||
8438 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, | 8441 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, ins.objectid, |
8439 | ins.objectid, ins.offset, | 8442 | ins.offset, parent, |
8440 | parent, root_objectid, level, | 8443 | root_objectid, level, |
8441 | BTRFS_ADD_DELAYED_EXTENT, | 8444 | BTRFS_ADD_DELAYED_EXTENT, |
8442 | extent_op); | 8445 | extent_op, NULL, NULL); |
8443 | if (ret) | 8446 | if (ret) |
8444 | goto out_free_delayed; | 8447 | goto out_free_delayed; |
8445 | } | 8448 | } |