autofs: add strictexpire mount option
authorIan Kent <raven@themaw.net>
Thu, 3 Jan 2019 23:27:43 +0000 (15:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 4 Jan 2019 21:13:47 +0000 (13:13 -0800)
Commit 092a53452bb7 ("autofs: take more care to not update last_used on
path walk") helped to (partially) resolve a problem where automounts
were not expiring due to aggressive accesses from user space.

This patch was later reverted because, for very large environments, it
meant more mount requests from clients and when there are a lot of
clients this caused a fairly significant increase in server load.

But there is a need for both types of expire check, depending on use
case, so add a mount option to allow for strict update of last use of
autofs dentrys (which just means not updating the last use on path walk
access).

Link: http://lkml.kernel.org/r/154296973880.9889.14085372741514507967.stgit@pluto-themaw-net
Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/autofs/autofs_i.h
fs/autofs/inode.c
fs/autofs/root.c
include/uapi/linux/auto_fs.h

index 9b81c10ef251dc61138c9bbf68f5266daa369bc3..3e59f0ed777bff66542a32cda86e2f90b1a821ef 100644 (file)
@@ -104,6 +104,7 @@ struct autofs_wait_queue {
 #define AUTOFS_SBI_MAGIC 0x6d4a556d
 
 #define AUTOFS_SBI_CATATONIC   0x0001
+#define AUTOFS_SBI_STRICTEXPIRE 0x0002
 
 struct autofs_sb_info {
        u32 magic;
index 3a94dbda36dd2ed64bf4bae886da9eb833c9c67c..0e8ea2d9a2bba20b185ffee82aff9652d1012d0f 100644 (file)
@@ -87,6 +87,8 @@ static int autofs_show_options(struct seq_file *m, struct dentry *root)
                seq_printf(m, ",direct");
        else
                seq_printf(m, ",indirect");
+       if (sbi->flags & AUTOFS_SBI_STRICTEXPIRE)
+               seq_printf(m, ",strictexpire");
 #ifdef CONFIG_CHECKPOINT_RESTORE
        if (sbi->pipe)
                seq_printf(m, ",pipe_ino=%ld", file_inode(sbi->pipe)->i_ino);
@@ -109,7 +111,7 @@ static const struct super_operations autofs_sops = {
 };
 
 enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto,
-       Opt_indirect, Opt_direct, Opt_offset};
+       Opt_indirect, Opt_direct, Opt_offset, Opt_strictexpire};
 
 static const match_table_t tokens = {
        {Opt_fd, "fd=%u"},
@@ -121,6 +123,7 @@ static const match_table_t tokens = {
        {Opt_indirect, "indirect"},
        {Opt_direct, "direct"},
        {Opt_offset, "offset"},
+       {Opt_strictexpire, "strictexpire"},
        {Opt_err, NULL}
 };
 
@@ -200,6 +203,9 @@ static int parse_options(char *options,
                case Opt_offset:
                        set_autofs_type_offset(&sbi->type);
                        break;
+               case Opt_strictexpire:
+                       sbi->flags |= AUTOFS_SBI_STRICTEXPIRE;
+                       break;
                default:
                        return 1;
                }
index 164ccd3402cf3d4e4a94c53dcb947bbd4c8f04e3..1246f396bf0e9dbffca16c6f8b856e43a9b8e05f 100644 (file)
@@ -275,8 +275,11 @@ static int autofs_mount_wait(const struct path *path, bool rcu_walk)
                pr_debug("waiting for mount name=%pd\n", path->dentry);
                status = autofs_wait(sbi, path, NFY_MOUNT);
                pr_debug("mount wait done status=%d\n", status);
+               ino->last_used = jiffies;
+               return status;
        }
-       ino->last_used = jiffies;
+       if (!(sbi->flags & AUTOFS_SBI_STRICTEXPIRE))
+               ino->last_used = jiffies;
        return status;
 }
 
index df31aa9c9a8c3abe699e5875d814eb354257bd25..082119630b49c2575512f7c7a876b4feff67c10b 100644 (file)
@@ -23,7 +23,7 @@
 #define AUTOFS_MIN_PROTO_VERSION       3
 #define AUTOFS_MAX_PROTO_VERSION       5
 
-#define AUTOFS_PROTO_SUBVERSION                3
+#define AUTOFS_PROTO_SUBVERSION                4
 
 /*
  * The wait_queue_token (autofs_wqt_t) is part of a structure which is passed