summaryrefslogtreecommitdiffstats
path: root/fs/autofs4/inode.c
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2006-03-27 11:14:46 +0200
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 18:44:39 +0200
commit1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9 (patch)
treebe50f4c89a14240b568010da1b0ce3c182352afc /fs/autofs4/inode.c
parent[PATCH] autofs4: simplify expire tree traversal (diff)
downloadlinux-1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9.tar.xz
linux-1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9.zip
[PATCH] autofs4: fix false negative return from expire
Fix the case where an expire returns busy on a tree mount when it is in fact not busy. This case was overlooked when the patch to prevent the expiring away of "scaffolding" directories for tree mounts was applied. The problem arises when a tree of mounts is a member of a map with other keys. The current logic will not expire the tree if any other mount in the map is busy. The solution is to maintain a "minimum" use count for each autofs dentry and compare this to the actual dentry usage count during expire. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r--fs/autofs4/inode.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 1ad98d48e550..2335b1d6490f 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -46,6 +46,7 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
ino->size = 0;
ino->last_used = jiffies;
+ atomic_set(&ino->count, 0);
ino->sbi = sbi;
@@ -64,10 +65,19 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
void autofs4_free_ino(struct autofs_info *ino)
{
+ struct autofs_info *p_ino;
+
if (ino->dentry) {
ino->dentry->d_fsdata = NULL;
- if (ino->dentry->d_inode)
+ if (ino->dentry->d_inode) {
+ struct dentry *parent = ino->dentry->d_parent;
+ if (atomic_dec_and_test(&ino->count)) {
+ p_ino = autofs4_dentry_ino(parent);
+ if (p_ino && parent != ino->dentry)
+ atomic_dec(&p_ino->count);
+ }
dput(ino->dentry);
+ }
ino->dentry = NULL;
}
if (ino->free)