Commit cae7a073 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Return delegation upon rename or removal of file.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent cdce5d6b
...@@ -142,7 +142,7 @@ static void nfs_msync_inode(struct inode *inode) ...@@ -142,7 +142,7 @@ static void nfs_msync_inode(struct inode *inode)
/* /*
* Basic procedure for returning a delegation to the server * Basic procedure for returning a delegation to the server
*/ */
int nfs_inode_return_delegation(struct inode *inode) int __nfs_inode_return_delegation(struct inode *inode)
{ {
struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
......
...@@ -25,7 +25,7 @@ struct nfs_delegation { ...@@ -25,7 +25,7 @@ struct nfs_delegation {
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
int nfs_inode_return_delegation(struct inode *inode); int __nfs_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
...@@ -47,11 +47,25 @@ static inline int nfs_have_delegation(struct inode *inode, int flags) ...@@ -47,11 +47,25 @@ static inline int nfs_have_delegation(struct inode *inode, int flags)
return 1; return 1;
return 0; return 0;
} }
static inline int nfs_inode_return_delegation(struct inode *inode)
{
int err = 0;
if (NFS_I(inode)->delegation != NULL)
err = __nfs_inode_return_delegation(inode);
return err;
}
#else #else
static inline int nfs_have_delegation(struct inode *inode, int flags) static inline int nfs_have_delegation(struct inode *inode, int flags)
{ {
return 0; return 0;
} }
static inline int nfs_inode_return_delegation(struct inode *inode)
{
return 0;
}
#endif #endif
#endif #endif
...@@ -801,6 +801,7 @@ static int nfs_dentry_delete(struct dentry *dentry) ...@@ -801,6 +801,7 @@ static int nfs_dentry_delete(struct dentry *dentry)
*/ */
static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
{ {
nfs_inode_return_delegation(inode);
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
lock_kernel(); lock_kernel();
inode->i_nlink--; inode->i_nlink--;
...@@ -1329,6 +1330,7 @@ static int nfs_safe_remove(struct dentry *dentry) ...@@ -1329,6 +1330,7 @@ static int nfs_safe_remove(struct dentry *dentry)
nfs_begin_data_update(dir); nfs_begin_data_update(dir);
if (inode != NULL) { if (inode != NULL) {
nfs_inode_return_delegation(inode);
nfs_begin_data_update(inode); nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */ /* The VFS may want to delete this inode */
...@@ -1547,6 +1549,7 @@ go_ahead: ...@@ -1547,6 +1549,7 @@ go_ahead:
nfs_wb_all(old_inode); nfs_wb_all(old_inode);
shrink_dcache_parent(old_dentry); shrink_dcache_parent(old_dentry);
} }
nfs_inode_return_delegation(old_inode);
if (new_inode) if (new_inode)
d_delete(new_dentry); d_delete(new_dentry);
......
...@@ -1671,8 +1671,7 @@ static void nfs4_clear_inode(struct inode *inode) ...@@ -1671,8 +1671,7 @@ static void nfs4_clear_inode(struct inode *inode)
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
/* If we are holding a delegation, return it! */ /* If we are holding a delegation, return it! */
if (nfsi->delegation != NULL) nfs_inode_return_delegation(inode);
nfs_inode_return_delegation(inode);
/* First call standard NFS clear_inode() code */ /* First call standard NFS clear_inode() code */
nfs_clear_inode(inode); nfs_clear_inode(inode);
/* Now clear out any remaining state */ /* Now clear out any remaining state */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment