From: NeilBrown <neilb@suse.de>
To: Ian Kent <raven@themaw.net>
Cc: autofs@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/5] autofs4: factor should_expire() out of autofs4_expire_indirect.
Date: Mon, 18 Aug 2014 16:33:01 +1000 [thread overview]
Message-ID: <20140818063300.9860.20538.stgit@notabene.brown> (raw)
In-Reply-To: <20140818062844.9860.43007.stgit@notabene.brown>
Future patch will potentially call this twice, so make it
separate.
Signed-off-by: NeilBrown <neilb@suse.de>
---
fs/autofs4/expire.c | 162 ++++++++++++++++++++++++++++-----------------------
1 file changed, 88 insertions(+), 74 deletions(-)
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 7e2f22ce6954..bee939efca2b 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -345,6 +345,89 @@ out:
return NULL;
}
+/* Check if 'dentry' should expire, or return a nearby
+ * dentry that is suitable.
+ * If returned dentry is different from arg dentry,
+ * then a dget() reference was taken, else not.
+ */
+static struct dentry *should_expire(struct dentry *dentry,
+ struct vfsmount *mnt,
+ unsigned long timeout,
+ int how)
+{
+ int do_now = how & AUTOFS_EXP_IMMEDIATE;
+ int exp_leaves = how & AUTOFS_EXP_LEAVES;
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+ unsigned int ino_count;
+
+ /* No point expiring a pending mount */
+ if (ino->flags & AUTOFS_INF_PENDING)
+ return NULL;
+
+ /*
+ * Case 1: (i) indirect mount or top level pseudo direct mount
+ * (autofs-4.1).
+ * (ii) indirect mount with offset mount, check the "/"
+ * offset (autofs-5.0+).
+ */
+ if (d_mountpoint(dentry)) {
+ DPRINTK("checking mountpoint %p %.*s",
+ dentry, (int)dentry->d_name.len, dentry->d_name.name);
+
+ /* Can we umount this guy */
+ if (autofs4_mount_busy(mnt, dentry))
+ return NULL;
+
+ /* Can we expire this guy */
+ if (autofs4_can_expire(dentry, timeout, do_now))
+ return dentry;
+ return NULL;
+ }
+
+ if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
+ DPRINTK("checking symlink %p %.*s",
+ dentry, (int)dentry->d_name.len, dentry->d_name.name);
+ /*
+ * A symlink can't be "busy" in the usual sense so
+ * just check last used for expire timeout.
+ */
+ if (autofs4_can_expire(dentry, timeout, do_now))
+ return dentry;
+ return NULL;
+ }
+
+ if (simple_empty(dentry))
+ return NULL;
+
+ /* Case 2: tree mount, expire iff entire tree is not busy */
+ if (!exp_leaves) {
+ /* Path walk currently on this dentry? */
+ ino_count = atomic_read(&ino->count) + 1;
+ if (d_count(dentry) > ino_count)
+ return NULL;
+
+ if (!autofs4_tree_busy(mnt, dentry, timeout, do_now))
+ return dentry;
+ /*
+ * Case 3: pseudo direct mount, expire individual leaves
+ * (autofs-4.1).
+ */
+ } else {
+ /* Path walk currently on this dentry? */
+ struct dentry *expired;
+ ino_count = atomic_read(&ino->count) + 1;
+ if (d_count(dentry) > ino_count)
+ return NULL;
+
+ expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
+ if (expired) {
+ if (expired == dentry)
+ dput(dentry);
+ return expired;
+ }
+ }
+ return NULL;
+}
/*
* Find an eligible tree to time-out
* A tree is eligible if :-
@@ -359,11 +442,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
unsigned long timeout;
struct dentry *root = sb->s_root;
struct dentry *dentry;
- struct dentry *expired = NULL;
- int do_now = how & AUTOFS_EXP_IMMEDIATE;
- int exp_leaves = how & AUTOFS_EXP_LEAVES;
+ struct dentry *expired;
struct autofs_info *ino;
- unsigned int ino_count;
if (!root)
return NULL;
@@ -374,78 +454,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
dentry = NULL;
while ((dentry = get_next_positive_subdir(dentry, root))) {
spin_lock(&sbi->fs_lock);
- ino = autofs4_dentry_ino(dentry);
- /* No point expiring a pending mount */
- if (ino->flags & AUTOFS_INF_PENDING)
- goto next;
-
- /*
- * Case 1: (i) indirect mount or top level pseudo direct mount
- * (autofs-4.1).
- * (ii) indirect mount with offset mount, check the "/"
- * offset (autofs-5.0+).
- */
- if (d_mountpoint(dentry)) {
- DPRINTK("checking mountpoint %p %.*s",
- dentry, (int)dentry->d_name.len, dentry->d_name.name);
-
- /* Can we umount this guy */
- if (autofs4_mount_busy(mnt, dentry))
- goto next;
-
- /* Can we expire this guy */
- if (autofs4_can_expire(dentry, timeout, do_now)) {
- expired = dentry;
- goto found;
- }
- goto next;
- }
-
- if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
- DPRINTK("checking symlink %p %.*s",
- dentry, (int)dentry->d_name.len, dentry->d_name.name);
- /*
- * A symlink can't be "busy" in the usual sense so
- * just check last used for expire timeout.
- */
- if (autofs4_can_expire(dentry, timeout, do_now)) {
- expired = dentry;
- goto found;
- }
- goto next;
- }
-
- if (simple_empty(dentry))
- goto next;
-
- /* Case 2: tree mount, expire iff entire tree is not busy */
- if (!exp_leaves) {
- /* Path walk currently on this dentry? */
- ino_count = atomic_read(&ino->count) + 1;
- if (d_count(dentry) > ino_count)
- goto next;
-
- if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
- expired = dentry;
- goto found;
- }
- /*
- * Case 3: pseudo direct mount, expire individual leaves
- * (autofs-4.1).
- */
- } else {
- /* Path walk currently on this dentry? */
- ino_count = atomic_read(&ino->count) + 1;
- if (d_count(dentry) > ino_count)
- goto next;
-
- expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
- if (expired) {
+ expired = should_expire(dentry, mnt, timeout, how);
+ if (expired) {
+ if (expired != dentry)
dput(dentry);
- goto found;
- }
+ goto found;
}
-next:
spin_unlock(&sbi->fs_lock);
}
return NULL;
next prev parent reply other threads:[~2014-08-18 6:33 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-18 6:33 [PATCH 0/5] RCU-walk support for autofs NeilBrown
2014-08-18 6:33 ` [PATCH 1/5] autofs4: allow RCU-walk to walk through autofs4 NeilBrown
2014-08-18 6:33 ` NeilBrown [this message]
2014-08-18 6:33 ` [PATCH 4/5] autofs4: d_manage() should return -EISDIR when appropriate in rcu-walk mode NeilBrown
2014-08-18 6:33 ` [PATCH 3/5] autofs4: avoid taking fs_lock during rcu-walk NeilBrown
2014-08-18 6:33 ` [PATCH 5/5] autofs: the documentation I wanted to read NeilBrown
2014-08-18 10:13 ` Ian Kent
2014-08-19 7:00 ` NeilBrown
2014-08-18 8:25 ` [PATCH 0/5] RCU-walk support for autofs Ian Kent
2014-08-19 10:02 ` Ian Kent
2014-08-19 11:16 ` NeilBrown
2014-08-19 12:30 ` Ian Kent
2014-08-19 12:36 ` Ian Kent
2014-08-20 3:13 ` NeilBrown
2014-08-20 3:42 ` Ian Kent
2014-08-20 3:50 ` Ian Kent
2014-08-20 9:52 ` Ian Kent
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=20140818063300.9860.20538.stgit@notabene.brown \
--to=neilb@suse.de \
--cc=autofs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=raven@themaw.net \
/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 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.