linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
@ 2004-03-15  3:55 Herbert Poetzl
  2004-03-15  4:14 ` Andrew Morton
  0 siblings, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  3:55 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Al Viro, linux-kernel


;
; Bind Mount Extensions 
;
; this patch adds some functionality to the --bind
; type of vfs mounts.
;
; (C) 2003-2004 Herbert Pötzl <herbert@13thfloor.at>
;
; Changelog:  
;
;   0.01  - readonly bind mounts
;   0.02  - added ro truncate handling
;         - added ro (f)chown, (f)chmod handling
;   0.03  - added ro utime(s) handling
;         - added ro access and *_ioctl
;   0.04  - added noatime and nodiratime
;         - made autofs4 update_atime uncond
;
; this patch is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
; 
; this patch is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
; 

diff -NurpP --minimal linux-2.6.4/drivers/char/random.c linux-2.6.4-bme0.04/drivers/char/random.c
--- linux-2.6.4/drivers/char/random.c	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.4-bme0.04/drivers/char/random.c	2004-03-12 20:51:58.000000000 +0100
@@ -1641,7 +1641,7 @@ random_read(struct file * file, char * b
 	 * If we gave the user some bytes, update the access time.
 	 */
 	if (count != 0) {
-		update_atime(file->f_dentry->d_inode);
+		update_atime(file->f_dentry->d_inode, file->f_vfsmnt);
 	}
 	
 	return (count ? count : retval);
diff -NurpP --minimal linux-2.6.4/fs/autofs4/root.c linux-2.6.4-bme0.04/fs/autofs4/root.c
--- linux-2.6.4/fs/autofs4/root.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/autofs4/root.c	2004-03-12 20:51:58.000000000 +0100
@@ -61,7 +61,8 @@ static void autofs4_update_usage(struct 
 		struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
 		if (ino) {
-			update_atime(dentry->d_inode);
+			/* Al Viro said: unconditional */
+			update_atime(dentry->d_inode, 0);
 			ino->last_used = jiffies;
 		}
 	}
diff -NurpP --minimal linux-2.6.4/fs/bfs/dir.c linux-2.6.4-bme0.04/fs/bfs/dir.c
--- linux-2.6.4/fs/bfs/dir.c	2004-03-11 03:55:44.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/bfs/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -65,7 +65,7 @@ static int bfs_readdir(struct file * f, 
 		brelse(bh);
 	}
 
-	update_atime(dir);
+	update_atime(dir, f->f_vfsmnt);
 	unlock_kernel();
 	return 0;	
 }
diff -NurpP --minimal linux-2.6.4/fs/ext2/dir.c linux-2.6.4-bme0.04/fs/ext2/dir.c
--- linux-2.6.4/fs/ext2/dir.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/ext2/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -310,7 +310,7 @@ ext2_readdir (struct file * filp, void *
 done:
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
 	filp->f_version = inode->i_version;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 	return 0;
 }
 
diff -NurpP --minimal linux-2.6.4/fs/ext2/ioctl.c linux-2.6.4-bme0.04/fs/ext2/ioctl.c
--- linux-2.6.4/fs/ext2/ioctl.c	2004-03-11 03:55:54.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/ext2/ioctl.c	2004-03-12 20:51:58.000000000 +0100
@@ -10,6 +10,7 @@
 #include "ext2.h"
 #include <linux/time.h>
 #include <linux/sched.h>
+#include <linux/mount.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 
@@ -29,7 +30,7 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETFLAGS: {
 		unsigned int oldflags;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -68,7 +69,7 @@ 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) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int *) arg))
 			return -EFAULT;	
diff -NurpP --minimal linux-2.6.4/fs/ext3/dir.c linux-2.6.4-bme0.04/fs/ext3/dir.c
--- linux-2.6.4/fs/ext3/dir.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/ext3/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -224,7 +224,7 @@ revalidate:
 		offset = 0;
 		brelse (bh);
 	}
-       update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 out:
 	return ret;
 }
@@ -506,7 +506,7 @@ static int ext3_dx_readdir(struct file *
 	}
 finished:
 	info->last_pos = filp->f_pos;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 	return 0;
 }
 
diff -NurpP --minimal linux-2.6.4/fs/ext3/ioctl.c linux-2.6.4-bme0.04/fs/ext3/ioctl.c
--- linux-2.6.4/fs/ext3/ioctl.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/ext3/ioctl.c	2004-03-12 20:51:58.000000000 +0100
@@ -12,6 +12,7 @@
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include <linux/time.h>
+#include <linux/mount.h>
 #include <asm/uaccess.h>
 
 
@@ -34,7 +35,7 @@ int ext3_ioctl (struct inode * inode, st
 		unsigned int oldflags;
 		unsigned int jflag;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -110,7 +111,7 @@ flags_err:
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 		if (get_user(generation, (int *) arg))
 			return -EFAULT;
diff -NurpP --minimal linux-2.6.4/fs/hugetlbfs/inode.c linux-2.6.4-bme0.04/fs/hugetlbfs/inode.c
--- linux-2.6.4/fs/hugetlbfs/inode.c	2004-03-11 03:55:44.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/hugetlbfs/inode.c	2004-03-12 20:51:58.000000000 +0100
@@ -62,7 +62,7 @@ static int hugetlbfs_file_mmap(struct fi
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
 	down(&inode->i_sem);
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
diff -NurpP --minimal linux-2.6.4/fs/inode.c linux-2.6.4-bme0.04/fs/inode.c
--- linux-2.6.4/fs/inode.c	2004-03-11 03:55:51.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/inode.c	2004-03-12 20:51:58.000000000 +0100
@@ -20,6 +20,7 @@
 #include <linux/security.h>
 #include <linux/pagemap.h>
 #include <linux/cdev.h>
+#include <linux/mount.h>
 
 /*
  * This is needed for the following functions:
@@ -1141,15 +1142,16 @@ static int inode_times_differ(struct ino
  *	This function automatically handles read only file systems and media,
  *	as well as the "noatime" flag and inode specific "noatime" markers.
  */
-void update_atime(struct inode *inode)
+void update_atime(struct inode *inode, struct vfsmount *mnt)
 {
 	struct timespec now;
 
-	if (IS_NOATIME(inode))
+	if (IS_NOATIME(inode) || MNT_IS_NOATIME(mnt))
 		return;
-	if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
+	if (S_ISDIR(inode->i_mode) &&
+		(IS_NODIRATIME(inode) || MNT_IS_NODIRATIME(mnt)))
 		return;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
 		return;
 
 	now = current_kernel_time();
diff -NurpP --minimal linux-2.6.4/fs/libfs.c linux-2.6.4-bme0.04/fs/libfs.c
--- linux-2.6.4/fs/libfs.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/libfs.c	2004-03-12 20:51:58.000000000 +0100
@@ -155,7 +155,7 @@ int dcache_readdir(struct file * filp, v
 			}
 			spin_unlock(&dcache_lock);
 	}
-	update_atime(dentry->d_inode);
+	update_atime(dentry->d_inode, filp->f_vfsmnt);
 	return 0;
 }
 
diff -NurpP --minimal linux-2.6.4/fs/minix/dir.c linux-2.6.4-bme0.04/fs/minix/dir.c
--- linux-2.6.4/fs/minix/dir.c	2004-03-11 03:55:37.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/minix/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -127,7 +127,7 @@ static int minix_readdir(struct file * f
 
 done:
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 	unlock_kernel();
 	return 0;
 }
diff -NurpP --minimal linux-2.6.4/fs/namei.c linux-2.6.4-bme0.04/fs/namei.c
--- linux-2.6.4/fs/namei.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/namei.c	2004-03-12 20:51:58.000000000 +0100
@@ -209,10 +209,14 @@ int permission(struct inode * inode,int 
 {
 	int retval;
 	int submask;
+	umode_t	mode = inode->i_mode;
 
 	/* Ordinary permission routines do not understand MAY_APPEND. */
 	submask = mask & ~MAY_APPEND;
 
+	if (nd && (mask & MAY_WRITE) && MNT_IS_RDONLY(nd->mnt) &&
+		(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+		return -EROFS;
 	if (inode->i_op && inode->i_op->permission)
 		retval = inode->i_op->permission(inode, submask, nd);
 	else
@@ -412,7 +416,7 @@ static inline int do_follow_link(struct 
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
-	update_atime(dentry->d_inode);
+	update_atime(dentry->d_inode, nd->mnt);
 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
 	current->link_count--;
 	return err;
@@ -1062,6 +1066,24 @@ static inline int may_create(struct inod
 	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
 }
 
+static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (child->d_inode)
+               return -EEXIST;
+       if (IS_DEADDIR(dir))
+               return -ENOENT;
+       if (mnt->mnt_flags & MNT_RDONLY)
+               return -EROFS;
+       return 0;
+}
+
+static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (!child->d_inode)
+               return -ENOENT;
+       if (mnt->mnt_flags & MNT_RDONLY)
+               return -EROFS;
+       return 0;
+}
+
 /* 
  * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
  * reasons.
@@ -1183,7 +1205,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.
@@ -1368,7 +1391,7 @@ do_link:
 	error = security_inode_follow_link(dentry, nd);
 	if (error)
 		goto exit_dput;
-	update_atime(dentry->d_inode);
+	update_atime(dentry->d_inode, nd->mnt);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	dput(dentry);
 	if (error)
@@ -1408,23 +1431,28 @@ do_link:
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
 	struct dentry *dentry;
+	int error;
 
 	down(&nd->dentry->d_inode->i_sem);
-	dentry = ERR_PTR(-EEXIST);
+	error = -EEXIST;
 	if (nd->last_type != LAST_NORM)
-		goto fail;
+		goto out;
 	nd->flags &= ~LOOKUP_PARENT;
 	dentry = lookup_hash(&nd->last, nd->dentry);
 	if (IS_ERR(dentry))
+		goto ret;
+	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
+	if (error)
 		goto fail;
+	error = -ENOENT;
 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-		goto enoent;
+		goto fail;
+ret:
 	return dentry;
-enoent:
-	dput(dentry);
-	dentry = ERR_PTR(-ENOENT);
 fail:
-	return dentry;
+	dput(dentry);
+out:
+	return ERR_PTR(error);
 }
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
@@ -1653,7 +1681,11 @@ asmlinkage long sys_rmdir(const char __u
 	dentry = lookup_hash(&nd.last, nd.dentry);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+	exit2:
 		dput(dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
@@ -1725,6 +1757,9 @@ asmlinkage long sys_unlink(const char __
 		/* Why not before? Because we want correct error value */
 		if (nd.last.name[nd.last.len])
 			goto slashes;
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
@@ -2089,6 +2124,9 @@ static inline int do_rename(const char *
 	error = -EINVAL;
 	if (old_dentry == trap)
 		goto exit4;
+	error = -EROFS;
+	if (MNT_IS_RDONLY(newnd.mnt))
+		goto exit4;
 	new_dentry = lookup_hash(&newnd.last, new_dir);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
diff -NurpP --minimal linux-2.6.4/fs/namespace.c linux-2.6.4-bme0.04/fs/namespace.c
--- linux-2.6.4/fs/namespace.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/namespace.c	2004-03-12 20:51:58.000000000 +0100
@@ -229,7 +229,8 @@ static int show_vfsmnt(struct seq_file *
 	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");
+	seq_puts(m, (MNT_IS_RDONLY(mnt) ||
+		(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);
@@ -522,11 +523,13 @@ out_unlock:
 /*
  * 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)
@@ -553,6 +556,7 @@ static int do_loopback(struct nameidata 
 			spin_unlock(&vfsmount_lock);
 		} else
 			mntput(mnt);
+		mnt->mnt_flags = mnt_flags;
 	}
 
 	up_write(&current->namespace->sem);
@@ -759,12 +763,18 @@ long do_mount(char * dev_name, char * di
 		((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)
 		mnt_flags |= MNT_NODEV;
 	if (flags & MS_NOEXEC)
 		mnt_flags |= MNT_NOEXEC;
+	if (flags & MS_NOATIME)
+		mnt_flags |= MNT_NOATIME;
+	if (flags & MS_NODIRATIME)
+		mnt_flags |= MNT_NODIRATIME;
 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 
 	/* ... and get the mountpoint */
@@ -780,7 +790,7 @@ long do_mount(char * dev_name, char * di
 		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_MOVE)
 		retval = do_move_mount(&nd, dev_name);
 	else
diff -NurpP --minimal linux-2.6.4/fs/nfsd/vfs.c linux-2.6.4-bme0.04/fs/nfsd/vfs.c
--- linux-2.6.4/fs/nfsd/vfs.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/nfsd/vfs.c	2004-03-12 20:51:58.000000000 +0100
@@ -1143,7 +1143,7 @@ nfsd_readlink(struct svc_rqst *rqstp, st
 	if (!inode->i_op || !inode->i_op->readlink)
 		goto out;
 
-	update_atime(inode);
+	update_atime(inode, fhp->fh_export->ex_mnt);
 	/* N.B. Why does this call need a get_fs()??
 	 * Remove the set_fs and watch the fireworks:-) --okir
 	 */
diff -NurpP --minimal linux-2.6.4/fs/open.c linux-2.6.4-bme0.04/fs/open.c
--- linux-2.6.4/fs/open.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/open.c	2004-03-12 20:51:58.000000000 +0100
@@ -226,7 +226,7 @@ static inline long do_sys_truncate(const
 		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;
@@ -350,7 +350,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() */
@@ -407,7 +407,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() */
@@ -489,8 +489,9 @@ asmlinkage long sys_access(const char __
 	if (!res) {
 		res = permission(nd.dentry->d_inode, mode, &nd);
 		/* SuS v2 requires we report a read only fs too */
-		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-		   && !special_file(nd.dentry->d_inode->i_mode))
+		if (!res && (mode & S_IWOTH)
+		   && !special_file(nd.dentry->d_inode->i_mode)
+		   && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt)))
 			res = -EROFS;
 		path_release(&nd);
 	}
@@ -595,7 +596,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))
@@ -627,7 +628,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;
@@ -648,7 +649,7 @@ out:
 	return error;
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct vfsmount *mnt, struct dentry * dentry, uid_t user, gid_t group)
 {
 	struct inode * inode;
 	int error;
@@ -660,7 +661,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))
@@ -690,7 +691,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.mnt, nd.dentry, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -703,7 +704,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.mnt, nd.dentry, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -717,7 +718,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_vfsmnt, file->f_dentry, user, group);
 		fput(file);
 	}
 	return error;
diff -NurpP --minimal linux-2.6.4/fs/pipe.c linux-2.6.4-bme0.04/fs/pipe.c
--- linux-2.6.4/fs/pipe.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/pipe.c	2004-03-12 20:51:58.000000000 +0100
@@ -165,7 +165,7 @@ pipe_readv(struct file *filp, const stru
 		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 	}
 	if (ret > 0)
-		update_atime(inode);
+		update_atime(inode, filp->f_vfsmnt);
 	return ret;
 }
 
diff -NurpP --minimal linux-2.6.4/fs/qnx4/dir.c linux-2.6.4-bme0.04/fs/qnx4/dir.c
--- linux-2.6.4/fs/qnx4/dir.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/qnx4/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -76,7 +76,7 @@ static int qnx4_readdir(struct file *fil
 		}
 		brelse(bh);
 	}
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 
 out:
 	unlock_kernel();
diff -NurpP --minimal linux-2.6.4/fs/reiserfs/dir.c linux-2.6.4-bme0.04/fs/reiserfs/dir.c
--- linux-2.6.4/fs/reiserfs/dir.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/reiserfs/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -186,7 +186,7 @@ static int reiserfs_readdir (struct file
     filp->f_pos = next_pos;
     pathrelse (&path_to_entry);
     reiserfs_check_path(&path_to_entry) ;
-    update_atime(inode) ;
+    update_atime(inode, filp->f_vfsmnt) ;
  out:
     reiserfs_write_unlock(inode->i_sb);
     return ret;
diff -NurpP --minimal linux-2.6.4/fs/reiserfs/ioctl.c linux-2.6.4-bme0.04/fs/reiserfs/ioctl.c
--- linux-2.6.4/fs/reiserfs/ioctl.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/reiserfs/ioctl.c	2004-03-12 20:51:58.000000000 +0100
@@ -5,6 +5,7 @@
 #include <linux/fs.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/time.h>
+#include <linux/mount.h>
 #include <asm/uaccess.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
@@ -38,7 +39,7 @@ int reiserfs_ioctl (struct inode * inode
 		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
 		return put_user(flags, (int *) arg);
 	case REISERFS_IOC_SETFLAGS: {
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -70,7 +71,7 @@ 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) || MNT_IS_RDONLY(filp->f_vfsmnt))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int *) arg))
 			return -EFAULT;	
diff -NurpP --minimal linux-2.6.4/fs/stat.c linux-2.6.4-bme0.04/fs/stat.c
--- linux-2.6.4/fs/stat.c	2004-03-11 03:55:23.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/stat.c	2004-03-12 20:51:58.000000000 +0100
@@ -272,7 +272,7 @@ asmlinkage long sys_readlink(const char 
 		if (inode->i_op && inode->i_op->readlink) {
 			error = security_inode_readlink(nd.dentry);
 			if (!error) {
-				update_atime(inode);
+				update_atime(inode, nd.mnt);
 				error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
 			}
 		}
diff -NurpP --minimal linux-2.6.4/fs/sysv/dir.c linux-2.6.4-bme0.04/fs/sysv/dir.c
--- linux-2.6.4/fs/sysv/dir.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/sysv/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -116,7 +116,7 @@ static int sysv_readdir(struct file * fi
 
 done:
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 	unlock_kernel();
 	return 0;
 }
diff -NurpP --minimal linux-2.6.4/fs/udf/dir.c linux-2.6.4-bme0.04/fs/udf/dir.c
--- linux-2.6.4/fs/udf/dir.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/udf/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -98,7 +98,7 @@ int udf_readdir(struct file *filp, void 
 	}
 
 	result = do_udf_readdir(dir, filp, filldir, dirent);
-	update_atime(dir);
+	update_atime(dir, filp->f_vfsmnt);
 	unlock_kernel();
  	return result;
 }
diff -NurpP --minimal linux-2.6.4/fs/ufs/dir.c linux-2.6.4-bme0.04/fs/ufs/dir.c
--- linux-2.6.4/fs/ufs/dir.c	2004-03-11 03:55:43.000000000 +0100
+++ linux-2.6.4-bme0.04/fs/ufs/dir.c	2004-03-12 20:51:58.000000000 +0100
@@ -166,7 +166,7 @@ revalidate:
 		offset = 0;
 		brelse (bh);
 	}
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 	unlock_kernel();
 	return 0;
 }
diff -NurpP --minimal linux-2.6.4/include/linux/fs.h linux-2.6.4-bme0.04/include/linux/fs.h
--- linux-2.6.4/include/linux/fs.h	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-bme0.04/include/linux/fs.h	2004-03-12 20:51:58.000000000 +0100
@@ -211,7 +211,7 @@ extern int leases_enable, dir_notify_ena
 #include <asm/byteorder.h>
 
 /* Used to be a macro which just called the function, now just a function */
-extern void update_atime (struct inode *);
+extern void update_atime (struct inode *, struct vfsmount *);
 
 extern void inode_init(unsigned long);
 extern void mnt_init(unsigned long);
diff -NurpP --minimal linux-2.6.4/include/linux/mount.h linux-2.6.4-bme0.04/include/linux/mount.h
--- linux-2.6.4/include/linux/mount.h	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.4-bme0.04/include/linux/mount.h	2004-03-12 20:51:58.000000000 +0100
@@ -14,9 +14,12 @@
 
 #include <linux/list.h>
 
-#define MNT_NOSUID	1
-#define MNT_NODEV	2
-#define MNT_NOEXEC	4
+#define MNT_RDONLY	1
+#define MNT_NOSUID	2
+#define MNT_NODEV	4
+#define MNT_NOEXEC	8
+#define MNT_NOATIME	1024
+#define MNT_NODIRATIME	2048
 
 struct vfsmount
 {
@@ -33,6 +36,11 @@ struct vfsmount
 	struct list_head mnt_list;
 };
 
+				/* remove (m) with fixmes */
+#define	MNT_IS_RDONLY(m)	((m) && ((m)->mnt_flags & MNT_RDONLY))
+#define	MNT_IS_NOATIME(m)	((m) && ((m)->mnt_flags & MNT_NOATIME))
+#define	MNT_IS_NODIRATIME(m)	((m) && ((m)->mnt_flags & MNT_NODIRATIME))
+
 static inline struct vfsmount *mntget(struct vfsmount *mnt)
 {
 	if (mnt)
diff -NurpP --minimal linux-2.6.4/ipc/shm.c linux-2.6.4-bme0.04/ipc/shm.c
--- linux-2.6.4/ipc/shm.c	2004-03-11 03:55:27.000000000 +0100
+++ linux-2.6.4-bme0.04/ipc/shm.c	2004-03-12 20:51:58.000000000 +0100
@@ -149,7 +149,7 @@ static void shm_close (struct vm_area_st
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	update_atime(file->f_dentry->d_inode);
+	update_atime(file->f_dentry->d_inode, file->f_vfsmnt);
 	vma->vm_ops = &shm_vm_ops;
 	shm_inc(file->f_dentry->d_inode->i_ino);
 	return 0;
diff -NurpP --minimal linux-2.6.4/mm/filemap.c linux-2.6.4-bme0.04/mm/filemap.c
--- linux-2.6.4/mm/filemap.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-bme0.04/mm/filemap.c	2004-03-12 20:51:58.000000000 +0100
@@ -725,7 +725,7 @@ no_cached_page:
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
 	if (cached_page)
 		page_cache_release(cached_page);
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 }
 
 EXPORT_SYMBOL(do_generic_mapping_read);
@@ -820,7 +820,7 @@ __generic_file_aio_read(struct kiocb *io
 			if (retval > 0)
 				*ppos = pos + retval;
 		}
-		update_atime(filp->f_dentry->d_inode);
+		update_atime(filp->f_dentry->d_inode, filp->f_vfsmnt);
 		goto out;
 	}
 
@@ -1357,7 +1357,7 @@ int generic_file_mmap(struct file * file
 
 	if (!mapping->a_ops->readpage)
 		return -ENOEXEC;
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 }
diff -NurpP --minimal linux-2.6.4/mm/shmem.c linux-2.6.4-bme0.04/mm/shmem.c
--- linux-2.6.4/mm/shmem.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-bme0.04/mm/shmem.c	2004-03-12 20:51:58.000000000 +0100
@@ -1067,7 +1067,7 @@ static int shmem_mmap(struct file *file,
 	ops = &shmem_vm_ops;
 	if (!S_ISREG(inode->i_mode))
 		return -EACCES;
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_ops = ops;
 	return 0;
 }
@@ -1363,7 +1363,7 @@ static void do_shmem_file_read(struct fi
 	}
 
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 }
 
 static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
diff -NurpP --minimal linux-2.6.4/net/unix/af_unix.c linux-2.6.4-bme0.04/net/unix/af_unix.c
--- linux-2.6.4/net/unix/af_unix.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-bme0.04/net/unix/af_unix.c	2004-03-12 20:51:58.000000000 +0100
@@ -691,7 +691,7 @@ static struct sock *unix_find_other(stru
 			goto put_fail;
 
 		if (u->sk_type == type)
-			update_atime(nd.dentry->d_inode);
+			update_atime(nd.dentry->d_inode, nd.mnt);
 
 		path_release(&nd);
 
@@ -707,7 +707,7 @@ static struct sock *unix_find_other(stru
 			struct dentry *dentry;
 			dentry = unix_sk(u)->dentry;
 			if (dentry)
-				update_atime(dentry->d_inode);
+				update_atime(dentry->d_inode, nd.mnt);
 		} else
 			goto fail;
 	}

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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15  3:55 [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Herbert Poetzl
@ 2004-03-15  4:14 ` Andrew Morton
  2004-03-15  4:25   ` Herbert Poetzl
  2004-03-15 13:25   ` [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Marc-Christian Petersen
  0 siblings, 2 replies; 24+ messages in thread
From: Andrew Morton @ 2004-03-15  4:14 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: torvalds, viro, linux-kernel

Herbert Poetzl <herbert@13thfloor.at> wrote:
>
>  ; this patch adds some functionality to the --bind
>  ; type of vfs mounts.

This won't apply any more.  We very recently changed a large number of
filesystems to not call update_atime() from within their readdir functions.
That operation was hoisted up to vfs_readdir().

Also, rather than adding MNT_IS_RDONLY() and having to remember to check
both the inode and the mount all over the kernel it would be better to
change IS_RDONLY() to take two arguments - the inode and the vfsmnt.  That
way we won't miss places, and unconverted code simpy won't compile, thus
drawing attention to itself.  I don't know if this is feasible, but please
consider it.

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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15  4:14 ` Andrew Morton
@ 2004-03-15  4:25   ` Herbert Poetzl
  2004-03-15  4:34     ` Andrew Morton
  2004-03-15 13:25   ` [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Marc-Christian Petersen
  1 sibling, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  4:25 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

On Sun, Mar 14, 2004 at 08:14:57PM -0800, Andrew Morton wrote:
> Herbert Poetzl <herbert@13thfloor.at> wrote:
> >
> >  ; this patch adds some functionality to the --bind
> >  ; type of vfs mounts.
> 
> This won't apply any more.  We very recently changed a large number of
> filesystems to not call update_atime() from within their readdir functions.
> That operation was hoisted up to vfs_readdir().

good decision, very recently probably means in the bk repository,
is there any link where I could download those changes?

> Also, rather than adding MNT_IS_RDONLY() and having to remember to check
> both the inode and the mount all over the kernel it would be better to
> change IS_RDONLY() to take two arguments - the inode and the vfsmnt.  That
> way we won't miss places, and unconverted code simpy won't compile, thus
> drawing attention to itself.  I don't know if this is feasible, but please
> consider it.

I don't have a problem with that, and it sounds good to me so
far, so I'll have a look at it, and will update the patch
accordingly ...

thanks for the response,
Herbert


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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15  4:25   ` Herbert Poetzl
@ 2004-03-15  4:34     ` Andrew Morton
  2004-03-15  7:55       ` Herbert Poetzl
                         ` (5 more replies)
  0 siblings, 6 replies; 24+ messages in thread
From: Andrew Morton @ 2004-03-15  4:34 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: torvalds, viro, linux-kernel

Herbert Poetzl <herbert@13thfloor.at> wrote:
>
> On Sun, Mar 14, 2004 at 08:14:57PM -0800, Andrew Morton wrote:
> > Herbert Poetzl <herbert@13thfloor.at> wrote:
> > >
> > >  ; this patch adds some functionality to the --bind
> > >  ; type of vfs mounts.
> > 
> > This won't apply any more.  We very recently changed a large number of
> > filesystems to not call update_atime() from within their readdir functions.
> > That operation was hoisted up to vfs_readdir().
> 
> good decision, very recently probably means in the bk repository,
> is there any link where I could download those changes?

The latest diff against the most-recently-release kernel is always at

	http://www.kernel.org/pub/linux/kernel/v2.5/testing/cset/

the topmost link.

> > Also, rather than adding MNT_IS_RDONLY() and having to remember to check
> > both the inode and the mount all over the kernel it would be better to
> > change IS_RDONLY() to take two arguments - the inode and the vfsmnt.  That
> > way we won't miss places, and unconverted code simpy won't compile, thus
> > drawing attention to itself.  I don't know if this is feasible, but please
> > consider it.
> 
> I don't have a problem with that, and it sounds good to me so
> far, so I'll have a look at it, and will update the patch
> accordingly ...

Thanks.

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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15  4:34     ` Andrew Morton
@ 2004-03-15  7:55       ` Herbert Poetzl
  2004-03-15  7:56       ` [PATCH] Bind Mount Extensions 0.04.1 1/5 Herbert Poetzl
                         ` (4 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:55 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

On Sun, Mar 14, 2004 at 08:34:27PM -0800, Andrew Morton wrote:
> Herbert Poetzl <herbert@13thfloor.at> wrote:
> > On Sun, Mar 14, 2004 at 08:14:57PM -0800, Andrew Morton wrote:
> > > 
> > > This won't apply any more.  We very recently changed a large 
> > > number of filesystems to not call update_atime() from within 
> > > their readdir functions.
> > > That operation was hoisted up to vfs_readdir().

okay, patches do reflect this change now ...

> > > Also, rather than adding MNT_IS_RDONLY() and having to 
> > > remember to check both the inode and the mount all over 
> > > the kernel it would be better to change IS_RDONLY() to 
> > > take two arguments - the inode and the vfsmnt.  That
> > > way we won't miss places, and unconverted code simpy 
> > > won't compile, thus drawing attention to itself.  
> > > I don't know if this is feasible, but please consider it.

I decided to split this up into five parts, a simple base
patch, a patch doing the noatime stuff, and three patches
for the IS_RDONLY changes ...

bme0.04.1-ro1 ... are the completely resolved ones
bme0.04.1-ro2 ... acl stuff, needs checking for nd
bme0.04.1-ro3 ... unresolved/legacy

currently I do not know where to get the vfsmnt for the
cases in bme0.04.1-ro3, so they use the legacy define
IS_RDONLY_INODE() for their checks ...

I hope this is what you had in mind, but anyways, let me
know how to proceed ...

best,
Herbert

PS: basic functionality has been verified.

http://www.13thfloor.at/patches/patch-2.6.4-20040314_2308-bme0.04.1.diff
http://www.13thfloor.at/patches/patch-2.6.4-20040314_2308-bme0.04.1-atime.diff
http://www.13thfloor.at/patches/patch-2.6.4-20040314_2308-bme0.04.1-ro1.diff
http://www.13thfloor.at/patches/patch-2.6.4-20040314_2308-bme0.04.1-ro2.diff
http://www.13thfloor.at/patches/patch-2.6.4-20040314_2308-bme0.04.1-ro3.diff


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

* [PATCH] Bind Mount Extensions 0.04.1 1/5
  2004-03-15  4:34     ` Andrew Morton
  2004-03-15  7:55       ` Herbert Poetzl
@ 2004-03-15  7:56       ` Herbert Poetzl
  2004-03-15  7:57       ` [PATCH] Bind Mount Extensions 0.04.1 2/5 Herbert Poetzl
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:56 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel


;
; Bind Mount Extensions 
;
; this patch adds some functionality to the --bind
; type of vfs mounts.
;
; (C) 2003-2004 Herbert Pötzl <herbert@13thfloor.at>
;
; Changelog:  
;
;   0.01  - readonly bind mounts
;   0.02  - added ro truncate handling
;         - added ro (f)chown, (f)chmod handling
;   0.03  - added ro utime(s) handling
;         - added ro access and *_ioctl
;   0.04  - added noatime and nodiratime
;         - made autofs4 update_atime uncond
;
;   0.04.1  IS_RDONLY extended by vfsmnt
;         - IS_RDONLY_INODE() added for legacy
;         - update_atime() updated (20040314_2308)
;
; this patch is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
; 
; this patch is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
; 

diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/namespace.c linux-2.6.4-20040314_2308-bme0.04.1/fs/namespace.c
--- linux-2.6.4-20040314_2308/fs/namespace.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/namespace.c	2004-03-15 07:51:27.000000000 +0100
@@ -229,7 +229,8 @@ static int show_vfsmnt(struct seq_file *
 	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");
+	seq_puts(m, (MNT_IS_RDONLY(mnt) ||
+		(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);
@@ -522,11 +523,13 @@ out_unlock:
 /*
  * 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)
@@ -553,6 +556,7 @@ static int do_loopback(struct nameidata 
 			spin_unlock(&vfsmount_lock);
 		} else
 			mntput(mnt);
+		mnt->mnt_flags = mnt_flags;
 	}
 
 	up_write(&current->namespace->sem);
@@ -759,12 +763,18 @@ long do_mount(char * dev_name, char * di
 		((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)
 		mnt_flags |= MNT_NODEV;
 	if (flags & MS_NOEXEC)
 		mnt_flags |= MNT_NOEXEC;
+	if (flags & MS_NOATIME)
+		mnt_flags |= MNT_NOATIME;
+	if (flags & MS_NODIRATIME)
+		mnt_flags |= MNT_NODIRATIME;
 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 
 	/* ... and get the mountpoint */
@@ -780,7 +790,7 @@ long do_mount(char * dev_name, char * di
 		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_MOVE)
 		retval = do_move_mount(&nd, dev_name);
 	else
diff -NurpP --minimal linux-2.6.4-20040314_2308/include/linux/mount.h linux-2.6.4-20040314_2308-bme0.04.1/include/linux/mount.h
--- linux-2.6.4-20040314_2308/include/linux/mount.h	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/include/linux/mount.h	2004-03-15 05:58:04.000000000 +0100
@@ -14,9 +14,12 @@
 
 #include <linux/list.h>
 
-#define MNT_NOSUID	1
-#define MNT_NODEV	2
-#define MNT_NOEXEC	4
+#define MNT_RDONLY	1
+#define MNT_NOSUID	2
+#define MNT_NODEV	4
+#define MNT_NOEXEC	8
+#define MNT_NOATIME	1024
+#define MNT_NODIRATIME	2048
 
 struct vfsmount
 {
@@ -33,6 +36,11 @@ struct vfsmount
 	struct list_head mnt_list;
 };
 
+				    	/* remove (m) when done */
+#define	MNT_IS_RDONLY(m)	((m) && ((m)->mnt_flags & MNT_RDONLY))
+#define	MNT_IS_NOATIME(m)	((m) && ((m)->mnt_flags & MNT_NOATIME))
+#define	MNT_IS_NODIRATIME(m)	((m) && ((m)->mnt_flags & MNT_NODIRATIME))
+
 static inline struct vfsmount *mntget(struct vfsmount *mnt)
 {
 	if (mnt)

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

* [PATCH] Bind Mount Extensions 0.04.1 2/5
  2004-03-15  4:34     ` Andrew Morton
  2004-03-15  7:55       ` Herbert Poetzl
  2004-03-15  7:56       ` [PATCH] Bind Mount Extensions 0.04.1 1/5 Herbert Poetzl
@ 2004-03-15  7:57       ` Herbert Poetzl
  2004-03-18 12:16         ` viro
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 3/5 Herbert Poetzl
                         ` (2 subsequent siblings)
  5 siblings, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:57 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

diff -NurpP --minimal linux-2.6.4-20040314_2308/include/linux/fs.h linux-2.6.4-20040314_2308-bme0.04.1/include/linux/fs.h
--- linux-2.6.4-20040314_2308/include/linux/fs.h	2004-03-15 05:41:50.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/include/linux/fs.h	2004-03-15 06:42:13.000000000 +0100
@@ -214,7 +216,7 @@ extern int leases_enable, dir_notify_ena
 #include <asm/byteorder.h>
 
 /* Used to be a macro which just called the function, now just a function */
-extern void update_atime (struct inode *);
+extern void update_atime (struct inode *, struct vfsmount *);
 
 extern void inode_init(unsigned long);
 extern void mnt_init(unsigned long);
@@ -1409,7 +1411,7 @@ extern void simple_release_fs(struct vfs
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern int inode_setattr(struct inode *, struct iattr *);
 
-extern void inode_update_time(struct inode *inode, int ctime_too);
+extern void inode_update_time(struct inode *inode, int ctime_too, struct vfsmount *mount);
 
 static inline ino_t parent_ino(struct dentry *dentry)
 {
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/inode.c
--- linux-2.6.4-20040314_2308/fs/inode.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/inode.c	2004-03-15 06:32:33.000000000 +0100
@@ -1141,15 +1142,16 @@ static int inode_times_differ(struct ino
  *	This function automatically handles read only file systems and media,
  *	as well as the "noatime" flag and inode specific "noatime" markers.
  */
-void update_atime(struct inode *inode)
+void update_atime(struct inode *inode, struct vfsmount *mnt)
 {
 	struct timespec now;
 
-	if (IS_NOATIME(inode))
+	if (IS_NOATIME(inode) || MNT_IS_NOATIME(mnt))
 		return;
-	if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
+	if (S_ISDIR(inode->i_mode) &&
+		(IS_NODIRATIME(inode) || MNT_IS_NODIRATIME(mnt)))
 		return;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, mnt))
 		return;
 
 	now = current_kernel_time();
diff -NurpP --minimal linux-2.6.4-20040314_2308/drivers/char/random.c linux-2.6.4-20040314_2308-bme0.04.1/drivers/char/random.c
--- linux-2.6.4-20040314_2308/drivers/char/random.c	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/drivers/char/random.c	2004-03-15 06:02:34.000000000 +0100
@@ -1641,7 +1641,7 @@ random_read(struct file * file, char * b
 	 * If we gave the user some bytes, update the access time.
 	 */
 	if (count != 0) {
-		update_atime(file->f_dentry->d_inode);
+		update_atime(file->f_dentry->d_inode, file->f_vfsmnt);
 	}
 	
 	return (count ? count : retval);
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/autofs4/root.c linux-2.6.4-20040314_2308-bme0.04.1/fs/autofs4/root.c
--- linux-2.6.4-20040314_2308/fs/autofs4/root.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/autofs4/root.c	2004-03-15 06:02:34.000000000 +0100
@@ -61,7 +61,8 @@ static void autofs4_update_usage(struct 
 		struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
 		if (ino) {
-			update_atime(dentry->d_inode);
+			/* Al Viro said: unconditional */
+			update_atime(dentry->d_inode, 0);
 			ino->last_used = jiffies;
 		}
 	}
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/coda/dir.c linux-2.6.4-20040314_2308-bme0.04.1/fs/coda/dir.c
--- linux-2.6.4-20040314_2308/fs/coda/dir.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/coda/dir.c	2004-03-15 06:59:42.000000000 +0100
@@ -512,7 +512,7 @@ int coda_readdir(struct file *coda_file,
 		ret = -ENOENT;
 		if (!IS_DEADDIR(host_inode)) {
 			ret = host_file->f_op->readdir(host_file, filldir, dirent);
-			update_atime(host_inode);
+			update_atime(host_inode, host_file->f_vfsmnt);
 		}
 	}
 out:
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/hugetlbfs/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/hugetlbfs/inode.c
--- linux-2.6.4-20040314_2308/fs/hugetlbfs/inode.c	2004-03-11 03:55:44.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/hugetlbfs/inode.c	2004-03-15 06:02:34.000000000 +0100
@@ -62,7 +62,7 @@ static int hugetlbfs_file_mmap(struct fi
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
 	down(&inode->i_sem);
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/namei.c linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c
--- linux-2.6.4-20040314_2308/fs/namei.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c	2004-03-15 07:29:50.000000000 +0100
@@ -412,7 +416,7 @@ static inline int do_follow_link(struct 
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
-	update_atime(dentry->d_inode);
+	update_atime(dentry->d_inode, nd->mnt);
 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
 	current->link_count--;
 	return err;
@@ -1368,7 +1390,7 @@ do_link:
 	error = security_inode_follow_link(dentry, nd);
 	if (error)
 		goto exit_dput;
-	update_atime(dentry->d_inode);
+	update_atime(dentry->d_inode, nd->mnt);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	dput(dentry);
 	if (error)
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/nfsd/vfs.c linux-2.6.4-20040314_2308-bme0.04.1/fs/nfsd/vfs.c
--- linux-2.6.4-20040314_2308/fs/nfsd/vfs.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/nfsd/vfs.c	2004-03-15 06:19:48.000000000 +0100
@@ -1143,7 +1143,7 @@ nfsd_readlink(struct svc_rqst *rqstp, st
 	if (!inode->i_op || !inode->i_op->readlink)
 		goto out;
 
-	update_atime(inode);
+	update_atime(inode, fhp->fh_export->ex_mnt);
 	/* N.B. Why does this call need a get_fs()??
 	 * Remove the set_fs and watch the fireworks:-) --okir
 	 */
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/pipe.c linux-2.6.4-20040314_2308-bme0.04.1/fs/pipe.c
--- linux-2.6.4-20040314_2308/fs/pipe.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/pipe.c	2004-03-15 06:30:26.000000000 +0100
@@ -165,7 +165,7 @@ pipe_readv(struct file *filp, const stru
 		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 	}
 	if (ret > 0)
-		update_atime(inode);
+		update_atime(inode, filp->f_vfsmnt);
 	return ret;
 }
 
@@ -263,7 +263,7 @@ pipe_writev(struct file *filp, const str
 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
 	}
 	if (ret > 0)
-		inode_update_time(inode, 1);	/* mtime and ctime */
+		inode_update_time(inode, 1, filp->f_vfsmnt);	/* mtime and ctime */
 	return ret;
 }
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/readdir.c linux-2.6.4-20040314_2308-bme0.04.1/fs/readdir.c
--- linux-2.6.4-20040314_2308/fs/readdir.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/readdir.c	2004-03-15 06:54:08.000000000 +0100
@@ -32,7 +32,7 @@ int vfs_readdir(struct file *file, filld
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
 		res = file->f_op->readdir(file, buf, filler);
-		update_atime(inode);
+		update_atime(inode, file->f_vfsmnt);
 	}
 	up(&inode->i_sem);
 out:
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/reiserfs/file.c linux-2.6.4-20040314_2308-bme0.04.1/fs/reiserfs/file.c
--- linux-2.6.4-20040314_2308/fs/reiserfs/file.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/reiserfs/file.c	2004-03-15 06:30:43.000000000 +0100
@@ -1061,7 +1061,7 @@ ssize_t reiserfs_file_write( struct file
 	goto out;
 
     remove_suid(file->f_dentry);
-    inode_update_time(inode, 1); /* Both mtime and ctime */
+    inode_update_time(inode, 1, file->f_vfsmnt); /* Both mtime and ctime */
 
     // Ok, we are done with all the checks.
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/stat.c linux-2.6.4-20040314_2308-bme0.04.1/fs/stat.c
--- linux-2.6.4-20040314_2308/fs/stat.c	2004-03-11 03:55:23.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/stat.c	2004-03-15 06:02:34.000000000 +0100
@@ -272,7 +272,7 @@ asmlinkage long sys_readlink(const char 
 		if (inode->i_op && inode->i_op->readlink) {
 			error = security_inode_readlink(nd.dentry);
 			if (!error) {
-				update_atime(inode);
+				update_atime(inode, nd.mnt);
 				error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
 			}
 		}
diff -NurpP --minimal linux-2.6.4-20040314_2308/ipc/shm.c linux-2.6.4-20040314_2308-bme0.04.1/ipc/shm.c
--- linux-2.6.4-20040314_2308/ipc/shm.c	2004-03-11 03:55:27.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/ipc/shm.c	2004-03-15 06:02:34.000000000 +0100
@@ -149,7 +149,7 @@ static void shm_close (struct vm_area_st
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	update_atime(file->f_dentry->d_inode);
+	update_atime(file->f_dentry->d_inode, file->f_vfsmnt);
 	vma->vm_ops = &shm_vm_ops;
 	shm_inc(file->f_dentry->d_inode->i_ino);
 	return 0;
diff -NurpP --minimal linux-2.6.4-20040314_2308/mm/filemap.c linux-2.6.4-20040314_2308-bme0.04.1/mm/filemap.c
--- linux-2.6.4-20040314_2308/mm/filemap.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/mm/filemap.c	2004-03-15 06:31:00.000000000 +0100
@@ -725,7 +725,7 @@ no_cached_page:
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
 	if (cached_page)
 		page_cache_release(cached_page);
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 }
 
 EXPORT_SYMBOL(do_generic_mapping_read);
@@ -820,7 +820,7 @@ __generic_file_aio_read(struct kiocb *io
 			if (retval > 0)
 				*ppos = pos + retval;
 		}
-		update_atime(filp->f_dentry->d_inode);
+		update_atime(filp->f_dentry->d_inode, filp->f_vfsmnt);
 		goto out;
 	}
 
@@ -1357,7 +1357,7 @@ int generic_file_mmap(struct file * file
 
 	if (!mapping->a_ops->readpage)
 		return -ENOEXEC;
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 }
@@ -1783,7 +1783,7 @@ generic_file_aio_write_nolock(struct kio
 		goto out;
 
 	remove_suid(file->f_dentry);
-	inode_update_time(inode, 1);
+	inode_update_time(inode, 1, file->f_vfsmnt);
 
 	/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
 	if (unlikely(file->f_flags & O_DIRECT)) {
diff -NurpP --minimal linux-2.6.4-20040314_2308/mm/shmem.c linux-2.6.4-20040314_2308-bme0.04.1/mm/shmem.c
--- linux-2.6.4-20040314_2308/mm/shmem.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/mm/shmem.c	2004-03-15 06:02:34.000000000 +0100
@@ -1067,7 +1067,7 @@ static int shmem_mmap(struct file *file,
 	ops = &shmem_vm_ops;
 	if (!S_ISREG(inode->i_mode))
 		return -EACCES;
-	update_atime(inode);
+	update_atime(inode, file->f_vfsmnt);
 	vma->vm_ops = ops;
 	return 0;
 }
@@ -1363,7 +1363,7 @@ static void do_shmem_file_read(struct fi
 	}
 
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
-	update_atime(inode);
+	update_atime(inode, filp->f_vfsmnt);
 }
 
 static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
diff -NurpP --minimal linux-2.6.4-20040314_2308/net/unix/af_unix.c linux-2.6.4-20040314_2308-bme0.04.1/net/unix/af_unix.c
--- linux-2.6.4-20040314_2308/net/unix/af_unix.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/net/unix/af_unix.c	2004-03-15 06:02:34.000000000 +0100
@@ -691,7 +691,7 @@ static struct sock *unix_find_other(stru
 			goto put_fail;
 
 		if (u->sk_type == type)
-			update_atime(nd.dentry->d_inode);
+			update_atime(nd.dentry->d_inode, nd.mnt);
 
 		path_release(&nd);
 
@@ -707,7 +707,7 @@ static struct sock *unix_find_other(stru
 			struct dentry *dentry;
 			dentry = unix_sk(u)->dentry;
 			if (dentry)
-				update_atime(dentry->d_inode);
+				update_atime(dentry->d_inode, nd.mnt);
 		} else
 			goto fail;
 	}

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

* [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15  4:34     ` Andrew Morton
                         ` (2 preceding siblings ...)
  2004-03-15  7:57       ` [PATCH] Bind Mount Extensions 0.04.1 2/5 Herbert Poetzl
@ 2004-03-15  7:58       ` Herbert Poetzl
  2004-03-15 22:10         ` Andrew Morton
  2004-03-18 12:26         ` viro
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 4/5 Herbert Poetzl
  2004-03-15  7:59       ` [PATCH] Bind Mount Extensions 0.04.1 5/5 Herbert Poetzl
  5 siblings, 2 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

diff -NurpP --minimal linux-2.6.4-20040314_2308/include/linux/posix_acl.h linux-2.6.4-20040314_2308-bme0.04.1/include/linux/posix_acl.h
--- linux-2.6.4-20040314_2308/include/linux/posix_acl.h	2004-03-11 03:55:54.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/include/linux/posix_acl.h	2004-03-15 07:45:19.000000000 +0100
@@ -9,6 +9,7 @@
 #define __LINUX_POSIX_ACL_H
 
 #include <linux/slab.h>
+#include <linux/namei.h>
 
 #define ACL_UNDEFINED_ID	(-1)
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/include/linux/fs.h linux-2.6.4-20040314_2308-bme0.04.1/include/linux/fs.h
--- linux-2.6.4-20040314_2308/include/linux/fs.h	2004-03-15 05:41:50.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/include/linux/fs.h	2004-03-15 06:42:13.000000000 +0100
@@ -19,6 +19,7 @@
 #include <linux/cache.h>
 #include <linux/radix-tree.h>
 #include <linux/kobject.h>
+#include <linux/mount.h>
 #include <asm/atomic.h>
 
 struct iovec;
@@ -155,7 +156,8 @@ extern int leases_enable, dir_notify_ena
  */
 #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(inode)	((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_RDONLY(inode,mount)	(IS_RDONLY_INODE(inode) || MNT_IS_RDONLY(mount))
 #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) || \
@@ -1226,7 +1228,7 @@ extern sector_t bmap(struct inode *, sec
 extern int setattr_mask(unsigned int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int, struct nameidata *);
-extern int vfs_permission(struct inode *, int);
+extern int vfs_permission(struct inode *, int, struct nameidata *);
 extern int get_write_access(struct inode *);
 extern int deny_write_access(struct file *);
 static inline void put_write_access(struct inode * inode)
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/open.c linux-2.6.4-20040314_2308-bme0.04.1/fs/open.c
--- linux-2.6.4-20040314_2308/fs/open.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/open.c	2004-03-15 05:58:51.000000000 +0100
@@ -226,7 +226,7 @@ static inline long do_sys_truncate(const
 		goto dput_and_out;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, nd.mnt))
 		goto dput_and_out;
 
 	error = -EPERM;
@@ -350,7 +350,7 @@ asmlinkage long sys_utime(char __user * 
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, nd.mnt))
 		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
@@ -407,7 +407,7 @@ long do_utimes(char __user * filename, s
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, nd.mnt))
 		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
@@ -489,8 +489,9 @@ asmlinkage long sys_access(const char __
 	if (!res) {
 		res = permission(nd.dentry->d_inode, mode, &nd);
 		/* SuS v2 requires we report a read only fs too */
-		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-		   && !special_file(nd.dentry->d_inode->i_mode))
+		if (!res && (mode & S_IWOTH)
+		   && !special_file(nd.dentry->d_inode->i_mode)
+		   && (IS_RDONLY(nd.dentry->d_inode, nd.mnt)))
 			res = -EROFS;
 		path_release(&nd);
 	}
@@ -595,7 +596,7 @@ asmlinkage long sys_fchmod(unsigned int 
 	inode = dentry->d_inode;
 
 	err = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, file->f_vfsmnt))
 		goto out_putf;
 	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
@@ -627,7 +628,7 @@ asmlinkage long sys_chmod(const char __u
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, nd.mnt))
 		goto dput_and_out;
 
 	error = -EPERM;
@@ -648,7 +649,7 @@ out:
 	return error;
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct vfsmount *mnt, struct dentry * dentry, uid_t user, gid_t group)
 {
 	struct inode * inode;
 	int error;
@@ -660,7 +661,7 @@ static int chown_common(struct dentry * 
 		goto out;
 	}
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, mnt))
 		goto out;
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
@@ -690,7 +691,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.mnt, nd.dentry, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -703,7 +704,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.mnt, nd.dentry, user, group);
 		path_release(&nd);
 	}
 	return error;
@@ -717,7 +718,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_vfsmnt, file->f_dentry, user, group);
 		fput(file);
 	}
 	return error;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/namei.c linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c
--- linux-2.6.4-20040314_2308/fs/namei.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c	2004-03-15 07:29:50.000000000 +0100
@@ -209,14 +209,18 @@ int permission(struct inode * inode,int 
 {
 	int retval;
 	int submask;
+	umode_t	mode = inode->i_mode;
 
 	/* Ordinary permission routines do not understand MAY_APPEND. */
 	submask = mask & ~MAY_APPEND;
 
+	if (nd && (mask & MAY_WRITE) && MNT_IS_RDONLY(nd->mnt) &&
+		(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+		return -EROFS;
 	if (inode->i_op && inode->i_op->permission)
 		retval = inode->i_op->permission(inode, submask, nd);
 	else
-		retval = vfs_permission(inode, submask);
+		retval = vfs_permission(inode, submask, nd);
 	if (retval)
 		return retval;
 
@@ -1062,6 +1066,24 @@ static inline int may_create(struct inod
 	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
 }
 
+static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (child->d_inode)
+               return -EEXIST;
+       if (IS_DEADDIR(dir))
+               return -ENOENT;
+       if (mnt->mnt_flags & MNT_RDONLY)
+               return -EROFS;
+       return 0;
+}
+
+static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (!child->d_inode)
+               return -ENOENT;
+       if (mnt->mnt_flags & MNT_RDONLY)
+               return -EROFS;
+       return 0;
+}
+
 /* 
  * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
  * reasons.
@@ -1183,7 +1205,7 @@ 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, nd->mnt)) && (flag & FMODE_WRITE))
 		return -EROFS;
 	/*
 	 * An append-only file must be opened in append mode for writing.
@@ -1408,23 +1430,28 @@ do_link:
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
 	struct dentry *dentry;
+	int error;
 
 	down(&nd->dentry->d_inode->i_sem);
-	dentry = ERR_PTR(-EEXIST);
+	error = -EEXIST;
 	if (nd->last_type != LAST_NORM)
-		goto fail;
+		goto out;
 	nd->flags &= ~LOOKUP_PARENT;
 	dentry = lookup_hash(&nd->last, nd->dentry);
 	if (IS_ERR(dentry))
+		goto ret;
+	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
+	if (error)
 		goto fail;
+	error = -ENOENT;
 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-		goto enoent;
+		goto fail;
+ret:
 	return dentry;
-enoent:
-	dput(dentry);
-	dentry = ERR_PTR(-ENOENT);
 fail:
-	return dentry;
+	dput(dentry);
+out:
+	return ERR_PTR(error);
 }
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
@@ -1653,7 +1680,11 @@ asmlinkage long sys_rmdir(const char __u
 	dentry = lookup_hash(&nd.last, nd.dentry);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+	exit2:
 		dput(dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
@@ -1725,6 +1756,9 @@ asmlinkage long sys_unlink(const char __
 		/* Why not before? Because we want correct error value */
 		if (nd.last.name[nd.last.len])
 			goto slashes;
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
@@ -2089,6 +2123,9 @@ static inline int do_rename(const char *
 	error = -EINVAL;
 	if (old_dentry == trap)
 		goto exit4;
+	error = -EROFS;
+	if (MNT_IS_RDONLY(newnd.mnt))
+		goto exit4;
 	new_dentry = lookup_hash(&newnd.last, new_dir);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
diff -NurpP --minimal linux-2.6.4-20040314_2308/arch/sparc64/solaris/fs.c linux-2.6.4-20040314_2308-bme0.04.1/arch/sparc64/solaris/fs.c
--- linux-2.6.4-20040314_2308/arch/sparc64/solaris/fs.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/arch/sparc64/solaris/fs.c	2004-03-15 06:26:55.000000000 +0100
@@ -405,7 +405,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)) i = 1;
 		if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
 		if (!sysv_valid_dev(inode->i_sb->s_dev))
 			return -EOVERFLOW;
@@ -441,7 +441,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)) 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.4-20040314_2308/fs/ext2/ioctl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/ioctl.c
--- linux-2.6.4-20040314_2308/fs/ext2/ioctl.c	2004-03-11 03:55:54.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/ioctl.c	2004-03-15 05:58:51.000000000 +0100
@@ -29,7 +30,7 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETFLAGS: {
 		unsigned int oldflags;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode, filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -68,7 +69,7 @@ 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->f_vfsmnt))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int *) arg))
 			return -EFAULT;	
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext2/xattr.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/xattr.c
--- linux-2.6.4-20040314_2308/fs/ext2/xattr.c	2004-03-11 03:55:34.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/xattr.c	2004-03-15 06:27:13.000000000 +0100
@@ -496,7 +496,7 @@ ext2_xattr_set(struct inode *inode, int 
 	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
 		  name_index, name, value, (long)value_len);
 
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY_INODE(inode))
 		return -EROFS;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext3/ioctl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/ioctl.c
--- linux-2.6.4-20040314_2308/fs/ext3/ioctl.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/ioctl.c	2004-03-15 05:58:51.000000000 +0100
@@ -34,7 +35,7 @@ int ext3_ioctl (struct inode * inode, st
 		unsigned int oldflags;
 		unsigned int jflag;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode, filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -110,7 +111,7 @@ flags_err:
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode, filp->f_vfsmnt))
 			return -EROFS;
 		if (get_user(generation, (int *) arg))
 			return -EFAULT;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext3/xattr.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/xattr.c
--- linux-2.6.4-20040314_2308/fs/ext3/xattr.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/xattr.c	2004-03-15 06:28:18.000000000 +0100
@@ -496,7 +496,7 @@ ext3_xattr_set_handle(handle_t *handle, 
 	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
 		  name_index, name, value, (long)value_len);
 
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY_INODE(inode))
 		return -EROFS;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/hfs/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/hfs/inode.c
--- linux-2.6.4-20040314_2308/fs/hfs/inode.c	2004-03-11 03:55:54.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/hfs/inode.c	2004-03-15 06:23:57.000000000 +0100
@@ -516,7 +516,7 @@ static int hfs_permission(struct inode *
 {
 	if (S_ISREG(inode->i_mode) && mask & MAY_EXEC)
 		return 0;
-	return vfs_permission(inode, mask);
+	return vfs_permission(inode, mask, nd);
 }
 
 static int hfs_file_open(struct inode *inode, struct file *file)
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/hfsplus/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/hfsplus/inode.c
--- linux-2.6.4-20040314_2308/fs/hfsplus/inode.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/hfsplus/inode.c	2004-03-15 06:23:48.000000000 +0100
@@ -260,7 +260,7 @@ static int hfsplus_permission(struct ino
 	 */
 	if (S_ISREG(inode->i_mode) && mask & MAY_EXEC && !(inode->i_mode & 0111))
 		return 0;
-	return vfs_permission(inode, mask);
+	return vfs_permission(inode, mask, nd);
 }
 
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/intermezzo/dir.c linux-2.6.4-20040314_2308-bme0.04.1/fs/intermezzo/dir.c
--- linux-2.6.4-20040314_2308/fs/intermezzo/dir.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/intermezzo/dir.c	2004-03-15 06:23:38.000000000 +0100
@@ -864,7 +864,7 @@ int presto_permission(struct inode *inod
         /* The cache filesystem doesn't have its own permission function,
          * so we call the default one.
          */
-        rc = vfs_permission(inode, mask);
+        rc = vfs_permission(inode, mask, nd);
 
         EXIT;
         return rc;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/intermezzo/vfs.c linux-2.6.4-20040314_2308-bme0.04.1/fs/intermezzo/vfs.c
--- linux-2.6.4-20040314_2308/fs/intermezzo/vfs.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/intermezzo/vfs.c	2004-03-15 06:40:07.000000000 +0100
@@ -258,7 +258,7 @@ int presto_settime(struct presto_file_se
                 inode = dentry->d_inode;
 
                 error = -EROFS;
-                if (IS_RDONLY(inode)) {
+                if (IS_RDONLY_INODE(inode)) {
                         EXIT;
                         return -EROFS;
                 }
@@ -373,7 +373,7 @@ int presto_do_setattr(struct presto_file
 
         ENTRY;
         error = -EROFS;
-        if (IS_RDONLY(inode)) {
+        if (IS_RDONLY_INODE(inode)) {
                 EXIT;
                 return -EROFS;
         }
@@ -2316,7 +2316,7 @@ int presto_do_set_ext_attr(struct presto
 
         ENTRY;
         error = -EROFS;
-        if (IS_RDONLY(inode)) {
+        if (IS_RDONLY_INODE(inode)) {
                 EXIT;
                 return -EROFS;
         }
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/hfsplus/ioctl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/hfsplus/ioctl.c
--- linux-2.6.4-20040314_2308/fs/hfsplus/ioctl.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/hfsplus/ioctl.c	2004-03-15 06:29:01.000000000 +0100
@@ -33,7 +33,7 @@ int hfsplus_ioctl(struct inode *inode, s
 			flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
 		return put_user(flags, (int *)arg);
 	case HFSPLUS_IOC_EXT2_SETFLAGS: {
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode, filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/inode.c
--- linux-2.6.4-20040314_2308/fs/inode.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/inode.c	2004-03-15 06:32:33.000000000 +0100
@@ -1173,14 +1175,14 @@ EXPORT_SYMBOL(update_atime);
  *	When ctime_too is specified update the ctime too.
  */
 
-void inode_update_time(struct inode *inode, int ctime_too)
+void inode_update_time(struct inode *inode, int ctime_too, struct vfsmount *mount)
 {
 	struct timespec now;
 	int sync_it = 0;
 
 	if (IS_NOCMTIME(inode))
 		return;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode, mount))
 		return;
 
 	now = current_kernel_time();
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/nfs/dir.c linux-2.6.4-20040314_2308-bme0.04.1/fs/nfs/dir.c
--- linux-2.6.4-20040314_2308/fs/nfs/dir.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/nfs/dir.c	2004-03-15 06:24:31.000000000 +0100
@@ -778,7 +778,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, nd->mnt) &&
+		(nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
 		return 0;
 	return 1;
 }
@@ -1514,7 +1515,7 @@ nfs_permission(struct inode *inode, int 
 		 * Nobody gets write access to a read-only fs.
 		 *
 		 */
-		if (IS_RDONLY(inode) &&
+		if (IS_RDONLY(inode, nd->mnt) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;
 
@@ -1565,7 +1566,7 @@ out:
 	return res;
 out_notsup:
 	nfs_revalidate_inode(NFS_SERVER(inode), inode);
-	res = vfs_permission(inode, mask);
+	res = vfs_permission(inode, mask, nd);
 	unlock_kernel();
 	return res;
 add_cache:
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/proc/base.c linux-2.6.4-20040314_2308-bme0.04.1/fs/proc/base.c
--- linux-2.6.4-20040314_2308/fs/proc/base.c	2004-03-11 03:55:34.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/proc/base.c	2004-03-15 06:24:42.000000000 +0100
@@ -449,7 +449,7 @@ out:
 
 static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-	if (vfs_permission(inode, mask) != 0)
+	if (vfs_permission(inode, mask, nd) != 0)
 		return -EACCES;
 	return proc_check_root(inode);
 }
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/reiserfs/ioctl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/reiserfs/ioctl.c
--- linux-2.6.4-20040314_2308/fs/reiserfs/ioctl.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/reiserfs/ioctl.c	2004-03-15 05:58:51.000000000 +0100
@@ -38,7 +39,7 @@ int reiserfs_ioctl (struct inode * inode
 		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
 		return put_user(flags, (int *) arg);
 	case REISERFS_IOC_SETFLAGS: {
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode, filp->f_vfsmnt))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
@@ -70,7 +71,7 @@ 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->f_vfsmnt))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int *) arg))
 			return -EFAULT;	

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

* [PATCH] Bind Mount Extensions 0.04.1 4/5
  2004-03-15  4:34     ` Andrew Morton
                         ` (3 preceding siblings ...)
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 3/5 Herbert Poetzl
@ 2004-03-15  7:58       ` Herbert Poetzl
  2004-03-15  7:59       ` [PATCH] Bind Mount Extensions 0.04.1 5/5 Herbert Poetzl
  5 siblings, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/namei.c linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c
--- linux-2.6.4-20040314_2308/fs/namei.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/namei.c	2004-03-15 07:29:50.000000000 +0100
@@ -156,15 +156,15 @@ char * getname(const char __user * filen
  * for filesystem access without changing the "normal" uids which
  * are used for other things..
  */
-int vfs_permission(struct inode * inode, int mask)
+int vfs_permission(struct inode * inode, int mask, struct nameidata *nd)
 {
-	umode_t			mode = inode->i_mode;
+	umode_t	mode = inode->i_mode;
 
 	if (mask & MAY_WRITE) {
 		/*
 		 * Nobody gets write access to a read-only fs.
 		 */
-		if (IS_RDONLY(inode) &&
+		if (IS_RDONLY(inode, nd ? nd->mnt : NULL) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext2/acl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/acl.c
--- linux-2.6.4-20040314_2308/fs/ext2/acl.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/acl.c	2004-03-15 07:44:41.000000000 +0100
@@ -291,7 +292,8 @@ ext2_permission(struct inode *inode, int
 	int mode = inode->i_mode;
 
 	/* Nobody gets write access to a read-only fs */
-	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+	if ((mask & MAY_WRITE) &&
+	    (IS_RDONLY(inode, nd ? nd->mnt : NULL)) &&
 	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 		return -EROFS;
 	/* Nobody gets write access to an immutable file */
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext3/acl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/acl.c
--- linux-2.6.4-20040314_2308/fs/ext3/acl.c	2004-03-15 05:41:49.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/acl.c	2004-03-15 07:38:42.000000000 +0100
@@ -296,7 +296,8 @@ ext3_permission(struct inode *inode, int
 	int mode = inode->i_mode;
 
 	/* Nobody gets write access to a read-only fs */
-	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+	if ((mask & MAY_WRITE) &&
+	    (IS_RDONLY(inode, nd ? nd->mnt : NULL)) &&
 	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 		return -EROFS;
 	/* Nobody gets write access to an immutable file */
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/jfs/acl.c linux-2.6.4-20040314_2308-bme0.04.1/fs/jfs/acl.c
--- linux-2.6.4-20040314_2308/fs/jfs/acl.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/jfs/acl.c	2004-03-15 07:37:45.000000000 +0100
@@ -136,7 +136,7 @@ int jfs_permission(struct inode * inode,
 		/*
 		 * Nobody gets write access to a read-only fs.
 		 */
-		if (IS_RDONLY(inode) &&
+		if (IS_RDONLY(inode, nd ? nd->mnt : NULL) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;

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

* [PATCH] Bind Mount Extensions 0.04.1 5/5
  2004-03-15  4:34     ` Andrew Morton
                         ` (4 preceding siblings ...)
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 4/5 Herbert Poetzl
@ 2004-03-15  7:59       ` Herbert Poetzl
  5 siblings, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15  7:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/xfs/xfs_inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/xfs/xfs_inode.c
--- linux-2.6.4-20040314_2308/fs/xfs/xfs_inode.c	2004-03-11 03:55:50.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/xfs/xfs_inode.c	2004-03-15 06:17:57.000000000 +0100
@@ -3677,7 +3677,7 @@ xfs_iaccess(
 	if (mode & S_IWUSR) {
 		umode_t		imode = inode->i_mode;
 
-		if (IS_RDONLY(inode) &&
+		if (IS_RDONLY_INODE(inode) &&
 		    (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode)))
 			return XFS_ERROR(EROFS);
 
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/nfsd/vfs.c linux-2.6.4-20040314_2308-bme0.04.1/fs/nfsd/vfs.c
--- linux-2.6.4-20040314_2308/fs/nfsd/vfs.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/nfsd/vfs.c	2004-03-15 06:19:48.000000000 +0100
@@ -1539,7 +1539,7 @@ nfsd_permission(struct svc_export *exp, 
 		inode->i_mode,
 		IS_IMMUTABLE(inode)?	" immut" : "",
 		IS_APPEND(inode)?	" append" : "",
-		IS_RDONLY(inode)?	" ro" : "");
+		IS_RDONLY_INODE(inode)?	" ro" : "");
 	dprintk("      owner %d/%d user %d/%d\n",
 		inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
 #endif
@@ -1550,7 +1550,7 @@ 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(inode))
 				return nfserr_rofs;
 			if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
 				return nfserr_perm;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ntfs/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ntfs/inode.c
--- linux-2.6.4-20040314_2308/fs/ntfs/inode.c	2004-03-11 03:55:44.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ntfs/inode.c	2004-03-15 06:18:51.000000000 +0100
@@ -885,7 +885,7 @@ skip_large_dir_stuff:
 		/* Everyone gets read and scan permissions. */
 		vi->i_mode |= S_IRUGO | S_IXUGO;
 		/* If not read-only, set write permissions. */
-		if (!IS_RDONLY(vi))
+		if (!IS_RDONLY_INODE(vi))
 			vi->i_mode |= S_IWUGO;
 		/*
 		 * Apply the directory permissions mask set in the mount
@@ -1026,7 +1026,7 @@ no_data_attr_special_case:
 		/* Everyone gets all permissions. */
 		vi->i_mode |= S_IRWXUGO;
 		/* If read-only, noone gets write permissions. */
-		if (IS_RDONLY(vi))
+		if (IS_RDONLY_INODE(vi))
 			vi->i_mode &= ~S_IWUGO;
 		/* Apply the file permissions mask set in the mount options. */
 		vi->i_mode &= ~vol->fmask;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/fat/file.c linux-2.6.4-20040314_2308-bme0.04.1/fs/fat/file.c
--- linux-2.6.4-20040314_2308/fs/fat/file.c	2004-03-11 03:55:24.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/fat/file.c	2004-03-15 06:28:31.000000000 +0100
@@ -90,7 +90,7 @@ void fat_truncate(struct inode *inode)
 	int nr_clusters;
 
 	/* Why no return value?  Surely the disk could fail... */
-	if (IS_RDONLY (inode))
+	if (IS_RDONLY_INODE(inode))
 		return /* -EPERM */;
 	if (IS_IMMUTABLE(inode))
 		return /* -EPERM */;
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/jfs/xattr.c linux-2.6.4-20040314_2308-bme0.04.1/fs/jfs/xattr.c
--- linux-2.6.4-20040314_2308/fs/jfs/xattr.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/jfs/xattr.c	2004-03-15 06:40:42.000000000 +0100
@@ -717,7 +717,7 @@ static int can_set_system_xattr(struct i
 static int can_set_xattr(struct inode *inode, const char *name,
 			 const void *value, size_t value_len)
 {
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY_INODE(inode))
 		return -EROFS;
 
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ext3/inode.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/inode.c
--- linux-2.6.4-20040314_2308/fs/ext3/inode.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext3/inode.c	2004-03-15 06:27:47.000000000 +0100
@@ -3018,7 +3018,7 @@ int ext3_change_inode_journal_flag(struc
 	 */
 
 	journal = EXT3_JOURNAL(inode);
-	if (is_journal_aborted(journal) || IS_RDONLY(inode))
+	if (is_journal_aborted(journal) || IS_RDONLY_INODE(inode))
 		return -EROFS;
 
 	journal_lock_updates(journal);
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ncpfs/file.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ncpfs/file.c
--- linux-2.6.4-20040314_2308/fs/ncpfs/file.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ncpfs/file.c	2004-03-15 06:21:31.000000000 +0100
@@ -175,7 +175,7 @@ ncp_file_read(struct file *file, char *b
 
 	*ppos = pos;
 
-	if (!IS_RDONLY(inode)) {
+	if (!IS_RDONLY_INODE(inode)) {
 		inode->i_atime = CURRENT_TIME;
 	}
 	
diff -NurpP --minimal linux-2.6.4-20040314_2308/fs/ncpfs/mmap.c linux-2.6.4-20040314_2308-bme0.04.1/fs/ncpfs/mmap.c
--- linux-2.6.4-20040314_2308/fs/ncpfs/mmap.c	2004-03-11 03:55:36.000000000 +0100
+++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ncpfs/mmap.c	2004-03-15 06:21:00.000000000 +0100
@@ -123,7 +123,7 @@ int ncp_mmap(struct file *file, struct v
 	if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff 
 	   > (1U << (32 - PAGE_SHIFT)))
 		return -EFBIG;
-	if (!IS_RDONLY(inode)) {
+	if (!IS_RDONLY_INODE(inode)) {
 		inode->i_atime = CURRENT_TIME;
 	}
 

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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15  4:14 ` Andrew Morton
  2004-03-15  4:25   ` Herbert Poetzl
@ 2004-03-15 13:25   ` Marc-Christian Petersen
  2004-03-15 18:25     ` Dariush Pietrzak
  1 sibling, 1 reply; 24+ messages in thread
From: Marc-Christian Petersen @ 2004-03-15 13:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andrew Morton, Herbert Poetzl, torvalds, viro

On Monday 15 March 2004 05:14, Andrew Morton wrote:

Hi Herbert, Andrew,

> Herbert Poetzl <herbert@13thfloor.at> wrote:
> >  ; this patch adds some functionality to the --bind
> >  ; type of vfs mounts.

> This won't apply any more.  We very recently changed a large number of
> filesystems to not call update_atime() from within their readdir functions.
> That operation was hoisted up to vfs_readdir().

right. Anyway, I like to see this merged into -mm for wider testing after 
Herbert has fixed up some things like update_atime removal etc.

I personally use it for a long time now and I really like it.

ciao, Marc


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

* Re: [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4)
  2004-03-15 13:25   ` [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Marc-Christian Petersen
@ 2004-03-15 18:25     ` Dariush Pietrzak
  0 siblings, 0 replies; 24+ messages in thread
From: Dariush Pietrzak @ 2004-03-15 18:25 UTC (permalink / raw)
  To: linux-kernel

> I personally use it for a long time now and I really like it.
 Same here, I hope this functionality gets merged sooner rather then later.
-- 
Dariush Pietrzak,
Key fingerprint = 40D0 9FFB 9939 7320 8294  05E0 BCC7 02C4 75CC 50D9

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 3/5 Herbert Poetzl
@ 2004-03-15 22:10         ` Andrew Morton
  2004-03-15 23:04           ` Herbert Poetzl
  2004-03-18 12:26         ` viro
  1 sibling, 1 reply; 24+ messages in thread
From: Andrew Morton @ 2004-03-15 22:10 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: torvalds, viro, linux-kernel

Herbert Poetzl <herbert@13thfloor.at> wrote:
>
> --- linux-2.6.4-20040314_2308/fs/ext2/xattr.c	2004-03-11 03:55:34.000000000 +0100
> +++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/xattr.c	2004-03-15 06:27:13.000000000 +0100
> @@ -496,7 +496,7 @@ ext2_xattr_set(struct inode *inode, int 
>  	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
>  		  name_index, name, value, (long)value_len);
>  
> -	if (IS_RDONLY(inode))
> +	if (IS_RDONLY_INODE(inode))

I do think that if we're going to do this thing it should have 100%
coverage, and not have little exceptions because the volume of changes got
too high.

The number of places where you need IS_RDONLY_INODE() are encouragingly
small.  It appears that all we need to do to get rid of it is to propagate
the file* down through the ext2 and ext3 xattr code.  A NULL value will
need to be permitted because ext2_new_inode doesn't have a file*, and we've
already performed the check.

Sure, it's a largeish patch but it is very safe: if it compiles, it works.

Could you please work that with Andreas?

IS_RDONLY_INODE() is also used in intermezzo, but that doesn't compile any
more anyway.

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15 22:10         ` Andrew Morton
@ 2004-03-15 23:04           ` Herbert Poetzl
  2004-03-15 23:31             ` Andrew Morton
  0 siblings, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-15 23:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

On Mon, Mar 15, 2004 at 02:10:04PM -0800, Andrew Morton wrote:
> Herbert Poetzl <herbert@13thfloor.at> wrote:
> >
> > --- linux-2.6.4-20040314_2308/fs/ext2/xattr.c	2004-03-11 03:55:34.000000000 +0100
> > +++ linux-2.6.4-20040314_2308-bme0.04.1/fs/ext2/xattr.c	2004-03-15 06:27:13.000000000 +0100
> > @@ -496,7 +496,7 @@ ext2_xattr_set(struct inode *inode, int 
> >  	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
> >  		  name_index, name, value, (long)value_len);
> >  
> > -	if (IS_RDONLY(inode))
> > +	if (IS_RDONLY_INODE(inode))
> 
> I do think that if we're going to do this thing it should have 100%
> coverage, and not have little exceptions because the volume of changes got
> too high.
> 
> The number of places where you need IS_RDONLY_INODE() are encouragingly
> small.  It appears that all we need to do to get rid of it is to propagate
> the file* down through the ext2 and ext3 xattr code.  A NULL value will
> need to be permitted because ext2_new_inode doesn't have a file*, and we've
> already performed the check.

I'm not sure we actually want to do this, but I'll
try ... seems to go up all the way to the syscall entry.

> Sure, it's a largeish patch but it is very safe: if it compiles, it works.

agreed.

> Could you please work that with Andreas?

sure, Andreas who?

> IS_RDONLY_INODE() is also used in intermezzo, but that doesn't compile any
> more anyway.

so I do not bother with that, but what about the nfs(d)
stuff? 

TIA,
Herbert


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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15 23:04           ` Herbert Poetzl
@ 2004-03-15 23:31             ` Andrew Morton
  2004-03-16  6:30               ` Herbert Poetzl
  0 siblings, 1 reply; 24+ messages in thread
From: Andrew Morton @ 2004-03-15 23:31 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: torvalds, viro, linux-kernel

Herbert Poetzl <herbert@13thfloor.at> wrote:
>
> > Could you please work that with Andreas?
> 
> sure, Andreas who?

Andreas Gruenbacher <agruen@suse.de>

> > IS_RDONLY_INODE() is also used in intermezzo, but that doesn't compile any
> > more anyway.
> 
> so I do not bother with that, but what about the nfs(d)
> stuff? 

er, what nfs stuff?  Your patches only have IS_RDONLY_INODE() being used in
the ext2/3 xattr code and in intermezzo.

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15 23:31             ` Andrew Morton
@ 2004-03-16  6:30               ` Herbert Poetzl
  0 siblings, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-16  6:30 UTC (permalink / raw)
  To: Andrew Morton; +Cc: torvalds, viro, linux-kernel

On Mon, Mar 15, 2004 at 03:31:53PM -0800, Andrew Morton wrote:
> Herbert Poetzl <herbert@13thfloor.at> wrote:
> >
> > > Could you please work that with Andreas?
> > 
> > sure, Andreas who?
> 
> Andreas Gruenbacher <agruen@suse.de>

okay, will contact him ...

> > > IS_RDONLY_INODE() is also used in intermezzo, but that doesn't compile any
> > > more anyway.
> > 
> > so I do not bother with that, but what about the nfs(d)
> > stuff? 

> er, what nfs stuff?  Your patches only have IS_RDONLY_INODE() being used in
> the ext2/3 xattr code and in intermezzo.

hmm, I guess nfsd_permission() can be considered nfs stuff,
but I'll look into that anyway, maybe Trond can help here ...
(patch-2.6.4-20040314_2308-bme0.04.1-ro3.diff 5/5)

best,
Herbert

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 2/5
  2004-03-15  7:57       ` [PATCH] Bind Mount Extensions 0.04.1 2/5 Herbert Poetzl
@ 2004-03-18 12:16         ` viro
  2004-03-19  1:57           ` Herbert Poetzl
  2004-04-02  1:23           ` Herbert Poetzl
  0 siblings, 2 replies; 24+ messages in thread
From: viro @ 2004-03-18 12:16 UTC (permalink / raw)
  To: Andrew Morton, torvalds, linux-kernel

On Mon, Mar 15, 2004 at 08:57:23AM +0100, Herbert Poetzl wrote:
> -void update_atime(struct inode *inode)
> +void update_atime(struct inode *inode, struct vfsmount *mnt)

_Hell_, no.  Proper solution is to move the callers upstream instead
of propagating vfsmounts downstream.  That, BTW, was the main reason
for readdir() patch.

BTW, update_atime() is exported.  And it's 2.6 now...

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 3/5 Herbert Poetzl
  2004-03-15 22:10         ` Andrew Morton
@ 2004-03-18 12:26         ` viro
  2004-03-19  2:52           ` Herbert Poetzl
  1 sibling, 1 reply; 24+ messages in thread
From: viro @ 2004-03-18 12:26 UTC (permalink / raw)
  To: Andrew Morton, torvalds, linux-kernel

On Mon, Mar 15, 2004 at 08:58:14AM +0100, Herbert Poetzl wrote:
> -extern int vfs_permission(struct inode *, int);
> +extern int vfs_permission(struct inode *, int, struct nameidata *);

Vetoed, along with IS_RDONLY() prototype change.

Note that you are doing exactly the opposite of the changes we'll need
to deal with remount races.

What we need is to push readonly checks _up_ - into callers of fs methods.
vfs_permission() is default ->permission() - no more, no less.  Neither
it nor other instances have any business touching "this vfsmount is readonly"
logics - it's not something where fs can override stuff; it's "admin said
no r/w access here".

IOW, the check for r/w access to file/directory/symlink on a r/o mount should
be moved into the callers (very few of them) of ->permission() and away from
the methods themselves.

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 2/5
  2004-03-18 12:16         ` viro
@ 2004-03-19  1:57           ` Herbert Poetzl
  2004-04-02  1:23           ` Herbert Poetzl
  1 sibling, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-19  1:57 UTC (permalink / raw)
  To: viro; +Cc: Andrew Morton, torvalds, linux-kernel

On Thu, Mar 18, 2004 at 12:16:50PM +0000, viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Mon, Mar 15, 2004 at 08:57:23AM +0100, Herbert Poetzl wrote:
> > -void update_atime(struct inode *inode)
> > +void update_atime(struct inode *inode, struct vfsmount *mnt)

Hi Alexander!

> _Hell_, no.  

thanks for looking at the code ;)

> Proper solution is to move the callers upstream instead of 
> propagating vfsmounts downstream.  That, BTW, was the main reason
> for readdir() patch.

it that what you have in mind?

	 -· update_atime()
	  ¦-· __generic_file_aio_read()         [done]
	  ¦ 
	  ¦-· autofs4_update_usage()            [removed]
	  ¦ ¦-· autofs4_revalidate()            [done]
	  ¦ ¦-· autofs4_root_revalidate()       [done]
	  ¦ ¦-· try_to_fill_dentry()            [done,NULL]
	  ¦ '-· try_to_fill_dentry()            [done,NULL]
	  ¦     
	  ¦-· coda_readdir()                    [done]
	  ¦-· do_follow_link()                  [done]
	  ¦-· do_generic_mapping_read()         [done]
	  ¦-· do_shmem_file_read()              [done]
	  ¦     
	  ¦-· generic_file_mmap()               [done]
	  ¦-· hugetlbfs_file_mmap()             [done]
	  ¦ 
	  ¦-· nfsd_readlink()                   [done]
	  ¦-· open_namei()                      [done]
	  ¦-· pipe_readv()                      [done]
	  ¦-· random_read()                     [done]
	  ¦-· shmem_mmap()                      [done]
	  ¦-· sys_readlink()                    [done]
	  ¦ 
	  ¦-· unix_find_other()                 [done,NULL]
	  ¦     
	  '-· vfs_readdir()                     [done]

> BTW, update_atime() is exported.  And it's 2.6 now...

patch is also available at:
http://www.13thfloor.at/patches/patch-2.6.5-rc1-bk3-bme0.04.2-atime.diff

best,
Herbert


diff -NurpP --minimal linux-2.6.5-rc1-bk3/drivers/char/random.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/drivers/char/random.c
--- linux-2.6.5-rc1-bk3/drivers/char/random.c	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/drivers/char/random.c	2004-03-19 01:43:33.000000000 +0100
@@ -1640,9 +1640,9 @@ random_read(struct file * file, char * b
 	/*
 	 * If we gave the user some bytes, update the access time.
 	 */
-	if (count != 0) {
+	if ((count != 0) &&
+		may_update_atime(file->f_dentry->d_inode, file->f_vfsmnt))
 		update_atime(file->f_dentry->d_inode);
-	}
 	
 	return (count ? count : retval);
 }
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/autofs/root.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/autofs/root.c
--- linux-2.6.5-rc1-bk3/fs/autofs/root.c	2004-03-11 03:55:27.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/autofs/root.c	2004-03-19 01:17:58.000000000 +0100
@@ -129,8 +129,10 @@ static int try_to_fill_dentry(struct den
 
 	/* We don't update the usages for the autofs daemon itself, this
 	   is necessary for recursive autofs mounts */
-	if ( !autofs_oz_mode(sbi) ) {
+	if (!autofs_oz_mode(sbi)) {
 		autofs_update_usage(&sbi->dirhash,ent);
+		if (may_update_atime(dentry->d_inode, NULL))
+			update_atime(dentry->d_inode);
 	}
 
 	dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/autofs4/root.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/autofs4/root.c
--- linux-2.6.5-rc1-bk3/fs/autofs4/root.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/autofs4/root.c	2004-03-19 02:22:01.000000000 +0100
@@ -15,6 +15,8 @@
 #include <linux/stat.h>
 #include <linux/param.h>
 #include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
 #include <linux/smp_lock.h>
 #include "autofs_i.h"
 
@@ -60,10 +62,8 @@ static void autofs4_update_usage(struct 
 	for(; dentry != top; dentry = dentry->d_parent) {
 		struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
-		if (ino) {
-			update_atime(dentry->d_inode);
+		if (ino)
 			ino->last_used = jiffies;
-		}
 	}
 }
 
@@ -129,8 +129,11 @@ static int try_to_fill_dentry(struct den
 
 	/* We don't update the usages for the autofs daemon itself, this
 	   is necessary for recursive autofs mounts */
-	if (!autofs4_oz_mode(sbi))
+	if (!autofs4_oz_mode(sbi)) {
 		autofs4_update_usage(dentry);
+		if (may_update_atime(dentry->d_inode, NULL))
+			update_atime(dentry->d_inode);
+	}
 
 	dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
 	return 1;
@@ -177,9 +180,11 @@ static int autofs4_root_revalidate(struc
 	spin_unlock(&dcache_lock);
 
 	/* Update the usage list */
-	if (!oz_mode)
+	if (!oz_mode) {
 		autofs4_update_usage(dentry);
-
+		if (may_update_atime(dentry->d_inode, nd->mnt))
+			update_atime(dentry->d_inode);
+	}
 	return 1;
 }
 
@@ -187,9 +192,11 @@ static int autofs4_revalidate(struct den
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
 
-	if (!autofs4_oz_mode(sbi))
+	if (!autofs4_oz_mode(sbi)) {
 		autofs4_update_usage(dentry);
-
+		if (may_update_atime(dentry->d_inode, nd->mnt))
+			update_atime(dentry->d_inode);
+	}
 	return 1;
 }
 
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/coda/dir.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/coda/dir.c
--- linux-2.6.5-rc1-bk3/fs/coda/dir.c	2004-03-16 10:21:19.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/coda/dir.c	2004-03-19 01:27:56.000000000 +0100
@@ -512,7 +512,8 @@ int coda_readdir(struct file *coda_file,
 		ret = -ENOENT;
 		if (!IS_DEADDIR(host_inode)) {
 			ret = host_file->f_op->readdir(host_file, filldir, dirent);
-			update_atime(host_inode);
+			if (may_update_atime(host_inode, host_file->f_vfsmnt))
+				update_atime(host_inode);
 		}
 	}
 out:
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/hugetlbfs/inode.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/hugetlbfs/inode.c
--- linux-2.6.5-rc1-bk3/fs/hugetlbfs/inode.c	2004-03-18 22:49:57.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/hugetlbfs/inode.c	2004-03-19 01:34:21.000000000 +0100
@@ -62,7 +62,8 @@ static int hugetlbfs_file_mmap(struct fi
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
 	down(&inode->i_sem);
-	update_atime(inode);
+	if (may_update_atime(inode, file->f_vfsmnt))
+		update_atime(inode);
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/inode.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/inode.c
--- linux-2.6.5-rc1-bk3/fs/inode.c	2004-03-16 10:21:19.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/inode.c	2004-03-19 02:31:59.000000000 +0100
@@ -1145,13 +1145,6 @@ void update_atime(struct inode *inode)
 {
 	struct timespec now;
 
-	if (IS_NOATIME(inode))
-		return;
-	if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
-		return;
-	if (IS_RDONLY(inode))
-		return;
-
 	now = current_kernel_time();
 	if (inode_times_differ(inode, &inode->i_atime, &now)) {
 		inode->i_atime = now;
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/namei.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namei.c
--- linux-2.6.5-rc1-bk3/fs/namei.c	2004-03-11 03:55:25.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namei.c	2004-03-19 01:40:53.000000000 +0100
@@ -412,7 +412,8 @@ static inline int do_follow_link(struct 
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
-	update_atime(dentry->d_inode);
+	if (may_update_atime(dentry->d_inode, nd->mnt))
+		update_atime(dentry->d_inode);
 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
 	current->link_count--;
 	return err;
@@ -1368,7 +1369,8 @@ do_link:
 	error = security_inode_follow_link(dentry, nd);
 	if (error)
 		goto exit_dput;
-	update_atime(dentry->d_inode);
+	if (may_update_atime(dentry->d_inode, nd->mnt))
+		update_atime(dentry->d_inode);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	dput(dentry);
 	if (error)
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/namespace.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namespace.c
--- linux-2.6.5-rc1-bk3/fs/namespace.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namespace.c	2004-03-19 02:48:01.000000000 +0100
@@ -206,37 +206,39 @@ 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" },
-		{ MS_NOATIME, ",noatime" },
-		{ MS_NODIRATIME, ",nodiratime" },
-		{ 0, NULL }
-	};
-	static struct proc_fs_info mnt_info[] = {
-		{ MNT_NOSUID, ",nosuid" },
-		{ MNT_NODEV, ",nodev" },
-		{ MNT_NOEXEC, ",noexec" },
-		{ 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);
+	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);
@@ -522,11 +524,13 @@ out_unlock:
 /*
  * 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)
@@ -553,6 +557,7 @@ static int do_loopback(struct nameidata 
 			spin_unlock(&vfsmount_lock);
 		} else
 			mntput(mnt);
+		mnt->mnt_flags = mnt_flags;
 	}
 
 	up_write(&current->namespace->sem);
@@ -759,12 +764,18 @@ long do_mount(char * dev_name, char * di
 		((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)
 		mnt_flags |= MNT_NODEV;
 	if (flags & MS_NOEXEC)
 		mnt_flags |= MNT_NOEXEC;
+	if (flags & MS_NOATIME)
+		mnt_flags |= MNT_NOATIME;
+	if (flags & MS_NODIRATIME)
+		mnt_flags |= MNT_NODIRATIME;
 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 
 	/* ... and get the mountpoint */
@@ -780,7 +791,7 @@ long do_mount(char * dev_name, char * di
 		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_MOVE)
 		retval = do_move_mount(&nd, dev_name);
 	else
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/nfsd/vfs.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/nfsd/vfs.c
--- linux-2.6.5-rc1-bk3/fs/nfsd/vfs.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/nfsd/vfs.c	2004-03-19 02:27:08.000000000 +0100
@@ -1143,7 +1143,8 @@ nfsd_readlink(struct svc_rqst *rqstp, st
 	if (!inode->i_op || !inode->i_op->readlink)
 		goto out;
 
-	update_atime(inode);
+	if (may_update_atime(inode, fhp->fh_export->ex_mnt))
+		update_atime(inode);
 	/* N.B. Why does this call need a get_fs()??
 	 * Remove the set_fs and watch the fireworks:-) --okir
 	 */
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/pipe.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/pipe.c
--- linux-2.6.5-rc1-bk3/fs/pipe.c	2004-03-11 03:55:28.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/pipe.c	2004-03-19 01:42:17.000000000 +0100
@@ -164,7 +164,8 @@ pipe_readv(struct file *filp, const stru
 		wake_up_interruptible(PIPE_WAIT(*inode));
 		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 	}
-	if (ret > 0)
+	if ((ret > 0) &&
+		may_update_atime(inode, filp->f_vfsmnt))
 		update_atime(inode);
 	return ret;
 }
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/readdir.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/readdir.c
--- linux-2.6.5-rc1-bk3/fs/readdir.c	2004-03-16 10:21:20.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/readdir.c	2004-03-19 01:48:32.000000000 +0100
@@ -32,7 +32,8 @@ int vfs_readdir(struct file *file, filld
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
 		res = file->f_op->readdir(file, buf, filler);
-		update_atime(inode);
+		if (may_update_atime(inode, file->f_vfsmnt))
+			update_atime(inode);
 	}
 	up(&inode->i_sem);
 out:
diff -NurpP --minimal linux-2.6.5-rc1-bk3/fs/stat.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/stat.c
--- linux-2.6.5-rc1-bk3/fs/stat.c	2004-03-11 03:55:23.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/stat.c	2004-03-19 01:45:44.000000000 +0100
@@ -272,7 +272,8 @@ asmlinkage long sys_readlink(const char 
 		if (inode->i_op && inode->i_op->readlink) {
 			error = security_inode_readlink(nd.dentry);
 			if (!error) {
-				update_atime(inode);
+				if (may_update_atime(inode, nd.mnt))
+					update_atime(inode);
 				error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
 			}
 		}
diff -NurpP --minimal linux-2.6.5-rc1-bk3/include/linux/fs.h linux-2.6.5-rc1-bk3-bme0.04.2-atime/include/linux/fs.h
--- linux-2.6.5-rc1-bk3/include/linux/fs.h	2004-03-16 10:21:20.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/include/linux/fs.h	2004-03-19 02:33:01.000000000 +0100
@@ -19,6 +19,7 @@
 #include <linux/cache.h>
 #include <linux/radix-tree.h>
 #include <linux/kobject.h>
+#include <linux/mount.h>
 #include <asm/atomic.h>
 
 struct iovec;
@@ -751,6 +753,22 @@ extern int vfs_rmdir(struct inode *, str
 extern int vfs_unlink(struct inode *, struct dentry *);
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
+static inline int may_update_atime(struct inode *inode, struct vfsmount *mnt)
+{
+	if (IS_RDONLY(inode) ||
+		(mnt && MNT_IS_RDONLY(mnt)))
+		return 0;
+	if (IS_NOATIME(inode) ||
+		(mnt && MNT_IS_NOATIME(mnt)))
+		return 0;
+	if (S_ISDIR(inode->i_mode) &&
+		(IS_NODIRATIME(inode) ||
+		(mnt && MNT_IS_NODIRATIME(mnt))))
+		return 0;
+	return 1;
+}
+
+
 /*
  * File types
  *
diff -NurpP --minimal linux-2.6.5-rc1-bk3/include/linux/mount.h linux-2.6.5-rc1-bk3-bme0.04.2-atime/include/linux/mount.h
--- linux-2.6.5-rc1-bk3/include/linux/mount.h	2004-03-11 03:55:22.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/include/linux/mount.h	2004-03-19 00:36:56.000000000 +0100
@@ -14,9 +14,12 @@
 
 #include <linux/list.h>
 
-#define MNT_NOSUID	1
-#define MNT_NODEV	2
-#define MNT_NOEXEC	4
+#define MNT_RDONLY	1
+#define MNT_NOSUID	2
+#define MNT_NODEV	4
+#define MNT_NOEXEC	8
+#define MNT_NOATIME	1024
+#define MNT_NODIRATIME	2048
 
 struct vfsmount
 {
@@ -33,6 +36,10 @@ struct vfsmount
 	struct list_head mnt_list;
 };
 
+#define	MNT_IS_RDONLY(m)	((m) && ((m)->mnt_flags & MNT_RDONLY))
+#define	MNT_IS_NOATIME(m)	((m) && ((m)->mnt_flags & MNT_NOATIME))
+#define	MNT_IS_NODIRATIME(m)	((m) && ((m)->mnt_flags & MNT_NODIRATIME))
+
 static inline struct vfsmount *mntget(struct vfsmount *mnt)
 {
 	if (mnt)
diff -NurpP --minimal linux-2.6.5-rc1-bk3/mm/filemap.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/mm/filemap.c
--- linux-2.6.5-rc1-bk3/mm/filemap.c	2004-03-18 22:49:57.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/mm/filemap.c	2004-03-19 02:11:00.000000000 +0100
@@ -21,6 +21,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>
@@ -725,7 +726,8 @@ no_cached_page:
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
 	if (cached_page)
 		page_cache_release(cached_page);
-	update_atime(inode);
+	if (may_update_atime(inode, filp->f_vfsmnt))
+		update_atime(inode);
 }
 
 EXPORT_SYMBOL(do_generic_mapping_read);
@@ -820,7 +822,8 @@ __generic_file_aio_read(struct kiocb *io
 			if (retval > 0)
 				*ppos = pos + retval;
 		}
-		update_atime(filp->f_dentry->d_inode);
+		if (may_update_atime(filp->f_dentry->d_inode, filp->f_vfsmnt))
+			update_atime(filp->f_dentry->d_inode);
 		goto out;
 	}
 
@@ -1357,7 +1360,8 @@ int generic_file_mmap(struct file * file
 
 	if (!mapping->a_ops->readpage)
 		return -ENOEXEC;
-	update_atime(inode);
+	if (may_update_atime(inode, file->f_vfsmnt))
+		update_atime(inode);
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 }
diff -NurpP --minimal linux-2.6.5-rc1-bk3/mm/shmem.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/mm/shmem.c
--- linux-2.6.5-rc1-bk3/mm/shmem.c	2004-03-11 03:55:26.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/mm/shmem.c	2004-03-19 02:12:34.000000000 +0100
@@ -1067,7 +1067,8 @@ static int shmem_mmap(struct file *file,
 	ops = &shmem_vm_ops;
 	if (!S_ISREG(inode->i_mode))
 		return -EACCES;
-	update_atime(inode);
+	if (may_update_atime(inode, file->f_vfsmnt))
+		update_atime(inode);
 	vma->vm_ops = ops;
 	return 0;
 }
@@ -1363,7 +1364,8 @@ static void do_shmem_file_read(struct fi
 	}
 
 	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
-	update_atime(inode);
+	if (may_update_atime(inode, filp->f_vfsmnt))
+		update_atime(inode);
 }
 
 static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
diff -NurpP --minimal linux-2.6.5-rc1-bk3/net/unix/af_unix.c linux-2.6.5-rc1-bk3-bme0.04.2-atime/net/unix/af_unix.c
--- linux-2.6.5-rc1-bk3/net/unix/af_unix.c	2004-03-11 03:55:35.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-atime/net/unix/af_unix.c	2004-03-19 01:47:43.000000000 +0100
@@ -706,7 +706,7 @@ static struct sock *unix_find_other(stru
 		if (u) {
 			struct dentry *dentry;
 			dentry = unix_sk(u)->dentry;
-			if (dentry)
+			if (dentry && may_update_atime(dentry->d_inode, NULL))
 				update_atime(dentry->d_inode);
 		} else
 			goto fail;

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-18 12:26         ` viro
@ 2004-03-19  2:52           ` Herbert Poetzl
  2004-03-19 11:11             ` viro
  0 siblings, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-19  2:52 UTC (permalink / raw)
  To: viro; +Cc: Andrew Morton, torvalds, linux-kernel

On Thu, Mar 18, 2004 at 12:26:45PM +0000, viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Mon, Mar 15, 2004 at 08:58:14AM +0100, Herbert Poetzl wrote:
> > -extern int vfs_permission(struct inode *, int);
> > +extern int vfs_permission(struct inode *, int, struct nameidata *);
> 
> Vetoed, along with IS_RDONLY() prototype change.

hmm, that is what I expected ...

> Note that you are doing exactly the opposite of the changes we'll need
> to deal with remount races.
> 
> What we need is to push readonly checks _up_ - into callers of fs methods.
> vfs_permission() is default ->permission() - no more, no less.  Neither
> it nor other instances have any business touching "this vfsmount is readonly"
> logics - it's not something where fs can override stuff; it's "admin said
> no r/w access here".
> 
> IOW, the check for r/w access to file/directory/symlink on a r/o mount should
> be moved into the callers (very few of them) of ->permission() and away from
> the methods themselves.

maybe like this ...

patch can be downloaded at:
http://www.13thfloor.at/patches/patch-2.6.5-rc1-bk3-bme0.04.2-permission.diff

best,
Herbert


diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/ext2/acl.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/ext2/acl.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/ext2/acl.c	2004-03-16 10:21:19.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/ext2/acl.c	2004-03-19 03:17:17.000000000 +0100
@@ -290,13 +290,6 @@ ext2_permission(struct inode *inode, int
 {
 	int mode = inode->i_mode;
 
-	/* Nobody gets write access to a read-only fs */
-	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
-	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-		return -EROFS;
-	/* Nobody gets write access to an immutable file */
-	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
-	    return -EACCES;
 	if (current->fsuid == inode->i_uid) {
 		mode >>= 6;
 	} else if (test_opt(inode->i_sb, POSIX_ACL)) {
diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/ext3/acl.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/ext3/acl.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/ext3/acl.c	2004-03-16 10:21:19.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/ext3/acl.c	2004-03-19 03:17:28.000000000 +0100
@@ -295,13 +295,6 @@ ext3_permission(struct inode *inode, int
 {
 	int mode = inode->i_mode;
 
-	/* Nobody gets write access to a read-only fs */
-	if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
-	    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-		return -EROFS;
-	/* Nobody gets write access to an immutable file */
-	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
-	    return -EACCES;
 	if (current->fsuid == inode->i_uid) {
 		mode >>= 6;
 	} else if (test_opt(inode->i_sb, POSIX_ACL)) {
diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/intermezzo/dir.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/intermezzo/dir.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/intermezzo/dir.c	2004-03-18 22:49:57.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/intermezzo/dir.c	2004-03-19 03:46:49.000000000 +0100
@@ -846,6 +846,16 @@ int presto_permission(struct inode *inod
 
         cache = presto_get_cache(inode);
 
+        /* Nobody gets write access to a read-only fs */
+        if ((mask & MAY_WRITE) &&
+                (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
+                (IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))))
+                return -EROFS;
+
+        /* Nobody gets write access to an immutable file */
+        if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
+                return -EACCES;
+
         if ( cache ) {
                 /* we only override the file/dir permission operations */
                 struct inode_operations *fiops = filter_c2cfiops(cache->cache_filter);
diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/jfs/acl.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/jfs/acl.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/jfs/acl.c	2004-03-11 03:55:21.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/jfs/acl.c	2004-03-19 03:18:12.000000000 +0100
@@ -132,21 +132,6 @@ int jfs_permission(struct inode * inode,
 	umode_t mode = inode->i_mode;
 	struct jfs_inode_info *ji = JFS_IP(inode);
 
-	if (mask & MAY_WRITE) {
-		/*
-		 * Nobody gets write access to a read-only fs.
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
-
-		/*
-		 * Nobody gets write access to an immutable file.
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
-
 	if (current->fsuid == inode->i_uid) {
 		mode >>= 6;
 		goto check_mode;
diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namei.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/namei.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/namei.c	2004-03-19 01:40:53.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/namei.c	2004-03-19 03:43:38.000000000 +0100
@@ -160,21 +160,6 @@ int vfs_permission(struct inode * inode,
 {
 	umode_t			mode = inode->i_mode;
 
-	if (mask & MAY_WRITE) {
-		/*
-		 * Nobody gets write access to a read-only fs.
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
-
-		/*
-		 * Nobody gets write access to an immutable file.
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
-
 	if (current->fsuid == inode->i_uid)
 		mode >>= 6;
 	else if (in_group_p(inode->i_gid))
@@ -207,9 +192,20 @@ int vfs_permission(struct inode * inode,
 
 int permission(struct inode * inode,int mask, struct nameidata *nd)
 {
+	int mode = inode->i_mode;
 	int retval;
 	int submask;
 
+	/* Nobody gets write access to a read-only fs */
+	if ((mask & MAY_WRITE) &&
+		(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
+		(IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))))
+		return -EROFS;
+
+	/* Nobody gets write access to an immutable file */
+	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
+		return -EACCES;
+
 	/* Ordinary permission routines do not understand MAY_APPEND. */
 	submask = mask & ~MAY_APPEND;
 
diff -NurpP --minimal linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/nfs/dir.c linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/nfs/dir.c
--- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/nfs/dir.c	2004-03-16 10:21:20.000000000 +0100
+++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/nfs/dir.c	2004-03-19 03:36:11.000000000 +0100
@@ -1503,29 +1503,11 @@ nfs_permission(struct inode *inode, int 
 {
 	struct nfs_access_cache *cache = &NFS_I(inode)->cache_access;
 	struct rpc_cred *cred;
-	int mode = inode->i_mode;
 	int res;
 
 	if (mask == 0)
 		return 0;
-	if (mask & MAY_WRITE) {
-		/*
-		 *
-		 * Nobody gets write access to a read-only fs.
-		 *
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
 
-		/*
-		 *
-		 * Nobody gets write access to an immutable file.
-		 *
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
 	/* Are we checking permissions on anything other than lookup/execute? */
 	if ((mask & MAY_EXEC) == 0) {
 		/* We only need to check permissions on file open() and access() */

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-19  2:52           ` Herbert Poetzl
@ 2004-03-19 11:11             ` viro
  2004-03-19 13:40               ` Herbert Poetzl
  0 siblings, 1 reply; 24+ messages in thread
From: viro @ 2004-03-19 11:11 UTC (permalink / raw)
  To: Andrew Morton, torvalds, linux-kernel

On Fri, Mar 19, 2004 at 03:52:36AM +0100, Herbert Poetzl wrote:
> @@ -846,6 +846,16 @@ int presto_permission(struct inode *inod
>  
>          cache = presto_get_cache(inode);
>  
> +        /* Nobody gets write access to a read-only fs */
> +        if ((mask & MAY_WRITE) &&
> +                (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
> +                (IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))))
> +                return -EROFS;
> +
> +        /* Nobody gets write access to an immutable file */
> +        if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
> +                return -EACCES;
> +

That is gratitious, since the only way presto_setattr() is ever called is
as ->permission().

> --- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/jfs/acl.c	2004-03-11 03:55:21.000000000 +0100
> +++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/jfs/acl.c	2004-03-19 03:18:12.000000000 +0100
> @@ -132,21 +132,6 @@ int jfs_permission(struct inode * inode,
>  	umode_t mode = inode->i_mode;
>  	struct jfs_inode_info *ji = JFS_IP(inode);
>  
> -	if (mask & MAY_WRITE) {
> -		/*

... and that is broken, since jfs_permission() can be called directly.

FWIW, I would start with
	1) split out simple_permission() - vfs_permission() sans the
r/o checks; vfs_permission() would call it and all in-tree calls of
vfs_permission() would get expanded.

	2) prove that all instances of ->permission() honour r/o checks.
Fix the broken ones (and yes, we do have them - e.g. hfs_permission()
or bogus return values in proc_permission()), after we'd shown that
it's safe.  Note that it's not obvious - e.g. anything around ACLs or
<barf> XFS ioctls is not just fscking ugly - it's brittle as hell and
will require very careful treatment.

	3) once that is done, put r/o checks into the beginning of
permission(9)

	4) for all instances of ->permission(), move r/o checks in
the places that call that instance directly.  Remove them from method
itself.

	And yes, #2 will hurt.  Badly.

BTW, IS_RDONLY() part of that stuff will really hit the fan when you start
touching the FPOS in fs/ext2/xattr.c and around it.  Have fun...

Note that it's not enough to bring relevant vfsmount to every caller of
IS_RDONLY() - if we are calling it to make sure that fs is not r/o,
we _really_ want to make sure that it doesn't get remounted r/o just as
IS_RDONLY() returns.  And yes, there are real bugs in that area.

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-19 11:11             ` viro
@ 2004-03-19 13:40               ` Herbert Poetzl
  2004-03-19 14:52                 ` viro
  0 siblings, 1 reply; 24+ messages in thread
From: Herbert Poetzl @ 2004-03-19 13:40 UTC (permalink / raw)
  To: viro; +Cc: Andrew Morton, torvalds, linux-kernel

On Fri, Mar 19, 2004 at 11:11:17AM +0000, viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Fri, Mar 19, 2004 at 03:52:36AM +0100, Herbert Poetzl wrote:
> > @@ -846,6 +846,16 @@ int presto_permission(struct inode *inod
> >  
> >          cache = presto_get_cache(inode);
> >  
> > +        /* Nobody gets write access to a read-only fs */
> > +        if ((mask & MAY_WRITE) &&
> > +                (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
> > +                (IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))))
> > +                return -EROFS;
> > +
> > +        /* Nobody gets write access to an immutable file */
> > +        if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
> > +                return -EACCES;
> > +
> 
> That is gratitious, since the only way presto_setattr() 
> is ever called is as ->permission().

you mean presto_permission(), and yes, so that can be removed

> > --- linux-2.6.5-rc1-bk3-bme0.04.2-atime/fs/jfs/acl.c	2004-03-11 03:55:21.000000000 +0100
> > +++ linux-2.6.5-rc1-bk3-bme0.04.2-permission/fs/jfs/acl.c	2004-03-19 03:18:12.000000000 +0100
> > @@ -132,21 +132,6 @@ int jfs_permission(struct inode * inode,
> >  	umode_t mode = inode->i_mode;
> >  	struct jfs_inode_info *ji = JFS_IP(inode);
> >  
> > -	if (mask & MAY_WRITE) {
> > -		/*
> 
> ... and that is broken, since jfs_permission() can be called directly.

incomplete, not broken ...

	 -· jfs_permission()
	  ¦-· can_get_xattr()
	  ¦ '-· __jfs_getxattr()
	  ¦   ¦-· jfs_get_acl()
	  ¦   ¦ ¦-· jfs_acl_chmod()
	  ¦   ¦ ¦ '-· jfs_setattr()
	  ¦   ¦ ¦ 
	  ¦   ¦ ¦-· jfs_init_acl()
	  ¦   ¦ ¦ ¦-· jfs_create()
	  ¦   ¦ ¦ ¦-· jfs_mkdir()
	  ¦   ¦ ¦ ¦-· jfs_mknod()
	  ¦   ¦ ¦ '-· jfs_symlink()
	  ¦   ¦ ¦ 
	  ¦   ¦ '-= jfs_permission()
	  ¦   ¦ 
	  ¦   '-· jfs_getxattr()
	  ¦   
	  '-· can_set_xattr()
	    '-· __jfs_setxattr()
	      ¦-· jfs_removexattr()
	      ¦-· jfs_set_acl()
	      ¦ ¦-= jfs_acl_chmod()
	      ¦ '-= jfs_init_acl()
	      ¦ 
	      '-· jfs_setxattr()


the xattr struff needs attention anyway, and many
of the functions calling jfs_permission() directly or
indirectly will have the check at a higher layer ...

> FWIW, I would start with
> 	1) split out simple_permission() - vfs_permission() sans the
> r/o checks; vfs_permission() would call it and all in-tree calls of
> vfs_permission() would get expanded.

	 -· vfs_permission()
	  ¦-· hfs_permission()
	  ¦-· hfsplus_permission()
	  ¦-· nfs_permission()
	  ¦-* permission()
	  ¦-· presto_permission()
	  '-· proc_permission()

please elaborate ...

> 	2) prove that all instances of ->permission() honour r/o checks.
> Fix the broken ones (and yes, we do have them - e.g. hfs_permission()
> or bogus return values in proc_permission()), after we'd shown that
> it's safe.  Note that it's not obvious - e.g. anything around ACLs or
> <barf> XFS ioctls is not just fscking ugly - it's brittle as hell and
> will require very careful treatment.

okay, but why not do it in permission(), and make
the few callers of vfs_permission use that one instead?

except for jfs_permission() and nfsd_permission()
(which is hell enough) there are no direct calls
of *_permission() ...

> 	3) once that is done, put r/o checks into the beginning of
> permission(9)

hmm, obviously you didn't read the patch at all, as that 
is exactly what I did, so please have a look at it ...

> 	4) for all instances of ->permission(), move r/o checks in
> the places that call that instance directly.  Remove them from method
> itself.
> 
> 	And yes, #2 will hurt.  Badly.

I don't see why, please enlighten me ...

> BTW, IS_RDONLY() part of that stuff will really hit the fan when you start
> touching the FPOS in fs/ext2/xattr.c and around it.  Have fun...
> 
> Note that it's not enough to bring relevant vfsmount to every caller of
> IS_RDONLY() - if we are calling it to make sure that fs is not r/o,
> we _really_ want to make sure that it doesn't get remounted r/o just as
> IS_RDONLY() returns.  And yes, there are real bugs in that area.

hmm, well but how would moving the ro checks around
or adding them for the vfs mounts influence that?

I agree that this _is_ an issue but why should this _not_
happen with mount -o remount,ro /xy ?

best,
Herbert


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

* Re: [PATCH] Bind Mount Extensions 0.04.1 3/5
  2004-03-19 13:40               ` Herbert Poetzl
@ 2004-03-19 14:52                 ` viro
  0 siblings, 0 replies; 24+ messages in thread
From: viro @ 2004-03-19 14:52 UTC (permalink / raw)
  To: Andrew Morton, torvalds, linux-kernel

On Fri, Mar 19, 2004 at 02:40:28PM +0100, Herbert Poetzl wrote:
> > FWIW, I would start with
> > 	1) split out simple_permission() - vfs_permission() sans the
> > r/o checks; vfs_permission() would call it and all in-tree calls of
> > vfs_permission() would get expanded.
> 
> 	 -· vfs_permission()
> 	  ¦-· hfs_permission()
> 	  ¦-· hfsplus_permission()
> 	  ¦-· nfs_permission()
> 	  ¦-* permission()
> 	  ¦-· presto_permission()
> 	  '-· proc_permission()
> 
> please elaborate ...

First chunk: replace calls of vfs_permission() with r/o checks +
simple_permission(), _leaving_ vfs_permission() _itself_ _as-is_.
 
> > 	2) prove that all instances of ->permission() honour r/o checks.
> > Fix the broken ones (and yes, we do have them - e.g. hfs_permission()
> > or bogus return values in proc_permission()), after we'd shown that
> > it's safe.  Note that it's not obvious - e.g. anything around ACLs or
> > <barf> XFS ioctls is not just fscking ugly - it's brittle as hell and
> > will require very careful treatment.
> 
> okay, but why not do it in permission(), and make
> the few callers of vfs_permission use that one instead?

Filesystem code might be calling permission(9) and expecting (broken)
behaviour from its own ->permission().  Switch to uniform behaviour
would break such places, forcing us to compensate there.  And analysis
won't be fun.

> except for jfs_permission() and nfsd_permission()
> (which is hell enough) there are no direct calls
> of *_permission() ...

fs code calling permission() is basically equivalent to direct call.

> > 	3) once that is done, put r/o checks into the beginning of
> > permission(9)
> 
> hmm, obviously you didn't read the patch at all, as that 
> is exactly what I did, so please have a look at it ...

Yes, I have read it.  Try to read the reply - what I'm saying is that it
should be a separate chunk in the series _and_ it will need some preparations
before it can go in.

> > 	4) for all instances of ->permission(), move r/o checks in
> > the places that call that instance directly.  Remove them from method
> > itself.
> > 
> > 	And yes, #2 will hurt.  Badly.
> 
> I don't see why, please enlighten me ...

See above.

> > BTW, IS_RDONLY() part of that stuff will really hit the fan when you start
> > touching the FPOS in fs/ext2/xattr.c and around it.  Have fun...
> > 
> > Note that it's not enough to bring relevant vfsmount to every caller of
> > IS_RDONLY() - if we are calling it to make sure that fs is not r/o,
> > we _really_ want to make sure that it doesn't get remounted r/o just as
> > IS_RDONLY() returns.  And yes, there are real bugs in that area.
> 
> hmm, well but how would moving the ro checks around
> or adding them for the vfs mounts influence that?
> 
> I agree that this _is_ an issue but why should this _not_
> happen with mount -o remount,ro /xy ?

Once the checks are moved up, we split them into pairs (want_write_access(),
drop_write_access()) where the former can fail.  Then the second call gets
moved past the call of fs method.  IOW, we go from

	start fs activity
	deep in the bowels of fs code check for r/o and possibly fail
	do the rest

to
	check for r/o and possibly fail
	do fs work

_and_ to

	request write access and possibly fail
	do fs work
	drop write access

Transition between (2) and (3) is simple and relatively easy to verify
_IF_ the checks are lifted up.  And result will give sane protection
for remount - switch to r/o would have to be atomic wrt requesting
write access and would fail if we had writers.

Note that per-mountpoint r/o will take pretty much the same amount of work -
propagating vfsmounts down to the IS_RDONLY checks only to have that reverted
when we lift the checks up would mean doing more or less the same twice.

It can be done and it can be merged gradually in small and simple chunks,
so that they could be (a) well-understood and (b) well-tested.

The way we split the series *does* matter - composition of these patches
will be large and will touch quite a few places (there's extra fun with
delayed writes - e.g. removal of last link in foo_unlink() will mean
extra request for write access, dropped when inode is finally deleted,
possibly hours after unlink(2) had returned).  Doing that in one or even
3-4 patches would be insane even in 2.7; in 2.6 it's so out of question
that it's not even funny.

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

* Re: [PATCH] Bind Mount Extensions 0.04.1 2/5
  2004-03-18 12:16         ` viro
  2004-03-19  1:57           ` Herbert Poetzl
@ 2004-04-02  1:23           ` Herbert Poetzl
  1 sibling, 0 replies; 24+ messages in thread
From: Herbert Poetzl @ 2004-04-02  1:23 UTC (permalink / raw)
  To: viro; +Cc: Andrew Morton, torvalds, linux-kernel

On Thu, Mar 18, 2004 at 12:16:50PM +0000, viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Mon, Mar 15, 2004 at 08:57:23AM +0100, Herbert Poetzl wrote:
> > -void update_atime(struct inode *inode)
> > +void update_atime(struct inode *inode, struct vfsmount *mnt)
> 
> _Hell_, no.  Proper solution is to move the callers upstream instead
> of propagating vfsmounts downstream.  That, BTW, was the main reason
> for readdir() patch.

# 04/03/18	viro@parcelfarce.linux.theplanet.co.uk	1.1795.6.4
# [PATCH] add touch_atime() helper
# 
# Preparation for per-mountpoint noatime, nodiratime and later -
# per-mountpoint r/o.  Depends on file_accessed() patch, should go after
# it.
# 
# New helper - touch_atime(mnt, dentry).  It's a wrapper for
# update_atime() and that's where all future per-mountpoint checks will
# go.

static inline void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
{
        /* per-mountpoint checks will go here */
        update_atime(dentry->d_inode);
}

Hum, so that is what you call 'moving the callers upstream'
instead of 'propagating vfsmounts downstream' ...

best,
Herbert

> BTW, update_atime() is exported.  And it's 2.6 now...
> -
> 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] 24+ messages in thread

end of thread, other threads:[~2004-04-02  1:23 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-15  3:55 [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Herbert Poetzl
2004-03-15  4:14 ` Andrew Morton
2004-03-15  4:25   ` Herbert Poetzl
2004-03-15  4:34     ` Andrew Morton
2004-03-15  7:55       ` Herbert Poetzl
2004-03-15  7:56       ` [PATCH] Bind Mount Extensions 0.04.1 1/5 Herbert Poetzl
2004-03-15  7:57       ` [PATCH] Bind Mount Extensions 0.04.1 2/5 Herbert Poetzl
2004-03-18 12:16         ` viro
2004-03-19  1:57           ` Herbert Poetzl
2004-04-02  1:23           ` Herbert Poetzl
2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 3/5 Herbert Poetzl
2004-03-15 22:10         ` Andrew Morton
2004-03-15 23:04           ` Herbert Poetzl
2004-03-15 23:31             ` Andrew Morton
2004-03-16  6:30               ` Herbert Poetzl
2004-03-18 12:26         ` viro
2004-03-19  2:52           ` Herbert Poetzl
2004-03-19 11:11             ` viro
2004-03-19 13:40               ` Herbert Poetzl
2004-03-19 14:52                 ` viro
2004-03-15  7:58       ` [PATCH] Bind Mount Extensions 0.04.1 4/5 Herbert Poetzl
2004-03-15  7:59       ` [PATCH] Bind Mount Extensions 0.04.1 5/5 Herbert Poetzl
2004-03-15 13:25   ` [PATCH] Bind Mount Extensions 0.04 (linux-2.6.4) Marc-Christian Petersen
2004-03-15 18:25     ` Dariush Pietrzak

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).