From: Theodore Ts'o Date: Tue, 15 Oct 2002 21:43:43 +0000 (-0400) Subject: Add support for new feature in ext2/3 filesystems; a default mount options field X-Git-Tag: E2FSPROGS-1_30~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0c3fd5e4cdc2e0b032c9ace89d960a622069c32;p=thirdparty%2Fe2fsprogs.git Add support for new feature in ext2/3 filesystems; a default mount options field in the superblock. Added the tune2fs '-o' option to set this field. --- diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog index 79714d4c3..ba6c7f991 100644 --- a/lib/e2p/ChangeLog +++ b/lib/e2p/ChangeLog @@ -1,3 +1,11 @@ +2002-10-15 + + * 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 * Release of E2fsprogs 1.29 diff --git a/lib/e2p/Makefile.in b/lib/e2p/Makefile.in index 8d20ab197..f78223e8c 100644 --- a/lib/e2p/Makefile.in +++ b/lib/e2p/Makefile.in @@ -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 diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h index f4e439818..d76155cef 100644 --- a/lib/e2p/e2p.h +++ b/lib/e2p/e2p.h @@ -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); diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c index 02388fff9..c18e0fff8 100644 --- a/lib/e2p/ls.c +++ b/lib/e2p/ls.c @@ -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 index 000000000..5db363e29 --- /dev/null +++ b/lib/e2p/mntopts.c @@ -0,0 +1,131 @@ +/* + * mountopts.c --- convert between default mount options and strings + * + * Copyright (C) 2002 Theodore Ts'o + * + * This file can be redistributed under the terms of the GNU Library General + * Public License + * + */ + +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index 3aea116e1..a12a6084a 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,3 +1,7 @@ +2002-10-15 + + * ext2_fs.h: Add new field in superblock for default mount options. + 2002-10-13 Theodore Ts'o * ext2fs.h: Add #include of header files necessary for ext2fs.h to diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index f2c4ac324..56fabbf33 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -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 */ }; /* @@ -500,6 +501,15 @@ struct ext2_super_block { #define EXT2_DEF_RESUID 0 #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 */ diff --git a/misc/ChangeLog b/misc/ChangeLog index 63351a1fd..038cb71cd 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,9 @@ +2002-10-15 + + * 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 * get_device_by_label.c (read_partitions): Use a 16k buffer to diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index 8c9825666..c146a2b8e 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -36,6 +36,11 @@ tune2fs \- adjust tunable filesystem parameters on second extended filesystems .B \-m .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 diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 2ea7abb3d..dd9f72478 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -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); @@ -248,6 +250,21 @@ static void remove_journal_inode(ext2_filsys fs) ext2fs_mark_super_dirty(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. */ @@ -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)