Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable

* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: fix error message formatting
Btrfs: fix use after free in btrfs_start_workers fail path
Btrfs: honor nodatacow/sum mount options for new files
Btrfs: update backrefs while dropping snapshot
Btrfs: account for space we may use in fallocate
Btrfs: fix the file clone ioctl for preallocated extents
Btrfs: don't log the inode in file_write while growing the file

+428 -198
+1 -1
fs/btrfs/async-thread.c
··· 299 299 "btrfs-%s-%d", workers->name, 300 300 workers->num_workers + i); 301 301 if (IS_ERR(worker->task)) { 302 - kfree(worker); 303 302 ret = PTR_ERR(worker->task); 303 + kfree(worker); 304 304 goto fail; 305 305 } 306 306
+1 -2
fs/btrfs/ctree.h
··· 2074 2074 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 2075 2075 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); 2076 2076 int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); 2077 - int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root 2078 - *root); 2077 + int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref); 2079 2078 int btrfs_drop_subtree(struct btrfs_trans_handle *trans, 2080 2079 struct btrfs_root *root, 2081 2080 struct extent_buffer *node,
+396 -180
fs/btrfs/extent-tree.c
··· 990 990 return type; 991 991 } 992 992 993 - static int find_next_key(struct btrfs_path *path, struct btrfs_key *key) 993 + static int find_next_key(struct btrfs_path *path, int level, 994 + struct btrfs_key *key) 994 995 995 996 { 996 - int level; 997 - BUG_ON(!path->keep_locks); 998 - for (level = 0; level < BTRFS_MAX_LEVEL; level++) { 997 + for (; level < BTRFS_MAX_LEVEL; level++) { 999 998 if (!path->nodes[level]) 1000 999 break; 1001 - btrfs_assert_tree_locked(path->nodes[level]); 1002 1000 if (path->slots[level] + 1 >= 1003 1001 btrfs_header_nritems(path->nodes[level])) 1004 1002 continue; ··· 1156 1158 * For simplicity, we just do not add new inline back 1157 1159 * ref if there is any kind of item for this block 1158 1160 */ 1159 - if (find_next_key(path, &key) == 0 && key.objectid == bytenr && 1161 + if (find_next_key(path, 0, &key) == 0 && 1162 + key.objectid == bytenr && 1160 1163 key.type < BTRFS_BLOCK_GROUP_ITEM_KEY) { 1161 1164 err = -EAGAIN; 1162 1165 goto out; ··· 2696 2697 2697 2698 printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" 2698 2699 ", %llu bytes_used, %llu bytes_reserved, " 2699 - "%llu bytes_pinned, %llu bytes_readonly, %llu may use" 2700 + "%llu bytes_pinned, %llu bytes_readonly, %llu may use " 2700 2701 "%llu total\n", (unsigned long long)bytes, 2701 2702 (unsigned long long)data_sinfo->bytes_delalloc, 2702 2703 (unsigned long long)data_sinfo->bytes_used, ··· 4127 4128 return buf; 4128 4129 } 4129 4130 4131 + #if 0 4130 4132 int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, 4131 4133 struct btrfs_root *root, struct extent_buffer *leaf) 4132 4134 { ··· 4170 4170 } 4171 4171 return 0; 4172 4172 } 4173 - 4174 - #if 0 4175 4173 4176 4174 static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, 4177 4175 struct btrfs_root *root, ··· 4551 4553 } 4552 4554 #endif 4553 4555 4556 + struct walk_control { 4557 + u64 refs[BTRFS_MAX_LEVEL]; 4558 + u64 flags[BTRFS_MAX_LEVEL]; 4559 + struct btrfs_key update_progress; 4560 + int stage; 4561 + int level; 4562 + int shared_level; 4563 + int update_ref; 4564 + int keep_locks; 4565 + }; 4566 + 4567 + #define DROP_REFERENCE 1 4568 + #define UPDATE_BACKREF 2 4569 + 4554 4570 /* 4555 - * helper function for drop_subtree, this function is similar to 4556 - * walk_down_tree. The main difference is that it checks reference 4557 - * counts while tree blocks are locked. 4571 + * hepler to process tree block while walking down the tree. 4572 + * 4573 + * when wc->stage == DROP_REFERENCE, this function checks 4574 + * reference count of the block. if the block is shared and 4575 + * we need update back refs for the subtree rooted at the 4576 + * block, this function changes wc->stage to UPDATE_BACKREF 4577 + * 4578 + * when wc->stage == UPDATE_BACKREF, this function updates 4579 + * back refs for pointers in the block. 4580 + * 4581 + * NOTE: return value 1 means we should stop walking down. 4558 4582 */ 4583 + static noinline int walk_down_proc(struct btrfs_trans_handle *trans, 4584 + struct btrfs_root *root, 4585 + struct btrfs_path *path, 4586 + struct walk_control *wc) 4587 + { 4588 + int level = wc->level; 4589 + struct extent_buffer *eb = path->nodes[level]; 4590 + struct btrfs_key key; 4591 + u64 flag = BTRFS_BLOCK_FLAG_FULL_BACKREF; 4592 + int ret; 4593 + 4594 + if (wc->stage == UPDATE_BACKREF && 4595 + btrfs_header_owner(eb) != root->root_key.objectid) 4596 + return 1; 4597 + 4598 + /* 4599 + * when reference count of tree block is 1, it won't increase 4600 + * again. once full backref flag is set, we never clear it. 4601 + */ 4602 + if ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || 4603 + (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag))) { 4604 + BUG_ON(!path->locks[level]); 4605 + ret = btrfs_lookup_extent_info(trans, root, 4606 + eb->start, eb->len, 4607 + &wc->refs[level], 4608 + &wc->flags[level]); 4609 + BUG_ON(ret); 4610 + BUG_ON(wc->refs[level] == 0); 4611 + } 4612 + 4613 + if (wc->stage == DROP_REFERENCE && 4614 + wc->update_ref && wc->refs[level] > 1) { 4615 + BUG_ON(eb == root->node); 4616 + BUG_ON(path->slots[level] > 0); 4617 + if (level == 0) 4618 + btrfs_item_key_to_cpu(eb, &key, path->slots[level]); 4619 + else 4620 + btrfs_node_key_to_cpu(eb, &key, path->slots[level]); 4621 + if (btrfs_header_owner(eb) == root->root_key.objectid && 4622 + btrfs_comp_cpu_keys(&key, &wc->update_progress) >= 0) { 4623 + wc->stage = UPDATE_BACKREF; 4624 + wc->shared_level = level; 4625 + } 4626 + } 4627 + 4628 + if (wc->stage == DROP_REFERENCE) { 4629 + if (wc->refs[level] > 1) 4630 + return 1; 4631 + 4632 + if (path->locks[level] && !wc->keep_locks) { 4633 + btrfs_tree_unlock(eb); 4634 + path->locks[level] = 0; 4635 + } 4636 + return 0; 4637 + } 4638 + 4639 + /* wc->stage == UPDATE_BACKREF */ 4640 + if (!(wc->flags[level] & flag)) { 4641 + BUG_ON(!path->locks[level]); 4642 + ret = btrfs_inc_ref(trans, root, eb, 1); 4643 + BUG_ON(ret); 4644 + ret = btrfs_dec_ref(trans, root, eb, 0); 4645 + BUG_ON(ret); 4646 + ret = btrfs_set_disk_extent_flags(trans, root, eb->start, 4647 + eb->len, flag, 0); 4648 + BUG_ON(ret); 4649 + wc->flags[level] |= flag; 4650 + } 4651 + 4652 + /* 4653 + * the block is shared by multiple trees, so it's not good to 4654 + * keep the tree lock 4655 + */ 4656 + if (path->locks[level] && level > 0) { 4657 + btrfs_tree_unlock(eb); 4658 + path->locks[level] = 0; 4659 + } 4660 + return 0; 4661 + } 4662 + 4663 + /* 4664 + * hepler to process tree block while walking up the tree. 4665 + * 4666 + * when wc->stage == DROP_REFERENCE, this function drops 4667 + * reference count on the block. 4668 + * 4669 + * when wc->stage == UPDATE_BACKREF, this function changes 4670 + * wc->stage back to DROP_REFERENCE if we changed wc->stage 4671 + * to UPDATE_BACKREF previously while processing the block. 4672 + * 4673 + * NOTE: return value 1 means we should stop walking up. 4674 + */ 4675 + static noinline int walk_up_proc(struct btrfs_trans_handle *trans, 4676 + struct btrfs_root *root, 4677 + struct btrfs_path *path, 4678 + struct walk_control *wc) 4679 + { 4680 + int ret = 0; 4681 + int level = wc->level; 4682 + struct extent_buffer *eb = path->nodes[level]; 4683 + u64 parent = 0; 4684 + 4685 + if (wc->stage == UPDATE_BACKREF) { 4686 + BUG_ON(wc->shared_level < level); 4687 + if (level < wc->shared_level) 4688 + goto out; 4689 + 4690 + BUG_ON(wc->refs[level] <= 1); 4691 + ret = find_next_key(path, level + 1, &wc->update_progress); 4692 + if (ret > 0) 4693 + wc->update_ref = 0; 4694 + 4695 + wc->stage = DROP_REFERENCE; 4696 + wc->shared_level = -1; 4697 + path->slots[level] = 0; 4698 + 4699 + /* 4700 + * check reference count again if the block isn't locked. 4701 + * we should start walking down the tree again if reference 4702 + * count is one. 4703 + */ 4704 + if (!path->locks[level]) { 4705 + BUG_ON(level == 0); 4706 + btrfs_tree_lock(eb); 4707 + btrfs_set_lock_blocking(eb); 4708 + path->locks[level] = 1; 4709 + 4710 + ret = btrfs_lookup_extent_info(trans, root, 4711 + eb->start, eb->len, 4712 + &wc->refs[level], 4713 + &wc->flags[level]); 4714 + BUG_ON(ret); 4715 + BUG_ON(wc->refs[level] == 0); 4716 + if (wc->refs[level] == 1) { 4717 + btrfs_tree_unlock(eb); 4718 + path->locks[level] = 0; 4719 + return 1; 4720 + } 4721 + } else { 4722 + BUG_ON(level != 0); 4723 + } 4724 + } 4725 + 4726 + /* wc->stage == DROP_REFERENCE */ 4727 + BUG_ON(wc->refs[level] > 1 && !path->locks[level]); 4728 + 4729 + if (wc->refs[level] == 1) { 4730 + if (level == 0) { 4731 + if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) 4732 + ret = btrfs_dec_ref(trans, root, eb, 1); 4733 + else 4734 + ret = btrfs_dec_ref(trans, root, eb, 0); 4735 + BUG_ON(ret); 4736 + } 4737 + /* make block locked assertion in clean_tree_block happy */ 4738 + if (!path->locks[level] && 4739 + btrfs_header_generation(eb) == trans->transid) { 4740 + btrfs_tree_lock(eb); 4741 + btrfs_set_lock_blocking(eb); 4742 + path->locks[level] = 1; 4743 + } 4744 + clean_tree_block(trans, root, eb); 4745 + } 4746 + 4747 + if (eb == root->node) { 4748 + if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) 4749 + parent = eb->start; 4750 + else 4751 + BUG_ON(root->root_key.objectid != 4752 + btrfs_header_owner(eb)); 4753 + } else { 4754 + if (wc->flags[level + 1] & BTRFS_BLOCK_FLAG_FULL_BACKREF) 4755 + parent = path->nodes[level + 1]->start; 4756 + else 4757 + BUG_ON(root->root_key.objectid != 4758 + btrfs_header_owner(path->nodes[level + 1])); 4759 + } 4760 + 4761 + ret = btrfs_free_extent(trans, root, eb->start, eb->len, parent, 4762 + root->root_key.objectid, level, 0); 4763 + BUG_ON(ret); 4764 + out: 4765 + wc->refs[level] = 0; 4766 + wc->flags[level] = 0; 4767 + return ret; 4768 + } 4769 + 4559 4770 static noinline int walk_down_tree(struct btrfs_trans_handle *trans, 4560 4771 struct btrfs_root *root, 4561 - struct btrfs_path *path, int *level) 4772 + struct btrfs_path *path, 4773 + struct walk_control *wc) 4562 4774 { 4563 4775 struct extent_buffer *next; 4564 4776 struct extent_buffer *cur; 4565 - struct extent_buffer *parent; 4566 4777 u64 bytenr; 4567 4778 u64 ptr_gen; 4568 - u64 refs; 4569 - u64 flags; 4570 4779 u32 blocksize; 4780 + int level = wc->level; 4571 4781 int ret; 4572 4782 4573 - cur = path->nodes[*level]; 4574 - ret = btrfs_lookup_extent_info(trans, root, cur->start, cur->len, 4575 - &refs, &flags); 4576 - BUG_ON(ret); 4577 - if (refs > 1) 4578 - goto out; 4783 + while (level >= 0) { 4784 + cur = path->nodes[level]; 4785 + BUG_ON(path->slots[level] >= btrfs_header_nritems(cur)); 4579 4786 4580 - BUG_ON(!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)); 4581 - 4582 - while (*level >= 0) { 4583 - cur = path->nodes[*level]; 4584 - if (*level == 0) { 4585 - ret = btrfs_drop_leaf_ref(trans, root, cur); 4586 - BUG_ON(ret); 4587 - clean_tree_block(trans, root, cur); 4787 + ret = walk_down_proc(trans, root, path, wc); 4788 + if (ret > 0) 4588 4789 break; 4589 - } 4590 - if (path->slots[*level] >= btrfs_header_nritems(cur)) { 4591 - clean_tree_block(trans, root, cur); 4592 - break; 4593 - } 4594 4790 4595 - bytenr = btrfs_node_blockptr(cur, path->slots[*level]); 4596 - blocksize = btrfs_level_size(root, *level - 1); 4597 - ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); 4791 + if (level == 0) 4792 + break; 4793 + 4794 + bytenr = btrfs_node_blockptr(cur, path->slots[level]); 4795 + blocksize = btrfs_level_size(root, level - 1); 4796 + ptr_gen = btrfs_node_ptr_generation(cur, path->slots[level]); 4598 4797 4599 4798 next = read_tree_block(root, bytenr, blocksize, ptr_gen); 4600 4799 btrfs_tree_lock(next); 4601 4800 btrfs_set_lock_blocking(next); 4602 4801 4603 - ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, 4604 - &refs, &flags); 4605 - BUG_ON(ret); 4606 - if (refs > 1) { 4607 - parent = path->nodes[*level]; 4608 - ret = btrfs_free_extent(trans, root, bytenr, 4609 - blocksize, parent->start, 4610 - btrfs_header_owner(parent), 4611 - *level - 1, 0); 4612 - BUG_ON(ret); 4613 - path->slots[*level]++; 4614 - btrfs_tree_unlock(next); 4615 - free_extent_buffer(next); 4616 - continue; 4617 - } 4618 - 4619 - BUG_ON(!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)); 4620 - 4621 - *level = btrfs_header_level(next); 4622 - path->nodes[*level] = next; 4623 - path->slots[*level] = 0; 4624 - path->locks[*level] = 1; 4625 - cond_resched(); 4802 + level--; 4803 + BUG_ON(level != btrfs_header_level(next)); 4804 + path->nodes[level] = next; 4805 + path->slots[level] = 0; 4806 + path->locks[level] = 1; 4807 + wc->level = level; 4626 4808 } 4627 - out: 4628 - if (path->nodes[*level] == root->node) 4629 - parent = path->nodes[*level]; 4630 - else 4631 - parent = path->nodes[*level + 1]; 4632 - bytenr = path->nodes[*level]->start; 4633 - blocksize = path->nodes[*level]->len; 4634 - 4635 - ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent->start, 4636 - btrfs_header_owner(parent), *level, 0); 4637 - BUG_ON(ret); 4638 - 4639 - if (path->locks[*level]) { 4640 - btrfs_tree_unlock(path->nodes[*level]); 4641 - path->locks[*level] = 0; 4642 - } 4643 - free_extent_buffer(path->nodes[*level]); 4644 - path->nodes[*level] = NULL; 4645 - *level += 1; 4646 - cond_resched(); 4647 4809 return 0; 4648 4810 } 4649 4811 4650 - /* 4651 - * helper for dropping snapshots. This walks back up the tree in the path 4652 - * to find the first node higher up where we haven't yet gone through 4653 - * all the slots 4654 - */ 4655 4812 static noinline int walk_up_tree(struct btrfs_trans_handle *trans, 4656 4813 struct btrfs_root *root, 4657 4814 struct btrfs_path *path, 4658 - int *level, int max_level) 4815 + struct walk_control *wc, int max_level) 4659 4816 { 4660 - struct btrfs_root_item *root_item = &root->root_item; 4661 - int i; 4662 - int slot; 4817 + int level = wc->level; 4663 4818 int ret; 4664 4819 4665 - for (i = *level; i < max_level && path->nodes[i]; i++) { 4666 - slot = path->slots[i]; 4667 - if (slot + 1 < btrfs_header_nritems(path->nodes[i])) { 4668 - /* 4669 - * there is more work to do in this level. 4670 - * Update the drop_progress marker to reflect 4671 - * the work we've done so far, and then bump 4672 - * the slot number 4673 - */ 4674 - path->slots[i]++; 4675 - WARN_ON(*level == 0); 4676 - if (max_level == BTRFS_MAX_LEVEL) { 4677 - btrfs_node_key(path->nodes[i], 4678 - &root_item->drop_progress, 4679 - path->slots[i]); 4680 - root_item->drop_level = i; 4681 - } 4682 - *level = i; 4820 + path->slots[level] = btrfs_header_nritems(path->nodes[level]); 4821 + while (level < max_level && path->nodes[level]) { 4822 + wc->level = level; 4823 + if (path->slots[level] + 1 < 4824 + btrfs_header_nritems(path->nodes[level])) { 4825 + path->slots[level]++; 4683 4826 return 0; 4684 4827 } else { 4685 - struct extent_buffer *parent; 4828 + ret = walk_up_proc(trans, root, path, wc); 4829 + if (ret > 0) 4830 + return 0; 4686 4831 4687 - /* 4688 - * this whole node is done, free our reference 4689 - * on it and go up one level 4690 - */ 4691 - if (path->nodes[*level] == root->node) 4692 - parent = path->nodes[*level]; 4693 - else 4694 - parent = path->nodes[*level + 1]; 4695 - 4696 - clean_tree_block(trans, root, path->nodes[i]); 4697 - ret = btrfs_free_extent(trans, root, 4698 - path->nodes[i]->start, 4699 - path->nodes[i]->len, 4700 - parent->start, 4701 - btrfs_header_owner(parent), 4702 - *level, 0); 4703 - BUG_ON(ret); 4704 - if (path->locks[*level]) { 4705 - btrfs_tree_unlock(path->nodes[i]); 4706 - path->locks[i] = 0; 4832 + if (path->locks[level]) { 4833 + btrfs_tree_unlock(path->nodes[level]); 4834 + path->locks[level] = 0; 4707 4835 } 4708 - free_extent_buffer(path->nodes[i]); 4709 - path->nodes[i] = NULL; 4710 - *level = i + 1; 4836 + free_extent_buffer(path->nodes[level]); 4837 + path->nodes[level] = NULL; 4838 + level++; 4711 4839 } 4712 4840 } 4713 4841 return 1; 4714 4842 } 4715 4843 4716 4844 /* 4717 - * drop the reference count on the tree rooted at 'snap'. This traverses 4718 - * the tree freeing any blocks that have a ref count of zero after being 4719 - * decremented. 4845 + * drop a subvolume tree. 4846 + * 4847 + * this function traverses the tree freeing any blocks that only 4848 + * referenced by the tree. 4849 + * 4850 + * when a shared tree block is found. this function decreases its 4851 + * reference count by one. if update_ref is true, this function 4852 + * also make sure backrefs for the shared block and all lower level 4853 + * blocks are properly updated. 4720 4854 */ 4721 - int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root 4722 - *root) 4855 + int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) 4723 4856 { 4724 - int ret = 0; 4725 - int wret; 4726 - int level; 4727 4857 struct btrfs_path *path; 4728 - int update_count; 4858 + struct btrfs_trans_handle *trans; 4859 + struct btrfs_root *tree_root = root->fs_info->tree_root; 4729 4860 struct btrfs_root_item *root_item = &root->root_item; 4861 + struct walk_control *wc; 4862 + struct btrfs_key key; 4863 + int err = 0; 4864 + int ret; 4865 + int level; 4730 4866 4731 4867 path = btrfs_alloc_path(); 4732 4868 BUG_ON(!path); 4733 4869 4734 - level = btrfs_header_level(root->node); 4870 + wc = kzalloc(sizeof(*wc), GFP_NOFS); 4871 + BUG_ON(!wc); 4872 + 4873 + trans = btrfs_start_transaction(tree_root, 1); 4874 + 4735 4875 if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { 4876 + level = btrfs_header_level(root->node); 4736 4877 path->nodes[level] = btrfs_lock_root_node(root); 4737 4878 btrfs_set_lock_blocking(path->nodes[level]); 4738 4879 path->slots[level] = 0; 4739 4880 path->locks[level] = 1; 4881 + memset(&wc->update_progress, 0, 4882 + sizeof(wc->update_progress)); 4740 4883 } else { 4741 - struct btrfs_key key; 4742 - struct btrfs_disk_key found_key; 4743 - struct extent_buffer *node; 4744 - 4745 4884 btrfs_disk_key_to_cpu(&key, &root_item->drop_progress); 4885 + memcpy(&wc->update_progress, &key, 4886 + sizeof(wc->update_progress)); 4887 + 4746 4888 level = root_item->drop_level; 4889 + BUG_ON(level == 0); 4747 4890 path->lowest_level = level; 4748 - wret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 4749 - if (wret < 0) { 4750 - ret = wret; 4891 + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 4892 + path->lowest_level = 0; 4893 + if (ret < 0) { 4894 + err = ret; 4751 4895 goto out; 4752 4896 } 4753 - node = path->nodes[level]; 4754 - btrfs_node_key(node, &found_key, path->slots[level]); 4755 - WARN_ON(memcmp(&found_key, &root_item->drop_progress, 4756 - sizeof(found_key))); 4897 + btrfs_node_key_to_cpu(path->nodes[level], &key, 4898 + path->slots[level]); 4899 + WARN_ON(memcmp(&key, &wc->update_progress, sizeof(key))); 4900 + 4757 4901 /* 4758 4902 * unlock our path, this is safe because only this 4759 4903 * function is allowed to delete this snapshot 4760 4904 */ 4761 4905 btrfs_unlock_up_safe(path, 0); 4762 - } 4763 - while (1) { 4764 - unsigned long update; 4765 - wret = walk_down_tree(trans, root, path, &level); 4766 - if (wret > 0) 4767 - break; 4768 - if (wret < 0) 4769 - ret = wret; 4770 4906 4771 - wret = walk_up_tree(trans, root, path, &level, 4772 - BTRFS_MAX_LEVEL); 4773 - if (wret > 0) 4774 - break; 4775 - if (wret < 0) 4776 - ret = wret; 4777 - if (trans->transaction->in_commit || 4778 - trans->transaction->delayed_refs.flushing) { 4779 - ret = -EAGAIN; 4907 + level = btrfs_header_level(root->node); 4908 + while (1) { 4909 + btrfs_tree_lock(path->nodes[level]); 4910 + btrfs_set_lock_blocking(path->nodes[level]); 4911 + 4912 + ret = btrfs_lookup_extent_info(trans, root, 4913 + path->nodes[level]->start, 4914 + path->nodes[level]->len, 4915 + &wc->refs[level], 4916 + &wc->flags[level]); 4917 + BUG_ON(ret); 4918 + BUG_ON(wc->refs[level] == 0); 4919 + 4920 + if (level == root_item->drop_level) 4921 + break; 4922 + 4923 + btrfs_tree_unlock(path->nodes[level]); 4924 + WARN_ON(wc->refs[level] != 1); 4925 + level--; 4926 + } 4927 + } 4928 + 4929 + wc->level = level; 4930 + wc->shared_level = -1; 4931 + wc->stage = DROP_REFERENCE; 4932 + wc->update_ref = update_ref; 4933 + wc->keep_locks = 0; 4934 + 4935 + while (1) { 4936 + ret = walk_down_tree(trans, root, path, wc); 4937 + if (ret < 0) { 4938 + err = ret; 4780 4939 break; 4781 4940 } 4782 - for (update_count = 0; update_count < 16; update_count++) { 4941 + 4942 + ret = walk_up_tree(trans, root, path, wc, BTRFS_MAX_LEVEL); 4943 + if (ret < 0) { 4944 + err = ret; 4945 + break; 4946 + } 4947 + 4948 + if (ret > 0) { 4949 + BUG_ON(wc->stage != DROP_REFERENCE); 4950 + break; 4951 + } 4952 + 4953 + if (wc->stage == DROP_REFERENCE) { 4954 + level = wc->level; 4955 + btrfs_node_key(path->nodes[level], 4956 + &root_item->drop_progress, 4957 + path->slots[level]); 4958 + root_item->drop_level = level; 4959 + } 4960 + 4961 + BUG_ON(wc->level == 0); 4962 + if (trans->transaction->in_commit || 4963 + trans->transaction->delayed_refs.flushing) { 4964 + ret = btrfs_update_root(trans, tree_root, 4965 + &root->root_key, 4966 + root_item); 4967 + BUG_ON(ret); 4968 + 4969 + btrfs_end_transaction(trans, tree_root); 4970 + trans = btrfs_start_transaction(tree_root, 1); 4971 + } else { 4972 + unsigned long update; 4783 4973 update = trans->delayed_ref_updates; 4784 4974 trans->delayed_ref_updates = 0; 4785 4975 if (update) 4786 - btrfs_run_delayed_refs(trans, root, update); 4787 - else 4788 - break; 4976 + btrfs_run_delayed_refs(trans, tree_root, 4977 + update); 4789 4978 } 4790 4979 } 4980 + btrfs_release_path(root, path); 4981 + BUG_ON(err); 4982 + 4983 + ret = btrfs_del_root(trans, tree_root, &root->root_key); 4984 + BUG_ON(ret); 4985 + 4986 + free_extent_buffer(root->node); 4987 + free_extent_buffer(root->commit_root); 4988 + kfree(root); 4791 4989 out: 4990 + btrfs_end_transaction(trans, tree_root); 4991 + kfree(wc); 4792 4992 btrfs_free_path(path); 4793 - return ret; 4993 + return err; 4794 4994 } 4795 4995 4996 + /* 4997 + * drop subtree rooted at tree block 'node'. 4998 + * 4999 + * NOTE: this function will unlock and release tree block 'node' 5000 + */ 4796 5001 int btrfs_drop_subtree(struct btrfs_trans_handle *trans, 4797 5002 struct btrfs_root *root, 4798 5003 struct extent_buffer *node, 4799 5004 struct extent_buffer *parent) 4800 5005 { 4801 5006 struct btrfs_path *path; 5007 + struct walk_control *wc; 4802 5008 int level; 4803 5009 int parent_level; 4804 5010 int ret = 0; 4805 5011 int wret; 4806 5012 5013 + BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); 5014 + 4807 5015 path = btrfs_alloc_path(); 4808 5016 BUG_ON(!path); 5017 + 5018 + wc = kzalloc(sizeof(*wc), GFP_NOFS); 5019 + BUG_ON(!wc); 4809 5020 4810 5021 btrfs_assert_tree_locked(parent); 4811 5022 parent_level = btrfs_header_level(parent); ··· 5024 4817 5025 4818 btrfs_assert_tree_locked(node); 5026 4819 level = btrfs_header_level(node); 5027 - extent_buffer_get(node); 5028 4820 path->nodes[level] = node; 5029 4821 path->slots[level] = 0; 4822 + path->locks[level] = 1; 4823 + 4824 + wc->refs[parent_level] = 1; 4825 + wc->flags[parent_level] = BTRFS_BLOCK_FLAG_FULL_BACKREF; 4826 + wc->level = level; 4827 + wc->shared_level = -1; 4828 + wc->stage = DROP_REFERENCE; 4829 + wc->update_ref = 0; 4830 + wc->keep_locks = 1; 5030 4831 5031 4832 while (1) { 5032 - wret = walk_down_tree(trans, root, path, &level); 5033 - if (wret < 0) 4833 + wret = walk_down_tree(trans, root, path, wc); 4834 + if (wret < 0) { 5034 4835 ret = wret; 5035 - if (wret != 0) 5036 4836 break; 4837 + } 5037 4838 5038 - wret = walk_up_tree(trans, root, path, &level, parent_level); 4839 + wret = walk_up_tree(trans, root, path, wc, parent_level); 5039 4840 if (wret < 0) 5040 4841 ret = wret; 5041 4842 if (wret != 0) 5042 4843 break; 5043 4844 } 5044 4845 4846 + kfree(wc); 5045 4847 btrfs_free_path(path); 5046 4848 return ret; 5047 4849 }
+4 -1
fs/btrfs/file.c
··· 151 151 } 152 152 if (end_pos > isize) { 153 153 i_size_write(inode, end_pos); 154 - btrfs_update_inode(trans, root, inode); 154 + /* we've only changed i_size in ram, and we haven't updated 155 + * the disk i_size. There is no need to log the inode 156 + * at this time. 157 + */ 155 158 } 156 159 err = btrfs_end_transaction(trans, root); 157 160 out_unlock:
+18 -7
fs/btrfs/inode.c
··· 3580 3580 owner = 1; 3581 3581 BTRFS_I(inode)->block_group = 3582 3582 btrfs_find_block_group(root, 0, alloc_hint, owner); 3583 - if ((mode & S_IFREG)) { 3584 - if (btrfs_test_opt(root, NODATASUM)) 3585 - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; 3586 - if (btrfs_test_opt(root, NODATACOW)) 3587 - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; 3588 - } 3589 3583 3590 3584 key[0].objectid = objectid; 3591 3585 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); ··· 3633 3639 btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); 3634 3640 3635 3641 btrfs_inherit_iflags(inode, dir); 3642 + 3643 + if ((mode & S_IFREG)) { 3644 + if (btrfs_test_opt(root, NODATASUM)) 3645 + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; 3646 + if (btrfs_test_opt(root, NODATACOW)) 3647 + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; 3648 + } 3636 3649 3637 3650 insert_inode_hash(inode); 3638 3651 inode_tree_add(inode); ··· 5083 5082 u64 mask = BTRFS_I(inode)->root->sectorsize - 1; 5084 5083 struct extent_map *em; 5085 5084 struct btrfs_trans_handle *trans; 5085 + struct btrfs_root *root; 5086 5086 int ret; 5087 5087 5088 5088 alloc_start = offset & ~mask; ··· 5102 5100 goto out; 5103 5101 } 5104 5102 5103 + root = BTRFS_I(inode)->root; 5104 + 5105 + ret = btrfs_check_data_free_space(root, inode, 5106 + alloc_end - alloc_start); 5107 + if (ret) 5108 + goto out; 5109 + 5105 5110 locked_end = alloc_end - 1; 5106 5111 while (1) { 5107 5112 struct btrfs_ordered_extent *ordered; ··· 5116 5107 trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1); 5117 5108 if (!trans) { 5118 5109 ret = -EIO; 5119 - goto out; 5110 + goto out_free; 5120 5111 } 5121 5112 5122 5113 /* the extent lock is ordered inside the running ··· 5177 5168 GFP_NOFS); 5178 5169 5179 5170 btrfs_end_transaction(trans, BTRFS_I(inode)->root); 5171 + out_free: 5172 + btrfs_free_reserved_data_space(root, inode, alloc_end - alloc_start); 5180 5173 out: 5181 5174 mutex_unlock(&inode->i_mutex); 5182 5175 return ret;
+4 -2
fs/btrfs/ioctl.c
··· 1028 1028 struct btrfs_file_extent_item); 1029 1029 comp = btrfs_file_extent_compression(leaf, extent); 1030 1030 type = btrfs_file_extent_type(leaf, extent); 1031 - if (type == BTRFS_FILE_EXTENT_REG) { 1031 + if (type == BTRFS_FILE_EXTENT_REG || 1032 + type == BTRFS_FILE_EXTENT_PREALLOC) { 1032 1033 disko = btrfs_file_extent_disk_bytenr(leaf, 1033 1034 extent); 1034 1035 diskl = btrfs_file_extent_disk_num_bytes(leaf, ··· 1052 1051 new_key.objectid = inode->i_ino; 1053 1052 new_key.offset = key.offset + destoff - off; 1054 1053 1055 - if (type == BTRFS_FILE_EXTENT_REG) { 1054 + if (type == BTRFS_FILE_EXTENT_REG || 1055 + type == BTRFS_FILE_EXTENT_PREALLOC) { 1056 1056 ret = btrfs_insert_empty_item(trans, root, path, 1057 1057 &new_key, size); 1058 1058 if (ret)
+1 -4
fs/btrfs/relocation.c
··· 1788 1788 btrfs_end_transaction(trans, root); 1789 1789 } 1790 1790 1791 - btrfs_drop_dead_root(reloc_root); 1791 + btrfs_drop_snapshot(reloc_root, 0); 1792 1792 1793 1793 if (atomic_dec_and_test(async->num_pending)) 1794 1794 complete(async->done); ··· 2075 2075 2076 2076 ret = btrfs_drop_subtree(trans, root, eb, upper->eb); 2077 2077 BUG_ON(ret); 2078 - 2079 - btrfs_tree_unlock(eb); 2080 - free_extent_buffer(eb); 2081 2078 } 2082 2079 if (!lowest) { 2083 2080 btrfs_tree_unlock(upper->eb);
+3 -1
fs/btrfs/transaction.c
··· 593 593 return 0; 594 594 } 595 595 596 + #if 0 596 597 /* 597 598 * when dropping snapshots, we generate a ton of delayed refs, and it makes 598 599 * sense not to join the transaction while it is trying to flush the current ··· 682 681 btrfs_btree_balance_dirty(tree_root, nr); 683 682 return ret; 684 683 } 684 + #endif 685 685 686 686 /* 687 687 * new snapshots need to be created at a very specific time in the ··· 1083 1081 while (!list_empty(&list)) { 1084 1082 root = list_entry(list.next, struct btrfs_root, root_list); 1085 1083 list_del_init(&root->root_list); 1086 - btrfs_drop_dead_root(root); 1084 + btrfs_drop_snapshot(root, 0); 1087 1085 } 1088 1086 return 0; 1089 1087 }