aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2017-06-06 19:45:30 -0400
committerDavid Sterba <dsterba@suse.com>2017-06-29 14:17:01 -0400
commit7be07912b32d103d9789082f27dd54b47c89c744 (patch)
tree5e432366945651742de3b48e72b0884d70ddcb02
parent0a16c7d7aecfae8987197e50116ebfc338cbe0a2 (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.c29
-rw-r--r--fs/btrfs/delayed-ref.h6
-rw-r--r--fs/btrfs/extent-tree.c51
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:
470static noinline void 470static noinline void
471update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs, 471update_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);
251int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, 252int 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);
256int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, 258int 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 }