]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_quota: add capabilities for use on non-XFS filesystems
authorBill O'Donnell <billodo@redhat.com>
Fri, 26 Aug 2016 01:20:32 +0000 (11:20 +1000)
committerDave Chinner <david@fromorbit.com>
Fri, 26 Aug 2016 01:20:32 +0000 (11:20 +1000)
This patch allows xfs_quota to be used on ext4 for project quota
testing in xfstests.  It was based on work originally from Dave
Chinner. As a part of its support for foreign filesystems xfs_quota
is modified with a "-f" command line flag to enable select commands
on those filesystems.

This requires us to discriminate different filesystem types when
walking the fileystem table during argument processing as the table
is now populated with mounted non-XFS filesystems. We should only
select a foreign filesystem mount point if the "-f" flag is present
on the command line.

This patch also updates the usage and man page information
for the new CLI flag appropriately.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
15 files changed:
include/command.h
include/path.h
io/init.h
libxcmd/paths.c
man/man8/xfs_quota.8
quota/free.c
quota/init.c
quota/init.h
quota/path.c
quota/project.c
quota/quot.c
quota/quota.c
quota/report.c
quota/state.c
quota/util.c

index 7b9fc284116c67895a4d0e24daf505bb4800600d..81d5a4dbb7f34209eb3acb0332fb1924dfa05e40 100644 (file)
@@ -20,7 +20,8 @@
 
 #include <sys/time.h>
 
-#define CMD_FLAG_GLOBAL        ((int)0x80000000)       /* don't iterate "args" */
+#define CMD_FLAG_GLOBAL                (1<<31) /* don't iterate "args" */
+#define CMD_FLAG_FOREIGN_OK    (1<<30) /* command not restricted to XFS */
 
 typedef int (*cfunc_t)(int argc, char **argv);
 typedef void (*helpfunc_t)(void);
index 46a887e51d7cad3c9e4a3b1f1e658e8bf6462a14..39c1a95a129e3cc7eaa905f4fbc368cff999ebd1 100644 (file)
@@ -29,6 +29,7 @@
 
 #define FS_MOUNT_POINT (1<<0)
 #define FS_PROJECT_PATH        (1<<1)
+#define FS_FOREIGN     (1<<2)
 
 typedef struct fs_path {
        char            *fs_name;       /* Data device for filesystem   */
index d773b1bcf0b936afab186724bfbd3ee09a5d694f..bb25242212707dc7f7edc2d890b16ca0c9f71f23 100644 (file)
--- a/io/init.h
+++ b/io/init.h
@@ -18,7 +18,7 @@
 
 #define CMD_NOFILE_OK  (1<<0)  /* command doesn't need an open file    */
 #define CMD_NOMAP_OK   (1<<1)  /* command doesn't need a mapped region */
-#define CMD_FOREIGN_OK (1<<2)  /* command not restricted to XFS files  */
+#define CMD_FOREIGN_OK CMD_FLAG_FOREIGN_OK
 
 extern char    *progname;
 extern int     exitcode;
index b08985f3c4fc8300174e65318b18f065985d9e1b..4158688231b7056ab53c3085dff4766b6b93a8ac 100644 (file)
@@ -113,6 +113,9 @@ fs_table_insert(
                        goto out_nodev;
        }
 
+       if (!platform_test_xfs_path(dir))
+               flags |= FS_FOREIGN;
+
        /*
         * Make copies of the directory and data device path.
         * The log device and real-time device, if non-null,
@@ -308,8 +311,6 @@ fs_table_initialise_mounts(
                        return errno;
 
        while ((mnt = getmntent(mtp)) != NULL) {
-               if (strcmp(mnt->mnt_type, "xfs") != 0)
-                       continue;
                if (!realpath(mnt->mnt_dir, rmnt_dir))
                        continue;
                if (!realpath(mnt->mnt_fsname, rmnt_fsname))
@@ -367,8 +368,6 @@ fs_table_initialise_mounts(
                        return errno;
 
        for (i = 0; i < count; i++) {
-               if (strcmp(stats[i].f_fstypename, "xfs") != 0)
-                       continue;
                if (!realpath(stats[i].f_mntfromname, rmntfromname))
                        continue;
                if (!realpath(stats[i].f_mntonname, rmntonname))
index f66e4212395bd4e2f95e166c7746c05f4c9de9cf..03add20cd7c523f79fb4bd51efaf847e34ce68b3 100644 (file)
@@ -6,6 +6,8 @@ xfs_quota \- manage use of quota on XFS filesystems
 [
 .B \-x
 ] [
+.B \-f
+] [
 .B \-p
 .I prog
 ] [
@@ -51,6 +53,11 @@ All of the administrative commands (see the ADMINISTRATOR COMMANDS
 section below) which allow modifications to the quota system are
 available only in expert mode.
 .TP
+.B \-f
+Enable foreign filesystem mode.
+A limited number of user and administrative commands are available for
+use on some foreign (non-XFS) filesystems.
+.TP
 .BI \-d " project"
 Project names or numeric identifiers may be specified with this option,
 which restricts the output of the individual
index e9e03196f5daa768b18e4fc016379293264889bf..b9be9547dc20703d9efaf4c6e384cc6a49f5925a 100644 (file)
@@ -16,6 +16,7 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdbool.h>
 #include "command.h"
 #include "init.h"
 #include "quota.h"
@@ -371,6 +372,7 @@ free_init(void)
        free_cmd.args = _("[-bir] [-hn] [-f file]");
        free_cmd.oneline = _("show free and used counts for blocks and inodes");
        free_cmd.help = free_help;
+       free_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        add_command(&free_cmd);
 }
index 52f7941b03533eeaa575541e751d30e3fa188fa9..137cd6852eeb08d5c1a805b6ef1ce588502b0ad9 100644 (file)
@@ -24,6 +24,7 @@
 char   *progname;
 int    exitcode;
 int    expert;
+bool   foreign_allowed = false;
 
 static char **projopts;        /* table of project names (cmdline) */
 static int nprojopts;  /* number of entries in name table. */
@@ -45,7 +46,7 @@ static void
 usage(void)
 {
        fprintf(stderr,
-               _("Usage: %s [-V] [-x] [-p prog] [-c cmd]... [-d project]... [path]\n"),
+               _("Usage: %s [-V] [-x] [-f] [-p prog] [-c cmd]... [-d project]... [path]\n"),
                progname);
        exit(1);
 }
@@ -83,15 +84,42 @@ init_args_command(
 
        do {
                fs_path = &fs_table[index++];
-       } while ((fs_path->fs_flags & FS_PROJECT_PATH) && index < fs_count);
+               /* skip project quota entries */
+               if ((fs_path->fs_flags & FS_PROJECT_PATH))
+                       continue;
+
+               /* only consider foreign filesystems if told so */
+               if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN))
+                       continue;
+
+               /* We can use this one */
+               break;
+       } while (index < fs_count);
 
        if (fs_path->fs_flags & FS_PROJECT_PATH)
                return 0;
+       if (!foreign_allowed && (fs_path->fs_flags & FS_FOREIGN))
+               return 0;
        if (index > fs_count)
                return 0;
        return index;
 }
 
+static int
+init_check_command(
+       const cmdinfo_t *ct)
+{
+       if (fs_path &&
+           !(ct->flags & CMD_FLAG_FOREIGN_OK) &&
+            (fs_path->fs_flags & FS_FOREIGN)) {
+               fprintf(stderr,
+       _("foreign mount active, %s command is for XFS filesystems only\n"),
+                       ct->name);
+               return 0;
+       }
+       return 1;
+}
+
 static void
 init(
        int             argc,
@@ -104,7 +132,7 @@ init(
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
-       while ((c = getopt(argc, argv, "c:d:D:P:p:t:xV")) != EOF) {
+       while ((c = getopt(argc, argv, "c:d:D:fP:p:t:xV")) != EOF) {
                switch (c) {
                case 'c':       /* commands */
                        add_user_command(optarg);
@@ -112,6 +140,8 @@ init(
                case 'd':
                        add_project_opt(optarg);
                        break;
+               case 'f':
+                       foreign_allowed = true;
                case 't':
                        mtab_file = optarg;
                        break;
@@ -140,6 +170,7 @@ init(
 
        init_commands();
        add_args_command(init_args_command);
+       add_check_command(init_check_command);
 
        /*
         * Ensure that global commands don't end up with an invalid path pointer
index 71706cb3388d51cc28a5c9601fa537465df28120..6879855578f03adcf5bc220a8e076813abe76920 100644 (file)
@@ -19,6 +19,7 @@
 extern char    *progname;
 extern int     exitcode;
 extern int     expert;
+extern bool    foreign_allowed;
 
 extern void    edit_init(void);
 extern void    free_init(void);
index bdb8c98c5176337addfa03a491989191eb485f94..a623d2551d1aea73bc7a767e5d138e78da7771f6 100644 (file)
@@ -42,6 +42,7 @@ printpath(
        if (number) {
                printf(_("%c%03d%c "), braces? '[':' ', index, braces? ']':' ');
        }
+       printf("%s ", (path->fs_flags & FS_FOREIGN) ? "(F)" : "   ");
        printf(_("%-19s %s"), path->fs_dir, path->fs_name);
        if (path->fs_flags & FS_PROJECT_PATH) {
                prj = getprprid(path->fs_prid);
@@ -127,7 +128,7 @@ path_init(void)
        path_cmd.cfunc = path_f;
        path_cmd.argmin = 0;
        path_cmd.argmax = 1;
-       path_cmd.flags = CMD_FLAG_GLOBAL;
+       path_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
        path_cmd.oneline = _("set current path, or show the list of paths");
 
        print_cmd.name = "print";
@@ -135,7 +136,7 @@ path_init(void)
        print_cmd.cfunc = print_f;
        print_cmd.argmin = 0;
        print_cmd.argmax = 0;
-       print_cmd.flags = CMD_FLAG_GLOBAL;
+       print_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
        print_cmd.oneline = _("list known mount points and projects");
 
        if (expert)
index fb8b9e1e4c26bed04dbdf7e7e4428cce2b25ab1e..e4e7a012fe85042fd02a9709ad8299787df3ba6b 100644 (file)
@@ -355,6 +355,7 @@ project_init(void)
        project_cmd.argmax = -1;
        project_cmd.oneline = _("check, setup or clear project quota trees");
        project_cmd.help = project_help;
+       project_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        if (expert)
                add_command(&project_cmd);
index 2e583e555061da9d9c81df82e179c9daeb5334b9..ccc154f5180c6e315c8e1b9e429fc8a907edbb48 100644 (file)
@@ -16,6 +16,7 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdbool.h>
 #include "command.h"
 #include <ctype.h>
 #include <pwd.h>
index e0da7c0ba246d4f11195dcf986bfe157713cf4d9..d09e239bd680f63e2d2216257116d974504d36d9 100644 (file)
@@ -16,6 +16,7 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdbool.h>
 #include "command.h"
 #include <ctype.h>
 #include <pwd.h>
@@ -469,6 +470,7 @@ quota_init(void)
        quota_cmd.args = _("[-bir] [-g|-p|-u] [-hnNv] [-f file] [id|name]...");
        quota_cmd.oneline = _("show usage and limits");
        quota_cmd.help = quota_help;
+       quota_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        add_command(&quota_cmd);
 }
index 70220b44dbc6565dafa12f1cb562a922789d795b..604f50dc6001b9f828312a2104eb4511a7b33a23 100644 (file)
@@ -15,7 +15,7 @@
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
+#include <stdbool.h>
 #include "command.h"
 #include <sys/types.h>
 #include <pwd.h>
@@ -618,6 +618,8 @@ report_any_type(
        if (type & XFS_USER_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_USER_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -629,6 +631,8 @@ report_any_type(
        if (type & XFS_GROUP_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_GROUP_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -640,6 +644,8 @@ report_any_type(
        if (type & XFS_PROJ_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_PROJ_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -754,16 +760,17 @@ report_init(void)
        dump_cmd.args = _("[-g|-p|-u] [-f file]");
        dump_cmd.oneline = _("dump quota information for backup utilities");
        dump_cmd.help = dump_help;
+       dump_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        report_cmd.name = "report";
        report_cmd.altname = "repquota";
        report_cmd.cfunc = report_f;
        report_cmd.argmin = 0;
        report_cmd.argmax = -1;
-       report_cmd.flags = CMD_FLAG_GLOBAL;
        report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]");
        report_cmd.oneline = _("report filesystem quota information");
        report_cmd.help = report_help;
+       report_cmd.flags = CMD_FLAG_GLOBAL | CMD_FLAG_FOREIGN_OK;
 
        if (expert) {
                add_command(&dump_cmd);
index 9f6616ea172658b2d9c7ad1df6a69b8f8b9d1341..05e4ec5290454f9d66addf913c1bce08e08b52b3 100644 (file)
@@ -15,7 +15,7 @@
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
+#include <stdbool.h>
 #include "command.h"
 #include "init.h"
 #include "quota.h"
@@ -584,6 +584,7 @@ state_init(void)
        off_cmd.args = _("[-gpu] [-v]");
        off_cmd.oneline = _("permanently switch quota off for a path");
        off_cmd.help = off_help;
+       off_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        state_cmd.name = "state";
        state_cmd.cfunc = state_f;
@@ -592,6 +593,7 @@ state_init(void)
        state_cmd.args = _("[-gpu] [-a] [-v] [-f file]");
        state_cmd.oneline = _("get overall quota state information");
        state_cmd.help = state_help;
+       state_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        enable_cmd.name = "enable";
        enable_cmd.cfunc = enable_f;
index e3c539831e285c3ddcd4f352b829404ca0282858..cafd45f59ae1f62695f2e2a9f588c07c07861d0e 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <sys/types.h>
+#include <stdbool.h>
 #include <pwd.h>
 #include <grp.h>
 #include <utmp.h>