lkml.org 
[lkml]   [2012]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 12/19] vfs: make rmdir retry on ESTALE errors
    Date
    Signed-off-by: Jeff Layton <jlayton@redhat.com>
    ---
    fs/namei.c | 83 +++++++++++++++++++++++++++++++++++---------------------------
    1 file changed, 47 insertions(+), 36 deletions(-)

    diff --git a/fs/namei.c b/fs/namei.c
    index d6e9754..7eb59cc 100644
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -3282,51 +3282,62 @@ out:
    static long do_rmdir(int dfd, const char __user *pathname)
    {
    int error = 0;
    - char * name;
    + char *name;
    struct dentry *dentry;
    struct nameidata nd;
    + unsigned int try = 0;
    + unsigned int lookup_flags = LOOKUP_PARENT;

    - error = user_path_parent(dfd, pathname, &nd, &name);
    - if (error)
    - return error;
    + name = getname(pathname);
    + if (IS_ERR(name))
    + return PTR_ERR(name);

    - switch(nd.last_type) {
    - case LAST_DOTDOT:
    - error = -ENOTEMPTY;
    - goto exit1;
    - case LAST_DOT:
    - error = -EINVAL;
    - goto exit1;
    - case LAST_ROOT:
    - error = -EBUSY;
    - goto exit1;
    - }
    + do {
    + error = do_path_lookup(dfd, name, lookup_flags, &nd);
    + if (error)
    + break;

    - nd.flags &= ~LOOKUP_PARENT;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto exit1;
    + switch (nd.last_type) {
    + case LAST_DOTDOT:
    + error = -ENOTEMPTY;
    + goto exit1;
    + case LAST_DOT:
    + error = -EINVAL;
    + goto exit1;
    + case LAST_ROOT:
    + error = -EBUSY;
    + goto exit1;
    + }

    - mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    - dentry = lookup_hash(&nd);
    - error = PTR_ERR(dentry);
    - if (IS_ERR(dentry))
    - goto exit2;
    - if (!dentry->d_inode) {
    - error = -ENOENT;
    - goto exit3;
    - }
    - error = security_path_rmdir(&nd.path, dentry);
    - if (error)
    - goto exit3;
    - error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
    + nd.flags &= ~LOOKUP_PARENT;
    + error = mnt_want_write(nd.path.mnt);
    + if (error)
    + goto exit1;
    +
    + mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex,
    + I_MUTEX_PARENT);
    + dentry = lookup_hash(&nd);
    + if (IS_ERR(dentry)) {
    + error = PTR_ERR(dentry);
    + goto exit2;
    + }
    + if (!dentry->d_inode) {
    + error = -ENOENT;
    + goto exit3;
    + }
    + error = security_path_rmdir(&nd.path, dentry);
    + if (error)
    + goto exit3;
    + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
    exit3:
    - dput(dentry);
    + dput(dentry);
    exit2:
    - mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    - mnt_drop_write(nd.path.mnt);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    + mnt_drop_write(nd.path.mnt);
    exit1:
    - path_put(&nd.path);
    + path_put(&nd.path);
    + lookup_flags |= LOOKUP_REVAL;
    + } while (retry_estale(error, try++));
    putname(name);
    return error;
    }
    --
    1.7.11.2


    \
     
     \ /
      Last update: 2012-08-09 00:21    [W:4.551 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site