From bf9faa2aa30e2ebf30287536712ed2717bb47002 Mon Sep 17 00:00:00 2001 From: "J. R. Okajima" Date: Wed, 23 Feb 2011 16:59:49 +0900 Subject: Unlock vfsmount_lock in do_umount By the commit b3e19d9 2011-01-07 fs: scale mntget/mntput vfsmount_lock was introduced around testing mnt_count. Fix the mis-typed 'unlock' Signed-off-by: J. R. Okajima Acked-by: Al Viro Signed-off-by: Al Viro --- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 7b0b95371696..d1edf26025dc 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1244,7 +1244,7 @@ static int do_umount(struct vfsmount *mnt, int flags) */ br_write_lock(vfsmount_lock); if (mnt_get_count(mnt) != 2) { - br_write_lock(vfsmount_lock); + br_write_unlock(vfsmount_lock); return -EBUSY; } br_write_unlock(vfsmount_lock); -- cgit From ff36fe2c845cab2102e4826c1ffa0a6ebf487c65 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 3 Mar 2011 16:09:14 -0500 Subject: LSM: Pass -o remount options to the LSM The VFS mount code passes the mount options to the LSM. The LSM will remove options it understands from the data and the VFS will then pass the remaining options onto the underlying filesystem. This is how options like the SELinux context= work. The problem comes in that -o remount never calls into LSM code. So if you include an LSM specific option it will get passed to the filesystem and will cause the remount to fail. An example of where this is a problem is the 'seclabel' option. The SELinux LSM hook will print this word in /proc/mounts if the filesystem is being labeled using xattrs. If you pass this word on mount it will be silently stripped and ignored. But if you pass this word on remount the LSM never gets called and it will be passed to the FS. The FS doesn't know what seclabel means and thus should fail the mount. For example an ext3 fs mounted over loop # mount -o loop /tmp/fs /mnt/tmp # cat /proc/mounts | grep /mnt/tmp /dev/loop0 /mnt/tmp ext3 rw,seclabel,relatime,errors=continue,barrier=0,data=ordered 0 0 # mount -o remount /mnt/tmp mount: /mnt/tmp not mounted already, or bad option # dmesg EXT3-fs (loop0): error: unrecognized mount option "seclabel" or missing value This patch passes the remount mount options to an new LSM hook. Signed-off-by: Eric Paris Reviewed-by: James Morris --- fs/namespace.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 3ddfd9046c44..1b3f2ac59c5e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1800,6 +1800,10 @@ static int do_remount(struct path *path, int flags, int mnt_flags, if (path->dentry != path->mnt->mnt_root) return -EINVAL; + err = security_sb_remount(sb, data); + if (err) + return err; + down_write(&sb->s_umount); if (flags & MS_BIND) err = change_mount_flags(path->mnt, flags); -- cgit From 93f1c20bc8cdb757be50566eff88d65c3b26881f Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 29 Jan 2011 18:43:38 +0530 Subject: vfs: Export file system uuid via /proc//mountinfo We add a per superblock uuid field. File systems should update the uuid in the fill_super callback Signed-off-by: Aneesh Kumar K.V Signed-off-by: Al Viro --- fs/namespace.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index d1edf26025dc..dffe6f49ab93 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1002,6 +1002,18 @@ const struct seq_operations mounts_op = { .show = show_vfsmnt }; +static int uuid_is_nil(u8 *uuid) +{ + int i; + u8 *cp = (u8 *)uuid; + + for (i = 0; i < 16; i++) { + if (*cp++) + return 0; + } + return 1; +} + static int show_mountinfo(struct seq_file *m, void *v) { struct proc_mounts *p = m->private; @@ -1040,6 +1052,10 @@ static int show_mountinfo(struct seq_file *m, void *v) if (IS_MNT_UNBINDABLE(mnt)) seq_puts(m, " unbindable"); + if (!uuid_is_nil(mnt->mnt_sb->s_uuid)) + /* print the uuid */ + seq_printf(m, " uuid:%pU", mnt->mnt_sb->s_uuid); + /* Filesystem specific data */ seq_puts(m, " - "); show_type(m, sb); -- cgit From c7f404b40a3665d9f4e9a927cc5c1ee0479ed8f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 16 Mar 2011 06:59:40 -0400 Subject: vfs: new superblock methods to override /proc/*/mount{s,info} a) ->show_devname(m, mnt) - what to put into devname columns in mounts, mountinfo and mountstats b) ->show_path(m, mnt) - what to put into relative path column in mountinfo Leaving those NULL gives old behaviour. NFS switched to using those. Signed-off-by: Al Viro --- fs/namespace.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index dffe6f49ab93..75d843ae46d2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -978,7 +978,13 @@ static int show_vfsmnt(struct seq_file *m, void *v) int err = 0; struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (mnt->mnt_sb->s_op->show_devname) { + err = mnt->mnt_sb->s_op->show_devname(m, mnt); + if (err) + goto out; + } else { + mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + } seq_putc(m, ' '); seq_path(m, &mnt_path, " \t\n\\"); seq_putc(m, ' '); @@ -1025,7 +1031,12 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, MAJOR(sb->s_dev), MINOR(sb->s_dev)); - seq_dentry(m, mnt->mnt_root, " \t\n\\"); + if (sb->s_op->show_path) + err = sb->s_op->show_path(m, mnt); + else + seq_dentry(m, mnt->mnt_root, " \t\n\\"); + if (err) + goto out; seq_putc(m, ' '); seq_path_root(m, &mnt_path, &root, " \t\n\\"); if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { @@ -1060,7 +1071,12 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_puts(m, " - "); show_type(m, sb); seq_putc(m, ' '); - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (sb->s_op->show_devname) + err = sb->s_op->show_devname(m, mnt); + else + mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); + if (err) + goto out; seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); err = show_sb_opts(m, sb); if (err) @@ -1086,11 +1102,15 @@ static int show_vfsstat(struct seq_file *m, void *v) int err = 0; /* device */ - if (mnt->mnt_devname) { - seq_puts(m, "device "); - mangle(m, mnt->mnt_devname); - } else - seq_puts(m, "no device"); + if (mnt->mnt_sb->s_op->show_devname) { + err = mnt->mnt_sb->s_op->show_devname(m, mnt); + } else { + if (mnt->mnt_devname) { + seq_puts(m, "device "); + mangle(m, mnt->mnt_devname); + } else + seq_puts(m, "no device"); + } /* mount point */ seq_puts(m, " mounted on "); @@ -1104,7 +1124,8 @@ static int show_vfsstat(struct seq_file *m, void *v) /* optional statistics */ if (mnt->mnt_sb->s_op->show_stats) { seq_putc(m, ' '); - err = mnt->mnt_sb->s_op->show_stats(m, mnt); + if (!err) + err = mnt->mnt_sb->s_op->show_stats(m, mnt); } seq_putc(m, '\n'); -- cgit