summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-29 01:43:18 +0100
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 08:05:22 +0100
commitd45b9d8baf41acb177abbbe6746b1dea094b8a28 (patch)
tree2bb90613fb21865b6b23c676c00073d3c4729929 /fs/nfs
parentNFS: Sillyrename: in the case of a race, check aliases are really positive (diff)
downloadlinux-d45b9d8baf41acb177abbbe6746b1dea094b8a28.tar.xz
linux-d45b9d8baf41acb177abbbe6746b1dea094b8a28.zip
NFS: Handle -ENOENT errors in unlink()/rmdir()/rename()
If the server returns an ENOENT error, we still need to do a d_delete() in order to ensure that the dentry is deleted. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d9abdb1d6a2a..06f26d40b4fe 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1267,6 +1267,12 @@ out_err:
return error;
}
+static void nfs_dentry_handle_enoent(struct dentry *dentry)
+{
+ if (dentry->d_inode != NULL && !d_unhashed(dentry))
+ d_delete(dentry);
+}
+
static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
{
int error;
@@ -1279,6 +1285,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
/* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL)
clear_nlink(dentry->d_inode);
+ else if (error == -ENOENT)
+ nfs_dentry_handle_enoent(dentry);
unlock_kernel();
return error;
@@ -1385,6 +1393,8 @@ static int nfs_safe_remove(struct dentry *dentry)
nfs_mark_for_revalidate(inode);
} else
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+ if (error == -ENOENT)
+ nfs_dentry_handle_enoent(dentry);
out:
return error;
}
@@ -1421,7 +1431,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
error = nfs_safe_remove(dentry);
- if (!error) {
+ if (!error || error == -ENOENT) {
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
} else if (need_rehash)
d_rehash(dentry);
@@ -1634,7 +1644,8 @@ out:
d_move(old_dentry, new_dentry);
nfs_set_verifier(new_dentry,
nfs_save_change_attribute(new_dir));
- }
+ } else if (error == -ENOENT)
+ nfs_dentry_handle_enoent(old_dentry);
/* new dentry created? */
if (dentry)