aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-28 19:43:18 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:05:22 -0500
commitd45b9d8baf41acb177abbbe6746b1dea094b8a28 (patch)
tree2bb90613fb21865b6b23c676c00073d3c4729929 /fs/nfs
parent609005c319bc6062b95ed82e132884ed7e22cdb9 (diff)
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:
1267 return error; 1267 return error;
1268} 1268}
1269 1269
1270static void nfs_dentry_handle_enoent(struct dentry *dentry)
1271{
1272 if (dentry->d_inode != NULL && !d_unhashed(dentry))
1273 d_delete(dentry);
1274}
1275
1270static int nfs_rmdir(struct inode *dir, struct dentry *dentry) 1276static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1271{ 1277{
1272 int error; 1278 int error;
@@ -1279,6 +1285,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1279 /* Ensure the VFS deletes this inode */ 1285 /* Ensure the VFS deletes this inode */
1280 if (error == 0 && dentry->d_inode != NULL) 1286 if (error == 0 && dentry->d_inode != NULL)
1281 clear_nlink(dentry->d_inode); 1287 clear_nlink(dentry->d_inode);
1288 else if (error == -ENOENT)
1289 nfs_dentry_handle_enoent(dentry);
1282 unlock_kernel(); 1290 unlock_kernel();
1283 1291
1284 return error; 1292 return error;
@@ -1385,6 +1393,8 @@ static int nfs_safe_remove(struct dentry *dentry)
1385 nfs_mark_for_revalidate(inode); 1393 nfs_mark_for_revalidate(inode);
1386 } else 1394 } else
1387 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1395 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1396 if (error == -ENOENT)
1397 nfs_dentry_handle_enoent(dentry);
1388out: 1398out:
1389 return error; 1399 return error;
1390} 1400}
@@ -1421,7 +1431,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
1421 spin_unlock(&dentry->d_lock); 1431 spin_unlock(&dentry->d_lock);
1422 spin_unlock(&dcache_lock); 1432 spin_unlock(&dcache_lock);
1423 error = nfs_safe_remove(dentry); 1433 error = nfs_safe_remove(dentry);
1424 if (!error) { 1434 if (!error || error == -ENOENT) {
1425 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1435 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1426 } else if (need_rehash) 1436 } else if (need_rehash)
1427 d_rehash(dentry); 1437 d_rehash(dentry);
@@ -1634,7 +1644,8 @@ out:
1634 d_move(old_dentry, new_dentry); 1644 d_move(old_dentry, new_dentry);
1635 nfs_set_verifier(new_dentry, 1645 nfs_set_verifier(new_dentry,
1636 nfs_save_change_attribute(new_dir)); 1646 nfs_save_change_attribute(new_dir));
1637 } 1647 } else if (error == -ENOENT)
1648 nfs_dentry_handle_enoent(old_dentry);
1638 1649
1639 /* new dentry created? */ 1650 /* new dentry created? */
1640 if (dentry) 1651 if (dentry)