diff options
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 12 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 21 | ||||
-rw-r--r-- | include/uapi/linux/btrfs.h | 1 |
4 files changed, 36 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a365400e38da..e36e97b473a8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1613,6 +1613,7 @@ struct btrfs_fs_info { | |||
1613 | struct mutex qgroup_rescan_lock; /* protects the progress item */ | 1613 | struct mutex qgroup_rescan_lock; /* protects the progress item */ |
1614 | struct btrfs_key qgroup_rescan_progress; | 1614 | struct btrfs_key qgroup_rescan_progress; |
1615 | struct btrfs_workers qgroup_rescan_workers; | 1615 | struct btrfs_workers qgroup_rescan_workers; |
1616 | struct completion qgroup_rescan_completion; | ||
1616 | 1617 | ||
1617 | /* filesystem state */ | 1618 | /* filesystem state */ |
1618 | unsigned long fs_state; | 1619 | unsigned long fs_state; |
@@ -3820,6 +3821,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, | |||
3820 | int btrfs_quota_disable(struct btrfs_trans_handle *trans, | 3821 | int btrfs_quota_disable(struct btrfs_trans_handle *trans, |
3821 | struct btrfs_fs_info *fs_info); | 3822 | struct btrfs_fs_info *fs_info); |
3822 | int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); | 3823 | int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); |
3824 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info); | ||
3823 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, | 3825 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, |
3824 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | 3826 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); |
3825 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, | 3827 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0f81d67cdc8d..1e0dda1feefe 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3937,6 +3937,16 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | |||
3937 | return ret; | 3937 | return ret; |
3938 | } | 3938 | } |
3939 | 3939 | ||
3940 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) | ||
3941 | { | ||
3942 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
3943 | |||
3944 | if (!capable(CAP_SYS_ADMIN)) | ||
3945 | return -EPERM; | ||
3946 | |||
3947 | return btrfs_qgroup_wait_for_completion(root->fs_info); | ||
3948 | } | ||
3949 | |||
3940 | static long btrfs_ioctl_set_received_subvol(struct file *file, | 3950 | static long btrfs_ioctl_set_received_subvol(struct file *file, |
3941 | void __user *arg) | 3951 | void __user *arg) |
3942 | { | 3952 | { |
@@ -4179,6 +4189,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
4179 | return btrfs_ioctl_quota_rescan(file, argp); | 4189 | return btrfs_ioctl_quota_rescan(file, argp); |
4180 | case BTRFS_IOC_QUOTA_RESCAN_STATUS: | 4190 | case BTRFS_IOC_QUOTA_RESCAN_STATUS: |
4181 | return btrfs_ioctl_quota_rescan_status(file, argp); | 4191 | return btrfs_ioctl_quota_rescan_status(file, argp); |
4192 | case BTRFS_IOC_QUOTA_RESCAN_WAIT: | ||
4193 | return btrfs_ioctl_quota_rescan_wait(file, argp); | ||
4182 | case BTRFS_IOC_DEV_REPLACE: | 4194 | case BTRFS_IOC_DEV_REPLACE: |
4183 | return btrfs_ioctl_dev_replace(root, argp); | 4195 | return btrfs_ioctl_dev_replace(root, argp); |
4184 | case BTRFS_IOC_GET_FSLABEL: | 4196 | case BTRFS_IOC_GET_FSLABEL: |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 7f38cce2528d..d059d86c3131 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -2070,6 +2070,8 @@ out: | |||
2070 | } else { | 2070 | } else { |
2071 | pr_err("btrfs: qgroup scan failed with %d\n", err); | 2071 | pr_err("btrfs: qgroup scan failed with %d\n", err); |
2072 | } | 2072 | } |
2073 | |||
2074 | complete_all(&fs_info->qgroup_rescan_completion); | ||
2073 | } | 2075 | } |
2074 | 2076 | ||
2075 | static void | 2077 | static void |
@@ -2110,6 +2112,7 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info) | |||
2110 | fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN; | 2112 | fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN; |
2111 | memset(&fs_info->qgroup_rescan_progress, 0, | 2113 | memset(&fs_info->qgroup_rescan_progress, 0, |
2112 | sizeof(fs_info->qgroup_rescan_progress)); | 2114 | sizeof(fs_info->qgroup_rescan_progress)); |
2115 | init_completion(&fs_info->qgroup_rescan_completion); | ||
2113 | 2116 | ||
2114 | /* clear all current qgroup tracking information */ | 2117 | /* clear all current qgroup tracking information */ |
2115 | for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) { | 2118 | for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) { |
@@ -2126,3 +2129,21 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info) | |||
2126 | 2129 | ||
2127 | return 0; | 2130 | return 0; |
2128 | } | 2131 | } |
2132 | |||
2133 | int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info) | ||
2134 | { | ||
2135 | int running; | ||
2136 | int ret = 0; | ||
2137 | |||
2138 | mutex_lock(&fs_info->qgroup_rescan_lock); | ||
2139 | spin_lock(&fs_info->qgroup_lock); | ||
2140 | running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN; | ||
2141 | spin_unlock(&fs_info->qgroup_lock); | ||
2142 | mutex_unlock(&fs_info->qgroup_rescan_lock); | ||
2143 | |||
2144 | if (running) | ||
2145 | ret = wait_for_completion_interruptible( | ||
2146 | &fs_info->qgroup_rescan_completion); | ||
2147 | |||
2148 | return ret; | ||
2149 | } | ||
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 5ef0df545a2a..5b683b5f63cd 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h | |||
@@ -530,6 +530,7 @@ struct btrfs_ioctl_send_args { | |||
530 | struct btrfs_ioctl_quota_rescan_args) | 530 | struct btrfs_ioctl_quota_rescan_args) |
531 | #define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \ | 531 | #define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \ |
532 | struct btrfs_ioctl_quota_rescan_args) | 532 | struct btrfs_ioctl_quota_rescan_args) |
533 | #define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46) | ||
533 | #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ | 534 | #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ |
534 | char[BTRFS_LABEL_SIZE]) | 535 | char[BTRFS_LABEL_SIZE]) |
535 | #define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ | 536 | #define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ |