linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags
@ 2006-01-21  8:38 Herbert Poetzl
  2006-01-21  8:40 ` [PATCH 1/6] vfs: add missing MNT_RDONLY and macro to check Herbert Poetzl
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:38 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton; +Cc: Christoph Hellwig, Al Viro, Linux Kernel ML


The following set of patches extends the per device 
'noatime', 'nodiratime' and last but not least the 
'ro' (read only) mount option to the vfs --bind mounts, 
allowing them to behave like any other mount, by 
honoring those mount flags (which are silently ignored 
by the current implementation in 2.4.x and 2.6.x)   	

the patch makes the following syscall variations behave 
as expected:

 - open (read/write/trunc), create
 - link, symlink, unlink
 - mknod (reg/block/char/fifo)
 - mkfifo, mkdir, rmdir, rename
 - (f,l)chown, (f)chmod, utime
 - access, truncate, mmap
 - ioctl (gen/ext2/ext3/reiser)
 - (f,l)setxattr, (f,l)removexattr

an older version of this patch was included in 
2.6.0-test6-mm2, and v2.6.4-wolk2.0, the patches are
in use by several people, without any issues ...

please consider inclusion (in -mm ?) and/or let me know
what needs to be changed to get this functionality into
mainline ...

TIA,
Herbert


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/6] vfs: add missing MNT_RDONLY and macro to check
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
@ 2006-01-21  8:40 ` Herbert Poetzl
  2006-01-21  8:40 ` [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount Herbert Poetzl
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:40 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; the missing MNT_RDONLY mount flag is added together with
; a macro MNT_IS_RDONLY(m) to check it on a vfsmount
;
; the separate flag to string structures in show_vfsmnt are
; combined and adjusted to honor the new flag, which is set
; at do_mount time
;
;
; Changelog:
;
;   0.01  - broken out part from bme0.05
;   0.02  - moved the loopback mounts into separate patch
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/fs/namespace.c linux-2.6.16-rc1-bme0.06.2-bm0.02/fs/namespace.c
--- linux-2.6.16-rc1/fs/namespace.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-bm0.02/fs/namespace.c	2006-01-21 09:08:20 +0100
@@ -354,37 +354,40 @@ static int show_vfsmnt(struct seq_file *
 	struct vfsmount *mnt = v;
 	int err = 0;
 	static struct proc_fs_info {
-		int flag;
-		char *str;
+		int s_flag;
+		int mnt_flag;
+		char *set_str;
+		char *unset_str;
 	} fs_info[] = {
-		{ MS_SYNCHRONOUS, ",sync" },
-		{ MS_DIRSYNC, ",dirsync" },
-		{ MS_MANDLOCK, ",mand" },
-		{ 0, NULL }
-	};
-	static struct proc_fs_info mnt_info[] = {
-		{ MNT_NOSUID, ",nosuid" },
-		{ MNT_NODEV, ",nodev" },
-		{ MNT_NOEXEC, ",noexec" },
-		{ MNT_NOATIME, ",noatime" },
-		{ MNT_NODIRATIME, ",nodiratime" },
-		{ 0, NULL }
+		{ MS_RDONLY, MNT_RDONLY, "ro", "rw" },
+		{ MS_SYNCHRONOUS, 0, ",sync", NULL },
+		{ MS_DIRSYNC, 0, ",dirsync", NULL },
+		{ MS_MANDLOCK, 0, ",mand", NULL },
+		{ MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
+		{ MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
+		{ 0, MNT_NOSUID, ",nosuid", NULL },
+		{ 0, MNT_NODEV, ",nodev", NULL },
+		{ 0, MNT_NOEXEC, ",noexec", NULL },
+		{ 0, 0, NULL, NULL }
 	};
-	struct proc_fs_info *fs_infop;
+	struct proc_fs_info *p;
+	unsigned long s_flags = mnt->mnt_sb->s_flags;
+	int mnt_flags = mnt->mnt_flags;
 
 	mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
 	seq_putc(m, ' ');
 	seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
 	seq_putc(m, ' ');
 	mangle(m, mnt->mnt_sb->s_type->name);
-	seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
-	for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
-		if (mnt->mnt_sb->s_flags & fs_infop->flag)
-			seq_puts(m, fs_infop->str);
-	}
-	for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
-		if (mnt->mnt_flags & fs_infop->flag)
-			seq_puts(m, fs_infop->str);
+	seq_putc(m, ' ');
+	for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
+		if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
+			if (p->set_str)
+				seq_puts(m, p->set_str);
+		} else {
+			if (p->unset_str)
+				seq_puts(m, p->unset_str);
+		}
 	}
 	if (mnt->mnt_sb->s_op->show_options)
 		err = mnt->mnt_sb->s_op->show_options(m, mnt);
@@ -1285,6 +1288,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)
diff -NurpP --minimal linux-2.6.16-rc1/include/linux/fs.h linux-2.6.16-rc1-bme0.06.2-bm0.02/include/linux/fs.h
--- linux-2.6.16-rc1/include/linux/fs.h	2006-01-18 06:08:43 +0100
+++ linux-2.6.16-rc1-bme0.06.2-bm0.02/include/linux/fs.h	2006-01-21 09:08:20 +0100
@@ -150,7 +150,7 @@ extern int dir_notify_enable;
  */
 #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
 
-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_RDONLY(inode)	__IS_FLG(inode, MS_RDONLY)
 #define IS_SYNC(inode)		(__IS_FLG(inode, MS_SYNCHRONOUS) || \
 					((inode)->i_flags & S_SYNC))
 #define IS_DIRSYNC(inode)	(__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
diff -NurpP --minimal linux-2.6.16-rc1/include/linux/mount.h linux-2.6.16-rc1-bme0.06.2-bm0.02/include/linux/mount.h
--- linux-2.6.16-rc1/include/linux/mount.h	2006-01-18 06:08:43 +0100
+++ linux-2.6.16-rc1-bme0.06.2-bm0.02/include/linux/mount.h	2006-01-21 09:08:20 +0100
@@ -22,6 +22,9 @@
 #define MNT_NOEXEC	0x04
 #define MNT_NOATIME	0x08
 #define MNT_NODIRATIME	0x10
+#define MNT_RDONLY	0x20
+
+#define MNT_IS_RDONLY(m)	((m) && ((m)->mnt_flags & MNT_RDONLY))
 
 #define MNT_SHARED	0x1000	/* if the vfsmount is a shared mount */
 #define MNT_UNBINDABLE	0x2000	/* if the vfsmount is a unbindable mount */


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
  2006-01-21  8:40 ` [PATCH 1/6] vfs: add missing MNT_RDONLY and macro to check Herbert Poetzl
@ 2006-01-21  8:40 ` Herbert Poetzl
  2006-01-22 10:06   ` Suleiman Souhlal
  2006-01-24 19:02   ` Christoph Hellwig
  2006-01-21  8:41 ` [PATCH 3/6] vfs: propagate vfsmount into chown_common() Herbert Poetzl
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:40 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; the mnt_flags are propagated into do_loopback(), so that
; they can be stored with the vfsmount
;
;
; Changelog:
;
;   0.01  - broken out from bm0.01
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/fs/namespace.c linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c
--- linux-2.6.16-rc1/fs/namespace.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c	2006-01-21 09:08:29 +0100
@@ -861,11 +861,13 @@ 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, unsigned long flags, int mnt_flags)
 {
 	struct nameidata old_nd;
 	struct vfsmount *mnt = NULL;
+	int recurse = flags & MS_REC;
 	int err = mount_is_safe(nd);
+
 	if (err)
 		return err;
 	if (!old_name || !*old_name)
@@ -899,6 +901,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);
@@ -1312,7 +1315,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, mnt_flags);
 	else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
 		retval = do_change_type(&nd, flags);
 	else if (flags & MS_MOVE)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3/6] vfs: propagate vfsmount into chown_common()
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
  2006-01-21  8:40 ` [PATCH 1/6] vfs: add missing MNT_RDONLY and macro to check Herbert Poetzl
  2006-01-21  8:40 ` [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount Herbert Poetzl
@ 2006-01-21  8:41 ` Herbert Poetzl
  2006-01-21  8:42 ` [PATCH 4/6] vfs: propagate the nameidata into the relevant vfs_*() Herbert Poetzl
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:41 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; the vfsmount is propagated into chown_common() to allow
; for vfsmount based checks there, in this case the
; MNT_IS_RDONLY() check to disallow changes
;
;
; Changelog:
;
;   0.01  - broken out from bme0.05
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/fs/open.c linux-2.6.16-rc1-bme0.06.2-cc0.01/fs/open.c
--- linux-2.6.16-rc1/fs/open.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-cc0.01/fs/open.c	2006-01-21 09:08:38 +0100
@@ -669,7 +669,8 @@ out:
 	return error;
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
+	uid_t user, gid_t group)
 {
 	struct inode * inode;
 	int error;
@@ -681,7 +682,7 @@ static int chown_common(struct dentry * 
 		goto out;
 	}
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
 		goto out;
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
@@ -711,7 +712,7 @@ asmlinkage long sys_chown(const char __u
 
 	error = user_path_walk(filename, &nd);
 	if (!error) {
-		error = chown_common(nd.dentry, user, group);
+		error = chown_common(nd.dentry, nd.mnt, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -724,7 +725,7 @@ asmlinkage long sys_lchown(const char __
 
 	error = user_path_walk_link(filename, &nd);
 	if (!error) {
-		error = chown_common(nd.dentry, user, group);
+		error = chown_common(nd.dentry, nd.mnt, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -738,7 +739,7 @@ asmlinkage long sys_fchown(unsigned int 
 
 	file = fget(fd);
 	if (file) {
-		error = chown_common(file->f_dentry, user, group);
+		error = chown_common(file->f_dentry, file->f_vfsmnt, user, group);
 		fput(file);
 	}
 	return error;


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4/6] vfs: propagate the nameidata into the relevant vfs_*()
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
                   ` (2 preceding siblings ...)
  2006-01-21  8:41 ` [PATCH 3/6] vfs: propagate vfsmount into chown_common() Herbert Poetzl
@ 2006-01-21  8:42 ` Herbert Poetzl
  2006-01-21  8:43 ` [PATCH 5/6] vfs: propagate the vfsmount into *xattr() Herbert Poetzl
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:42 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; propagate the nameidata into the relevant vfs_*() functions
; similar to the existing vfs_create() to allow for proper
; checks via may_create(), may_delete() and permission()
;
;
; Changelog:
;
;   0.01  - initial version
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/fs/namei.c linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/namei.c
--- linux-2.6.16-rc1/fs/namei.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/namei.c	2006-01-21 09:08:56 +0100
@@ -1294,7 +1294,8 @@ static inline int check_sticky(struct in
  * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
  *     nfs_async_unlink().
  */
-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
+static int may_delete(struct inode *dir, struct dentry *victim,
+	int isdir, struct nameidata *nd)
 {
 	int error;
 
@@ -1303,7 +1304,7 @@ static int may_delete(struct inode *dir,
 
 	BUG_ON(victim->d_parent->d_inode != dir);
 
-	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
+	error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
 	if (error)
 		return error;
 	if (IS_APPEND(dir))
@@ -1720,9 +1721,10 @@ fail:
 }
 EXPORT_SYMBOL_GPL(lookup_create);
 
-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+int vfs_mknod(struct inode *dir, struct dentry *dentry,
+	int mode, dev_t dev, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
@@ -1771,11 +1773,12 @@ asmlinkage long sys_mknod(const char __u
 			error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
 			break;
 		case S_IFCHR: case S_IFBLK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
-					new_decode_dev(dev));
+			error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
+					new_decode_dev(dev), &nd);
 			break;
 		case S_IFIFO: case S_IFSOCK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+			error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
+					0, &nd);
 			break;
 		case S_IFDIR:
 			error = -EPERM;
@@ -1793,9 +1796,10 @@ out:
 	return error;
 }
 
-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int vfs_mkdir(struct inode *dir, struct dentry *dentry,
+	int mode, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
@@ -1834,7 +1838,8 @@ asmlinkage long sys_mkdir(const char __u
 		if (!IS_ERR(dentry)) {
 			if (!IS_POSIXACL(nd.dentry->d_inode))
 				mode &= ~current->fs->umask;
-			error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+			error = vfs_mkdir(nd.dentry->d_inode, dentry,
+				mode, &nd);
 			dput(dentry);
 		}
 		mutex_unlock(&nd.dentry->d_inode->i_mutex);
@@ -1874,9 +1879,10 @@ void dentry_unhash(struct dentry *dentry
 	spin_unlock(&dcache_lock);
 }
 
-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
+int vfs_rmdir(struct inode *dir, struct dentry *dentry,
+	struct nameidata *nd)
 {
-	int error = may_delete(dir, dentry, 1);
+	int error = may_delete(dir, dentry, 1, nd);
 
 	if (error)
 		return error;
@@ -1937,7 +1943,7 @@ asmlinkage long sys_rmdir(const char __u
 	dentry = lookup_hash(&nd);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
-		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+		error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
 		dput(dentry);
 	}
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
@@ -1948,9 +1954,10 @@ exit:
 	return error;
 }
 
-int vfs_unlink(struct inode *dir, struct dentry *dentry)
+int vfs_unlink(struct inode *dir, struct dentry *dentry,
+	struct nameidata *nd)
 {
-	int error = may_delete(dir, dentry, 0);
+	int error = may_delete(dir, dentry, 0, nd);
 
 	if (error)
 		return error;
@@ -2012,7 +2019,7 @@ asmlinkage long sys_unlink(const char __
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
-		error = vfs_unlink(nd.dentry->d_inode, dentry);
+		error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
 	exit2:
 		dput(dentry);
 	}
@@ -2031,9 +2038,10 @@ slashes:
 	goto exit2;
 }
 
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
+int vfs_symlink(struct inode *dir, struct dentry *dentry,
+	const char *oldname, int mode, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
@@ -2073,7 +2081,8 @@ asmlinkage long sys_symlink(const char _
 		dentry = lookup_create(&nd, 0);
 		error = PTR_ERR(dentry);
 		if (!IS_ERR(dentry)) {
-			error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+			error = vfs_symlink(nd.dentry->d_inode, dentry,
+				from, S_IALLUGO, &nd);
 			dput(dentry);
 		}
 		mutex_unlock(&nd.dentry->d_inode->i_mutex);
@@ -2085,7 +2094,8 @@ out:
 	return error;
 }
 
-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+int vfs_link(struct dentry *old_dentry, struct inode *dir,
+	struct dentry *new_dentry, struct nameidata *nd)
 {
 	struct inode *inode = old_dentry->d_inode;
 	int error;
@@ -2093,7 +2103,7 @@ int vfs_link(struct dentry *old_dentry, 
 	if (!inode)
 		return -ENOENT;
 
-	error = may_create(dir, new_dentry, NULL);
+	error = may_create(dir, new_dentry, nd);
 	if (error)
 		return error;
 
@@ -2155,7 +2165,8 @@ asmlinkage long sys_link(const char __us
 	new_dentry = lookup_create(&nd, 0);
 	error = PTR_ERR(new_dentry);
 	if (!IS_ERR(new_dentry)) {
-		error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+		error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
+			new_dentry, &nd);
 		dput(new_dentry);
 	}
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
@@ -2282,14 +2293,14 @@ int vfs_rename(struct inode *old_dir, st
 	if (old_dentry->d_inode == new_dentry->d_inode)
  		return 0;
  
-	error = may_delete(old_dir, old_dentry, is_dir);
+	error = may_delete(old_dir, old_dentry, is_dir, NULL);
 	if (error)
 		return error;
 
 	if (!new_dentry->d_inode)
 		error = may_create(new_dir, new_dentry, NULL);
 	else
-		error = may_delete(new_dir, new_dentry, is_dir);
+		error = may_delete(new_dir, new_dentry, is_dir, NULL);
 	if (error)
 		return error;
 
diff -NurpP --minimal linux-2.6.16-rc1/fs/nfsd/vfs.c linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/nfsd/vfs.c
--- linux-2.6.16-rc1/fs/nfsd/vfs.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/nfsd/vfs.c	2006-01-21 09:08:56 +0100
@@ -1159,13 +1159,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
 		err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
 		break;
 	case S_IFDIR:
-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+		err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
 		break;
 	case S_IFCHR:
 	case S_IFBLK:
 	case S_IFIFO:
 	case S_IFSOCK:
-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
 		break;
 	default:
 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
@@ -1441,11 +1441,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
 		else {
 			strncpy(path_alloced, path, plen);
 			path_alloced[plen] = 0;
-			err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
+			err = vfs_symlink(dentry->d_inode, dnew,
+				path_alloced, mode, NULL);
 			kfree(path_alloced);
 		}
 	} else
-		err = vfs_symlink(dentry->d_inode, dnew, path, mode);
+		err = vfs_symlink(dentry->d_inode, dnew,
+			path, mode, NULL);
 
 	if (!err) {
 		if (EX_ISSYNC(fhp->fh_export))
@@ -1503,7 +1505,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
 	dold = tfhp->fh_dentry;
 	dest = dold->d_inode;
 
-	err = vfs_link(dold, dirp, dnew);
+	err = vfs_link(dold, dirp, dnew, NULL);
 	if (!err) {
 		if (EX_ISSYNC(ffhp->fh_export)) {
 			nfsd_sync_dir(ddir);
@@ -1664,9 +1666,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
 			err = nfserr_perm;
 		} else
 #endif
-		err = vfs_unlink(dirp, rdentry);
+		err = vfs_unlink(dirp, rdentry, NULL);
 	} else { /* It's RMDIR */
-		err = vfs_rmdir(dirp, rdentry);
+		err = vfs_rmdir(dirp, rdentry, NULL);
 	}
 
 	dput(rdentry);
diff -NurpP --minimal linux-2.6.16-rc1/fs/reiserfs/xattr.c linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/reiserfs/xattr.c
--- linux-2.6.16-rc1/fs/reiserfs/xattr.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/fs/reiserfs/xattr.c	2006-01-21 09:08:56 +0100
@@ -35,6 +35,7 @@
 #include <linux/namei.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/file.h>
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
@@ -827,7 +828,7 @@ int reiserfs_delete_xattrs(struct inode 
 	if (dir->d_inode->i_nlink <= 2) {
 		root = get_xa_root(inode->i_sb);
 		reiserfs_write_lock_xattrs(inode->i_sb);
-		err = vfs_rmdir(root->d_inode, dir);
+		err = vfs_rmdir(root->d_inode, dir, NULL);
 		reiserfs_write_unlock_xattrs(inode->i_sb);
 		dput(root);
 	} else {
diff -NurpP --minimal linux-2.6.16-rc1/include/linux/fs.h linux-2.6.16-rc1-bme0.06.2-nd0.01/include/linux/fs.h
--- linux-2.6.16-rc1/include/linux/fs.h	2006-01-18 06:08:43 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/include/linux/fs.h	2006-01-21 09:08:56 +0100
@@ -901,12 +901,12 @@ static inline void unlock_super(struct s
  */
 extern int vfs_permission(struct nameidata *, int);
 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
-extern int vfs_mkdir(struct inode *, struct dentry *, int);
-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
-extern int vfs_rmdir(struct inode *, struct dentry *);
-extern int vfs_unlink(struct inode *, struct dentry *);
+extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
+extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
+extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
+extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
+extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
+extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
 /*
diff -NurpP --minimal linux-2.6.16-rc1/ipc/mqueue.c linux-2.6.16-rc1-bme0.06.2-nd0.01/ipc/mqueue.c
--- linux-2.6.16-rc1/ipc/mqueue.c	2006-01-18 06:08:45 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/ipc/mqueue.c	2006-01-21 09:08:59 +0100
@@ -738,7 +738,7 @@ asmlinkage long sys_mq_unlink(const char
 	if (inode)
 		atomic_inc(&inode->i_count);
 
-	err = vfs_unlink(dentry->d_parent->d_inode, dentry);
+	err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
 out_err:
 	dput(dentry);
 
diff -NurpP --minimal linux-2.6.16-rc1/net/unix/af_unix.c linux-2.6.16-rc1-bme0.06.2-nd0.01/net/unix/af_unix.c
--- linux-2.6.16-rc1/net/unix/af_unix.c	2006-01-18 06:08:56 +0100
+++ linux-2.6.16-rc1-bme0.06.2-nd0.01/net/unix/af_unix.c	2006-01-21 09:09:04 +0100
@@ -781,7 +781,7 @@ static int unix_bind(struct socket *sock
 		 */
 		mode = S_IFSOCK |
 		       (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
-		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
+		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
 		if (err)
 			goto out_mknod_dput;
 		mutex_unlock(&nd.dentry->d_inode->i_mutex);


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 5/6] vfs: propagate the vfsmount into *xattr()
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
                   ` (3 preceding siblings ...)
  2006-01-21  8:42 ` [PATCH 4/6] vfs: propagate the nameidata into the relevant vfs_*() Herbert Poetzl
@ 2006-01-21  8:43 ` Herbert Poetzl
  2006-01-21  8:43 ` [PATCH 6/6] vfs: extend IS_RDONLY() checks to MNT_IS_RDONLY() Herbert Poetzl
  2006-01-24 19:06 ` [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Christoph Hellwig
  6 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:43 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; propagate the vfsmount into both setxattr() and removexattr()
; to allow for vfsmount based checks there ensuring that
; the vfsmount isn't read-only
;
;
; Changelog:
;
;   0.01  - broken out part from bme0.05
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/fs/xattr.c linux-2.6.16-rc1-bme0.06.2-xa0.01/fs/xattr.c
--- linux-2.6.16-rc1/fs/xattr.c	2006-01-18 06:08:35 +0100
+++ linux-2.6.16-rc1-bme0.06.2-xa0.01/fs/xattr.c	2006-01-21 09:09:20 +0100
@@ -17,6 +17,7 @@
 #include <linux/syscalls.h>
 #include <linux/module.h>
 #include <linux/fsnotify.h>
+#include <linux/mount.h>
 #include <asm/uaccess.h>
 
 
@@ -167,7 +168,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
  */
 static long
 setxattr(struct dentry *d, char __user *name, void __user *value,
-	 size_t size, int flags)
+	 size_t size, int flags, struct vfsmount *mnt)
 {
 	int error;
 	void *kvalue = NULL;
@@ -194,6 +195,9 @@ setxattr(struct dentry *d, char __user *
 		}
 	}
 
+	if (MNT_IS_RDONLY(mnt))
+		return -EROFS;
+
 	error = vfs_setxattr(d, kname, kvalue, size, flags);
 	kfree(kvalue);
 	return error;
@@ -209,7 +213,7 @@ sys_setxattr(char __user *path, char __u
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
 	path_release(&nd);
 	return error;
 }
@@ -224,7 +228,7 @@ sys_lsetxattr(char __user *path, char __
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
 	path_release(&nd);
 	return error;
 }
@@ -239,7 +243,7 @@ sys_fsetxattr(int fd, char __user *name,
 	f = fget(fd);
 	if (!f)
 		return error;
-	error = setxattr(f->f_dentry, name, value, size, flags);
+	error = setxattr(f->f_dentry, name, value, size, flags, f->f_vfsmnt);
 	fput(f);
 	return error;
 }
@@ -412,7 +416,7 @@ sys_flistxattr(int fd, char __user *list
  * Extended attribute REMOVE operations
  */
 static long
-removexattr(struct dentry *d, char __user *name)
+removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
 {
 	int error;
 	char kname[XATTR_NAME_MAX + 1];
@@ -423,6 +427,9 @@ removexattr(struct dentry *d, char __use
 	if (error < 0)
 		return error;
 
+	if (MNT_IS_RDONLY(mnt))
+		return -EROFS;
+
 	return vfs_removexattr(d, kname);
 }
 
@@ -435,7 +442,7 @@ sys_removexattr(char __user *path, char 
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.dentry, name, nd.mnt);
 	path_release(&nd);
 	return error;
 }
@@ -449,7 +456,7 @@ sys_lremovexattr(char __user *path, char
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.dentry, name, nd.mnt);
 	path_release(&nd);
 	return error;
 }
@@ -463,7 +470,7 @@ sys_fremovexattr(int fd, char __user *na
 	f = fget(fd);
 	if (!f)
 		return error;
-	error = removexattr(f->f_dentry, name);
+	error = removexattr(f->f_dentry, name, f->f_vfsmnt);
 	fput(f);
 	return error;
 }


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 6/6] vfs: extend IS_RDONLY() checks to MNT_IS_RDONLY()
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
                   ` (4 preceding siblings ...)
  2006-01-21  8:43 ` [PATCH 5/6] vfs: propagate the vfsmount into *xattr() Herbert Poetzl
@ 2006-01-21  8:43 ` Herbert Poetzl
  2006-01-24 19:06 ` [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Christoph Hellwig
  6 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-21  8:43 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML


;
; Bind Mount Extensions
;
; Copyright (C) 2003-2006 Herbert Pötzl <herbert@13thfloor.at>
;
; wherever checks for IS_RDONLY(inode) happen, this adds
; the proper MNT_IS_RDONLY(mnt) checks to ensure that the
; vfsmount isn't read-only
;
;
; Changelog:
;
;   0.01  - broken out part from bme0.05
;   0.02  - removed redundant checks
;

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>

diff -NurpP --minimal linux-2.6.16-rc1/arch/sparc64/solaris/fs.c linux-2.6.16-rc1-bme0.06.2-ro0.02/arch/sparc64/solaris/fs.c
--- linux-2.6.16-rc1/arch/sparc64/solaris/fs.c	2006-01-18 06:07:57 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/arch/sparc64/solaris/fs.c	2006-01-21 09:09:32 +0100
@@ -363,7 +363,7 @@ static int report_statvfs(struct vfsmoun
 		int j = strlen (p);
 		
 		if (j > 15) j = 15;
-		if (IS_RDONLY(inode)) i = 1;
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
 		if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
 		if (!sysv_valid_dev(inode->i_sb->s_dev))
 			return -EOVERFLOW;
@@ -399,7 +399,7 @@ static int report_statvfs64(struct vfsmo
 		int j = strlen (p);
 		
 		if (j > 15) j = 15;
-		if (IS_RDONLY(inode)) i = 1;
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
 		if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
 		if (!sysv_valid_dev(inode->i_sb->s_dev))
 			return -EOVERFLOW;
diff -NurpP --minimal linux-2.6.16-rc1/fs/ext2/ioctl.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/ext2/ioctl.c
--- linux-2.6.16-rc1/fs/ext2/ioctl.c	2006-01-18 06:08:29 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/ext2/ioctl.c	2006-01-21 09:09:32 +0100
@@ -11,6 +11,7 @@
 #include <linux/capability.h>
 #include <linux/time.h>
 #include <linux/sched.h>
+#include <linux/mount.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 
@@ -30,7 +31,8 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETFLAGS: {
 		unsigned int oldflags;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -69,7 +71,8 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETVERSION:
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
diff -NurpP --minimal linux-2.6.16-rc1/fs/ext3/ioctl.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/ext3/ioctl.c
--- linux-2.6.16-rc1/fs/ext3/ioctl.c	2006-01-18 06:08:29 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/ext3/ioctl.c	2006-01-21 09:09:32 +0100
@@ -8,6 +8,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/jbd.h>
 #include <linux/capability.h>
 #include <linux/ext3_fs.h>
@@ -36,7 +37,8 @@ int ext3_ioctl (struct inode * inode, st
 		unsigned int oldflags;
 		unsigned int jflag;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -112,7 +114,8 @@ flags_err:
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(generation, (int __user *) arg))
 			return -EFAULT;
@@ -166,7 +169,8 @@ flags_err:
 		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
 			return -ENOTTY;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -201,7 +205,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (get_user(n_blocks_count, (__u32 __user *)arg))
@@ -222,7 +227,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
diff -NurpP --minimal linux-2.6.16-rc1/fs/hfsplus/ioctl.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/hfsplus/ioctl.c
--- linux-2.6.16-rc1/fs/hfsplus/ioctl.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/hfsplus/ioctl.c	2006-01-21 09:09:32 +0100
@@ -35,7 +35,8 @@ int hfsplus_ioctl(struct inode *inode, s
 			flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
 		return put_user(flags, (int __user *)arg);
 	case HFSPLUS_IOC_EXT2_SETFLAGS: {
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
diff -NurpP --minimal linux-2.6.16-rc1/fs/namei.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/namei.c
--- linux-2.6.16-rc1/fs/namei.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/namei.c	2006-01-21 09:09:32 +0100
@@ -233,7 +233,7 @@ int permission(struct inode *inode, int 
 		/*
 		 * Nobody gets write access to a read-only fs.
 		 */
-		if (IS_RDONLY(inode) &&
+		if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;
 
@@ -1456,7 +1456,8 @@ int may_open(struct nameidata *nd, int a
 			return -EACCES;
 
 		flag &= ~O_TRUNC;
-	} else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
+	} else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
+		&& (flag & FMODE_WRITE))
 		return -EROFS;
 	/*
 	 * An append-only file must be opened in append mode for writing.
@@ -2366,6 +2367,9 @@ static int do_rename(const char * oldnam
 	error = -EINVAL;
 	if (old_dentry == trap)
 		goto exit4;
+	error = -EROFS;
+	if (MNT_IS_RDONLY(newnd.mnt))
+		goto exit4;
 	new_dentry = lookup_hash(&newnd);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
diff -NurpP --minimal linux-2.6.16-rc1/fs/nfs/dir.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/nfs/dir.c
--- linux-2.6.16-rc1/fs/nfs/dir.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/nfs/dir.c	2006-01-21 09:09:32 +0100
@@ -902,7 +902,8 @@ static int is_atomic_open(struct inode *
 	if (nd->flags & LOOKUP_DIRECTORY)
 		return 0;
 	/* Are we trying to write to a read only partition? */
-	if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+	if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
+		(nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
 		return 0;
 	return 1;
 }
diff -NurpP --minimal linux-2.6.16-rc1/fs/nfsd/vfs.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/nfsd/vfs.c
--- linux-2.6.16-rc1/fs/nfsd/vfs.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/nfsd/vfs.c	2006-01-21 09:09:32 +0100
@@ -1778,7 +1778,8 @@ nfsd_permission(struct svc_export *exp, 
 	 */
 	if (!(acc & MAY_LOCAL_ACCESS))
 		if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
-			if (EX_RDONLY(exp) || IS_RDONLY(inode))
+			if (EX_RDONLY(exp) || IS_RDONLY(inode)
+				|| MNT_IS_RDONLY(exp->ex_mnt))
 				return nfserr_rofs;
 			if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
 				return nfserr_perm;
diff -NurpP --minimal linux-2.6.16-rc1/fs/open.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/open.c
--- linux-2.6.16-rc1/fs/open.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/open.c	2006-01-21 09:09:32 +0100
@@ -247,7 +247,7 @@ static long do_sys_truncate(const char _
 		goto dput_and_out;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	error = -EPERM;
@@ -371,7 +371,7 @@ asmlinkage long sys_utime(char __user * 
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
@@ -428,7 +428,7 @@ long do_utimes(char __user * filename, s
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
@@ -510,7 +510,8 @@ asmlinkage long sys_access(const char __
 	if (!res) {
 		res = vfs_permission(&nd, mode);
 		/* SuS v2 requires we report a read only fs too */
-		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+		if(!res && (mode & S_IWOTH)
+		   && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
 		   && !special_file(nd.dentry->d_inode->i_mode))
 			res = -EROFS;
 		path_release(&nd);
@@ -616,7 +617,7 @@ asmlinkage long sys_fchmod(unsigned int 
 	inode = dentry->d_inode;
 
 	err = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
 		goto out_putf;
 	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
@@ -648,7 +649,7 @@ asmlinkage long sys_chmod(const char __u
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	error = -EPERM;
diff -NurpP --minimal linux-2.6.16-rc1/fs/reiserfs/ioctl.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/reiserfs/ioctl.c
--- linux-2.6.16-rc1/fs/reiserfs/ioctl.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/reiserfs/ioctl.c	2006-01-21 09:09:32 +0100
@@ -4,6 +4,7 @@
 
 #include <linux/capability.h>
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/time.h>
 #include <asm/uaccess.h>
@@ -47,7 +48,8 @@ int reiserfs_ioctl(struct inode *inode, 
 			if (!reiserfs_attrs(inode->i_sb))
 				return -ENOTTY;
 
-			if (IS_RDONLY(inode))
+			if (IS_RDONLY(inode) ||
+				(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 				return -EROFS;
 
 			if ((current->fsuid != inode->i_uid)
@@ -82,7 +84,8 @@ int reiserfs_ioctl(struct inode *inode, 
 	case REISERFS_IOC_SETVERSION:
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *)arg))
 			return -EFAULT;
diff -NurpP --minimal linux-2.6.16-rc1/fs/reiserfs/xattr.c linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/reiserfs/xattr.c
--- linux-2.6.16-rc1/fs/reiserfs/xattr.c	2006-01-18 06:08:34 +0100
+++ linux-2.6.16-rc1-bme0.06.2-ro0.02/fs/reiserfs/xattr.c	2006-01-21 09:09:32 +0100
@@ -1332,7 +1332,7 @@ __reiserfs_permission(struct inode *inod
 		/*
 		 * Nobody gets write access to a read-only fs.
 		 */
-		if (IS_RDONLY(inode) &&
+		if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;
 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-21  8:40 ` [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount Herbert Poetzl
@ 2006-01-22 10:06   ` Suleiman Souhlal
  2006-01-22 10:59     ` Suleiman Souhlal
  2006-01-24 19:02   ` Christoph Hellwig
  1 sibling, 1 reply; 15+ messages in thread
From: Suleiman Souhlal @ 2006-01-22 10:06 UTC (permalink / raw)
  To: Herbert Poetzl
  Cc: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML

Herbert Poetzl wrote:
> @@ -1312,7 +1315,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, mnt_flags);

Shouldn't it be retval = do_loopback(&nd, dev_name, recurse, mnt_flags); ?

-- Suleiman

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-22 10:06   ` Suleiman Souhlal
@ 2006-01-22 10:59     ` Suleiman Souhlal
  0 siblings, 0 replies; 15+ messages in thread
From: Suleiman Souhlal @ 2006-01-22 10:59 UTC (permalink / raw)
  To: Suleiman Souhlal
  Cc: Herbert Poetzl, Linus Torvalds, Andrew Morton, Christoph Hellwig,
	Al Viro, Linux Kernel ML

Suleiman Souhlal wrote:
> Shouldn't it be retval = do_loopback(&nd, dev_name, recurse, mnt_flags); ?

Nevermind.
-- Suleiman

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-21  8:40 ` [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount Herbert Poetzl
  2006-01-22 10:06   ` Suleiman Souhlal
@ 2006-01-24 19:02   ` Christoph Hellwig
  2006-01-26 21:04     ` Herbert Poetzl
  2006-01-27 20:03     ` Herbert Poetzl
  1 sibling, 2 replies; 15+ messages in thread
From: Christoph Hellwig @ 2006-01-24 19:02 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML

This one looks good, it's an obvious fix.  But please follow the proper
patch format, see http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
for details.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags
  2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
                   ` (5 preceding siblings ...)
  2006-01-21  8:43 ` [PATCH 6/6] vfs: extend IS_RDONLY() checks to MNT_IS_RDONLY() Herbert Poetzl
@ 2006-01-24 19:06 ` Christoph Hellwig
  2006-01-26 21:08   ` Herbert Poetzl
  6 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2006-01-24 19:06 UTC (permalink / raw)
  To: Linus Torvalds, Andrew Morton, Christoph Hellwig, Al Viro,
	Linux Kernel ML, linu-fsdevel

On Sat, Jan 21, 2006 at 09:38:43AM +0100, Herbert Poetzl wrote:
> 
> The following set of patches extends the per device 
> 'noatime', 'nodiratime' and last but not least the 
> 'ro' (read only) mount option to the vfs --bind mounts, 
> allowing them to behave like any other mount, by 
> honoring those mount flags (which are silently ignored 
> by the current implementation in 2.4.x and 2.6.x)   	
> 
> the patch makes the following syscall variations behave 
> as expected:
> 
>  - open (read/write/trunc), create
>  - link, symlink, unlink
>  - mknod (reg/block/char/fifo)
>  - mkfifo, mkdir, rmdir, rename
>  - (f,l)chown, (f)chmod, utime
>  - access, truncate, mmap
>  - ioctl (gen/ext2/ext3/reiser)
>  - (f,l)setxattr, (f,l)removexattr
> 
> an older version of this patch was included in 
> 2.6.0-test6-mm2, and v2.6.4-wolk2.0, the patches are
> in use by several people, without any issues ...
> 
> please consider inclusion (in -mm ?) and/or let me know
> what needs to be changed to get this functionality into
> mainline ...

Please see the original mail from Al on this subject.  We need to
split the "am I allowed to write to the fs" part out of permission().
Once we're at it we can pair it with the "don't need to write to fs anymore"
even and get saner unmount/remount semantics.

To get there we will still need the vfsmount propagatios, so these should
come first in the series.  Then the get/release write access helpers and
last the actual per-mount ro bit.  Your mnt_flags propagation fix is fine
on it's own and should go in asap.

And please send the patches to -fsdevel and in the proper patch format.
I have planned to look at this again in February, tell me if you want to
finish it before or at the same time, then I won't spend time on it.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-24 19:02   ` Christoph Hellwig
@ 2006-01-26 21:04     ` Herbert Poetzl
  2006-01-27 20:03     ` Herbert Poetzl
  1 sibling, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-26 21:04 UTC (permalink / raw)
  To: Christoph Hellwig, Linus Torvalds, Andrew Morton, Al Viro,
	Linux Kernel ML

On Tue, Jan 24, 2006 at 07:02:56PM +0000, Christoph Hellwig wrote:
> This one looks good, it's an obvious fix.  But please follow the proper
> patch format, see http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
> for details.

huh? please help me figure out what's wrong this time ...

TIA,
Herbert

> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags
  2006-01-24 19:06 ` [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Christoph Hellwig
@ 2006-01-26 21:08   ` Herbert Poetzl
  0 siblings, 0 replies; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-26 21:08 UTC (permalink / raw)
  To: Christoph Hellwig, Linus Torvalds, Andrew Morton, Al Viro,
	Linux Kernel ML, linu-fsdevel

On Tue, Jan 24, 2006 at 07:06:32PM +0000, Christoph Hellwig wrote:
> On Sat, Jan 21, 2006 at 09:38:43AM +0100, Herbert Poetzl wrote:
> > 
> > The following set of patches extends the per device 
> > 'noatime', 'nodiratime' and last but not least the 
> > 'ro' (read only) mount option to the vfs --bind mounts, 
> > allowing them to behave like any other mount, by 
> > honoring those mount flags (which are silently ignored 
> > by the current implementation in 2.4.x and 2.6.x)   	
> > 
> > the patch makes the following syscall variations behave 
> > as expected:
> > 
> >  - open (read/write/trunc), create
> >  - link, symlink, unlink
> >  - mknod (reg/block/char/fifo)
> >  - mkfifo, mkdir, rmdir, rename
> >  - (f,l)chown, (f)chmod, utime
> >  - access, truncate, mmap
> >  - ioctl (gen/ext2/ext3/reiser)
> >  - (f,l)setxattr, (f,l)removexattr
> > 
> > an older version of this patch was included in 
> > 2.6.0-test6-mm2, and v2.6.4-wolk2.0, the patches are
> > in use by several people, without any issues ...
> > 
> > please consider inclusion (in -mm ?) and/or let me know
> > what needs to be changed to get this functionality into
> > mainline ...
> 
> Please see the original mail from Al on this subject. We need to
> split the "am I allowed to write to the fs" part out of permission().
> Once we're at it we can pair it with the "don't need to write to fs
> anymore" even and get saner unmount/remount semantics.

could you point me to this thread/email, so that I can
(re)read it?

> To get there we will still need the vfsmount propagatios, so these
> should come first in the series. Then the get/release write access
> helpers and last the actual per-mount ro bit. Your mnt_flags
> propagation fix is fine on it's own and should go in asap.
>
> And please send the patches to -fsdevel and in the proper patch

will do so, once I figure out what was improper ...
(as I tried to follow Andrew's tpp document in the first palce)

> format. I have planned to look at this again in February, tell me if
> you want to finish it before or at the same time, then I won't spend
> time on it.

once I figured out what is desired/wanted/acceptable, I'm
willing to do it ...

best,
Herbert

> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-24 19:02   ` Christoph Hellwig
  2006-01-26 21:04     ` Herbert Poetzl
@ 2006-01-27 20:03     ` Herbert Poetzl
  2006-04-01 17:02       ` Christoph Hellwig
  1 sibling, 1 reply; 15+ messages in thread
From: Herbert Poetzl @ 2006-01-27 20:03 UTC (permalink / raw)
  To: Christoph Hellwig, Linus Torvalds, Andrew Morton, Al Viro; +Cc: Linux Kernel ML


the mnt_flags are propagated into do_loopback(), so that
they can be stored with the vfsmount

Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>
Acked-by: Christoph Hellwig <hch@infradead.org>
---
; Bind Mount Extensions
; 02_2.6.16-rc1_lo0.01.diff

diff -NurpP --minimal linux-2.6.16-rc1/fs/namespace.c linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c
--- linux-2.6.16-rc1/fs/namespace.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c	2006-01-21 09:08:29 +0100
@@ -861,11 +861,13 @@ 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, unsigned long flags, int mnt_flags)
 {
 	struct nameidata old_nd;
 	struct vfsmount *mnt = NULL;
+	int recurse = flags & MS_REC;
 	int err = mount_is_safe(nd);
+
 	if (err)
 		return err;
 	if (!old_name || !*old_name)
@@ -899,6 +901,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);
@@ -1312,7 +1315,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, mnt_flags);
 	else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
 		retval = do_change_type(&nd, flags);
 	else if (flags & MS_MOVE)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount
  2006-01-27 20:03     ` Herbert Poetzl
@ 2006-04-01 17:02       ` Christoph Hellwig
  0 siblings, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2006-04-01 17:02 UTC (permalink / raw)
  To: Christoph Hellwig, Linus Torvalds, Andrew Morton, Al Viro,
	Linux Kernel ML

On Fri, Jan 27, 2006 at 09:03:04PM +0100, Herbert Poetzl wrote:
> 

Andrew, Linus any reason this still isn't in?

--

From: Herbert P?tzl <herbert@13thfloor.at>

the mnt_flags are propagated into do_loopback(), so that
they can be stored with the vfsmount

Signed-off-by: Herbert P?tzl <herbert@13thfloor.at>
Acked-by: Christoph Hellwig <hch@infradead.org>


diff -NurpP --minimal linux-2.6.16-rc1/fs/namespace.c linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c
--- linux-2.6.16-rc1/fs/namespace.c	2006-01-18 06:08:30 +0100
+++ linux-2.6.16-rc1-bme0.06.2-lo0.01/fs/namespace.c	2006-01-21 09:08:29 +0100
@@ -861,11 +861,13 @@ 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, unsigned long flags, int mnt_flags)
 {
 	struct nameidata old_nd;
 	struct vfsmount *mnt = NULL;
+	int recurse = flags & MS_REC;
 	int err = mount_is_safe(nd);
+
 	if (err)
 		return err;
 	if (!old_name || !*old_name)
@@ -899,6 +901,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);
@@ -1312,7 +1315,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, mnt_flags);
 	else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
 		retval = do_change_type(&nd, flags);
 	else if (flags & MS_MOVE)


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2006-04-01 17:02 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-21  8:38 [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Herbert Poetzl
2006-01-21  8:40 ` [PATCH 1/6] vfs: add missing MNT_RDONLY and macro to check Herbert Poetzl
2006-01-21  8:40 ` [PATCH 2/6] vfs: propagate mnt_flags into do_loopback/vfsmount Herbert Poetzl
2006-01-22 10:06   ` Suleiman Souhlal
2006-01-22 10:59     ` Suleiman Souhlal
2006-01-24 19:02   ` Christoph Hellwig
2006-01-26 21:04     ` Herbert Poetzl
2006-01-27 20:03     ` Herbert Poetzl
2006-04-01 17:02       ` Christoph Hellwig
2006-01-21  8:41 ` [PATCH 3/6] vfs: propagate vfsmount into chown_common() Herbert Poetzl
2006-01-21  8:42 ` [PATCH 4/6] vfs: propagate the nameidata into the relevant vfs_*() Herbert Poetzl
2006-01-21  8:43 ` [PATCH 5/6] vfs: propagate the vfsmount into *xattr() Herbert Poetzl
2006-01-21  8:43 ` [PATCH 6/6] vfs: extend IS_RDONLY() checks to MNT_IS_RDONLY() Herbert Poetzl
2006-01-24 19:06 ` [PATCH 0/6] vfs: extend loopback (bind) mounts by mnt_flags Christoph Hellwig
2006-01-26 21:08   ` Herbert Poetzl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).