in the superblock. Added the tune2fs '-o' option to set this field.
+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
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
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);
#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
} 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");
--- /dev/null
+/*
+ * 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;
+}
+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
__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 */
};
/*
#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
+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
.I reserved-blocks-percentage
]
[
+.B \-o
+.RI [^] mount-options [,...]
+]
+
+[
.B \-r
.I reserved-blocks-count
]
.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
static unsigned short errors;
static int open_flag;
static char *features_cmd;
+static char *mntopts_cmd;
int journal_size, journal_flags;
char *journal_device;
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);
}
/*
+ * 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)
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':
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,
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)