Btrfs-progs: quota rescan
authorJan Schmidt <list.btrfs@jan-o-sch.net>
Fri, 5 Apr 2013 11:44:06 +0000 (13:44 +0200)
committerDavid Sterba <dsterba@suse.cz>
Tue, 23 Apr 2013 16:56:27 +0000 (18:56 +0200)
This adds the quota rescan command to be used if qgroup tracking should get
out of sync. Can also be used to query the status of a running rescan
operation.

Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
cmds-quota.c
ioctl.h

index 71cd9f1..2e2971a 100644 (file)
@@ -93,18 +93,70 @@ static int cmd_quota_disable(int argc, char **argv)
 }
 
 static const char * const cmd_quota_rescan_usage[] = {
-       "btrfs quota rescan <path>",
-       "Rescan the subvolume for a changed quota setting.",
-       "Not yet implemented.",
+       "btrfs quota rescan [-s] <path>",
+       "Trash all qgroup numbers and scan the metadata again with the current config.",
+       "",
+       "-s   show status of a running rescan operation",
        NULL
 };
 
 static int cmd_quota_rescan(int argc, char **argv)
 {
-       int ret = quota_ctl(BTRFS_QUOTA_CTL_RESCAN, argc, argv);
-       if (ret < 0)
+       int ret = 0;
+       int fd;
+       int e;
+       char *path = NULL;
+       struct btrfs_ioctl_quota_rescan_args args;
+       int ioctlnum = BTRFS_IOC_QUOTA_RESCAN;
+
+       optind = 1;
+       while (1) {
+               int c = getopt(argc, argv, "s");
+               if (c < 0)
+                       break;
+               switch (c) {
+               case 's':
+                       ioctlnum = BTRFS_IOC_QUOTA_RESCAN_STATUS;
+                       break;
+               default:
+                       usage(cmd_quota_rescan_usage);
+               }
+       }
+
+       if (check_argc_exact(argc - optind, 1))
                usage(cmd_quota_rescan_usage);
-       return ret;
+
+       memset(&args, 0, sizeof(args));
+
+       path = argv[optind];
+       fd = open_file_or_dir(path);
+       if (fd < 0) {
+               fprintf(stderr, "ERROR: can't access '%s'\n", path);
+               return 12;
+       }
+
+       ret = ioctl(fd, ioctlnum, &args);
+       e = errno;
+       close(fd);
+
+       if (ioctlnum == BTRFS_IOC_QUOTA_RESCAN) {
+               if (ret < 0) {
+                       fprintf(stderr, "ERROR: quota rescan failed: "
+                               "%s\n", strerror(e));
+                       return 30;
+               }  else {
+                       printf("quota rescan started\n");
+               }
+       } else {
+               if (!args.flags) {
+                       printf("no rescan operation in progress\n");
+               } else {
+                       printf("rescan operation running (current key %lld)\n",
+                               args.progress);
+               }
+       }
+
+       return 0;
 }
 
 const struct cmd_group quota_cmd_group = {
diff --git a/ioctl.h b/ioctl.h
index e841913..1ee631a 100644 (file)
--- a/ioctl.h
+++ b/ioctl.h
@@ -384,25 +384,6 @@ struct btrfs_ioctl_send_args {
        __u64 reserved[4];              /* in */
 };
 
-#define BTRFS_QUOTA_CTL_ENABLE 1
-#define BTRFS_QUOTA_CTL_DISABLE        2
-#define BTRFS_QUOTA_CTL_RESCAN 3
-struct btrfs_ioctl_quota_ctl_args {
-       __u64 cmd;
-       __u64 status;
-};
-
-struct btrfs_ioctl_qgroup_assign_args {
-       __u64 assign;
-       __u64 src;
-       __u64 dst;
-};
-
-struct btrfs_ioctl_qgroup_create_args {
-       __u64 create;
-       __u64 qgroupid;
-};
-
 enum btrfs_dev_stat_values {
        /* disk I/O failure stats */
        BTRFS_DEV_STAT_WRITE_ERRS, /* EIO or EREMOTEIO from lower layers */
@@ -437,6 +418,29 @@ struct btrfs_ioctl_get_dev_stats {
 };
 
 /* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
+#define BTRFS_QUOTA_CTL_ENABLE 1
+#define BTRFS_QUOTA_CTL_DISABLE        2
+/* 3 has formerly been reserved for BTRFS_QUOTA_CTL_RESCAN */
+struct btrfs_ioctl_quota_ctl_args {
+       __u64 cmd;
+       __u64 status;
+};
+
+struct btrfs_ioctl_quota_rescan_args {
+       __u64   flags;
+       __u64   progress;
+};
+
+struct btrfs_ioctl_qgroup_assign_args {
+       __u64 assign;
+       __u64 src;
+       __u64 dst;
+};
+
+struct btrfs_ioctl_qgroup_create_args {
+       __u64 create;
+       __u64 qgroupid;
+};
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
                                   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -520,6 +524,10 @@ struct btrfs_ioctl_clone_range_args {
                                        struct btrfs_ioctl_qgroup_create_args)
 #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
                                        struct btrfs_ioctl_qgroup_limit_args)
+#define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \
+                              struct btrfs_ioctl_quota_rescan_args)
+#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
+                              struct btrfs_ioctl_quota_rescan_args)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
                                   char[BTRFS_LABEL_SIZE])
 #define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \