Skip to content

Commit

Permalink
autofs4 - use simple_empty() for empty directory check
Browse files Browse the repository at this point in the history
For direct (and offset) mounts, if an automounted mount is manually
umounted the trigger mount dentry can appear non-empty causing it to
not trigger mounts. This can also happen if there is a file handle
leak in a user space automounting application.

This happens because, when a ioctl control file handle is opened
on the mount, a cursor dentry is created which causes list_empty()
to see the dentry as non-empty. Since there is a case where listing
the directory of these dentrys is needed, the use of dcache_dir_*()
functions for .open() and .release() is needed.

Consequently simple_empty() must be used instead of list_empty()
when checking for an empty directory.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ian Kent authored and Linus Torvalds committed Dec 14, 2012
1 parent f55fb0c commit 0259cb0
Showing 1 changed file with 5 additions and 17 deletions.
22 changes: 5 additions & 17 deletions fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,10 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
* it.
*/
spin_lock(&sbi->lookup_lock);
spin_lock(&dentry->d_lock);
if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
spin_unlock(&dentry->d_lock);
if (!d_mountpoint(dentry) && simple_empty(dentry)) {
spin_unlock(&sbi->lookup_lock);
return -ENOENT;
}
spin_unlock(&dentry->d_lock);
spin_unlock(&sbi->lookup_lock);

out:
Expand Down Expand Up @@ -386,12 +383,8 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
goto done;
}
} else {
spin_lock(&dentry->d_lock);
if (!list_empty(&dentry->d_subdirs)) {
spin_unlock(&dentry->d_lock);
if (!simple_empty(dentry))
goto done;
}
spin_unlock(&dentry->d_lock);
}
ino->flags |= AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
Expand Down Expand Up @@ -610,9 +603,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)

spin_lock(&sbi->lookup_lock);
__autofs4_add_expiring(dentry);
spin_lock(&dentry->d_lock);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
d_drop(dentry);
spin_unlock(&sbi->lookup_lock);

return 0;
Expand Down Expand Up @@ -683,15 +674,12 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
return -EACCES;

spin_lock(&sbi->lookup_lock);
spin_lock(&dentry->d_lock);
if (!list_empty(&dentry->d_subdirs)) {
spin_unlock(&dentry->d_lock);
if (!simple_empty(dentry)) {
spin_unlock(&sbi->lookup_lock);
return -ENOTEMPTY;
}
__autofs4_add_expiring(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
d_drop(dentry);
spin_unlock(&sbi->lookup_lock);

if (sbi->version < 5)
Expand Down

0 comments on commit 0259cb0

Please sign in to comment.