All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 0/7] Automount behaviour correction
@ 2011-09-23 16:24 David Howells
  2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:24 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists



Here are a set of patches to correct the behaviour of automounting, hopefully
without introducing extra fragility.  We might want to merge them together in
various ways, and the last one or two patches we may want to drop, depending on
what we actually want the behaviour to actually be.

They are:

 (1) Revert Miklos's patch.  Not strictly a necessary part of the series, but
     it does fix the NFS4 regression immediately.

 (2) Make chown and lchown jump to fchownat with appropriate flags.  This is a
     useful cleanup for the following patches.

 (3) Replace LOOKUP_NO_AUTOMOUNT with LOOKUP_AUTOMOUNT and set it where
     appropriate before calling pathwalk (usually when we'd be setting
     LOOKUP_FOLLOW).  This just switches the polarity of the flag.

 (4) Move the automount/no-automount policy to the callers of pathwalk so that
     things such as NFS4 don't get caught out by changes to the policy.  The
     policy is outlined in that patch header.

 (5) Remove the logic from follow_automount() to try and guess from the
     LOOKUP_* flags whether or not we should be automounting this time.  It's
     shown to be a bit fragile and the policy is better predetermined by this
     point.

 (6) Make stat and xattr unconditionally _not_ automount.  This reinstates the
     old autofs behaviour, but does then regress NFS, AFS and CIFS.

 (7) Make stat and xattr vary their behaviour depending on whether the
     automount point belongs to autofs or not.  This should reinstate the NFS,
     AFS and CIFS behaviour without regressing autofs.

Now if we want 6 and maybe 7, these can be rolled into 4.  Patch 1 can be
discarded entirely if 5 is taken.

David
---
David Howells (7):
      VFS: Vary the automounting rules for autofs
      VFS: Make stat and xattr calls not automount
      VFS: Ignore symlink following advice when pathwalking
      VFS: Move the automount suppression decision out to the initial callers of
      VFS: Change LOOKUP_NO_AUTOMOUNT to LOOKUP_AUTOMOUNT
      VFS: Make chown() and lchown() call fchownat()
      NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW


 drivers/mtd/ubi/build.c            |    2 +
 drivers/mtd/ubi/kapi.c             |    2 +
 fs/autofs4/dev-ioctl.c             |    2 +
 fs/block_dev.c                     |    2 +
 fs/configfs/symlink.c              |    2 +
 fs/ecryptfs/main.c                 |    2 +
 fs/exec.c                          |    5 ++-
 fs/fhandle.c                       |   11 +++----
 fs/gfs2/ops_fstype.c               |    2 +
 fs/internal.h                      |   24 +++++++++++++++
 fs/namei.c                         |   30 ++++++-------------
 fs/namespace.c                     |    8 +++--
 fs/nfs/super.c                     |    2 +
 fs/nfsd/nfs4state.c                |    2 +
 fs/notify/fanotify/fanotify_user.c |    2 +
 fs/notify/inotify/inotify_user.c   |    2 +
 fs/open.c                          |   57 +++++++++---------------------------
 fs/quota/quota.c                   |    2 +
 fs/stat.c                          |   20 ++++++-------
 fs/statfs.c                        |    2 +
 fs/utimes.c                        |   14 ++++-----
 fs/xattr.c                         |   24 ++++++++++-----
 include/linux/fcntl.h              |    1 +
 include/linux/namei.h              |   10 ++++--
 net/unix/af_unix.c                 |    2 +
 security/tomoyo/load_policy.c      |    2 +
 security/tomoyo/mount.c            |    3 +-
 27 files changed, 116 insertions(+), 121 deletions(-)


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

* [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
@ 2011-09-23 16:24 ` David Howells
  2011-09-23 16:35   ` Linus Torvalds
  2011-09-23 16:53   ` David Howells
  2011-09-23 16:25 ` [PATCH 2/7] VFS: Make chown() and lchown() call fchownat() David Howells
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:24 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Revert the following change:

	commit 0ec26fd0698285b31248e34bf1abb022c00f23d6
	Author: Miklos Szeredi <mszeredi@suse.cz>
	Date:   Mon Sep 5 18:06:26 2011 +0200
	Subject: vfs: automount should ignore LOOKUP_FOLLOW

which makes stat(), getxattr(), etc. behave as lstat(), lgetxattr(), etc. with
respect to automounting: it prevents them from triggering terminal automounts.

The problem with this is that this breaks nfs_follow_remote_path() used by NFS4
to find the root object to mount for the mount() syscall.

This can be tested by the following procedure:

 (1) Export a directory from an NFS4 server that has something mounted upon it
     and that isn't "/" - say, for example, "/scratch".  It must have a
     different FSID from "/".

 (2) Mount this on the client.

	mount sirius:/scratch /mnt

 (3) List the contents of the client's mountpoint:

	ls /mnt

 (4) Examine /proc/fs/nfsfs/volumes.  You should see one entry (assuming
     nothing else is NFS mounted) :

	NV SERVER   PORT DEV     FSID              FSC
	v4 200108b001940000021125fffe84efad  801 0:34    1:0               no

     which corresponds to the filesystem mounted on /scratch on the server.

     If, however, you see two entries:

	NV SERVER   PORT DEV     FSID              FSC
	v4 200108b001940000021125fffe84efad  801 0:33    0:0               no
	v4 200108b001940000021125fffe84efad  801 0:34    1:0               no

     then it went wrong.

When it goes wrong, what happens is that nfs_follow_remote_path() walks from
the rootfh to the remote directory (/scratch) using vfs_path_lookup().  It
passes LOOKUP_FOLLOW to vfs_path_lookup() to tell it to transit terminal
symlinks and terminal automounts.  Unfortunately, with the problematic commit,
LOOKUP_FOLLOW now expressly does not follow terminal automounts, and so the
dummy automount directory fabricated in fsid 0:0 gets mounted instead of the
root of fsid 1:0.

Reported-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/namei.c |   33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index f478836..c64b81d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -727,22 +727,25 @@ static int follow_automount(struct path *path, unsigned flags,
 	if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
 		return -EISDIR; /* we actually want to stop here */
 
-	/* We don't want to mount if someone's just doing a stat -
-	 * unless they're stat'ing a directory and appended a '/' to
-	 * the name.
-	 *
-	 * We do, however, want to mount if someone wants to open or
-	 * create a file of any type under the mountpoint, wants to
-	 * traverse through the mountpoint or wants to open the
-	 * mounted directory.  Also, autofs may mark negative dentries
-	 * as being automount points.  These will need the attentions
-	 * of the daemon to instantiate them before they can be used.
+	/*
+	 * We don't want to mount if someone's just doing a stat and they've
+	 * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
+	 * appended a '/' to the name.
 	 */
-	if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
-		     LOOKUP_OPEN | LOOKUP_CREATE)) &&
-	    path->dentry->d_inode)
-		return -EISDIR;
-
+	if (!(flags & LOOKUP_FOLLOW)) {
+		/* We do, however, want to mount if someone wants to open or
+		 * create a file of any type under the mountpoint, wants to
+		 * traverse through the mountpoint or wants to open the mounted
+		 * directory.
+		 * Also, autofs may mark negative dentries as being automount
+		 * points.  These will need the attentions of the daemon to
+		 * instantiate them before they can be used.
+		 */
+		if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
+			     LOOKUP_OPEN | LOOKUP_CREATE)) &&
+		    path->dentry->d_inode)
+			return -EISDIR;
+	}
 	current->total_link_count++;
 	if (current->total_link_count >= 40)
 		return -ELOOP;


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

* [PATCH 2/7] VFS: Make chown() and lchown() call fchownat()
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
  2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
@ 2011-09-23 16:25 ` David Howells
  2011-09-23 16:25 ` [PATCH 3/7] VFS: Change LOOKUP_NO_AUTOMOUNT to LOOKUP_AUTOMOUNT David Howells
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:25 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Make the chown() and lchown() syscalls jump to the fchownat() syscall with the
appropriate extra arguments.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/open.c |   40 ++++++----------------------------------
 1 files changed, 6 insertions(+), 34 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index f711921..6d6cd90 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -527,25 +527,6 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
 	return error;
 }
 
-SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
-{
-	struct path path;
-	int error;
-
-	error = user_path(filename, &path);
-	if (error)
-		goto out;
-	error = mnt_want_write(path.mnt);
-	if (error)
-		goto out_release;
-	error = chown_common(&path, user, group);
-	mnt_drop_write(path.mnt);
-out_release:
-	path_put(&path);
-out:
-	return error;
-}
-
 SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 		gid_t, group, int, flag)
 {
@@ -573,23 +554,14 @@ out:
 	return error;
 }
 
-SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
+SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	struct path path;
-	int error;
+	return fchownat(AT_FDCWD, filename, user, group, 0);
+}
 
-	error = user_lpath(filename, &path);
-	if (error)
-		goto out;
-	error = mnt_want_write(path.mnt);
-	if (error)
-		goto out_release;
-	error = chown_common(&path, user, group);
-	mnt_drop_write(path.mnt);
-out_release:
-	path_put(&path);
-out:
-	return error;
+SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
+{
+	return fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW);
 }
 
 SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)


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

* [PATCH 3/7] VFS: Change LOOKUP_NO_AUTOMOUNT to LOOKUP_AUTOMOUNT
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
  2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
  2011-09-23 16:25 ` [PATCH 2/7] VFS: Make chown() and lchown() call fchownat() David Howells
@ 2011-09-23 16:25 ` David Howells
  2011-09-23 16:25 ` [PATCH 4/7] VFS: Move the automount suppression decision out to the initial callers of David Howells
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:25 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Change LOOKUP_NO_AUTOMOUNT (don't do terminal automount) to LOOKUP_AUTOMOUNT
(do terminal automount) to parallel LOOKUP_FOLLOW and set it everywhere
LOOKUP_FOLLOW is set.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/mtd/ubi/build.c            |    2 +-
 drivers/mtd/ubi/kapi.c             |    2 +-
 fs/autofs4/dev-ioctl.c             |    2 +-
 fs/block_dev.c                     |    2 +-
 fs/configfs/symlink.c              |    2 +-
 fs/ecryptfs/main.c                 |    2 +-
 fs/exec.c                          |    5 +++--
 fs/fhandle.c                       |    2 +-
 fs/gfs2/ops_fstype.c               |    2 +-
 fs/namei.c                         |   11 ++++++-----
 fs/namespace.c                     |    8 ++++----
 fs/nfs/super.c                     |    2 +-
 fs/nfsd/nfs4state.c                |    2 +-
 fs/notify/fanotify/fanotify_user.c |    2 +-
 fs/notify/inotify/inotify_user.c   |    2 +-
 fs/open.c                          |   12 ++++++------
 fs/quota/quota.c                   |    2 +-
 fs/stat.c                          |    4 ++--
 fs/utimes.c                        |    2 +-
 include/linux/namei.h              |    9 +++++----
 net/unix/af_unix.c                 |    2 +-
 security/tomoyo/load_policy.c      |    2 +-
 security/tomoyo/mount.c            |    3 ++-
 23 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 6c3fb5a..28627f1 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -1122,7 +1122,7 @@ static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
 	struct path path;
 
 	/* Probably this is an MTD character device node path */
-	err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+	err = kern_path(mtd_dev, LOOKUP_FOLLOW_ALL, &path);
 	if (err)
 		return ERR_PTR(err);
 
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index d39716e..056fbdb 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -303,7 +303,7 @@ struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
 	if (!pathname || !*pathname)
 		return ERR_PTR(-EINVAL);
 
-	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	error = kern_path(pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return ERR_PTR(error);
 
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 509fe1e..1b2120d 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -533,7 +533,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
 
 	if (!fp || param->ioctlfd == -1) {
 		if (autofs_type_any(type))
-			err = kern_path(name, LOOKUP_FOLLOW, &path);
+			err = kern_path(name, LOOKUP_FOLLOW_ALL, &path);
 		else
 			err = find_autofs_mount(name, &path, test_by_type, &type);
 		if (err)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 95f786e..ff38dc5 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1629,7 +1629,7 @@ struct block_device *lookup_bdev(const char *pathname)
 	if (!pathname || !*pathname)
 		return ERR_PTR(-EINVAL);
 
-	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	error = kern_path(pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return ERR_PTR(error);
 
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index 0f3eb41..c602b92 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -114,7 +114,7 @@ static int get_target(const char *symname, struct path *path,
 {
 	int ret;
 
-	ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
+	ret = kern_path(symname, LOOKUP_FOLLOW_ALL|LOOKUP_DIRECTORY, path);
 	if (!ret) {
 		if (path->dentry->d_sb == configfs_sb) {
 			*target = configfs_get_config_item(path->dentry);
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index b4a6bef..00e8ba7 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -519,7 +519,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 	s->s_d_op = &ecryptfs_dops;
 
 	err = "Reading sb failed";
-	rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+	rc = kern_path(dev_name, LOOKUP_FOLLOW_ALL | LOOKUP_DIRECTORY, &path);
 	if (rc) {
 		ecryptfs_printk(KERN_WARNING, "kern_path() failed\n");
 		goto out1;
diff --git a/fs/exec.c b/fs/exec.c
index 25dcbe5..7d56198 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -124,7 +124,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
 	if (IS_ERR(tmp))
 		goto out;
 
-	file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
+	file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW_ALL);
 	putname(tmp);
 	error = PTR_ERR(file);
 	if (IS_ERR(file))
@@ -769,7 +769,8 @@ struct file *open_exec(const char *name)
 		.intent = LOOKUP_OPEN
 	};
 
-	file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW);
+	file = do_filp_open(AT_FDCWD, name, &open_exec_flags,
+			    LOOKUP_FOLLOW_ALL);
 	if (IS_ERR(file))
 		goto out;
 
diff --git a/fs/fhandle.c b/fs/fhandle.c
index 6b08864..131e1ae 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -98,7 +98,7 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
 	if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
 		return -EINVAL;
 
-	lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
+	lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW_ALL : 0;
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
 	err = user_path_at(dfd, name, lookup_flags, &path);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 079587e..c532776 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1350,7 +1350,7 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
 	struct path path;
 	int error;
 
-	error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
+	error = kern_path(dev_name, LOOKUP_FOLLOW_ALL, &path);
 	if (error) {
 		printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
 		       dev_name, error);
diff --git a/fs/namei.c b/fs/namei.c
index c64b81d..30a364b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -724,7 +724,7 @@ static int follow_automount(struct path *path, unsigned flags,
 	/* We don't want to mount if someone supplied AT_NO_AUTOMOUNT
 	 * and this is the terminal part of the path.
 	 */
-	if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
+	if (!(flags & LOOKUP_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
 		return -EISDIR; /* we actually want to stop here */
 
 	/*
@@ -1573,7 +1573,7 @@ out_fail:
 static inline int lookup_last(struct nameidata *nd, struct path *path)
 {
 	if (nd->last_type == LAST_NORM && nd->last.name[nd->last.len])
-		nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
+		nd->flags |= LOOKUP_FOLLOW_ALL | LOOKUP_DIRECTORY;
 
 	nd->flags &= ~LOOKUP_PARENT;
 	return walk_component(nd, path, &nd->last, nd->last_type,
@@ -2125,8 +2125,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 	if (!(open_flag & O_CREAT)) {
 		int symlink_ok = 0;
 		if (nd->last.name[nd->last.len])
-			nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
-		if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
+			nd->flags |= LOOKUP_FOLLOW_ALL | LOOKUP_DIRECTORY;
+		if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW_ALL))
 			symlink_ok = 1;
 		/* we _can_ be in RCU mode here */
 		error = walk_component(nd, path, &nd->last, LAST_NORM,
@@ -2928,7 +2928,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 {
 	struct dentry *new_dentry;
 	struct path old_path, new_path;
-	int how = 0;
+	int how;
 	int error;
 
 	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
@@ -2946,6 +2946,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 
 	if (flags & AT_SYMLINK_FOLLOW)
 		how |= LOOKUP_FOLLOW;
+	how |= LOOKUP_AUTOMOUNT;
 
 	error = user_path_at(olddfd, oldname, how, &old_path);
 	if (error)
diff --git a/fs/namespace.c b/fs/namespace.c
index 22bfe82..71c218a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1368,7 +1368,7 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
 		return -EINVAL;
 
 	if (!(flags & UMOUNT_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW;
+		lookup_flags |= LOOKUP_FOLLOW_ALL;
 
 	retval = user_path_at(AT_FDCWD, name, lookup_flags, &path);
 	if (retval)
@@ -1757,7 +1757,7 @@ static int do_loopback(struct path *path, char *old_name,
 		return err;
 	if (!old_name || !*old_name)
 		return -EINVAL;
-	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+	err = kern_path(old_name, LOOKUP_FOLLOW_ALL, &old_path);
 	if (err)
 		return err;
 
@@ -1875,7 +1875,7 @@ static int do_move_mount(struct path *path, char *old_name)
 		return -EPERM;
 	if (!old_name || !*old_name)
 		return -EINVAL;
-	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+	err = kern_path(old_name, LOOKUP_FOLLOW_ALL, &old_path);
 	if (err)
 		return err;
 
@@ -2305,7 +2305,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
 		((char *)data_page)[PAGE_SIZE - 1] = 0;
 
 	/* ... and get the mountpoint */
-	retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+	retval = kern_path(dir_name, LOOKUP_FOLLOW_ALL, &path);
 	if (retval)
 		return retval;
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9b7dd70..1143a77 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2798,7 +2798,7 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
 		goto out_put_mnt_ns;
 
 	ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
-			export_path, LOOKUP_FOLLOW, &path);
+			export_path, LOOKUP_FOLLOW_ALL, &path);
 
 	nfs_referral_loop_unprotect();
 	put_mnt_ns(ns_private);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3787ec1..0d50e6e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4656,7 +4656,7 @@ nfs4_reset_recoverydir(char *recdir)
 	int status;
 	struct path path;
 
-	status = kern_path(recdir, LOOKUP_FOLLOW, &path);
+	status = kern_path(recdir, LOOKUP_FOLLOW_ALL, &path);
 	if (status)
 		return status;
 	status = -ENOTDIR;
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 9fde1c0..e8a4467 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -491,7 +491,7 @@ static int fanotify_find_path(int dfd, const char __user *filename,
 		path_get(path);
 		fput_light(file, fput_needed);
 	} else {
-		unsigned int lookup_flags = 0;
+		unsigned int lookup_flags = LOOKUP_AUTOMOUNT;
 
 		if (!(flags & FAN_MARK_DONT_FOLLOW))
 			lookup_flags |= LOOKUP_FOLLOW;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 8445fbc..90f6010 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -759,7 +759,7 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
 	struct path path;
 	struct file *filp;
 	int ret, fput_needed;
-	unsigned flags = 0;
+	unsigned flags = LOOKUP_AUTOMOUNT;
 
 	filp = fget_light(fd, &fput_needed);
 	if (unlikely(!filp))
diff --git a/fs/open.c b/fs/open.c
index 6d6cd90..414939e 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -325,7 +325,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 
 	old_cred = override_creds(override_cred);
 
-	res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
+	res = user_path_at(dfd, filename, LOOKUP_FOLLOW_ALL, &path);
 	if (res)
 		goto out;
 
@@ -487,7 +487,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
 	struct path path;
 	int error;
 
-	error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
+	error = user_path_at(dfd, filename, LOOKUP_FOLLOW_ALL, &path);
 	if (!error) {
 		error = chmod_common(&path, mode);
 		path_put(&path);
@@ -537,7 +537,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
 		goto out;
 
-	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW_ALL;
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
 	error = user_path_at(dfd, filename, lookup_flags, &path);
@@ -556,12 +556,12 @@ out:
 
 SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	return fchownat(AT_FDCWD, filename, user, group, 0);
+	return sys_fchownat(AT_FDCWD, filename, user, group, 0);
 }
 
 SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	return fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW);
+	return sys_fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW);
 }
 
 SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
@@ -901,7 +901,7 @@ static inline int build_open_flags(int flags, int mode, struct open_flags *op)
 	if (flags & O_DIRECTORY)
 		lookup_flags |= LOOKUP_DIRECTORY;
 	if (!(flags & O_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW;
+		lookup_flags |= LOOKUP_FOLLOW_ALL;
 	return lookup_flags;
 }
 
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index b34bdb2..156486a 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -355,7 +355,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
 	 * resolution (think about autofs) and thus deadlocks could arise.
 	 */
 	if (cmds == Q_QUOTAON) {
-		ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW, &path);
+		ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW_ALL, &path);
 		if (ret)
 			pathp = ERR_PTR(ret);
 		else
diff --git a/fs/stat.c b/fs/stat.c
index ba5316f..52ead31 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -80,9 +80,9 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 		goto out;
 
 	if (!(flag & AT_SYMLINK_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW;
+		lookup_flags |= LOOKUP_FOLLOW_ALL;
 	if (flag & AT_NO_AUTOMOUNT)
-		lookup_flags |= LOOKUP_NO_AUTOMOUNT;
+		lookup_flags &= ~LOOKUP_AUTOMOUNT;
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
 
diff --git a/fs/utimes.c b/fs/utimes.c
index ba653f3..ea82831 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -157,7 +157,7 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
 		int lookup_flags = 0;
 
 		if (!(flags & AT_SYMLINK_NOFOLLOW))
-			lookup_flags |= LOOKUP_FOLLOW;
+			lookup_flags |= LOOKUP_FOLLOW_ALL;
 
 		error = user_path_at(dfd, filename, lookup_flags, &path);
 		if (error)
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 76fe2c6..86d6993 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -44,7 +44,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
  *  - ending slashes ok even for nonexistent files
  *  - internal "there are more path components" flag
  *  - dentry cache is untrusted; force a real lookup
- *  - suppress terminal automount
+ *  - follow terminal automount
  */
 #define LOOKUP_FOLLOW		0x0001
 #define LOOKUP_DIRECTORY	0x0002
@@ -52,7 +52,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 #define LOOKUP_PARENT		0x0010
 #define LOOKUP_REVAL		0x0020
 #define LOOKUP_RCU		0x0040
-#define LOOKUP_NO_AUTOMOUNT	0x0080
+#define LOOKUP_AUTOMOUNT	0x0080
+#define LOOKUP_FOLLOW_ALL	(LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT)
 /*
  * Intent data
  */
@@ -67,10 +68,10 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 
 extern int user_path_at(int, const char __user *, unsigned, struct path *);
 
-#define user_path(name, path) user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW, path)
+#define user_path(name, path) user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW_ALL, path)
 #define user_lpath(name, path) user_path_at(AT_FDCWD, name, 0, path)
 #define user_path_dir(name, path) \
-	user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path)
+	user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW_ALL | LOOKUP_DIRECTORY, path)
 
 extern int kern_path(const char *, unsigned, struct path *);
 
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ec68e1c..0c091d5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -756,7 +756,7 @@ static struct sock *unix_find_other(struct net *net,
 
 	if (sunname->sun_path[0]) {
 		struct inode *inode;
-		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
+		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW_ALL, &path);
 		if (err)
 			goto fail;
 		inode = path.dentry->d_inode;
diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c
index 6797540..8de4d49 100644
--- a/security/tomoyo/load_policy.c
+++ b/security/tomoyo/load_policy.c
@@ -38,7 +38,7 @@ static bool tomoyo_policy_loader_exists(void)
 	struct path path;
 	if (!tomoyo_loader)
 		tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
-	if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
+	if (kern_path(tomoyo_loader, LOOKUP_FOLLOW_ALL, &path)) {
 		printk(KERN_INFO "Not activating Mandatory Access Control "
 		       "as %s does not exist.\n", tomoyo_loader);
 		return false;
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index bee09d0..786c47f 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -128,7 +128,8 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
 	}
 	if (need_dev) {
 		/* Get mount point or device file. */
-		if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
+		if (!dev_name ||
+		    kern_path(dev_name, LOOKUP_FOLLOW_ALL, &path)) {
 			error = -ENOENT;
 			goto out;
 		}


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

* [PATCH 4/7] VFS: Move the automount suppression decision out to the initial callers of
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
                   ` (2 preceding siblings ...)
  2011-09-23 16:25 ` [PATCH 3/7] VFS: Change LOOKUP_NO_AUTOMOUNT to LOOKUP_AUTOMOUNT David Howells
@ 2011-09-23 16:25 ` David Howells
  2011-09-23 16:25 ` [PATCH 5/7] VFS: Ignore symlink following advice when pathwalking David Howells
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:25 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

pathwalk, in particular get attribute-fetching system calls and define the
to-terminal-automount-or-not policy there by supplying LOOKUP_AUTOMOUNT or not
as appropriate.

Suppress automount on the following:

	lchown
	lgetxattr
	llistxattr
	lremovexattr
	lsetxattr
	lstat
	openat/open with O_NOFOLLOW but not O_DIRECTORY
	readlinkat, readlink

	ocfs2_reflink_ioctl()

Require terminal automounting on the following:

	chdir
	chown
	chroot
	execve
	faccessat, access
	fanotify
	fchmodat, chmod
	getxattr
	inotify
	linkat, link
	listxattr
	mkdirat, mkdir
	mknodat, mknod
	mount
	openat/open without O_NOFOLLOW or with O_DIRECTORY
	quotactl
	removexattr
	renameat, rename
	setxattr
	socket(AF_UNIX)
	stat
	statfs
	symlinkat, symlink
	unlinkat, unlink, rmdir
	uselib
	utimes, futimesat

	autofs_dev_ioctl_ismountpoint()
	ecryptfs_mount()
	get_target() in configfs/symlink.c
	gfs2_mount_meta()
	lookup_bdev()
	nfs4_reset_recoverydir()
	nfs_follow_remote_path()
	open_mtd_by_chdev()
	tomoyo_mount_acl()
	tomoyo_policy_loader_exists()
	ubi_open_volume_path()

Default the automount-follow setting to the same as the symlink-follow setting
(as controlled by AT_SYMLINK_NOFOLLOW, UMOUNT_NOFOLLOW or
FAN_MARK_DONT_FOLLOW):

	fchownat
	fstatat
	name_to_handle_at
	umount
	utimensat

Provide an AT_AUTOMOUNT_FOLLOW option where possible to override the
behaviour, and try to make all four relevant AT_ flags available to all AT_
flag taking functions.  Given the flags available, the behaviour is then
calculated using the following rules in order of descending priority:

  (1) If the path ends in a '/', follow the automount.

  (2) If AT_AUTOMOUNT_FOLLOW is set, follow the automount.

  (3) If AT_NO_AUTOMOUNT is set, don't follow the automount.

  (4) If AT_SYMLINK_FOLLOW is set, follow the automount.

  (5) If AT_SYMLINK_NOFOLLOW is set, don't follow the automount.

  (6) Follow the automount.

To change the behaviour to make stat, xattr functions always suppress
automounting too is then a matter of changing vfs_fstatat() and the
appropriate xattr syscalls.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/fhandle.c          |   11 +++++------
 fs/internal.h         |   17 +++++++++++++++++
 fs/namei.c            |    2 +-
 fs/open.c             |   13 +++++++------
 fs/stat.c             |   14 +++++---------
 fs/statfs.c           |    2 +-
 fs/utimes.c           |   14 +++++++-------
 fs/xattr.c            |   16 ++++++++--------
 include/linux/fcntl.h |    1 +
 9 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/fs/fhandle.c b/fs/fhandle.c
index 131e1ae..d81c506 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -92,15 +92,14 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
 		int, flag)
 {
 	struct path path;
-	int lookup_flags;
-	int err;
+	int err, lookup_flags;
 
-	if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
+	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW |
+		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW |
+		      AT_EMPTY_PATH)) != 0)
 		return -EINVAL;
+	lookup_flags = at_to_lookup_flags(flag, 0);
 
-	lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW_ALL : 0;
-	if (flag & AT_EMPTY_PATH)
-		lookup_flags |= LOOKUP_EMPTY;
 	err = user_path_at(dfd, name, lookup_flags, &path);
 	if (!err) {
 		err = do_sys_name_to_handle(&path, handle, mnt_id);
diff --git a/fs/internal.h b/fs/internal.h
index fe327c2..11664f5 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/namei.h>
 #include <linux/lglock.h>
 
 struct super_block;
@@ -16,6 +17,22 @@ struct file_system_type;
 struct linux_binprm;
 struct path;
 
+/**
+ * at_to_lookup_flags - Translate AT_ flags to LOOKUP_ flags
+ * @flags: The AT_ flags to translate.
+ * @lookup_flags: The default.
+ */
+static inline int at_to_lookup_flags(int flag, int lookup_flags)
+{
+	if (flag & AT_SYMLINK_NOFOLLOW)	lookup_flags &= ~LOOKUP_FOLLOW_ALL;
+	if (flag & AT_SYMLINK_FOLLOW)	lookup_flags |= LOOKUP_FOLLOW_ALL;
+	if (flag & AT_NO_AUTOMOUNT)	lookup_flags &= ~LOOKUP_AUTOMOUNT;
+	if (flag & AT_AUTOMOUNT_FOLLOW)	lookup_flags |= LOOKUP_AUTOMOUNT;
+	if (flag & AT_EMPTY_PATH)	lookup_flags |= LOOKUP_EMPTY;
+
+	return lookup_flags;
+}
+
 /*
  * block_dev.c
  */
diff --git a/fs/namei.c b/fs/namei.c
index 30a364b..c2a2cc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2126,7 +2126,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 		int symlink_ok = 0;
 		if (nd->last.name[nd->last.len])
 			nd->flags |= LOOKUP_FOLLOW_ALL | LOOKUP_DIRECTORY;
-		if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW_ALL))
+		if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
 			symlink_ok = 1;
 		/* we _can_ be in RCU mode here */
 		error = walk_component(nd, path, &nd->last, LAST_NORM,
diff --git a/fs/open.c b/fs/open.c
index 414939e..b592c18 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -534,12 +534,12 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 	int error = -EINVAL;
 	int lookup_flags;
 
-	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW |
+		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW |
+		      AT_EMPTY_PATH)) != 0)
 		goto out;
+	lookup_flags = at_to_lookup_flags(flag, LOOKUP_FOLLOW_ALL);
 
-	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW_ALL;
-	if (flag & AT_EMPTY_PATH)
-		lookup_flags |= LOOKUP_EMPTY;
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (error)
 		goto out;
@@ -561,7 +561,8 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
 
 SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
 {
-	return sys_fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW);
+	return sys_fchownat(AT_FDCWD, filename, user, group,
+			    AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT);
 }
 
 SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
@@ -899,7 +900,7 @@ static inline int build_open_flags(int flags, int mode, struct open_flags *op)
 	}
 
 	if (flags & O_DIRECTORY)
-		lookup_flags |= LOOKUP_DIRECTORY;
+		lookup_flags |= LOOKUP_DIRECTORY | LOOKUP_AUTOMOUNT;
 	if (!(flags & O_NOFOLLOW))
 		lookup_flags |= LOOKUP_FOLLOW_ALL;
 	return lookup_flags;
diff --git a/fs/stat.c b/fs/stat.c
index 52ead31..305aa10 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -17,6 +17,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include "internal.h"
 
 void generic_fillattr(struct inode *inode, struct kstat *stat)
 {
@@ -73,18 +74,13 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 {
 	struct path path;
 	int error = -EINVAL;
-	int lookup_flags = 0;
+	int lookup_flags;
 
-	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
+	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW |
+		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW |
 		      AT_EMPTY_PATH)) != 0)
 		goto out;
-
-	if (!(flag & AT_SYMLINK_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW_ALL;
-	if (flag & AT_NO_AUTOMOUNT)
-		lookup_flags &= ~LOOKUP_AUTOMOUNT;
-	if (flag & AT_EMPTY_PATH)
-		lookup_flags |= LOOKUP_EMPTY;
+	lookup_flags = at_to_lookup_flags(flag, LOOKUP_FOLLOW_ALL);
 
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (error)
diff --git a/fs/statfs.c b/fs/statfs.c
index 8244924..e82eae2 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -76,7 +76,7 @@ EXPORT_SYMBOL(vfs_statfs);
 int user_statfs(const char __user *pathname, struct kstatfs *st)
 {
 	struct path path;
-	int error = user_path(pathname, &path);
+	int error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (!error) {
 		error = vfs_statfs(&path, st);
 		path_put(&path);
diff --git a/fs/utimes.c b/fs/utimes.c
index ea82831..72f10c5 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -10,6 +10,7 @@
 #include <linux/syscalls.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include "internal.h"
 
 #ifdef __ARCH_WANT_SYS_UTIME
 
@@ -116,7 +117,7 @@ out:
  * @dfd: open file descriptor, -1 or AT_FDCWD
  * @filename: path name or NULL
  * @times: new times or NULL
- * @flags: zero or more flags (only AT_SYMLINK_NOFOLLOW for the moment)
+ * @flags: zero or more AT_* flags
  *
  * If filename is NULL and dfd refers to an open file, then operate on
  * the file.  Otherwise look up filename, possibly using dfd as a
@@ -136,13 +137,15 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
 		goto out;
 	}
 
-	if (flags & ~AT_SYMLINK_NOFOLLOW)
+	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW |
+		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW))
 		goto out;
 
 	if (filename == NULL && dfd != AT_FDCWD) {
 		struct file *file;
 
-		if (flags & AT_SYMLINK_NOFOLLOW)
+		if (flags & (AT_SYMLINK_NOFOLLOW | AT_SYMLINK_FOLLOW |
+			     AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW))
 			goto out;
 
 		file = fget(dfd);
@@ -154,10 +157,7 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
 		fput(file);
 	} else {
 		struct path path;
-		int lookup_flags = 0;
-
-		if (!(flags & AT_SYMLINK_NOFOLLOW))
-			lookup_flags |= LOOKUP_FOLLOW_ALL;
+		int lookup_flags = at_to_lookup_flags(flags, LOOKUP_FOLLOW_ALL);
 
 		error = user_path_at(dfd, filename, lookup_flags, &path);
 		if (error)
diff --git a/fs/xattr.c b/fs/xattr.c
index f060663..4921010 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -290,7 +290,7 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
@@ -309,7 +309,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_lpath(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, 0, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
@@ -386,7 +386,7 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
 	struct path path;
 	ssize_t error;
 
-	error = user_path(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return error;
 	error = getxattr(path.dentry, name, value, size);
@@ -400,7 +400,7 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
 	struct path path;
 	ssize_t error;
 
-	error = user_lpath(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, 0, &path);
 	if (error)
 		return error;
 	error = getxattr(path.dentry, name, value, size);
@@ -459,7 +459,7 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
 	struct path path;
 	ssize_t error;
 
-	error = user_path(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return error;
 	error = listxattr(path.dentry, list, size);
@@ -473,7 +473,7 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
 	struct path path;
 	ssize_t error;
 
-	error = user_lpath(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, 0, &path);
 	if (error)
 		return error;
 	error = listxattr(path.dentry, list, size);
@@ -519,7 +519,7 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
@@ -537,7 +537,7 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_lpath(pathname, &path);
+	error = user_path_at(AT_FDCWD, pathname, 0, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index f550f89..768fb66 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -47,6 +47,7 @@
 #define AT_SYMLINK_FOLLOW	0x400   /* Follow symbolic links.  */
 #define AT_NO_AUTOMOUNT		0x800	/* Suppress terminal automount traversal */
 #define AT_EMPTY_PATH		0x1000	/* Allow empty relative pathname */
+#define AT_AUTOMOUNT_FOLLOW	0x2000	/* Follow terminal automounts */
 
 #ifdef __KERNEL__
 


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

* [PATCH 5/7] VFS: Ignore symlink following advice when pathwalking
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
                   ` (3 preceding siblings ...)
  2011-09-23 16:25 ` [PATCH 4/7] VFS: Move the automount suppression decision out to the initial callers of David Howells
@ 2011-09-23 16:25 ` David Howells
  2011-09-23 16:25 ` [PATCH 6/7] VFS: Make stat and xattr calls not automount David Howells
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:25 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Ignore symlink advice (LOOKUP_FOLLOW) when walking the terminal component of a
path.  Base the decision entirely on LOOKUP_NO_AUTOMOUNT as this is now set
(or not) by the callers of path walk, most notably the relevant syscall
handlers.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/namei.c |   19 -------------------
 1 files changed, 0 insertions(+), 19 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c2a2cc3..89e3dc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -727,25 +727,6 @@ static int follow_automount(struct path *path, unsigned flags,
 	if (!(flags & LOOKUP_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
 		return -EISDIR; /* we actually want to stop here */
 
-	/*
-	 * We don't want to mount if someone's just doing a stat and they've
-	 * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
-	 * appended a '/' to the name.
-	 */
-	if (!(flags & LOOKUP_FOLLOW)) {
-		/* We do, however, want to mount if someone wants to open or
-		 * create a file of any type under the mountpoint, wants to
-		 * traverse through the mountpoint or wants to open the mounted
-		 * directory.
-		 * Also, autofs may mark negative dentries as being automount
-		 * points.  These will need the attentions of the daemon to
-		 * instantiate them before they can be used.
-		 */
-		if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
-			     LOOKUP_OPEN | LOOKUP_CREATE)) &&
-		    path->dentry->d_inode)
-			return -EISDIR;
-	}
 	current->total_link_count++;
 	if (current->total_link_count >= 40)
 		return -ELOOP;


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

* [PATCH 6/7] VFS: Make stat and xattr calls not automount
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
                   ` (4 preceding siblings ...)
  2011-09-23 16:25 ` [PATCH 5/7] VFS: Ignore symlink following advice when pathwalking David Howells
@ 2011-09-23 16:25 ` David Howells
  2011-09-23 16:26 ` [PATCH 7/7] VFS: Vary the automounting rules for autofs David Howells
  2011-09-23 16:29 ` [RFC][PATCH 0/7] Automount behaviour correction Linus Torvalds
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:25 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Make stat() and get/set/list/removexattr calls not automount so that the
autofs behaviour remains the same.  This causes NFS, AFS and CIFS automounting
behaviour to change, however.

To vary the behaviour follow_automount() needs to know when it is mounting for
autofs and when the aforementioned calls are the ones being processed.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/stat.c  |    7 ++++---
 fs/xattr.c |    8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index 305aa10..7fa96a1 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -80,7 +80,7 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW |
 		      AT_EMPTY_PATH)) != 0)
 		goto out;
-	lookup_flags = at_to_lookup_flags(flag, LOOKUP_FOLLOW_ALL);
+	lookup_flags = at_to_lookup_flags(flag, LOOKUP_FOLLOW);
 
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (error)
@@ -95,13 +95,14 @@ EXPORT_SYMBOL(vfs_fstatat);
 
 int vfs_stat(const char __user *name, struct kstat *stat)
 {
-	return vfs_fstatat(AT_FDCWD, name, stat, 0);
+	return vfs_fstatat(AT_FDCWD, name, stat, AT_NO_AUTOMOUNT);
 }
 EXPORT_SYMBOL(vfs_stat);
 
 int vfs_lstat(const char __user *name, struct kstat *stat)
 {
-	return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW);
+	return vfs_fstatat(AT_FDCWD, name, stat,
+			   AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT);
 }
 EXPORT_SYMBOL(vfs_lstat);
 
diff --git a/fs/xattr.c b/fs/xattr.c
index 4921010..bb9d5be 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -290,7 +290,7 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
@@ -386,7 +386,7 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
 	struct path path;
 	ssize_t error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
 	if (error)
 		return error;
 	error = getxattr(path.dentry, name, value, size);
@@ -459,7 +459,7 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
 	struct path path;
 	ssize_t error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
 	if (error)
 		return error;
 	error = listxattr(path.dentry, list, size);
@@ -519,7 +519,7 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW_ALL, &path);
+	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);


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

* [PATCH 7/7] VFS: Vary the automounting rules for autofs
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
                   ` (5 preceding siblings ...)
  2011-09-23 16:25 ` [PATCH 6/7] VFS: Make stat and xattr calls not automount David Howells
@ 2011-09-23 16:26 ` David Howells
  2011-09-23 16:29 ` [RFC][PATCH 0/7] Automount behaviour correction Linus Torvalds
  7 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:26 UTC (permalink / raw)
  To: miklos, raven, viro, torvalds
  Cc: dhowells, jlayton, gregkh, linux-nfs, leonardo.lists

Allow the behaviour of in-kernel automounting to vary according to whether
we're mounting on autofs or not.

The differences of behaviour concern the fstatat, stat, getxattr, setxattr,
listxattr and removexattr system calls.  Prior to the d_automount changes
being applied, these caused automounting for NFS, AFS and CIFS automount
points, but not for autofs mountpounts.

After the d_automount changes they caused automounting unconditionally because
LOOKUP_FOLLOW was set.

With the application of a later patch from Miklos Szeredi to revert the
behaviour of autofs to the original, these no longer cause a mountpoint to
automount.

Reinstate the pre-d_automount behaviour.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/internal.h         |   17 ++++++++++++-----
 fs/namei.c            |    7 +++++--
 fs/stat.c             |    3 ++-
 fs/xattr.c            |   16 ++++++++++++----
 include/linux/namei.h |    1 +
 5 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 11664f5..b54c5e6 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -24,11 +24,18 @@ struct path;
  */
 static inline int at_to_lookup_flags(int flag, int lookup_flags)
 {
-	if (flag & AT_SYMLINK_NOFOLLOW)	lookup_flags &= ~LOOKUP_FOLLOW_ALL;
-	if (flag & AT_SYMLINK_FOLLOW)	lookup_flags |= LOOKUP_FOLLOW_ALL;
-	if (flag & AT_NO_AUTOMOUNT)	lookup_flags &= ~LOOKUP_AUTOMOUNT;
-	if (flag & AT_AUTOMOUNT_FOLLOW)	lookup_flags |= LOOKUP_AUTOMOUNT;
-	if (flag & AT_EMPTY_PATH)	lookup_flags |= LOOKUP_EMPTY;
+	if (flag & AT_SYMLINK_NOFOLLOW)
+		lookup_flags &= ~(LOOKUP_FOLLOW_ALL | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS);
+	if (flag & AT_SYMLINK_FOLLOW)
+		lookup_flags |= LOOKUP_FOLLOW_ALL;
+	if (flag & AT_NO_AUTOMOUNT)
+		lookup_flags &= ~(LOOKUP_AUTOMOUNT | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS);
+	if (flag & AT_AUTOMOUNT_FOLLOW)	{
+		lookup_flags |= LOOKUP_AUTOMOUNT;
+		lookup_flags &= ~LOOKUP_AUTOMOUNT_UNLESS_AUTOFS;
+	}
+	if (flag & AT_EMPTY_PATH)
+		lookup_flags |= LOOKUP_EMPTY;
 
 	return lookup_flags;
 }
diff --git a/fs/namei.c b/fs/namei.c
index 89e3dc3..3b1da48 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -724,8 +724,11 @@ static int follow_automount(struct path *path, unsigned flags,
 	/* We don't want to mount if someone supplied AT_NO_AUTOMOUNT
 	 * and this is the terminal part of the path.
 	 */
-	if (!(flags & LOOKUP_AUTOMOUNT) && !(flags & LOOKUP_PARENT))
-		return -EISDIR; /* we actually want to stop here */
+	if (!(flags & LOOKUP_AUTOMOUNT) && !(flags & LOOKUP_PARENT)) {
+		if (!(flags & LOOKUP_AUTOMOUNT_UNLESS_AUTOFS) ||
+		    strcmp(path->dentry->d_sb->s_type->name, "autofs") == 0)
+			return -EISDIR; /* we actually want to stop here */
+	}
 
 	current->total_link_count++;
 	if (current->total_link_count >= 40)
diff --git a/fs/stat.c b/fs/stat.c
index 7fa96a1..f7e9abb 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -80,7 +80,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW |
 		      AT_EMPTY_PATH)) != 0)
 		goto out;
-	lookup_flags = at_to_lookup_flags(flag, LOOKUP_FOLLOW);
+	lookup_flags = at_to_lookup_flags(
+		flag, LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS);
 
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (error)
diff --git a/fs/xattr.c b/fs/xattr.c
index bb9d5be..7a85b9a 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -290,7 +290,9 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
+	error = user_path_at(AT_FDCWD, pathname,
+			     LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS,
+			     &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
@@ -386,7 +388,9 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
 	struct path path;
 	ssize_t error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
+	error = user_path_at(AT_FDCWD, pathname,
+			     LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS,
+			     &path);
 	if (error)
 		return error;
 	error = getxattr(path.dentry, name, value, size);
@@ -459,7 +463,9 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
 	struct path path;
 	ssize_t error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
+	error = user_path_at(AT_FDCWD, pathname,
+			     LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS,
+			     &path);
 	if (error)
 		return error;
 	error = listxattr(path.dentry, list, size);
@@ -519,7 +525,9 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
 	struct path path;
 	int error;
 
-	error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
+	error = user_path_at(AT_FDCWD, pathname,
+			     LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT_UNLESS_AUTOFS,
+			     &path);
 	if (error)
 		return error;
 	error = mnt_want_write(path.mnt);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 86d6993..e1b03a0 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -65,6 +65,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 #define LOOKUP_JUMPED		0x1000
 #define LOOKUP_ROOT		0x2000
 #define LOOKUP_EMPTY		0x4000
+#define LOOKUP_AUTOMOUNT_UNLESS_AUTOFS	0x8000
 
 extern int user_path_at(int, const char __user *, unsigned, struct path *);
 


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

* Re: [RFC][PATCH 0/7] Automount behaviour correction
  2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
                   ` (6 preceding siblings ...)
  2011-09-23 16:26 ` [PATCH 7/7] VFS: Vary the automounting rules for autofs David Howells
@ 2011-09-23 16:29 ` Linus Torvalds
  7 siblings, 0 replies; 11+ messages in thread
From: Linus Torvalds @ 2011-09-23 16:29 UTC (permalink / raw)
  To: David Howells
  Cc: miklos, raven, viro, jlayton, gregkh, linux-nfs, leonardo.lists

On Fri, Sep 23, 2011 at 9:24 AM, David Howells <dhowells@redhat.com> wrote:
>
> They are:

Christ, this is like the worst of all worlds. We make more code to
make more random decisions that now depend not just on random system
calls but on what filesystem those system calls act on too.

Ugh. Seriously nasty.

I did like the lchown/fchownat unification, but that was independent.

                     Linus

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

* Re: [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW
  2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
@ 2011-09-23 16:35   ` Linus Torvalds
  2011-09-23 16:53   ` David Howells
  1 sibling, 0 replies; 11+ messages in thread
From: Linus Torvalds @ 2011-09-23 16:35 UTC (permalink / raw)
  To: David Howells
  Cc: miklos, raven, viro, jlayton, gregkh, linux-nfs, leonardo.lists

On Fri, Sep 23, 2011 at 9:24 AM, David Howells <dhowells@redhat.com> wrote:
>
> The problem with this is that this breaks nfs_follow_remote_path() used by NFS4
> to find the root object to mount for the mount() syscall.

The above message is basically dishonest.

That's not AT ALL the problem.

That problem could have been fixed with a one-liner patch that already exists.

This whole patch-series looks like just excuses for doing stupid things.

Afaik, LOOKUP_OPEN and LOOKUP_DIRECTORY already force the auto-mount.
You can use either or both to force it.

Why are people so deep in denial about this?

                        Linus

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

* Re: [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW
  2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
  2011-09-23 16:35   ` Linus Torvalds
@ 2011-09-23 16:53   ` David Howells
  1 sibling, 0 replies; 11+ messages in thread
From: David Howells @ 2011-09-23 16:53 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: dhowells, miklos, raven, viro, jlayton, gregkh, linux-nfs,
	leonardo.lists

Linus Torvalds <torvalds@linux-foundation.org> wrote:

> > The problem with this is that this breaks nfs_follow_remote_path() used by
> > NFS4 to find the root object to mount for the mount() syscall.
> 
> The above message is basically dishonest.
>
> That's not AT ALL the problem.

Dishonest?  In what way am I lying about it?  After I wrote that line I went
on to explain how to reproduce it and what was happening.

That was the problem addressed by that patch.  I was including it as a means
to fix the NFS regression and as I pointed out in the cover note, it can be
actually be dropped if one of the further patches is introduced.

> That problem could have been fixed with a one-liner patch that already exists.

Which is fragile.

> This whole patch-series looks like just excuses for doing stupid things.

I believe you to be wrong.

Anyway, if I'm going to be accused of dishonesty, I see no further reason to
continuing in this discussion.

Have a good weekend.

David

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

end of thread, other threads:[~2011-09-23 16:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-23 16:24 [RFC][PATCH 0/7] Automount behaviour correction David Howells
2011-09-23 16:24 ` [PATCH 1/7] NFS4: Revert commit to make the automount code ignore LOOKUP_FOLLOW David Howells
2011-09-23 16:35   ` Linus Torvalds
2011-09-23 16:53   ` David Howells
2011-09-23 16:25 ` [PATCH 2/7] VFS: Make chown() and lchown() call fchownat() David Howells
2011-09-23 16:25 ` [PATCH 3/7] VFS: Change LOOKUP_NO_AUTOMOUNT to LOOKUP_AUTOMOUNT David Howells
2011-09-23 16:25 ` [PATCH 4/7] VFS: Move the automount suppression decision out to the initial callers of David Howells
2011-09-23 16:25 ` [PATCH 5/7] VFS: Ignore symlink following advice when pathwalking David Howells
2011-09-23 16:25 ` [PATCH 6/7] VFS: Make stat and xattr calls not automount David Howells
2011-09-23 16:26 ` [PATCH 7/7] VFS: Vary the automounting rules for autofs David Howells
2011-09-23 16:29 ` [RFC][PATCH 0/7] Automount behaviour correction Linus Torvalds

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.