diff options
Diffstat (limited to 'fs/btrfs/qgroup.c')
-rw-r--r-- | fs/btrfs/qgroup.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index a5c856234323..aee4b1cc3d98 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -23,13 +23,13 @@ | |||
23 | #include <linux/rbtree.h> | 23 | #include <linux/rbtree.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <linux/btrfs.h> | ||
26 | 27 | ||
27 | #include "ctree.h" | 28 | #include "ctree.h" |
28 | #include "transaction.h" | 29 | #include "transaction.h" |
29 | #include "disk-io.h" | 30 | #include "disk-io.h" |
30 | #include "locking.h" | 31 | #include "locking.h" |
31 | #include "ulist.h" | 32 | #include "ulist.h" |
32 | #include "ioctl.h" | ||
33 | #include "backref.h" | 33 | #include "backref.h" |
34 | 34 | ||
35 | /* TODO XXX FIXME | 35 | /* TODO XXX FIXME |
@@ -620,7 +620,9 @@ static int update_qgroup_limit_item(struct btrfs_trans_handle *trans, | |||
620 | key.offset = qgroupid; | 620 | key.offset = qgroupid; |
621 | 621 | ||
622 | path = btrfs_alloc_path(); | 622 | path = btrfs_alloc_path(); |
623 | BUG_ON(!path); | 623 | if (!path) |
624 | return -ENOMEM; | ||
625 | |||
624 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); | 626 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); |
625 | if (ret > 0) | 627 | if (ret > 0) |
626 | ret = -ENOENT; | 628 | ret = -ENOENT; |
@@ -661,7 +663,9 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans, | |||
661 | key.offset = qgroup->qgroupid; | 663 | key.offset = qgroup->qgroupid; |
662 | 664 | ||
663 | path = btrfs_alloc_path(); | 665 | path = btrfs_alloc_path(); |
664 | BUG_ON(!path); | 666 | if (!path) |
667 | return -ENOMEM; | ||
668 | |||
665 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); | 669 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); |
666 | if (ret > 0) | 670 | if (ret > 0) |
667 | ret = -ENOENT; | 671 | ret = -ENOENT; |
@@ -702,7 +706,9 @@ static int update_qgroup_status_item(struct btrfs_trans_handle *trans, | |||
702 | key.offset = 0; | 706 | key.offset = 0; |
703 | 707 | ||
704 | path = btrfs_alloc_path(); | 708 | path = btrfs_alloc_path(); |
705 | BUG_ON(!path); | 709 | if (!path) |
710 | return -ENOMEM; | ||
711 | |||
706 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); | 712 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); |
707 | if (ret > 0) | 713 | if (ret > 0) |
708 | ret = -ENOENT; | 714 | ret = -ENOENT; |
@@ -732,33 +738,38 @@ static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans, | |||
732 | { | 738 | { |
733 | struct btrfs_path *path; | 739 | struct btrfs_path *path; |
734 | struct btrfs_key key; | 740 | struct btrfs_key key; |
741 | struct extent_buffer *leaf = NULL; | ||
735 | int ret; | 742 | int ret; |
736 | 743 | int nr = 0; | |
737 | if (!root) | ||
738 | return -EINVAL; | ||
739 | 744 | ||
740 | path = btrfs_alloc_path(); | 745 | path = btrfs_alloc_path(); |
741 | if (!path) | 746 | if (!path) |
742 | return -ENOMEM; | 747 | return -ENOMEM; |
743 | 748 | ||
744 | while (1) { | 749 | path->leave_spinning = 1; |
745 | key.objectid = 0; | ||
746 | key.offset = 0; | ||
747 | key.type = 0; | ||
748 | 750 | ||
749 | path->leave_spinning = 1; | 751 | key.objectid = 0; |
752 | key.offset = 0; | ||
753 | key.type = 0; | ||
754 | |||
755 | while (1) { | ||
750 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 756 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
751 | if (ret > 0) { | 757 | if (ret < 0) |
752 | if (path->slots[0] == 0) | 758 | goto out; |
753 | break; | 759 | leaf = path->nodes[0]; |
754 | path->slots[0]--; | 760 | nr = btrfs_header_nritems(leaf); |
755 | } else if (ret < 0) { | 761 | if (!nr) |
756 | break; | 762 | break; |
757 | } | 763 | /* |
758 | 764 | * delete the leaf one by one | |
759 | ret = btrfs_del_item(trans, root, path); | 765 | * since the whole tree is going |
766 | * to be deleted. | ||
767 | */ | ||
768 | path->slots[0] = 0; | ||
769 | ret = btrfs_del_items(trans, root, path, 0, nr); | ||
760 | if (ret) | 770 | if (ret) |
761 | goto out; | 771 | goto out; |
772 | |||
762 | btrfs_release_path(path); | 773 | btrfs_release_path(path); |
763 | } | 774 | } |
764 | ret = 0; | 775 | ret = 0; |
@@ -847,6 +858,10 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, | |||
847 | int ret = 0; | 858 | int ret = 0; |
848 | 859 | ||
849 | spin_lock(&fs_info->qgroup_lock); | 860 | spin_lock(&fs_info->qgroup_lock); |
861 | if (!fs_info->quota_root) { | ||
862 | spin_unlock(&fs_info->qgroup_lock); | ||
863 | return 0; | ||
864 | } | ||
850 | fs_info->quota_enabled = 0; | 865 | fs_info->quota_enabled = 0; |
851 | fs_info->pending_quota_state = 0; | 866 | fs_info->pending_quota_state = 0; |
852 | quota_root = fs_info->quota_root; | 867 | quota_root = fs_info->quota_root; |