From patchwork Thu Mar 26 05:23:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Kent X-Patchwork-Id: 11459283 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D9AA913 for ; Thu, 26 Mar 2020 05:32:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5710B207FC for ; Thu, 26 Mar 2020 05:32:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727652AbgCZFcz (ORCPT ); Thu, 26 Mar 2020 01:32:55 -0400 Received: from icp-osb-irony-out5.external.iinet.net.au ([203.59.1.221]:30174 "EHLO icp-osb-irony-out5.external.iinet.net.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727600AbgCZFcy (ORCPT ); Thu, 26 Mar 2020 01:32:54 -0400 X-SMTP-MATCH: 0 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2A8BQBuO3xe/4G50HZmHAEBAQEBBwEBEQEEBAEBgWoEAQELAQGBdjGBYRIqhBqPZoESOIlniimHJAoBAQEBAQEBAQEbGQECBAEBhEQCgigkNwYOAhABAQEFAQEBAQEFAwFthQpYQgEMAYUUBiMEUhAYDQIYDgICRxAGE4V+JK4gfzMaAopOgQ4qAYwuGnmBB4FEA4E2c3OBBAGGV4JeBI1wgwOHDUWBAJcQgkaNMolXHY87A4whLaZbhg4jgVhNLgqDJ1AYjkKOPTcwgQYBAYQZiSVfAQE X-IPAS-Result: A2A8BQBuO3xe/4G50HZmHAEBAQEBBwEBEQEEBAEBgWoEAQELAQGBdjGBYRIqhBqPZoESOIlniimHJAoBAQEBAQEBAQEbGQECBAEBhEQCgigkNwYOAhABAQEFAQEBAQEFAwFthQpYQgEMAYUUBiMEUhAYDQIYDgICRxAGE4V+JK4gfzMaAopOgQ4qAYwuGnmBB4FEA4E2c3OBBAGGV4JeBI1wgwOHDUWBAJcQgkaNMolXHY87A4whLaZbhg4jgVhNLgqDJ1AYjkKOPTcwgQYBAYQZiSVfAQE X-IronPort-AV: E=Sophos;i="5.72,307,1580745600"; d="scan'208";a="304456561" Received: from unknown (HELO mickey.themaw.net) ([118.208.185.129]) by icp-osb-irony-out5.iinet.net.au with ESMTP; 26 Mar 2020 13:23:30 +0800 Subject: [PATCH 3/4] vfs: check for autofs expiring dentry in follow_automount() From: Ian Kent To: Al Viro Cc: autofs mailing list , linux-fsdevel , Kernel Mailing List Date: Thu, 26 Mar 2020 13:23:29 +0800 Message-ID: <158520020932.5325.1998880625163566595.stgit@mickey.themaw.net> In-Reply-To: <158520019862.5325.7856909810909592388.stgit@mickey.themaw.net> References: <158520019862.5325.7856909810909592388.stgit@mickey.themaw.net> User-Agent: StGit/unknown-version MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org follow_automount() checks if a stat family system call path walk is being done on a positive dentry and and returns -EISDIR to indicate the dentry should be used as is without attempting an automount. But if autofs is expiring the dentry at the time it should be remounted following the expire. There are two cases, in the case of a "nobrowse" indirect autofs mount it would have been mounted on lookup anyway. In the case of a "browse" indirect or direct autofs mount re-mounting it will maintain the mount which is what user space would be expected. This will defer expiration of the mount which might lead to mounts unexpectedly remaining mounted under heavy stat activity but there's no other choice in order to maintain consistency for user space. Signed-off-by: Ian Kent --- fs/autofs/root.c | 10 +++++++++- fs/namei.c | 13 +++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/autofs/root.c b/fs/autofs/root.c index a1c9c32e104f..308cc49aca1d 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -406,9 +406,17 @@ static int autofs_d_manage(const struct path *path, bool rcu_walk) /* Check for (possible) pending expire */ if (ino->flags & AUTOFS_INF_WANT_EXPIRE) { + /* dentry possibly going to be picked for expire, + * proceed to ref-walk mode. + */ if (rcu_walk) return -ECHILD; - return 0; + + /* ref-walk mode, return 1 so follow_automount() + * can to wait on the expire outcome and possibly + * attempt a re-mount. + */ + return 1; } /* diff --git a/fs/namei.c b/fs/namei.c index db6565c99825..34a03928d32d 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1227,11 +1227,20 @@ static int follow_automount(struct path *path, struct nameidata *nd, * 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. + * + * Also if ->d_manage() returns 1 the dentry transit needs + * managing, for autofs it tells us the dentry might be expired, + * so proceed to ->d_automount(). */ if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | LOOKUP_OPEN | LOOKUP_CREATE | LOOKUP_AUTOMOUNT)) && - path->dentry->d_inode) - return -EISDIR; + path->dentry->d_inode) { + if (path->dentry->d_flags & DCACHE_MANAGE_TRANSIT) { + if (!path->dentry->d_op->d_manage(path, false)) + return -EISDIR; + } else + return -EISDIR; + } nd->total_link_count++; if (nd->total_link_count >= 40)