Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 260875
b: refs/heads/master
c: 73ca100
h: refs/heads/master
i:
  260873: 6cee480
  260871: 11789e6
v: v3
  • Loading branch information
Jeff Layton authored and Trond Myklebust committed Jul 25, 2011
1 parent e2db010 commit 6744673
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2773395b34883fe54418de188733a63bb38e0ad6
refs/heads/master: 73ca1001ed6881b476e8252adcd0eede1ea368ea
29 changes: 19 additions & 10 deletions trunk/fs/nfs/unlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,24 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n

alias = d_lookup(parent, &data->args.name);
if (alias != NULL) {
int ret = 0;
int ret;
void *devname_garbage = NULL;

/*
* Hey, we raced with lookup... See if we need to transfer
* the sillyrename information to the aliased dentry.
*/
nfs_free_dname(data);
ret = nfs_copy_dname(alias, data);
spin_lock(&alias->d_lock);
if (alias->d_inode != NULL &&
if (ret == 0 && alias->d_inode != NULL &&
!(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
devname_garbage = alias->d_fsdata;
alias->d_fsdata = data;
alias->d_flags |= DCACHE_NFSFS_RENAMED;
ret = 1;
}
} else
ret = 0;
spin_unlock(&alias->d_lock);
nfs_dec_sillycount(dir);
dput(alias);
Expand All @@ -171,8 +173,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n
* point dentry is definitely not a root, so we won't need
* that anymore.
*/
if (devname_garbage)
kfree(devname_garbage);
kfree(devname_garbage);
return ret;
}
data->dir = igrab(dir);
Expand Down Expand Up @@ -204,8 +205,6 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
if (parent == NULL)
goto out_free;
dir = parent->d_inode;
if (nfs_copy_dname(dentry, data) != 0)
goto out_dput;
/* Non-exclusive lock protects against concurrent lookup() calls */
spin_lock(&dir->i_lock);
if (atomic_inc_not_zero(&NFS_I(dir)->silly_count) == 0) {
Expand Down Expand Up @@ -366,19 +365,21 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
struct nfs_renamedata *data = calldata;
struct inode *old_dir = data->old_dir;
struct inode *new_dir = data->new_dir;
struct dentry *old_dentry = data->old_dentry;
struct dentry *new_dentry = data->new_dentry;

if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
nfs_restart_rpc(task, NFS_SERVER(old_dir)->nfs_client);
return;
}

if (task->tk_status != 0) {
nfs_cancel_async_unlink(data->old_dentry);
nfs_cancel_async_unlink(old_dentry);
return;
}

nfs_set_verifier(data->old_dentry, nfs_save_change_attribute(old_dir));
d_move(data->old_dentry, data->new_dentry);
d_drop(old_dentry);
d_drop(new_dentry);
}

/**
Expand Down Expand Up @@ -568,6 +569,14 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
if (error)
goto out_dput;

/* populate unlinkdata with the right dname */
error = nfs_copy_dname(sdentry,
(struct nfs_unlinkdata *)dentry->d_fsdata);
if (error) {
nfs_cancel_async_unlink(dentry);
goto out_dput;
}

/* run the rename task, undo unlink if it fails */
task = nfs_async_rename(dir, dir, dentry, sdentry);
if (IS_ERR(task)) {
Expand Down

0 comments on commit 6744673

Please sign in to comment.