Whamcloud - gitweb
Add support for new feature in ext2/3 filesystems; a default mount options field
authorTheodore Ts'o <tytso@mit.edu>
Tue, 15 Oct 2002 21:43:43 +0000 (17:43 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 15 Oct 2002 21:43:43 +0000 (17:43 -0400)
in the superblock.  Added the tune2fs '-o' option to set this field.

lib/e2p/ChangeLog
lib/e2p/Makefile.in
lib/e2p/e2p.h
lib/e2p/ls.c
lib/e2p/mntopts.c [new file with mode: 0644]
lib/ext2fs/ChangeLog
lib/ext2fs/ext2_fs.h
misc/ChangeLog
misc/tune2fs.8.in
misc/tune2fs.c

index 79714d4..ba6c7f9 100644 (file)
@@ -1,3 +1,11 @@
+2002-10-15    <tytso@snap.thunk.org>
+
+       * ls.c (print_mntopts, list_super2): Print any default mount
+               options which the filesystem might have.
+
+       * e2p.h, mntopts.c: New function which converts back and forth
+               between strings and default mount options.
+
 2001-09-24  Theodore Tso  <tytso@mit.edu>
 
        * Release of E2fsprogs 1.29
index 8d20ab1..f78223e 100644 (file)
@@ -17,16 +17,16 @@ INSTALL = @INSTALL@
 all::
 
 OBJS=          feature.o fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
-               getflags.o getversion.o hashstr.o iod.o ls.o pe.o pf.o ps.o \
-               setflags.o setversion.o uuid.o 
+               getflags.o getversion.o hashstr.o iod.o ls.o mntopts.o \
+               pe.o pf.o ps.o setflags.o setversion.o uuid.o 
 
 SRCS=          $(srcdir)/feature.c $(srcdir)/fgetflags.c \
                $(srcdir)/fsetflags.c $(srcdir)/fgetversion.c \
                $(srcdir)/fsetversion.c $(srcdir)/getflags.c \
                $(srcdir)/getversion.c $(srcdir)/hashstr.o $(srcdir)/iod.c \
-               $(srcdir)/ls.c $(srcdir)/pe.c $(srcdir)/pf.c $(srcdir)/ps.c \
-               $(srcdir)/setflags.c $(srcdir)/setversion.c \
-               $(srcdir)/uuid.c
+               $(srcdir)/ls.c (srcdir)/mntopts.o $(srcdir)/pe.c \
+               $(srcdir)/pf.c $(srcdir)/ps.c $(srcdir)/setflags.c \
+               $(srcdir)/setversion.c $(srcdir)/uuid.c
 
 HFILES= e2p.h
 
index f4e4398..d76155c 100644 (file)
@@ -41,3 +41,7 @@ const char *e2p_uuid2str(void *uu);
 
 const char *e2p_hash2string(int num);
 int e2p_string2hash(char *string);
+
+const char *e2p_mntopt2string(int compat, unsigned int mask);
+int e2p_string2mntopt(char *string, unsigned int *mask);
+int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok);
index 02388ff..c18e0ff 100644 (file)
@@ -112,6 +112,24 @@ static void print_features(struct ext2_super_block * s, FILE *f)
 #endif
 }
 
+static void print_mntopts(struct ext2_super_block * s, FILE *f)
+{
+#ifdef EXT2_DYNAMIC_REV
+       int     i, printed=0;
+       __u32   mask = s->s_default_mount_opts, m;
+
+       fprintf(f, "Default mount options:   ");
+       for (i=0,m=1; i < 32; i++, m<<=1) {
+               if (mask & m) {
+                       fprintf(f, " %s", e2p_mntopt2string(i, m));
+                       printed++;
+               }
+       }
+       if (printed == 0)
+               fprintf(f, " (none)");
+       fprintf(f, "\n");
+#endif
+}
 
 
 #ifndef EXT2_INODE_SIZE
@@ -157,6 +175,7 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
        } else
                fprintf(f, " (unknown)\n");
        print_features(sb, f);
+       print_mntopts(sb, f);
        fprintf(f, "Filesystem state:        ");
        print_fs_state (f, sb->s_state);
        fprintf(f, "\n");
diff --git a/lib/e2p/mntopts.c b/lib/e2p/mntopts.c
new file mode 100644 (file)
index 0000000..5db363e
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * mountopts.c --- convert between default mount options and strings
+ * 
+ * Copyright (C) 2002  Theodore Ts'o <tytso@mit.edu>
+ * 
+ * This file can be redistributed under the terms of the GNU Library General
+ * Public License
+ * 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "e2p.h"
+
+struct mntopt {
+       unsigned int    mask;
+       const char      *string;
+};
+
+static struct mntopt mntopt_list[] = {
+       { EXT2_DEFM_DEBUG,      "debug" },
+       { EXT2_DEFM_BSDGROUPS,  "bsdgroups" },
+       { EXT2_DEFM_XATTR_USER, "user_xattr" },
+       { EXT2_DEFM_ACL,        "acl" },
+       { EXT2_DEFM_UID16,      "uid16" },
+       {       0, 0 },
+};
+
+const char *e2p_mntopt2string(int compat, unsigned int mask)
+{
+       struct mntopt  *f;
+       static char buf[20];
+       int     fnum;
+
+       for (f = mntopt_list; f->string; f++) {
+               if (mask == f->mask)
+                       return f->string;
+       }
+       for (fnum = 0; mask >>= 1; fnum++);
+       sprintf(buf, "MNTOPT_%d", fnum);
+       return buf;
+}
+
+int e2p_string2mntopt(char *string, unsigned int *mask)
+{
+       struct mntopt  *f;
+       char            *eptr;
+       int             num;
+
+       for (f = mntopt_list; f->string; f++) {
+               if (!strcasecmp(string, f->string)) {
+                       *mask = f->mask;
+                       return 0;
+               }
+       }
+       if (strncasecmp(string, "MNTOPT_", 8))
+               return 1;
+
+       if (string[8] == 0)
+               return 1;
+       num = strtol(string+8, &eptr, 10);
+       if (num > 32 || num < 0)
+               return 1;
+       if (*eptr)
+               return 1;
+       *mask = 1 << num;
+       return 0;
+}
+
+static char *skip_over_blanks(char *cp)
+{
+       while (*cp && isspace(*cp))
+               cp++;
+       return cp;
+}
+
+static char *skip_over_word(char *cp)
+{
+       while (*cp && !isspace(*cp) && *cp != ',')
+               cp++;
+       return cp;
+}
+
+/*
+ * Edit a mntopt set array as requested by the user.  The ok
+ * parameter, if non-zero, allows the application to limit what
+ * mntopts the user is allowed to set or clear using this function.
+ */
+int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok)
+{
+       char    *cp, *buf, *next;
+       int     neg;
+       unsigned int    mask;
+
+       buf = malloc(strlen(str)+1);
+       if (!buf)
+               return 1;
+       strcpy(buf, str);
+       cp = buf;
+       while (cp && *cp) {
+               neg = 0;
+               cp = skip_over_blanks(cp);
+               next = skip_over_word(cp);
+               if (*next == 0)
+                       next = 0;
+               else
+                       *next = 0;
+               switch (*cp) {
+               case '-':
+               case '^':
+                       neg++;
+               case '+':
+                       cp++;
+                       break;
+               }
+               if (e2p_string2mntopt(cp, &mask))
+                       return 1;
+               if (ok && !(ok & mask))
+                       return 1;
+               if (neg)
+                       *mntopts &= ~mask;
+               else
+                       *mntopts |= mask;
+               cp = next ? next+1 : 0;
+       }
+       return 0;
+}
index 3aea116..a12a608 100644 (file)
@@ -1,3 +1,7 @@
+2002-10-15    <tytso@snap.thunk.org>
+
+       * ext2_fs.h: Add new field in superblock for default mount options.
+
 2002-10-13  Theodore Ts'o  <tytso@mit.edu>
 
        * ext2fs.h: Add #include of header files necessary for ext2fs.h to
index f2c4ac3..56fabbf 100644 (file)
@@ -438,7 +438,8 @@ struct ext2_super_block {
        __u8    s_def_hash_version;     /* Default hash version to use */
        __u8    s_reserved_char_pad;
        __u16   s_reserved_word_pad;
-       __u32   s_reserved[192];        /* Padding to the end of the block */
+       __u32   s_default_mount_opts;
+       __u32   s_reserved[191];        /* Padding to the end of the block */
 };
 
 /*
@@ -501,6 +502,15 @@ struct ext2_super_block {
 #define EXT2_DEF_RESGID                0
 
 /*
+ * Default mount options
+ */
+#define EXT2_DEFM_DEBUG                0x0001
+#define EXT2_DEFM_BSDGROUPS    0x0002
+#define EXT2_DEFM_XATTR_USER   0x0004
+#define EXT2_DEFM_ACL          0x0008
+#define EXT2_DEFM_UID16                0x0010
+
+/*
  * Structure of a directory entry
  */
 #define EXT2_NAME_LEN 255
index 63351a1..038cb71 100644 (file)
@@ -1,3 +1,9 @@
+2002-10-15    <tytso@snap.thunk.org>
+
+       * tune2fs.8.in, tune2fs.c (update_mntopts, main): Add new option
+               'o' which allows the system administrator to specify
+               default mount options.
+
 2002-10-13  Theodore Ts'o  <tytso@mit.edu>
 
        * get_device_by_label.c (read_partitions): Use a 16k buffer to
index 8c98256..c146a2b 100644 (file)
@@ -37,6 +37,11 @@ tune2fs \- adjust tunable filesystem parameters on second extended filesystems
 .I reserved-blocks-percentage
 ]
 [
+.B \-o
+.RI [^] mount-options [,...]
+]
+
+[
 .B \-r
 .I reserved-blocks-count
 ]
@@ -256,6 +261,49 @@ Set the percentage of reserved filesystem blocks.
 .BI \-M " last-mounted-directory"
 Set the last-mounted directory for the filesystem.
 .TP
+.BR \-o " [^]\fImount-option\fR[,...]"
+Set or clear the indicated default mount options in the filesystem.
+Default mount options can be overriden by mount options specified 
+either in 
+.BR /etc/fstab (5)
+or on the command line arguments to
+.BR mount (8).   
+Older kernels may not support this feature; in particular,
+kernels which predate 2.4.20 will almost certainly ignore the
+default mount options field in the superblock.
+.IP
+More than one mount option can be cleared or set by separating
+features with commas.  Mount options prefixed with a 
+caret character ('^') will be cleared in the filesystem's superblock; 
+mount options without a prefix character or prefixed with a plus 
+character ('+') will be added to the filesystem.
+.IP
+The following mount options can be set or cleared using
+.BR tune2fs :
+.RS 1.2i
+.TP
+.B debug
+Enable debugging code for this filesystem.
+.TP
+.B bsdgroups
+Emulate BSD behaviour when creating new files: they will take the group-id
+of the directory in which they were created.  The standard System V behaviour
+is the default, where newly created files take on the fsgid of the crrent
+process, unless the directry has the setgid bit set, in which case it takes 
+the gid from the parent directory, and also gets the setgid bit set if it is 
+directory itself.
+.TP
+.B user_xattr
+Enable user-specified extended attributes.
+.TP
+.B acl
+Enable Posix Access Control Lists.
+.TP
+.B uid16
+Disables 32-bit UIDs and GIDs.  This is for interoperability with
+older kernels which only store and expect 16-bit values.
+.RE
+.TP
 .BR \-O " [^]\fIfeature\fR[,...]"
 Set or clear the indicated filesystem features (options) in the filesystem.
 More than one filesystem feature can be cleared or set by separating
index 2ea7abb..dd9f724 100644 (file)
@@ -66,6 +66,7 @@ static unsigned long resgid, resuid;
 static unsigned short errors;
 static int open_flag;
 static char *features_cmd;
+static char *mntopts_cmd;
 
 int journal_size, journal_flags;
 char *journal_device;
@@ -79,10 +80,11 @@ static void usage(void)
        fprintf(stderr,
                _("Usage: %s [-c max-mounts-count] [-e errors-behavior] "
                  "[-g group]\n"
-                "\t[-i interval[d|m|w]] [-j] [-J journal-options]\n"
-                "\t[-l] [-s sparse-flag] [-m reserved-blocks-percent]\n"
-                 "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
-                 "\t[-L volume-label] [-M last-mounted-dir]\n"
+                 "\t[-i interval[d|m|w]] [-j] [-J journal-options]\n"
+                 "\t[-l] [-s sparse-flag] [-m reserved-blocks-percent]\n"
+                 "\t[-o [^]mount-options[,...]] [-r reserved-blocks-count]\n"
+                 "\t[-u user] [-C mount-count] [-L volume-label] "
+                 "[-M last-mounted-dir]\n"
                  "\t[-O [^]feature[,...]] [-T last-check-time] [-U UUID]"
                  " device\n"), program_name);
        exit (1);
@@ -249,6 +251,21 @@ static void remove_journal_inode(ext2_filsys fs)
 }
 
 /*
+ * Update the default mount options
+ */
+static void update_mntopts(ext2_filsys fs, char *mntopts)
+{
+       struct ext2_super_block *sb= fs->super;
+
+       if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) {
+               fprintf(stderr, _("Invalid mount option set: %s\n"),
+                       mntopts);
+               exit(1);
+       }
+       ext2fs_mark_super_dirty(fs);
+}
+
+/*
  * Update the feature set as provided by the user.
  */
 static void update_feature_set(ext2_filsys fs, char *features)
@@ -445,7 +462,7 @@ static void parse_tune2fs_options(int argc, char **argv)
        struct passwd * pw;
 
        printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
-       while ((c = getopt(argc, argv, "c:e:fg:i:jlm:r:s:u:C:J:L:M:O:T:U:")) != EOF)
+       while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF)
                switch (c)
                {
                        case 'c':
@@ -577,6 +594,16 @@ static void parse_tune2fs_options(int argc, char **argv)
                                M_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
+                       case 'o':
+                               if (mntopts_cmd) {
+                                       com_err (program_name, 0,
+                                        _("-o may only be specified once"));
+                                       usage();
+                               }
+                               mntopts_cmd = optarg;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
+                               
                        case 'O':
                                if (features_cmd) {
                                        com_err (program_name, 0,
@@ -811,6 +838,8 @@ int main (int argc, char ** argv)
                        sizeof(sb->s_last_mounted));
                ext2fs_mark_super_dirty(fs);
        }
+       if (mntopts_cmd)
+               update_mntopts(fs, mntopts_cmd);
        if (features_cmd)
                update_feature_set(fs, features_cmd);
        if (journal_size || journal_device)