diff options
author | Ian Kent <ikent@redhat.com> | 2016-11-28 10:12:14 +0800 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-12-03 20:51:50 -0500 |
commit | 1c4344a50d702307185cb98fb67bff938cd66aa0 (patch) | |
tree | 72ed2eb1737d3562bd7f8c5e137fe908e4d82f6b | |
parent | 455e8f1030de82b68ee4e82f71516f3692f5e626 (diff) | |
download | linux-1c4344a50d702307185cb98fb67bff938cd66aa0.tar.bz2 |
autofs - dont hold spin lock over direct mount expire
Commit 7cbdb4a286 altered the autofs indirect mount expire to
not hold a spin lock during the expire check.
The direct mount expire needs the same treatment because to
make autofs expires namespace aware may_umount_tree() needs to
to use a similar method to may_umount() when checking if a mount
tree is in use.
This means may_umount_tree() will end up taking the namespace_sem
for the check so the autofs direct mount expire won't be allowed
to hold a spin lock over the check.
Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/autofs4/expire.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 13178bf2c431..57725d4a8c59 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -310,26 +310,29 @@ struct dentry *autofs4_expire_direct(struct super_block *sb, now = jiffies; timeout = sbi->exp_timeout; - spin_lock(&sbi->fs_lock); - ino = autofs4_dentry_ino(root); - /* No point expiring a pending mount */ - if (ino->flags & AUTOFS_INF_PENDING) - goto out; if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { + spin_lock(&sbi->fs_lock); + ino = autofs4_dentry_ino(root); + /* No point expiring a pending mount */ + if (ino->flags & AUTOFS_INF_PENDING) { + spin_unlock(&sbi->fs_lock); + goto out; + } ino->flags |= AUTOFS_INF_WANT_EXPIRE; spin_unlock(&sbi->fs_lock); synchronize_rcu(); - spin_lock(&sbi->fs_lock); if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { + spin_lock(&sbi->fs_lock); ino->flags |= AUTOFS_INF_EXPIRING; init_completion(&ino->expire_complete); spin_unlock(&sbi->fs_lock); return root; } + spin_lock(&sbi->fs_lock); ino->flags &= ~AUTOFS_INF_WANT_EXPIRE; + spin_unlock(&sbi->fs_lock); } out: - spin_unlock(&sbi->fs_lock); dput(root); return NULL; |