From 3a9720ce73c9247e5262922d65e90444ea75eb50 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Sun, 1 May 2005 08:59:17 -0700 Subject: [PATCH] autofs4: tree race fix For tree mount maps, a call to chdir or chroot, to a directory above the moint point directories at a certain time during the expire results in the expire incorrectly thinking the tree is not busy. This patch adds a check to see if the filesystem above the tree mount points is busy and also locks the filesystem during the tree mount expire to prevent the race. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/expire.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'fs/autofs4/expire.c') diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 31540a6404d9..500425e24fba 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -99,6 +99,10 @@ static int autofs4_check_tree(struct vfsmount *mnt, if (!autofs4_can_expire(top, timeout, do_now)) return 0; + /* Is someone visiting anywhere in the tree ? */ + if (may_umount_tree(mnt)) + return 0; + spin_lock(&dcache_lock); repeat: next = this_parent->d_subdirs.next; @@ -270,10 +274,18 @@ static struct dentry *autofs4_expire(struct super_block *sb, /* Case 2: tree mount, expire iff entire tree is not busy */ if (!exp_leaves) { + /* Lock the tree as we must expire as a whole */ + spin_lock(&sbi->fs_lock); if (autofs4_check_tree(mnt, dentry, timeout, do_now)) { - expired = dentry; - break; + struct autofs_info *inf = autofs4_dentry_ino(dentry); + + /* Set this flag early to catch sys_chdir and the like */ + inf->flags |= AUTOFS_INF_EXPIRING; + spin_unlock(&sbi->fs_lock); + expired = dentry; + break; } + spin_unlock(&sbi->fs_lock); /* Case 3: direct mount, expire individual leaves */ } else { expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); -- cgit v1.2.2