Add an AT_NO_AUTOMOUNT flag to suppress terminal automount
authorDavid Howells <dhowells@redhat.com>
Fri, 14 Jan 2011 18:45:31 +0000 (18:45 +0000)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 16 Jan 2011 01:07:33 +0000 (20:07 -0500)
Add an AT_NO_AUTOMOUNT flag to suppress terminal automounting of automount
point directories.  This can be used by fstatat() users to permit the
gathering of attributes on an automount point and also prevent
mass-automounting of a directory of automount points by ls.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Ian Kent <raven@themaw.net>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c
fs/stat.c
include/linux/fcntl.h
include/linux/namei.h

index 9d3033dc22e9cd7637364a545c29b104c93f9fdd..dc50bfb2f5d6fac3b613cc41c6d8833694fa2196 100644 (file)
@@ -908,6 +908,12 @@ static int follow_automount(struct path *path, unsigned flags,
        if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
                return -EREMOTE;
 
+       /* 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_CONTINUE))
+               return -EISDIR; /* we actually want to stop here */
+
        /* We want to mount if someone is trying to open/create a file of any
         * type under the mountpoint, wants to traverse through the mountpoint
         * or wants to open the mounted directory.
index 12e90e213900542291a0fa74da940c0588b69ace..d5c61cf2b7033cb459920b556b235d38b865596c 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -75,11 +75,13 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
        int error = -EINVAL;
        int lookup_flags = 0;
 
-       if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+       if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)) != 0)
                goto out;
 
        if (!(flag & AT_SYMLINK_NOFOLLOW))
                lookup_flags |= LOOKUP_FOLLOW;
+       if (flag & AT_NO_AUTOMOUNT)
+               lookup_flags |= LOOKUP_NO_AUTOMOUNT;
 
        error = user_path_at(dfd, filename, lookup_flags, &path);
        if (error)
index afc00af3229b5c6a6d0d7367edd32457b6784e14..a562fa5fb4e3ca2d879c6e7cb359b969e1d1a2e6 100644 (file)
@@ -45,6 +45,7 @@
 #define AT_REMOVEDIR           0x200   /* Remove directory instead of
                                            unlinking file.  */
 #define AT_SYMLINK_FOLLOW      0x400   /* Follow symbolic links.  */
+#define AT_NO_AUTOMOUNT                0x800   /* Suppress terminal automount traversal */
 
 #ifdef __KERNEL__
 
index 8ef2c789c2a8962f67bb25045cf4887078870749..f276d4fa01fc886fe7a3dbff57733501d00eaece 100644 (file)
@@ -45,6 +45,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
  */
 #define LOOKUP_FOLLOW          0x0001
 #define LOOKUP_DIRECTORY       0x0002
@@ -53,6 +54,7 @@ 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
 /*
  * Intent data
  */