lkml.org 
[lkml]   [2012]   [Dec]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/2] autofs4 - use simple_empty() for empty directory check
    Date
    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>
    ---

    fs/autofs4/root.c | 22 +++++-----------------
    1 files changed, 5 insertions(+), 17 deletions(-)

    diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
    index 30a6ab66..c934476 100644
    --- a/fs/autofs4/root.c
    +++ b/fs/autofs4/root.c
    @@ -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:
    @@ -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);
    @@ -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;
    @@ -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)


    \
     
     \ /
      Last update: 2012-12-14 04:01    [W:3.188 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site