linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: miklos@szeredi.hu, raven@themaw.net, viro@ZenIV.linux.org.uk,
	torvalds@linux-foundation.org
Cc: dhowells@redhat.com, jlayton@redhat.com, gregkh@suse.de,
	linux-nfs@vger.kernel.org, leonardo.lists@gmail.com
Subject: [PATCH 7/7] VFS: Vary the automounting rules for autofs
Date: Fri, 23 Sep 2011 17:26:06 +0100	[thread overview]
Message-ID: <20110923162605.13574.86939.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20110923162438.13574.52985.stgit@warthog.procyon.org.uk>

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 *);
 


  parent reply	other threads:[~2011-09-23 16:26 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` David Howells [this message]
2011-09-23 16:29 ` [RFC][PATCH 0/7] Automount behaviour correction Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110923162605.13574.86939.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=gregkh@suse.de \
    --cc=jlayton@redhat.com \
    --cc=leonardo.lists@gmail.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=raven@themaw.net \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).