2007-07-23 20:18:33

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 1/3] ext2: show all mount options

From: Miklos Szeredi <[email protected]>

Signed-off-by: Miklos Szeredi <[email protected]>
---

Index: linux-2.6/fs/ext2/super.c
===================================================================
--- linux-2.6.orig/fs/ext2/super.c 2007-07-23 17:41:29.000000000 +0200
+++ linux-2.6/fs/ext2/super.c 2007-07-23 18:02:38.000000000 +0200
@@ -203,10 +203,66 @@ static void ext2_clear_inode(struct inod

static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
- struct ext2_sb_info *sbi = EXT2_SB(vfs->mnt_sb);
+ struct super_block *sb = vfs->mnt_sb;
+ struct ext2_sb_info *sbi = EXT2_SB(sb);
+ struct ext2_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);

- if (sbi->s_mount_opt & EXT2_MOUNT_GRPID)
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT2_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT2_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT2_ERRORS_PANIC ||
+ def_errors == EXT2_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+
+#ifdef CONFIG_EXT2_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT2_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT2_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");

#if defined(CONFIG_QUOTA)
if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA)
@@ -658,6 +714,7 @@ static int ext2_fill_super(struct super_
if (!sbi)
return -ENOMEM;
sb->s_fs_info = sbi;
+ sbi->s_sb_block = sb_block;

/*
* See what the current blocksize for the device is, and
Index: linux-2.6/include/linux/ext2_fs_sb.h
===================================================================
--- linux-2.6.orig/include/linux/ext2_fs_sb.h 2007-07-23 17:41:29.000000000 +0200
+++ linux-2.6/include/linux/ext2_fs_sb.h 2007-07-23 18:01:40.000000000 +0200
@@ -39,6 +39,7 @@ struct ext2_sb_info {
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ unsigned long s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;


2007-07-23 20:19:33

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 3/3] ext4: show all mount options

From: Miklos Szeredi <[email protected]>

Signed-off-by: Miklos Szeredi <[email protected]>
---

Index: linux-2.6/fs/ext4/super.c
===================================================================
--- linux-2.6.orig/fs/ext4/super.c 2007-07-20 12:22:35.000000000 +0200
+++ linux-2.6/fs/ext4/super.c 2007-07-23 21:02:47.000000000 +0200
@@ -596,9 +596,80 @@ static inline void ext4_show_quota_optio
#endif
}

+/*
+ * Show an option if
+ * - it's set to a non-default value OR
+ * - if the per-sb default is different from the global default
+ */
static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct super_block *sb = vfs->mnt_sb;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%llu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
+ seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT4_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT4_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT4_ERRORS_PANIC ||
+ def_errors == EXT4_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+#ifdef CONFIG_EXT4_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT4_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+#ifdef CONFIG_EXT4_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+ if (!test_opt(sb, RESERVATION))
+ seq_puts(seq, ",noreservation");
+ if (sbi->s_commit_interval) {
+ seq_printf(seq, ",commit=%u",
+ (unsigned) (sbi->s_commit_interval / HZ));
+ }
+ if (test_opt(sb, BARRIER))
+ seq_puts(seq, ",barrier=1");
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");
+ if (!test_opt(sb, EXTENTS))
+ seq_puts(seq, ",noextents");

if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
seq_puts(seq, ",data=journal");
@@ -1487,6 +1558,7 @@ static int ext4_fill_super (struct super
sbi->s_mount_opt = 0;
sbi->s_resuid = EXT4_DEF_RESUID;
sbi->s_resgid = EXT4_DEF_RESGID;
+ sbi->s_sb_block = sb_block;

unlock_kernel();

Index: linux-2.6/include/linux/ext4_fs_sb.h
===================================================================
--- linux-2.6.orig/include/linux/ext4_fs_sb.h 2007-07-20 12:22:40.000000000 +0200
+++ linux-2.6/include/linux/ext4_fs_sb.h 2007-07-23 20:55:28.000000000 +0200
@@ -45,6 +45,7 @@ struct ext4_sb_info {
struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ ext4_fsblk_t s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;

2007-07-23 20:26:36

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 2/3] ext3: show all mount options

From: Miklos Szeredi <[email protected]>

Signed-off-by: Miklos Szeredi <[email protected]>
---

Index: linux-2.6/fs/ext3/super.c
===================================================================
--- linux-2.6.orig/fs/ext3/super.c 2007-07-20 12:22:35.000000000 +0200
+++ linux-2.6/fs/ext3/super.c 2007-07-23 18:03:46.000000000 +0200
@@ -545,9 +545,78 @@ static inline void ext3_show_quota_optio
#endif
}

+/*
+ * Show an option if
+ * - it's set to a non-default value OR
+ * - if the per-sb default is different from the global default
+ */
static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct super_block *sb = vfs->mnt_sb;
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+ struct ext3_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
+ seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT3_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT3_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT3_ERRORS_PANIC ||
+ def_errors == EXT3_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+#ifdef CONFIG_EXT3_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT3_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT3_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+ if (!test_opt(sb, RESERVATION))
+ seq_puts(seq, ",noreservation");
+ if (sbi->s_commit_interval) {
+ seq_printf(seq, ",commit=%u",
+ (unsigned) (sbi->s_commit_interval / HZ));
+ }
+ if (test_opt(sb, BARRIER))
+ seq_puts(seq, ",barrier=1");
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");

if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
seq_puts(seq, ",data=journal");
@@ -1424,6 +1493,7 @@ static int ext3_fill_super (struct super
sbi->s_mount_opt = 0;
sbi->s_resuid = EXT3_DEF_RESUID;
sbi->s_resgid = EXT3_DEF_RESGID;
+ sbi->s_sb_block = sb_block;

unlock_kernel();

Index: linux-2.6/include/linux/ext3_fs_sb.h
===================================================================
--- linux-2.6.orig/include/linux/ext3_fs_sb.h 2007-07-20 12:22:40.000000000 +0200
+++ linux-2.6/include/linux/ext3_fs_sb.h 2007-07-23 18:05:24.000000000 +0200
@@ -44,6 +44,7 @@ struct ext3_sb_info {
struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ ext3_fsblk_t s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;

2007-07-23 20:57:24

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 1/3] ext2: show all mount options

On Mon, 23 Jul 2007 22:12:54 +0200
Miklos Szeredi <[email protected]> wrote:

> From: Miklos Szeredi <[email protected]>
>
> Signed-off-by: Miklos Szeredi <[email protected]>

Could we have changelogs for these patches, please?

ie: what's wrong with the existing code, what change does this patch make?

2007-07-23 23:21:21

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH 1/3] ext2: show all mount options

On Mon, Jul 23, 2007 at 01:56:42PM -0700, Andrew Morton wrote:
> On Mon, 23 Jul 2007 22:12:54 +0200
> Miklos Szeredi <[email protected]> wrote:
>
> > From: Miklos Szeredi <[email protected]>
> >
> > Signed-off-by: Miklos Szeredi <[email protected]>
>
> Could we have changelogs for these patches, please?
>
> ie: what's wrong with the existing code, what change does this patch make?

The idea is to allow /proc/mounts to display all of the mount options
that were used to mount a particular filesystem. This is useful if
you want /proc/mounts to replace /etc/mtab.

I keep thinking that this is really the wrong approach, though, since
it means adding a lot of coding to every single filesystem to
reconstruct the mount options, and in some cases it will still never
be enough to reconstruct exactly what was in /etc/mtab. (For example,
the fully qualified domain named passed into some remote filesystem.)

It seems to me the right answer would be to enhance the mount(2)
system call with a new mount operation which would allow the user
space mount command can stash exactly the options used to mount the
filesystem. That we the kernel can store the exact ascii string in
allocated memory and regurgitate it for the benefit of /proc/mounts,
instead of adding a lot of code into ext2, ext3, ext4, et. al in an
attempt partially reconstruct the mount options.

- Ted

2007-07-24 05:11:37

by Miklos Szeredi

[permalink] [raw]
Subject: Re: [PATCH 1/3] ext2: show all mount options

> The idea is to allow /proc/mounts to display all of the mount options
> that were used to mount a particular filesystem. This is useful if
> you want /proc/mounts to replace /etc/mtab.
>
> I keep thinking that this is really the wrong approach, though, since
> it means adding a lot of coding to every single filesystem to
> reconstruct the mount options, and in some cases it will still never
> be enough to reconstruct exactly what was in /etc/mtab. (For example,
> the fully qualified domain named passed into some remote filesystem.)
>
> It seems to me the right answer would be to enhance the mount(2)
> system call with a new mount operation which would allow the user
> space mount command can stash exactly the options used to mount the
> filesystem.

Well, that would be good for emulating /etc/mtab. But the problem is
that that's wrong a lot of times. For example in ext* "mount
-oremount,opt" doesn't reset all options, it just changes "opt". And
this is different from fs to fs, so there's no easy way to handle it
from generic code.

I think it shouln't be hard to keep the shown mount options in sync
with the parsed options. The problem is just that people have been
lazy to do that, because /etc/mtab was good enough.

Miklos