Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d45b9d8b authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 609005c3
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -1267,6 +1267,12 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
	return error;
	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)
static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
{
{
	int error;
	int error;
@@ -1279,6 +1285,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
	/* Ensure the VFS deletes this inode */
	/* Ensure the VFS deletes this inode */
	if (error == 0 && dentry->d_inode != NULL)
	if (error == 0 && dentry->d_inode != NULL)
		clear_nlink(dentry->d_inode);
		clear_nlink(dentry->d_inode);
	else if (error == -ENOENT)
		nfs_dentry_handle_enoent(dentry);
	unlock_kernel();
	unlock_kernel();


	return error;
	return error;
@@ -1385,6 +1393,8 @@ static int nfs_safe_remove(struct dentry *dentry)
		nfs_mark_for_revalidate(inode);
		nfs_mark_for_revalidate(inode);
	} else
	} else
		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
	if (error == -ENOENT)
		nfs_dentry_handle_enoent(dentry);
out:
out:
	return error;
	return error;
}
}
@@ -1421,7 +1431,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
	spin_unlock(&dentry->d_lock);
	spin_unlock(&dentry->d_lock);
	spin_unlock(&dcache_lock);
	spin_unlock(&dcache_lock);
	error = nfs_safe_remove(dentry);
	error = nfs_safe_remove(dentry);
	if (!error) {
	if (!error || error == -ENOENT) {
		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
	} else if (need_rehash)
	} else if (need_rehash)
		d_rehash(dentry);
		d_rehash(dentry);
@@ -1634,7 +1644,8 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
		d_move(old_dentry, new_dentry);
		d_move(old_dentry, new_dentry);
		nfs_set_verifier(new_dentry,
		nfs_set_verifier(new_dentry,
					nfs_save_change_attribute(new_dir));
					nfs_save_change_attribute(new_dir));
	}
	} else if (error == -ENOENT)
		nfs_dentry_handle_enoent(old_dentry);


	/* new dentry created? */
	/* new dentry created? */
	if (dentry)
	if (dentry)