Whamcloud - gitweb
mke2fs: fix the parsing used for -E quotatype=usrquota:grpquota:prjquota
authorTheodore Ts'o <tytso@mit.edu>
Mon, 9 May 2016 01:11:18 +0000 (21:11 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 9 May 2016 01:25:55 +0000 (21:25 -0400)
Commit 2d2d799c7261 tried to use parse_quota_options(), which uses
commas to separate out the quota types.  Unfortunately, when parsing
extended options, commands are used to separate different extended
options.

To fix this, I've add a new support function parse_quota_type(), which
allows either commas or colons to used as a separator character, and
which manipulates a bit field to indicate which quota types should be
enabled.  Eventually tune2fs should be converted to use
parse_quota_type() as well, thus obsoleting parse_quota_options(), but
that's a more complicated cleanup patch for later.

Fix a lint warning which could the number of blocks to be incorretly
printed if it exceeds 2**32.

Also fix some typos and other minor bugs in the usage message.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/support/Makefile.in
lib/support/Makefile.in.old [new file with mode: 0644]
lib/support/parse_qtype.c [new file with mode: 0644]
lib/support/quotaio.h
misc/mke2fs.c

index 4b57bbb..461e3d0 100644 (file)
@@ -15,6 +15,7 @@ all::
 OBJS=          mkquota.o \
                plausible.o \
                profile.o \
+               parse_qtype.o \
                profile_helpers.o \
                prof_err.o \
                quotaio.o \
@@ -24,6 +25,7 @@ OBJS=         mkquota.o \
 
 SRCS=          $(srcdir)/argv_parse.c \
                $(srcdir)/mkquota.c \
+               $(srcdir)/parse_qtype.c \
                $(srcdir)/plausible.c \
                $(srcdir)/profile.c \
                $(srcdir)/profile_helpers.c \
@@ -103,6 +105,14 @@ mkquota.o: $(srcdir)/mkquota.c $(top_builddir)/lib/config.h \
  $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/quotaio.h $(srcdir)/dqblk_v2.h \
  $(srcdir)/quotaio_tree.h $(srcdir)/quotaio_v2.h $(srcdir)/common.h \
  $(srcdir)/dict.h
+parse_qtype.o: $(srcdir)/parse_qtype.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/quotaio.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/dqblk_v2.h $(srcdir)/quotaio_tree.h
 plausible.o: $(srcdir)/plausible.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/plausible.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
diff --git a/lib/support/Makefile.in.old b/lib/support/Makefile.in.old
new file mode 100644 (file)
index 0000000..caacc85
--- /dev/null
@@ -0,0 +1,150 @@
+# Makefile for e2fsprog's internal support
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/support
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+all::
+
+OBJS=          mkquota.o \
+               plausible.o \
+               profile.o \
+               parse_qtype.o \
+               profile_helpers.o \
+               prof_err.o \
+               quotaio.o \
+               quotaio_v2.o \
+               quotaio_tree.o \
+               dict.o
+
+SRCS=          $(srcdir)/argv_parse.c \
+               $(srcdir)/mkquota.c \
+               $(srcdir)/parse_qtype.c \
+               $(srcdir)/plausible.c \
+               $(srcdir)/profile.c \
+               $(srcdir)/profile_helpers.c \
+               prof_err.c \
+               $(srcdir)/quotaio.c \
+               $(srcdir)/quotaio_tree.c \
+               $(srcdir)/quotaio_v2.c \
+               $(srcdir)/dict.c
+
+LIBRARY= libsupport
+LIBDIR= support
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_PROFILE@
+
+COMPILE_ET=$(top_builddir)/lib/et/compile_et --build-tree
+
+.c.o:
+       $(E) "  CC $<"
+       $(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+       $(Q) $(CHECK_CMD) $(ALL_CFLAGS) $<
+       $(Q) $(CPPCHECK_CMD) $(CPPFLAGS) $<
+@PROFILE_CMT@  $(Q) $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+
+installdirs::
+
+install:: all
+
+uninstall::
+
+prof_err.c prof_err.h: prof_err.et
+       $(E) "  COMPILE_ET prof_err.et"
+       $(Q) $(COMPILE_ET) $(srcdir)/prof_err.et
+
+test_profile: $(srcdir)/profile.c profile_helpers.o argv_parse.o \
+               prof_err.o profile.h $(DEPSTATIC_LIBCOM_ERR)
+       $(E) "  LD $@"
+       $(Q) $(CC) -o test_profile -DDEBUG_PROGRAM $(srcdir)/profile.c prof_err.o \
+               profile_helpers.o argv_parse.o $(STATIC_LIBCOM_ERR) \
+               $(ALL_CFLAGS)
+
+clean::
+       $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* \
+               ../libsupport.a ../libsupport_p.a $(SMANPAGES) \
+               prof_err.c prof_err.h test_profile
+
+#check:: tst_uuid
+#      LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_uuid
+
+mostlyclean:: clean
+distclean:: clean
+       $(RM) -f .depend Makefile \
+               $(srcdir)/TAGS $(srcdir)/Makefile.in.old
+
+#
+# Hack to parallel makes recognize dependencies correctly.
+#
+../../lib/libsupport.a: libsupport.a
+../../lib/libsupport.so: image
+../../lib/libsupport.dylib: image
+
+$(OBJS):
+
+# +++ Dependency line eater +++
+# 
+# Makefile dependencies follow.  This must be the last section in
+# the Makefile.in file
+#
+argv_parse.o: $(srcdir)/argv_parse.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/argv_parse.h
+mkquota.o: $(srcdir)/mkquota.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/quotaio.h $(srcdir)/dqblk_v2.h \
+ $(srcdir)/quotaio_tree.h $(srcdir)/quotaio_v2.h $(srcdir)/common.h \
+ $(srcdir)/dict.h
+plausible.o: $(srcdir)/plausible.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/plausible.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/nls-enable.h
+profile.o: $(srcdir)/profile.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/profile.h prof_err.h
+profile_helpers.o: $(srcdir)/profile_helpers.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/profile.h prof_err.h
+prof_err.o: prof_err.c
+quotaio.o: $(srcdir)/quotaio.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/dqblk_v2.h $(srcdir)/quotaio_tree.h
+quotaio_tree.o: $(srcdir)/quotaio_tree.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio_tree.h \
+ $(srcdir)/quotaio.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/dqblk_v2.h
+quotaio_v2.o: $(srcdir)/quotaio_v2.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio_v2.h \
+ $(srcdir)/quotaio.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/dqblk_v2.h $(srcdir)/quotaio_tree.h
+dict.o: $(srcdir)/dict.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/dict.h
diff --git a/lib/support/parse_qtype.c b/lib/support/parse_qtype.c
new file mode 100644 (file)
index 0000000..098639e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * parse_qtype.c
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "quotaio.h"
+
+#define PARSE_DELIM ":,"
+
+int parse_quota_types(const char *in_str, unsigned int *qtype_bits,
+                     char **err_token)
+{
+       char    *buf, *token, *next, *tmp;
+       unsigned int qtype = *qtype_bits;
+       int     len, ret = 0;
+
+       if (!in_str)
+               return 0;
+
+       len = strlen(in_str);
+       buf = malloc(len + 1);
+       if (!buf)
+               return ENOMEM;
+       strcpy(buf, in_str);
+
+       for (token = buf, next = strtok_r(buf, PARSE_DELIM, &tmp);
+            token && *token; token = next) {
+               int     not = 0;
+               char    *p = token;
+
+               if (*p == '^') {
+                       not = 1;
+                       p++;
+               }
+               if (!strcmp(p, "usr") || !strcmp(p, "usrquota")) {
+                       if (not)
+                               qtype &= ~QUOTA_USR_BIT;
+                       else
+                               qtype |= QUOTA_USR_BIT;
+               } else if (!strcmp(p, "grp") || !strcmp(p, "grpquota")) {
+                       if (not)
+                               qtype &= ~QUOTA_GRP_BIT;
+                       else
+                               qtype |= QUOTA_GRP_BIT;
+               } else if (!strcmp(p, "prj") || !strcmp(p, "prjquota")) {
+                       if (not)
+                               qtype &= ~QUOTA_PRJ_BIT;
+                       else
+                               qtype |= QUOTA_PRJ_BIT;
+               } else {
+                       if (err_token) {
+                               *err_token = malloc(strlen(token) + 1);
+                               if (*err_token)
+                                       strcpy(*err_token, token);
+                       }
+                       ret = EINVAL;
+                       goto errout;
+               }
+               printf("word: %s\n", token);
+               next = strtok_r(NULL, PARSE_DELIM, &tmp);
+       }
+       *qtype_bits = qtype;
+errout:
+       free(buf);
+       return ret;
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+       unsigned int qtype_bits = 0;
+       int ret;
+       char *err_token = 0;
+
+       ret = parse_quota_types(argv[1], &qtype_bits, &err_token);
+       printf("parse_quota_types returns %d, %d\n", ret, qtype_bits);
+       if (err_token)
+               printf("err_token is %s\n", err_token);
+       return 0;
+}
+#endif
index a8e6443..5f1073f 100644 (file)
@@ -235,6 +235,10 @@ errcode_t quota_compare_and_update(quota_ctx_t qctx, enum quota_type qtype,
                                   int *usage_inconsistent);
 int parse_quota_opts(const char *opts, int (*func)(char *, void *), void *data);
 
+/* parse_qtype.c */
+int parse_quota_types(const char *in_str, unsigned int *qtype_bits,
+                     char **err_token);
+
 /*
  * Return pointer to reserved inode field in superblock for given quota type.
  *
index b558214..003473a 100644 (file)
@@ -132,7 +132,7 @@ static void usage(void)
        "[-r fs-revision] [-E extended-option[,...]]\n"
        "\t[-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior]"
        "[-z undo_file]\n"
-       "\t[-jnqvDFKSV] device [blocks-count]\n"),
+       "\t[-jnqvDFSV] device [blocks-count]\n"),
                program_name);
        exit(1);
 }
@@ -771,23 +771,6 @@ static int set_os(struct ext2_super_block *sb, char *os)
 
 #define PATH_SET "PATH=/sbin"
 
-static int option_handle_function(char *token, void *data)
-{
-       if (!strncmp(token, "usr", 3)) {
-               quotatype_bits |= QUOTA_USR_BIT;
-       } else if (!strncmp(token, "grp", 3)) {
-               quotatype_bits |= QUOTA_GRP_BIT;
-       } else if (!strncmp(token, "prj", 3)) {
-               quotatype_bits |= QUOTA_PRJ_BIT;
-       } else {
-               fprintf(stderr, _("Invalid quotatype parameter: %s\n"),
-                               token);
-               return 1;
-       }
-       return 0;
-
-}
-
 static void parse_extended_opts(struct ext2_super_block *param,
                                const char *opts)
 {
@@ -1022,15 +1005,24 @@ static void parse_extended_opts(struct ext2_super_block *param,
                } else if (!strcmp(token, "nodiscard")) {
                        discard = 0;
                } else if (!strcmp(token, "quotatype")) {
+                       char *errtok = NULL;
+
                        if (!arg) {
                                r_usage++;
                                badopt = token;
                                continue;
                        }
-                       ret = parse_quota_opts(arg, option_handle_function,
-                                              NULL);
+                       quotatype_bits = 0;
+                       ret = parse_quota_types(arg, &quotatype_bits, &errtok);
                        if (ret) {
+                               if (errtok)
+                                       fprintf(stderr,
+                               "Failed to parse quota type at %s", errtok);
+                               else
+                                       com_err(program_name, ret,
+                                               "while parsing quota type");
                                r_usage++;
+                               badopt = token;
                                continue;
                        }
                } else {
@@ -1053,12 +1045,11 @@ static void parse_extended_opts(struct ext2_super_block *param,
                        "\tpacked_meta_blocks=<0 to disable, 1 to enable>\n"
                        "\tlazy_itable_init=<0 to disable, 1 to enable>\n"
                        "\tlazy_journal_init=<0 to disable, 1 to enable>\n"
-                       "\troot_uid=<uid of root directory>\n"
-                       "\troot_gid=<gid of root directory>\n"
+                       "\troot_owner=<uid of root dir>:<gid of root dir>\n"
                        "\ttest_fs\n"
                        "\tdiscard\n"
                        "\tnodiscard\n"
-                       "\tquotatype=<usr OR grp>\n\n"),
+                       "\tquotatype=<quota type(s) to be enabled>\n\n"),
                        badopt ? badopt : "");
                free(buf);
                exit(1);
@@ -2282,9 +2273,10 @@ profile_error:
                fprintf(stderr,
                        _("\nWarning: offset specified without an "
                          "explicit file system size.\n"
-                         "Creating a file system with %d blocks "
+                         "Creating a file system with %llu blocks "
                          "but this might\n"
-                         "not be what you want.\n\n"), fs_blocks_count);
+                         "not be what you want.\n\n"),
+                       (unsigned long long) fs_blocks_count);
        }
 
        /* Don't allow user to set both metadata_csum and uninit_bg bits. */