diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 285 |
1 files changed, 272 insertions, 13 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 813537f362f9..102ed3143976 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3057,7 +3057,7 @@ out: | |||
3057 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 3057 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, |
3058 | struct btrfs_root *root, | 3058 | struct btrfs_root *root, |
3059 | struct extent_buffer *buf, | 3059 | struct extent_buffer *buf, |
3060 | int full_backref, int inc, int no_quota) | 3060 | int full_backref, int inc) |
3061 | { | 3061 | { |
3062 | u64 bytenr; | 3062 | u64 bytenr; |
3063 | u64 num_bytes; | 3063 | u64 num_bytes; |
@@ -3111,7 +3111,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3111 | key.offset -= btrfs_file_extent_offset(buf, fi); | 3111 | key.offset -= btrfs_file_extent_offset(buf, fi); |
3112 | ret = process_func(trans, root, bytenr, num_bytes, | 3112 | ret = process_func(trans, root, bytenr, num_bytes, |
3113 | parent, ref_root, key.objectid, | 3113 | parent, ref_root, key.objectid, |
3114 | key.offset, no_quota); | 3114 | key.offset, 1); |
3115 | if (ret) | 3115 | if (ret) |
3116 | goto fail; | 3116 | goto fail; |
3117 | } else { | 3117 | } else { |
@@ -3119,7 +3119,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
3119 | num_bytes = btrfs_level_size(root, level - 1); | 3119 | num_bytes = btrfs_level_size(root, level - 1); |
3120 | ret = process_func(trans, root, bytenr, num_bytes, | 3120 | ret = process_func(trans, root, bytenr, num_bytes, |
3121 | parent, ref_root, level - 1, 0, | 3121 | parent, ref_root, level - 1, 0, |
3122 | no_quota); | 3122 | 1); |
3123 | if (ret) | 3123 | if (ret) |
3124 | goto fail; | 3124 | goto fail; |
3125 | } | 3125 | } |
@@ -3130,15 +3130,15 @@ fail: | |||
3130 | } | 3130 | } |
3131 | 3131 | ||
3132 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3132 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3133 | struct extent_buffer *buf, int full_backref, int no_quota) | 3133 | struct extent_buffer *buf, int full_backref) |
3134 | { | 3134 | { |
3135 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1, no_quota); | 3135 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1); |
3136 | } | 3136 | } |
3137 | 3137 | ||
3138 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3138 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
3139 | struct extent_buffer *buf, int full_backref, int no_quota) | 3139 | struct extent_buffer *buf, int full_backref) |
3140 | { | 3140 | { |
3141 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0, no_quota); | 3141 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0); |
3142 | } | 3142 | } |
3143 | 3143 | ||
3144 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 3144 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
@@ -7478,6 +7478,220 @@ reada: | |||
7478 | wc->reada_slot = slot; | 7478 | wc->reada_slot = slot; |
7479 | } | 7479 | } |
7480 | 7480 | ||
7481 | static int account_leaf_items(struct btrfs_trans_handle *trans, | ||
7482 | struct btrfs_root *root, | ||
7483 | struct extent_buffer *eb) | ||
7484 | { | ||
7485 | int nr = btrfs_header_nritems(eb); | ||
7486 | int i, extent_type, ret; | ||
7487 | struct btrfs_key key; | ||
7488 | struct btrfs_file_extent_item *fi; | ||
7489 | u64 bytenr, num_bytes; | ||
7490 | |||
7491 | for (i = 0; i < nr; i++) { | ||
7492 | btrfs_item_key_to_cpu(eb, &key, i); | ||
7493 | |||
7494 | if (key.type != BTRFS_EXTENT_DATA_KEY) | ||
7495 | continue; | ||
7496 | |||
7497 | fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item); | ||
7498 | /* filter out non qgroup-accountable extents */ | ||
7499 | extent_type = btrfs_file_extent_type(eb, fi); | ||
7500 | |||
7501 | if (extent_type == BTRFS_FILE_EXTENT_INLINE) | ||
7502 | continue; | ||
7503 | |||
7504 | bytenr = btrfs_file_extent_disk_bytenr(eb, fi); | ||
7505 | if (!bytenr) | ||
7506 | continue; | ||
7507 | |||
7508 | num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); | ||
7509 | |||
7510 | ret = btrfs_qgroup_record_ref(trans, root->fs_info, | ||
7511 | root->objectid, | ||
7512 | bytenr, num_bytes, | ||
7513 | BTRFS_QGROUP_OPER_SUB_SUBTREE, 0); | ||
7514 | if (ret) | ||
7515 | return ret; | ||
7516 | } | ||
7517 | return 0; | ||
7518 | } | ||
7519 | |||
7520 | /* | ||
7521 | * Walk up the tree from the bottom, freeing leaves and any interior | ||
7522 | * nodes which have had all slots visited. If a node (leaf or | ||
7523 | * interior) is freed, the node above it will have it's slot | ||
7524 | * incremented. The root node will never be freed. | ||
7525 | * | ||
7526 | * At the end of this function, we should have a path which has all | ||
7527 | * slots incremented to the next position for a search. If we need to | ||
7528 | * read a new node it will be NULL and the node above it will have the | ||
7529 | * correct slot selected for a later read. | ||
7530 | * | ||
7531 | * If we increment the root nodes slot counter past the number of | ||
7532 | * elements, 1 is returned to signal completion of the search. | ||
7533 | */ | ||
7534 | static int adjust_slots_upwards(struct btrfs_root *root, | ||
7535 | struct btrfs_path *path, int root_level) | ||
7536 | { | ||
7537 | int level = 0; | ||
7538 | int nr, slot; | ||
7539 | struct extent_buffer *eb; | ||
7540 | |||
7541 | if (root_level == 0) | ||
7542 | return 1; | ||
7543 | |||
7544 | while (level <= root_level) { | ||
7545 | eb = path->nodes[level]; | ||
7546 | nr = btrfs_header_nritems(eb); | ||
7547 | path->slots[level]++; | ||
7548 | slot = path->slots[level]; | ||
7549 | if (slot >= nr || level == 0) { | ||
7550 | /* | ||
7551 | * Don't free the root - we will detect this | ||
7552 | * condition after our loop and return a | ||
7553 | * positive value for caller to stop walking the tree. | ||
7554 | */ | ||
7555 | if (level != root_level) { | ||
7556 | btrfs_tree_unlock_rw(eb, path->locks[level]); | ||
7557 | path->locks[level] = 0; | ||
7558 | |||
7559 | free_extent_buffer(eb); | ||
7560 | path->nodes[level] = NULL; | ||
7561 | path->slots[level] = 0; | ||
7562 | } | ||
7563 | } else { | ||
7564 | /* | ||
7565 | * We have a valid slot to walk back down | ||
7566 | * from. Stop here so caller can process these | ||
7567 | * new nodes. | ||
7568 | */ | ||
7569 | break; | ||
7570 | } | ||
7571 | |||
7572 | level++; | ||
7573 | } | ||
7574 | |||
7575 | eb = path->nodes[root_level]; | ||
7576 | if (path->slots[root_level] >= btrfs_header_nritems(eb)) | ||
7577 | return 1; | ||
7578 | |||
7579 | return 0; | ||
7580 | } | ||
7581 | |||
7582 | /* | ||
7583 | * root_eb is the subtree root and is locked before this function is called. | ||
7584 | */ | ||
7585 | static int account_shared_subtree(struct btrfs_trans_handle *trans, | ||
7586 | struct btrfs_root *root, | ||
7587 | struct extent_buffer *root_eb, | ||
7588 | u64 root_gen, | ||
7589 | int root_level) | ||
7590 | { | ||
7591 | int ret = 0; | ||
7592 | int level; | ||
7593 | struct extent_buffer *eb = root_eb; | ||
7594 | struct btrfs_path *path = NULL; | ||
7595 | |||
7596 | BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL); | ||
7597 | BUG_ON(root_eb == NULL); | ||
7598 | |||
7599 | if (!root->fs_info->quota_enabled) | ||
7600 | return 0; | ||
7601 | |||
7602 | if (!extent_buffer_uptodate(root_eb)) { | ||
7603 | ret = btrfs_read_buffer(root_eb, root_gen); | ||
7604 | if (ret) | ||
7605 | goto out; | ||
7606 | } | ||
7607 | |||
7608 | if (root_level == 0) { | ||
7609 | ret = account_leaf_items(trans, root, root_eb); | ||
7610 | goto out; | ||
7611 | } | ||
7612 | |||
7613 | path = btrfs_alloc_path(); | ||
7614 | if (!path) | ||
7615 | return -ENOMEM; | ||
7616 | |||
7617 | /* | ||
7618 | * Walk down the tree. Missing extent blocks are filled in as | ||
7619 | * we go. Metadata is accounted every time we read a new | ||
7620 | * extent block. | ||
7621 | * | ||
7622 | * When we reach a leaf, we account for file extent items in it, | ||
7623 | * walk back up the tree (adjusting slot pointers as we go) | ||
7624 | * and restart the search process. | ||
7625 | */ | ||
7626 | extent_buffer_get(root_eb); /* For path */ | ||
7627 | path->nodes[root_level] = root_eb; | ||
7628 | path->slots[root_level] = 0; | ||
7629 | path->locks[root_level] = 0; /* so release_path doesn't try to unlock */ | ||
7630 | walk_down: | ||
7631 | level = root_level; | ||
7632 | while (level >= 0) { | ||
7633 | if (path->nodes[level] == NULL) { | ||
7634 | int child_bsize = root->nodesize; | ||
7635 | int parent_slot; | ||
7636 | u64 child_gen; | ||
7637 | u64 child_bytenr; | ||
7638 | |||
7639 | /* We need to get child blockptr/gen from | ||
7640 | * parent before we can read it. */ | ||
7641 | eb = path->nodes[level + 1]; | ||
7642 | parent_slot = path->slots[level + 1]; | ||
7643 | child_bytenr = btrfs_node_blockptr(eb, parent_slot); | ||
7644 | child_gen = btrfs_node_ptr_generation(eb, parent_slot); | ||
7645 | |||
7646 | eb = read_tree_block(root, child_bytenr, child_bsize, | ||
7647 | child_gen); | ||
7648 | if (!eb || !extent_buffer_uptodate(eb)) { | ||
7649 | ret = -EIO; | ||
7650 | goto out; | ||
7651 | } | ||
7652 | |||
7653 | path->nodes[level] = eb; | ||
7654 | path->slots[level] = 0; | ||
7655 | |||
7656 | btrfs_tree_read_lock(eb); | ||
7657 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | ||
7658 | path->locks[level] = BTRFS_READ_LOCK_BLOCKING; | ||
7659 | |||
7660 | ret = btrfs_qgroup_record_ref(trans, root->fs_info, | ||
7661 | root->objectid, | ||
7662 | child_bytenr, | ||
7663 | child_bsize, | ||
7664 | BTRFS_QGROUP_OPER_SUB_SUBTREE, | ||
7665 | 0); | ||
7666 | if (ret) | ||
7667 | goto out; | ||
7668 | |||
7669 | } | ||
7670 | |||
7671 | if (level == 0) { | ||
7672 | ret = account_leaf_items(trans, root, path->nodes[level]); | ||
7673 | if (ret) | ||
7674 | goto out; | ||
7675 | |||
7676 | /* Nonzero return here means we completed our search */ | ||
7677 | ret = adjust_slots_upwards(root, path, root_level); | ||
7678 | if (ret) | ||
7679 | break; | ||
7680 | |||
7681 | /* Restart search with new slots */ | ||
7682 | goto walk_down; | ||
7683 | } | ||
7684 | |||
7685 | level--; | ||
7686 | } | ||
7687 | |||
7688 | ret = 0; | ||
7689 | out: | ||
7690 | btrfs_free_path(path); | ||
7691 | |||
7692 | return ret; | ||
7693 | } | ||
7694 | |||
7481 | /* | 7695 | /* |
7482 | * helper to process tree block while walking down the tree. | 7696 | * helper to process tree block while walking down the tree. |
7483 | * | 7697 | * |
@@ -7532,9 +7746,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, | |||
7532 | /* wc->stage == UPDATE_BACKREF */ | 7746 | /* wc->stage == UPDATE_BACKREF */ |
7533 | if (!(wc->flags[level] & flag)) { | 7747 | if (!(wc->flags[level] & flag)) { |
7534 | BUG_ON(!path->locks[level]); | 7748 | BUG_ON(!path->locks[level]); |
7535 | ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); | 7749 | ret = btrfs_inc_ref(trans, root, eb, 1); |
7536 | BUG_ON(ret); /* -ENOMEM */ | 7750 | BUG_ON(ret); /* -ENOMEM */ |
7537 | ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); | 7751 | ret = btrfs_dec_ref(trans, root, eb, 0); |
7538 | BUG_ON(ret); /* -ENOMEM */ | 7752 | BUG_ON(ret); /* -ENOMEM */ |
7539 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, | 7753 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, |
7540 | eb->len, flag, | 7754 | eb->len, flag, |
@@ -7581,6 +7795,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7581 | int level = wc->level; | 7795 | int level = wc->level; |
7582 | int reada = 0; | 7796 | int reada = 0; |
7583 | int ret = 0; | 7797 | int ret = 0; |
7798 | bool need_account = false; | ||
7584 | 7799 | ||
7585 | generation = btrfs_node_ptr_generation(path->nodes[level], | 7800 | generation = btrfs_node_ptr_generation(path->nodes[level], |
7586 | path->slots[level]); | 7801 | path->slots[level]); |
@@ -7626,6 +7841,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7626 | 7841 | ||
7627 | if (wc->stage == DROP_REFERENCE) { | 7842 | if (wc->stage == DROP_REFERENCE) { |
7628 | if (wc->refs[level - 1] > 1) { | 7843 | if (wc->refs[level - 1] > 1) { |
7844 | need_account = true; | ||
7629 | if (level == 1 && | 7845 | if (level == 1 && |
7630 | (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF)) | 7846 | (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF)) |
7631 | goto skip; | 7847 | goto skip; |
@@ -7689,6 +7905,16 @@ skip: | |||
7689 | parent = 0; | 7905 | parent = 0; |
7690 | } | 7906 | } |
7691 | 7907 | ||
7908 | if (need_account) { | ||
7909 | ret = account_shared_subtree(trans, root, next, | ||
7910 | generation, level - 1); | ||
7911 | if (ret) { | ||
7912 | printk_ratelimited(KERN_ERR "BTRFS: %s Error " | ||
7913 | "%d accounting shared subtree. Quota " | ||
7914 | "is out of sync, rescan required.\n", | ||
7915 | root->fs_info->sb->s_id, ret); | ||
7916 | } | ||
7917 | } | ||
7692 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, | 7918 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, |
7693 | root->root_key.objectid, level - 1, 0, 0); | 7919 | root->root_key.objectid, level - 1, 0, 0); |
7694 | BUG_ON(ret); /* -ENOMEM */ | 7920 | BUG_ON(ret); /* -ENOMEM */ |
@@ -7769,12 +7995,17 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
7769 | if (wc->refs[level] == 1) { | 7995 | if (wc->refs[level] == 1) { |
7770 | if (level == 0) { | 7996 | if (level == 0) { |
7771 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) | 7997 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) |
7772 | ret = btrfs_dec_ref(trans, root, eb, 1, | 7998 | ret = btrfs_dec_ref(trans, root, eb, 1); |
7773 | wc->for_reloc); | ||
7774 | else | 7999 | else |
7775 | ret = btrfs_dec_ref(trans, root, eb, 0, | 8000 | ret = btrfs_dec_ref(trans, root, eb, 0); |
7776 | wc->for_reloc); | ||
7777 | BUG_ON(ret); /* -ENOMEM */ | 8001 | BUG_ON(ret); /* -ENOMEM */ |
8002 | ret = account_leaf_items(trans, root, eb); | ||
8003 | if (ret) { | ||
8004 | printk_ratelimited(KERN_ERR "BTRFS: %s Error " | ||
8005 | "%d accounting leaf items. Quota " | ||
8006 | "is out of sync, rescan required.\n", | ||
8007 | root->fs_info->sb->s_id, ret); | ||
8008 | } | ||
7778 | } | 8009 | } |
7779 | /* make block locked assertion in clean_tree_block happy */ | 8010 | /* make block locked assertion in clean_tree_block happy */ |
7780 | if (!path->locks[level] && | 8011 | if (!path->locks[level] && |
@@ -7900,6 +8131,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
7900 | int level; | 8131 | int level; |
7901 | bool root_dropped = false; | 8132 | bool root_dropped = false; |
7902 | 8133 | ||
8134 | btrfs_debug(root->fs_info, "Drop subvolume %llu", root->objectid); | ||
8135 | |||
7903 | path = btrfs_alloc_path(); | 8136 | path = btrfs_alloc_path(); |
7904 | if (!path) { | 8137 | if (!path) { |
7905 | err = -ENOMEM; | 8138 | err = -ENOMEM; |
@@ -8025,6 +8258,24 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
8025 | goto out_end_trans; | 8258 | goto out_end_trans; |
8026 | } | 8259 | } |
8027 | 8260 | ||
8261 | /* | ||
8262 | * Qgroup update accounting is run from | ||
8263 | * delayed ref handling. This usually works | ||
8264 | * out because delayed refs are normally the | ||
8265 | * only way qgroup updates are added. However, | ||
8266 | * we may have added updates during our tree | ||
8267 | * walk so run qgroups here to make sure we | ||
8268 | * don't lose any updates. | ||
8269 | */ | ||
8270 | ret = btrfs_delayed_qgroup_accounting(trans, | ||
8271 | root->fs_info); | ||
8272 | if (ret) | ||
8273 | printk_ratelimited(KERN_ERR "BTRFS: Failure %d " | ||
8274 | "running qgroup updates " | ||
8275 | "during snapshot delete. " | ||
8276 | "Quota is out of sync, " | ||
8277 | "rescan required.\n", ret); | ||
8278 | |||
8028 | btrfs_end_transaction_throttle(trans, tree_root); | 8279 | btrfs_end_transaction_throttle(trans, tree_root); |
8029 | if (!for_reloc && btrfs_need_cleaner_sleep(root)) { | 8280 | if (!for_reloc && btrfs_need_cleaner_sleep(root)) { |
8030 | pr_debug("BTRFS: drop snapshot early exit\n"); | 8281 | pr_debug("BTRFS: drop snapshot early exit\n"); |
@@ -8078,6 +8329,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
8078 | } | 8329 | } |
8079 | root_dropped = true; | 8330 | root_dropped = true; |
8080 | out_end_trans: | 8331 | out_end_trans: |
8332 | ret = btrfs_delayed_qgroup_accounting(trans, tree_root->fs_info); | ||
8333 | if (ret) | ||
8334 | printk_ratelimited(KERN_ERR "BTRFS: Failure %d " | ||
8335 | "running qgroup updates " | ||
8336 | "during snapshot delete. " | ||
8337 | "Quota is out of sync, " | ||
8338 | "rescan required.\n", ret); | ||
8339 | |||
8081 | btrfs_end_transaction_throttle(trans, tree_root); | 8340 | btrfs_end_transaction_throttle(trans, tree_root); |
8082 | out_free: | 8341 | out_free: |
8083 | kfree(wc); | 8342 | kfree(wc); |