Originally from: Herbert Poetzl <herbert@xxxxxxxxxxxx> This is the core of the read-only bind mount patch set. This patch introduces MNT_RDONLY and ensures that it is checked before any users may obtain write permissions for a file through any mount. Signed-off-by: Dave Hansen <haveblue@xxxxxxxxxx> --- lxc-dave/fs/file.c | 1 + lxc-dave/fs/inode.c | 2 +- lxc-dave/fs/namespace.c | 8 ++++++-- lxc-dave/include/linux/mount.h | 3 +++ lxc-dave/mm/filemap.c | 3 +++ 5 files changed, 14 insertions(+), 3 deletions(-) diff -puN fs/file.c~D8-actually-add-flags fs/file.c --- lxc/fs/file.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/file.c 2006-06-07 16:53:29.000000000 -0700 @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/file.h> +#include <linux/mount.h> #include <linux/bitops.h> #include <linux/interrupt.h> #include <linux/spinlock.h> diff -puN fs/inode.c~D8-actually-add-flags fs/inode.c --- lxc/fs/inode.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/inode.c 2006-06-07 16:53:29.000000000 -0700 @@ -1185,7 +1185,7 @@ void touch_atime(struct vfsmount *mnt, s struct inode *inode = dentry->d_inode; struct timespec now; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || (mnt->mnt_flags & MNT_RDONLY)) return; if ((inode->i_flags & S_NOATIME) || diff -puN fs/namespace.c~D8-actually-add-flags fs/namespace.c --- lxc/fs/namespace.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/namespace.c 2006-06-07 16:53:29.000000000 -0700 @@ -905,7 +905,8 @@ static int do_change_type(struct nameida /* * do loopback mount. */ -static int do_loopback(struct nameidata *nd, char *old_name, int recurse) +static int do_loopback(struct nameidata *nd, char *old_name, + int recurse, int mnt_flags) { struct nameidata old_nd; struct vfsmount *mnt = NULL; @@ -943,6 +944,7 @@ static int do_loopback(struct nameidata spin_unlock(&vfsmount_lock); release_mounts(&umount_list); } + mnt->mnt_flags = mnt_flags; out: up_write(&namespace_sem); @@ -1403,6 +1405,8 @@ long do_mount(char *dev_name, char *dir_ ((char *)data_page)[PAGE_SIZE - 1] = 0; /* Separate the per-mountpoint flags */ + if (flags & MS_RDONLY) + mnt_flags |= MNT_RDONLY; if (flags & MS_NOSUID) mnt_flags |= MNT_NOSUID; if (flags & MS_NODEV) @@ -1430,7 +1434,7 @@ long do_mount(char *dev_name, char *dir_ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, data_page); else if (flags & MS_BIND) - retval = do_loopback(&nd, dev_name, flags & MS_REC); + retval = do_loopback(&nd, dev_name, flags & MS_REC, mnt_flags); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&nd, flags); else if (flags & MS_MOVE) diff -puN include/linux/mount.h~D8-actually-add-flags include/linux/mount.h --- lxc/include/linux/mount.h~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/include/linux/mount.h 2006-06-07 16:53:29.000000000 -0700 @@ -24,6 +24,7 @@ #define MNT_NOEXEC 0x04 #define MNT_NOATIME 0x08 #define MNT_NODIRATIME 0x10 +#define MNT_RDONLY 0x20 #define MNT_SHRINKABLE 0x100 @@ -63,6 +64,8 @@ static inline struct vfsmount *mntget(st static inline int mnt_want_write(struct vfsmount *mnt) { + if (mnt->mnt_flags & MNT_RDONLY) + return -EROFS; atomic_inc(&mnt->mnt_writers); return 0; } diff -puN mm/filemap.c~D8-actually-add-flags mm/filemap.c --- lxc/mm/filemap.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/mm/filemap.c 2006-06-07 16:53:29.000000000 -0700 @@ -23,6 +23,7 @@ #include <linux/mman.h> #include <linux/pagemap.h> #include <linux/file.h> +#include <linux/mount.h> #include <linux/uio.h> #include <linux/hash.h> #include <linux/writeback.h> @@ -1960,6 +1961,8 @@ inline int generic_write_checks(struct f return -EINVAL; if (!isblk) { + if (file->f_vfsmnt->mnt_flags & MNT_RDONLY) + return -EROFS; /* FIXME: this is for backwards compatibility with 2.4 */ if (file->f_flags & O_APPEND) *pos = i_size_read(inode); _ - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html