aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2013-04-25 12:04:51 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:55:19 -0400
commit2f2320360b0c35b86938bfc561124474f0dac6e4 (patch)
treef7b1cbec89d9c6d030f15817e77ee42e5941244a
parent46b665ceb1edd2ac149ff701313c115f52dc0348 (diff)
Btrfs: rescan for qgroups
If qgroup tracking is out of sync, a rescan operation can be started. It iterates the complete extent tree and recalculates all qgroup tracking data. This is an expensive operation and should not be used unless required. A filesystem under rescan can still be umounted. The rescan continues on the next mount. Status information is provided with a separate ioctl while a rescan operation is in progress. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/ctree.h17
-rw-r--r--fs/btrfs/disk-io.c5
-rw-r--r--fs/btrfs/ioctl.c83
-rw-r--r--fs/btrfs/qgroup.c318
-rw-r--r--include/uapi/linux/btrfs.h12
5 files changed, 400 insertions, 35 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2c48f52aba40..d9bed5fd3347 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1021,9 +1021,9 @@ struct btrfs_block_group_item {
1021 */ 1021 */
1022#define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) 1022#define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0)
1023/* 1023/*
1024 * SCANNING is set during the initialization phase 1024 * RESCAN is set during the initialization phase
1025 */ 1025 */
1026#define BTRFS_QGROUP_STATUS_FLAG_SCANNING (1ULL << 1) 1026#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1)
1027/* 1027/*
1028 * Some qgroup entries are known to be out of date, 1028 * Some qgroup entries are known to be out of date,
1029 * either because the configuration has changed in a way that 1029 * either because the configuration has changed in a way that
@@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item {
1052 * only used during scanning to record the progress 1052 * only used during scanning to record the progress
1053 * of the scan. It contains a logical address 1053 * of the scan. It contains a logical address
1054 */ 1054 */
1055 __le64 scan; 1055 __le64 rescan;
1056} __attribute__ ((__packed__)); 1056} __attribute__ ((__packed__));
1057 1057
1058struct btrfs_qgroup_info_item { 1058struct btrfs_qgroup_info_item {
@@ -1603,6 +1603,11 @@ struct btrfs_fs_info {
1603 /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ 1603 /* used by btrfs_qgroup_record_ref for an efficient tree traversal */
1604 u64 qgroup_seq; 1604 u64 qgroup_seq;
1605 1605
1606 /* qgroup rescan items */
1607 struct mutex qgroup_rescan_lock; /* protects the progress item */
1608 struct btrfs_key qgroup_rescan_progress;
1609 struct btrfs_workers qgroup_rescan_workers;
1610
1606 /* filesystem state */ 1611 /* filesystem state */
1607 unsigned long fs_state; 1612 unsigned long fs_state;
1608 1613
@@ -2886,8 +2891,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct btrfs_qgroup_status_item,
2886 version, 64); 2891 version, 64);
2887BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, 2892BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item,
2888 flags, 64); 2893 flags, 64);
2889BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, 2894BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item,
2890 scan, 64); 2895 rescan, 64);
2891 2896
2892/* btrfs_qgroup_info_item */ 2897/* btrfs_qgroup_info_item */
2893BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, 2898BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,
@@ -3828,7 +3833,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
3828 struct btrfs_fs_info *fs_info); 3833 struct btrfs_fs_info *fs_info);
3829int btrfs_quota_disable(struct btrfs_trans_handle *trans, 3834int btrfs_quota_disable(struct btrfs_trans_handle *trans,
3830 struct btrfs_fs_info *fs_info); 3835 struct btrfs_fs_info *fs_info);
3831int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); 3836int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info);
3832int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, 3837int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
3833 struct btrfs_fs_info *fs_info, u64 src, u64 dst); 3838 struct btrfs_fs_info *fs_info, u64 src, u64 dst);
3834int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, 3839int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 92c44ed78de1..d96305e5cc93 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1976,6 +1976,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info)
1976 btrfs_stop_workers(&fs_info->caching_workers); 1976 btrfs_stop_workers(&fs_info->caching_workers);
1977 btrfs_stop_workers(&fs_info->readahead_workers); 1977 btrfs_stop_workers(&fs_info->readahead_workers);
1978 btrfs_stop_workers(&fs_info->flush_workers); 1978 btrfs_stop_workers(&fs_info->flush_workers);
1979 btrfs_stop_workers(&fs_info->qgroup_rescan_workers);
1979} 1980}
1980 1981
1981/* helper to cleanup tree roots */ 1982/* helper to cleanup tree roots */
@@ -2267,6 +2268,7 @@ int open_ctree(struct super_block *sb,
2267 fs_info->qgroup_seq = 1; 2268 fs_info->qgroup_seq = 1;
2268 fs_info->quota_enabled = 0; 2269 fs_info->quota_enabled = 0;
2269 fs_info->pending_quota_state = 0; 2270 fs_info->pending_quota_state = 0;
2271 mutex_init(&fs_info->qgroup_rescan_lock);
2270 2272
2271 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); 2273 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
2272 btrfs_init_free_cluster(&fs_info->data_alloc_cluster); 2274 btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
@@ -2476,6 +2478,8 @@ int open_ctree(struct super_block *sb,
2476 btrfs_init_workers(&fs_info->readahead_workers, "readahead", 2478 btrfs_init_workers(&fs_info->readahead_workers, "readahead",
2477 fs_info->thread_pool_size, 2479 fs_info->thread_pool_size,
2478 &fs_info->generic_worker); 2480 &fs_info->generic_worker);
2481 btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1,
2482 &fs_info->generic_worker);
2479 2483
2480 /* 2484 /*
2481 * endios are largely parallel and should have a very 2485 * endios are largely parallel and should have a very
@@ -2510,6 +2514,7 @@ int open_ctree(struct super_block *sb,
2510 ret |= btrfs_start_workers(&fs_info->caching_workers); 2514 ret |= btrfs_start_workers(&fs_info->caching_workers);
2511 ret |= btrfs_start_workers(&fs_info->readahead_workers); 2515 ret |= btrfs_start_workers(&fs_info->readahead_workers);
2512 ret |= btrfs_start_workers(&fs_info->flush_workers); 2516 ret |= btrfs_start_workers(&fs_info->flush_workers);
2517 ret |= btrfs_start_workers(&fs_info->qgroup_rescan_workers);
2513 if (ret) { 2518 if (ret) {
2514 err = -ENOMEM; 2519 err = -ENOMEM;
2515 goto fail_sb_buffer; 2520 goto fail_sb_buffer;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a74edc797531..f5f6af338b53 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3701,12 +3701,10 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg)
3701 } 3701 }
3702 3702
3703 down_write(&root->fs_info->subvol_sem); 3703 down_write(&root->fs_info->subvol_sem);
3704 if (sa->cmd != BTRFS_QUOTA_CTL_RESCAN) { 3704 trans = btrfs_start_transaction(root->fs_info->tree_root, 2);
3705 trans = btrfs_start_transaction(root->fs_info->tree_root, 2); 3705 if (IS_ERR(trans)) {
3706 if (IS_ERR(trans)) { 3706 ret = PTR_ERR(trans);
3707 ret = PTR_ERR(trans); 3707 goto out;
3708 goto out;
3709 }
3710 } 3708 }
3711 3709
3712 switch (sa->cmd) { 3710 switch (sa->cmd) {
@@ -3716,9 +3714,6 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg)
3716 case BTRFS_QUOTA_CTL_DISABLE: 3714 case BTRFS_QUOTA_CTL_DISABLE:
3717 ret = btrfs_quota_disable(trans, root->fs_info); 3715 ret = btrfs_quota_disable(trans, root->fs_info);
3718 break; 3716 break;
3719 case BTRFS_QUOTA_CTL_RESCAN:
3720 ret = btrfs_quota_rescan(root->fs_info);
3721 break;
3722 default: 3717 default:
3723 ret = -EINVAL; 3718 ret = -EINVAL;
3724 break; 3719 break;
@@ -3727,11 +3722,9 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg)
3727 if (copy_to_user(arg, sa, sizeof(*sa))) 3722 if (copy_to_user(arg, sa, sizeof(*sa)))
3728 ret = -EFAULT; 3723 ret = -EFAULT;
3729 3724
3730 if (trans) { 3725 err = btrfs_commit_transaction(trans, root->fs_info->tree_root);
3731 err = btrfs_commit_transaction(trans, root->fs_info->tree_root); 3726 if (err && !ret)
3732 if (err && !ret) 3727 ret = err;
3733 ret = err;
3734 }
3735out: 3728out:
3736 kfree(sa); 3729 kfree(sa);
3737 up_write(&root->fs_info->subvol_sem); 3730 up_write(&root->fs_info->subvol_sem);
@@ -3886,6 +3879,64 @@ drop_write:
3886 return ret; 3879 return ret;
3887} 3880}
3888 3881
3882static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg)
3883{
3884 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
3885 struct btrfs_ioctl_quota_rescan_args *qsa;
3886 int ret;
3887
3888 if (!capable(CAP_SYS_ADMIN))
3889 return -EPERM;
3890
3891 ret = mnt_want_write_file(file);
3892 if (ret)
3893 return ret;
3894
3895 qsa = memdup_user(arg, sizeof(*qsa));
3896 if (IS_ERR(qsa)) {
3897 ret = PTR_ERR(qsa);
3898 goto drop_write;
3899 }
3900
3901 if (qsa->flags) {
3902 ret = -EINVAL;
3903 goto out;
3904 }
3905
3906 ret = btrfs_qgroup_rescan(root->fs_info);
3907
3908out:
3909 kfree(qsa);
3910drop_write:
3911 mnt_drop_write_file(file);
3912 return ret;
3913}
3914
3915static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg)
3916{
3917 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
3918 struct btrfs_ioctl_quota_rescan_args *qsa;
3919 int ret = 0;
3920
3921 if (!capable(CAP_SYS_ADMIN))
3922 return -EPERM;
3923
3924 qsa = kzalloc(sizeof(*qsa), GFP_NOFS);
3925 if (!qsa)
3926 return -ENOMEM;
3927
3928 if (root->fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
3929 qsa->flags = 1;
3930 qsa->progress = root->fs_info->qgroup_rescan_progress.objectid;
3931 }
3932
3933 if (copy_to_user(arg, qsa, sizeof(*qsa)))
3934 ret = -EFAULT;
3935
3936 kfree(qsa);
3937 return ret;
3938}
3939
3889static long btrfs_ioctl_set_received_subvol(struct file *file, 3940static long btrfs_ioctl_set_received_subvol(struct file *file,
3890 void __user *arg) 3941 void __user *arg)
3891{ 3942{
@@ -4124,6 +4175,10 @@ long btrfs_ioctl(struct file *file, unsigned int
4124 return btrfs_ioctl_qgroup_create(file, argp); 4175 return btrfs_ioctl_qgroup_create(file, argp);
4125 case BTRFS_IOC_QGROUP_LIMIT: 4176 case BTRFS_IOC_QGROUP_LIMIT:
4126 return btrfs_ioctl_qgroup_limit(file, argp); 4177 return btrfs_ioctl_qgroup_limit(file, argp);
4178 case BTRFS_IOC_QUOTA_RESCAN:
4179 return btrfs_ioctl_quota_rescan(file, argp);
4180 case BTRFS_IOC_QUOTA_RESCAN_STATUS:
4181 return btrfs_ioctl_quota_rescan_status(file, argp);
4127 case BTRFS_IOC_DEV_REPLACE: 4182 case BTRFS_IOC_DEV_REPLACE:
4128 return btrfs_ioctl_dev_replace(root, argp); 4183 return btrfs_ioctl_dev_replace(root, argp);
4129 case BTRFS_IOC_GET_FSLABEL: 4184 case BTRFS_IOC_GET_FSLABEL:
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 1fb7d8da3084..da8458357b57 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -31,13 +31,13 @@
31#include "locking.h" 31#include "locking.h"
32#include "ulist.h" 32#include "ulist.h"
33#include "backref.h" 33#include "backref.h"
34#include "extent_io.h"
34 35
35/* TODO XXX FIXME 36/* TODO XXX FIXME
36 * - subvol delete -> delete when ref goes to 0? delete limits also? 37 * - subvol delete -> delete when ref goes to 0? delete limits also?
37 * - reorganize keys 38 * - reorganize keys
38 * - compressed 39 * - compressed
39 * - sync 40 * - sync
40 * - rescan
41 * - copy also limits on subvol creation 41 * - copy also limits on subvol creation
42 * - limit 42 * - limit
43 * - caches fuer ulists 43 * - caches fuer ulists
@@ -98,6 +98,14 @@ struct btrfs_qgroup_list {
98 struct btrfs_qgroup *member; 98 struct btrfs_qgroup *member;
99}; 99};
100 100
101struct qgroup_rescan {
102 struct btrfs_work work;
103 struct btrfs_fs_info *fs_info;
104};
105
106static void qgroup_rescan_start(struct btrfs_fs_info *fs_info,
107 struct qgroup_rescan *qscan);
108
101/* must be called with qgroup_ioctl_lock held */ 109/* must be called with qgroup_ioctl_lock held */
102static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info, 110static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
103 u64 qgroupid) 111 u64 qgroupid)
@@ -298,7 +306,20 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
298 } 306 }
299 fs_info->qgroup_flags = btrfs_qgroup_status_flags(l, 307 fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
300 ptr); 308 ptr);
301 /* FIXME read scan element */ 309 fs_info->qgroup_rescan_progress.objectid =
310 btrfs_qgroup_status_rescan(l, ptr);
311 if (fs_info->qgroup_flags &
312 BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
313 struct qgroup_rescan *qscan =
314 kmalloc(sizeof(*qscan), GFP_NOFS);
315 if (!qscan) {
316 ret = -ENOMEM;
317 goto out;
318 }
319 fs_info->qgroup_rescan_progress.type = 0;
320 fs_info->qgroup_rescan_progress.offset = 0;
321 qgroup_rescan_start(fs_info, qscan);
322 }
302 goto next1; 323 goto next1;
303 } 324 }
304 325
@@ -719,7 +740,8 @@ static int update_qgroup_status_item(struct btrfs_trans_handle *trans,
719 ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item); 740 ptr = btrfs_item_ptr(l, slot, struct btrfs_qgroup_status_item);
720 btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags); 741 btrfs_set_qgroup_status_flags(l, ptr, fs_info->qgroup_flags);
721 btrfs_set_qgroup_status_generation(l, ptr, trans->transid); 742 btrfs_set_qgroup_status_generation(l, ptr, trans->transid);
722 /* XXX scan */ 743 btrfs_set_qgroup_status_rescan(l, ptr,
744 fs_info->qgroup_rescan_progress.objectid);
723 745
724 btrfs_mark_buffer_dirty(l); 746 btrfs_mark_buffer_dirty(l);
725 747
@@ -830,7 +852,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
830 fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON | 852 fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
831 BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; 853 BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
832 btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags); 854 btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags);
833 btrfs_set_qgroup_status_scan(leaf, ptr, 0); 855 btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
834 856
835 btrfs_mark_buffer_dirty(leaf); 857 btrfs_mark_buffer_dirty(leaf);
836 858
@@ -944,10 +966,11 @@ out:
944 return ret; 966 return ret;
945} 967}
946 968
947int btrfs_quota_rescan(struct btrfs_fs_info *fs_info) 969static void qgroup_dirty(struct btrfs_fs_info *fs_info,
970 struct btrfs_qgroup *qgroup)
948{ 971{
949 /* FIXME */ 972 if (list_empty(&qgroup->dirty))
950 return 0; 973 list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
951} 974}
952 975
953int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, 976int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
@@ -1155,13 +1178,6 @@ out:
1155 return ret; 1178 return ret;
1156} 1179}
1157 1180
1158static void qgroup_dirty(struct btrfs_fs_info *fs_info,
1159 struct btrfs_qgroup *qgroup)
1160{
1161 if (list_empty(&qgroup->dirty))
1162 list_add(&qgroup->dirty, &fs_info->dirty_qgroups);
1163}
1164
1165/* 1181/*
1166 * btrfs_qgroup_record_ref is called when the ref is added or deleted. it puts 1182 * btrfs_qgroup_record_ref is called when the ref is added or deleted. it puts
1167 * the modification into a list that's later used by btrfs_end_transaction to 1183 * the modification into a list that's later used by btrfs_end_transaction to
@@ -1390,6 +1406,15 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
1390 BUG(); 1406 BUG();
1391 } 1407 }
1392 1408
1409 mutex_lock(&fs_info->qgroup_rescan_lock);
1410 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
1411 if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
1412 mutex_unlock(&fs_info->qgroup_rescan_lock);
1413 return 0;
1414 }
1415 }
1416 mutex_unlock(&fs_info->qgroup_rescan_lock);
1417
1393 /* 1418 /*
1394 * the delayed ref sequence number we pass depends on the direction of 1419 * the delayed ref sequence number we pass depends on the direction of
1395 * the operation. for add operations, we pass 1420 * the operation. for add operations, we pass
@@ -1403,7 +1428,15 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
1403 if (ret < 0) 1428 if (ret < 0)
1404 return ret; 1429 return ret;
1405 1430
1431 mutex_lock(&fs_info->qgroup_rescan_lock);
1406 spin_lock(&fs_info->qgroup_lock); 1432 spin_lock(&fs_info->qgroup_lock);
1433 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) {
1434 if (fs_info->qgroup_rescan_progress.objectid <= node->bytenr) {
1435 ret = 0;
1436 goto unlock;
1437 }
1438 }
1439
1407 quota_root = fs_info->quota_root; 1440 quota_root = fs_info->quota_root;
1408 if (!quota_root) 1441 if (!quota_root)
1409 goto unlock; 1442 goto unlock;
@@ -1445,6 +1478,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
1445 1478
1446unlock: 1479unlock:
1447 spin_unlock(&fs_info->qgroup_lock); 1480 spin_unlock(&fs_info->qgroup_lock);
1481 mutex_unlock(&fs_info->qgroup_rescan_lock);
1448 ulist_free(roots); 1482 ulist_free(roots);
1449 ulist_free(tmp); 1483 ulist_free(tmp);
1450 1484
@@ -1823,3 +1857,259 @@ void assert_qgroups_uptodate(struct btrfs_trans_handle *trans)
1823 (u32)trans->delayed_ref_elem.seq); 1857 (u32)trans->delayed_ref_elem.seq);
1824 BUG(); 1858 BUG();
1825} 1859}
1860
1861/*
1862 * returns < 0 on error, 0 when more leafs are to be scanned.
1863 * returns 1 when done, 2 when done and FLAG_INCONSISTENT was cleared.
1864 */
1865static int
1866qgroup_rescan_leaf(struct qgroup_rescan *qscan, struct btrfs_path *path,
1867 struct btrfs_trans_handle *trans, struct ulist *tmp,
1868 struct extent_buffer *scratch_leaf)
1869{
1870 struct btrfs_key found;
1871 struct btrfs_fs_info *fs_info = qscan->fs_info;
1872 struct ulist *roots = NULL;
1873 struct ulist_node *unode;
1874 struct ulist_iterator uiter;
1875 struct seq_list tree_mod_seq_elem = {};
1876 u64 seq;
1877 int slot;
1878 int ret;
1879
1880 path->leave_spinning = 1;
1881 mutex_lock(&fs_info->qgroup_rescan_lock);
1882 ret = btrfs_search_slot_for_read(fs_info->extent_root,
1883 &fs_info->qgroup_rescan_progress,
1884 path, 1, 0);
1885
1886 pr_debug("current progress key (%llu %u %llu), search_slot ret %d\n",
1887 (unsigned long long)fs_info->qgroup_rescan_progress.objectid,
1888 fs_info->qgroup_rescan_progress.type,
1889 (unsigned long long)fs_info->qgroup_rescan_progress.offset,
1890 ret);
1891
1892 if (ret) {
1893 /*
1894 * The rescan is about to end, we will not be scanning any
1895 * further blocks. We cannot unset the RESCAN flag here, because
1896 * we want to commit the transaction if everything went well.
1897 * To make the live accounting work in this phase, we set our
1898 * scan progress pointer such that every real extent objectid
1899 * will be smaller.
1900 */
1901 fs_info->qgroup_rescan_progress.objectid = (u64)-1;
1902 btrfs_release_path(path);
1903 mutex_unlock(&fs_info->qgroup_rescan_lock);
1904 return ret;
1905 }
1906
1907 btrfs_item_key_to_cpu(path->nodes[0], &found,
1908 btrfs_header_nritems(path->nodes[0]) - 1);
1909 fs_info->qgroup_rescan_progress.objectid = found.objectid + 1;
1910
1911 btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1912 memcpy(scratch_leaf, path->nodes[0], sizeof(*scratch_leaf));
1913 slot = path->slots[0];
1914 btrfs_release_path(path);
1915 mutex_unlock(&fs_info->qgroup_rescan_lock);
1916
1917 for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
1918 btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
1919 if (found.type != BTRFS_EXTENT_ITEM_KEY)
1920 continue;
1921 ret = btrfs_find_all_roots(trans, fs_info, found.objectid,
1922 tree_mod_seq_elem.seq, &roots);
1923 if (ret < 0)
1924 goto out;
1925 spin_lock(&fs_info->qgroup_lock);
1926 seq = fs_info->qgroup_seq;
1927 fs_info->qgroup_seq += roots->nnodes + 1; /* max refcnt */
1928
1929 ret = qgroup_account_ref_step1(fs_info, roots, tmp, seq);
1930 if (ret) {
1931 spin_unlock(&fs_info->qgroup_lock);
1932 ulist_free(roots);
1933 goto out;
1934 }
1935
1936 /*
1937 * step2 of btrfs_qgroup_account_ref works from a single root,
1938 * we're doing all at once here.
1939 */
1940 ulist_reinit(tmp);
1941 ULIST_ITER_INIT(&uiter);
1942 while ((unode = ulist_next(roots, &uiter))) {
1943 struct btrfs_qgroup *qg;
1944
1945 qg = find_qgroup_rb(fs_info, unode->val);
1946 if (!qg)
1947 continue;
1948
1949 ret = ulist_add(tmp, qg->qgroupid, (uintptr_t)qg,
1950 GFP_ATOMIC);
1951 if (ret < 0) {
1952 spin_unlock(&fs_info->qgroup_lock);
1953 ulist_free(roots);
1954 goto out;
1955 }
1956 }
1957
1958 /* this loop is similar to step 2 of btrfs_qgroup_account_ref */
1959 ULIST_ITER_INIT(&uiter);
1960 while ((unode = ulist_next(tmp, &uiter))) {
1961 struct btrfs_qgroup *qg;
1962 struct btrfs_qgroup_list *glist;
1963
1964 qg = (struct btrfs_qgroup *)(uintptr_t) unode->aux;
1965 qg->rfer += found.offset;
1966 qg->rfer_cmpr += found.offset;
1967 WARN_ON(qg->tag >= seq);
1968 if (qg->refcnt - seq == roots->nnodes) {
1969 qg->excl += found.offset;
1970 qg->excl_cmpr += found.offset;
1971 }
1972 qgroup_dirty(fs_info, qg);
1973
1974 list_for_each_entry(glist, &qg->groups, next_group) {
1975 ret = ulist_add(tmp, glist->group->qgroupid,
1976 (uintptr_t)glist->group,
1977 GFP_ATOMIC);
1978 if (ret < 0) {
1979 spin_unlock(&fs_info->qgroup_lock);
1980 ulist_free(roots);
1981 goto out;
1982 }
1983 }
1984 }
1985
1986 spin_unlock(&fs_info->qgroup_lock);
1987 ulist_free(roots);
1988 ret = 0;
1989 }
1990
1991out:
1992 btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
1993
1994 return ret;
1995}
1996
1997static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
1998{
1999 struct qgroup_rescan *qscan = container_of(work, struct qgroup_rescan,
2000 work);
2001 struct btrfs_path *path;
2002 struct btrfs_trans_handle *trans = NULL;
2003 struct btrfs_fs_info *fs_info = qscan->fs_info;
2004 struct ulist *tmp = NULL;
2005 struct extent_buffer *scratch_leaf = NULL;
2006 int err = -ENOMEM;
2007
2008 path = btrfs_alloc_path();
2009 if (!path)
2010 goto out;
2011 tmp = ulist_alloc(GFP_NOFS);
2012 if (!tmp)
2013 goto out;
2014 scratch_leaf = kmalloc(sizeof(*scratch_leaf), GFP_NOFS);
2015 if (!scratch_leaf)
2016 goto out;
2017
2018 err = 0;
2019 while (!err) {
2020 trans = btrfs_start_transaction(fs_info->fs_root, 0);
2021 if (IS_ERR(trans)) {
2022 err = PTR_ERR(trans);
2023 break;
2024 }
2025 if (!fs_info->quota_enabled) {
2026 err = -EINTR;
2027 } else {
2028 err = qgroup_rescan_leaf(qscan, path, trans,
2029 tmp, scratch_leaf);
2030 }
2031 if (err > 0)
2032 btrfs_commit_transaction(trans, fs_info->fs_root);
2033 else
2034 btrfs_end_transaction(trans, fs_info->fs_root);
2035 }
2036
2037out:
2038 kfree(scratch_leaf);
2039 ulist_free(tmp);
2040 btrfs_free_path(path);
2041 kfree(qscan);
2042
2043 mutex_lock(&fs_info->qgroup_rescan_lock);
2044 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2045
2046 if (err == 2 &&
2047 fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
2048 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2049 } else if (err < 0) {
2050 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
2051 }
2052 mutex_unlock(&fs_info->qgroup_rescan_lock);
2053
2054 if (err >= 0) {
2055 pr_info("btrfs: qgroup scan completed%s\n",
2056 err == 2 ? " (inconsistency flag cleared)" : "");
2057 } else {
2058 pr_err("btrfs: qgroup scan failed with %d\n", err);
2059 }
2060}
2061
2062static void
2063qgroup_rescan_start(struct btrfs_fs_info *fs_info, struct qgroup_rescan *qscan)
2064{
2065 memset(&qscan->work, 0, sizeof(qscan->work));
2066 qscan->work.func = btrfs_qgroup_rescan_worker;
2067 qscan->fs_info = fs_info;
2068
2069 pr_info("btrfs: qgroup scan started\n");
2070 btrfs_queue_worker(&fs_info->qgroup_rescan_workers, &qscan->work);
2071}
2072
2073int
2074btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
2075{
2076 int ret = 0;
2077 struct rb_node *n;
2078 struct btrfs_qgroup *qgroup;
2079 struct qgroup_rescan *qscan = kmalloc(sizeof(*qscan), GFP_NOFS);
2080
2081 if (!qscan)
2082 return -ENOMEM;
2083
2084 mutex_lock(&fs_info->qgroup_rescan_lock);
2085 spin_lock(&fs_info->qgroup_lock);
2086 if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
2087 ret = -EINPROGRESS;
2088 else if (!(fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON))
2089 ret = -EINVAL;
2090 if (ret) {
2091 spin_unlock(&fs_info->qgroup_lock);
2092 mutex_unlock(&fs_info->qgroup_rescan_lock);
2093 kfree(qscan);
2094 return ret;
2095 }
2096
2097 fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
2098 memset(&fs_info->qgroup_rescan_progress, 0,
2099 sizeof(fs_info->qgroup_rescan_progress));
2100
2101 /* clear all current qgroup tracking information */
2102 for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
2103 qgroup = rb_entry(n, struct btrfs_qgroup, node);
2104 qgroup->rfer = 0;
2105 qgroup->rfer_cmpr = 0;
2106 qgroup->excl = 0;
2107 qgroup->excl_cmpr = 0;
2108 }
2109 spin_unlock(&fs_info->qgroup_lock);
2110 mutex_unlock(&fs_info->qgroup_rescan_lock);
2111
2112 qgroup_rescan_start(fs_info, qscan);
2113
2114 return 0;
2115}
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 5e39e859a848..5ef0df545a2a 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -376,12 +376,18 @@ struct btrfs_ioctl_get_dev_stats {
376 376
377#define BTRFS_QUOTA_CTL_ENABLE 1 377#define BTRFS_QUOTA_CTL_ENABLE 1
378#define BTRFS_QUOTA_CTL_DISABLE 2 378#define BTRFS_QUOTA_CTL_DISABLE 2
379#define BTRFS_QUOTA_CTL_RESCAN 3 379#define BTRFS_QUOTA_CTL_RESCAN__NOTUSED 3
380struct btrfs_ioctl_quota_ctl_args { 380struct btrfs_ioctl_quota_ctl_args {
381 __u64 cmd; 381 __u64 cmd;
382 __u64 status; 382 __u64 status;
383}; 383};
384 384
385struct btrfs_ioctl_quota_rescan_args {
386 __u64 flags;
387 __u64 progress;
388 __u64 reserved[6];
389};
390
385struct btrfs_ioctl_qgroup_assign_args { 391struct btrfs_ioctl_qgroup_assign_args {
386 __u64 assign; 392 __u64 assign;
387 __u64 src; 393 __u64 src;
@@ -520,6 +526,10 @@ struct btrfs_ioctl_send_args {
520 struct btrfs_ioctl_qgroup_create_args) 526 struct btrfs_ioctl_qgroup_create_args)
521#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ 527#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
522 struct btrfs_ioctl_qgroup_limit_args) 528 struct btrfs_ioctl_qgroup_limit_args)
529#define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \
530 struct btrfs_ioctl_quota_rescan_args)
531#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
532 struct btrfs_ioctl_quota_rescan_args)
523#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ 533#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
524 char[BTRFS_LABEL_SIZE]) 534 char[BTRFS_LABEL_SIZE])
525#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ 535#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \