aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:19 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:19 -0400
commitcae7a073a4c5484cc5713eab606bf54b46724ab3 (patch)
treee5cdcf0376da5b04bca9bbbf8f226abe13f33275
parentcdce5d6b94b6182f6d8a5b7b52923933e98cbc92 (diff)
NFSv4: Return delegation upon rename or removal of file.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/delegation.h16
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/inode.c3
4 files changed, 20 insertions, 4 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 4a36839f0bbd..44135af9894c 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -142,7 +142,7 @@ static void nfs_msync_inode(struct inode *inode)
142/* 142/*
143 * Basic procedure for returning a delegation to the server 143 * Basic procedure for returning a delegation to the server
144 */ 144 */
145int nfs_inode_return_delegation(struct inode *inode) 145int __nfs_inode_return_delegation(struct inode *inode)
146{ 146{
147 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; 147 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state;
148 struct nfs_inode *nfsi = NFS_I(inode); 148 struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 3f6c45a29d6a..8017846b561f 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -25,7 +25,7 @@ struct nfs_delegation {
25 25
26int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 26int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
27void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 27void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
28int nfs_inode_return_delegation(struct inode *inode); 28int __nfs_inode_return_delegation(struct inode *inode);
29int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); 29int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
30 30
31struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); 31struct 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 return 1; 47 return 1;
48 return 0; 48 return 0;
49} 49}
50
51static inline int nfs_inode_return_delegation(struct inode *inode)
52{
53 int err = 0;
54
55 if (NFS_I(inode)->delegation != NULL)
56 err = __nfs_inode_return_delegation(inode);
57 return err;
58}
50#else 59#else
51static inline int nfs_have_delegation(struct inode *inode, int flags) 60static inline int nfs_have_delegation(struct inode *inode, int flags)
52{ 61{
53 return 0; 62 return 0;
54} 63}
64
65static inline int nfs_inode_return_delegation(struct inode *inode)
66{
67 return 0;
68}
55#endif 69#endif
56 70
57#endif 71#endif
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ac331d2d4c4a..72f50c0117b1 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -801,6 +801,7 @@ static int nfs_dentry_delete(struct dentry *dentry)
801 */ 801 */
802static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) 802static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
803{ 803{
804 nfs_inode_return_delegation(inode);
804 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { 805 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
805 lock_kernel(); 806 lock_kernel();
806 inode->i_nlink--; 807 inode->i_nlink--;
@@ -1329,6 +1330,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1329 1330
1330 nfs_begin_data_update(dir); 1331 nfs_begin_data_update(dir);
1331 if (inode != NULL) { 1332 if (inode != NULL) {
1333 nfs_inode_return_delegation(inode);
1332 nfs_begin_data_update(inode); 1334 nfs_begin_data_update(inode);
1333 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1335 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
1334 /* The VFS may want to delete this inode */ 1336 /* The VFS may want to delete this inode */
@@ -1547,6 +1549,7 @@ go_ahead:
1547 nfs_wb_all(old_inode); 1549 nfs_wb_all(old_inode);
1548 shrink_dcache_parent(old_dentry); 1550 shrink_dcache_parent(old_dentry);
1549 } 1551 }
1552 nfs_inode_return_delegation(old_inode);
1550 1553
1551 if (new_inode) 1554 if (new_inode)
1552 d_delete(new_dentry); 1555 d_delete(new_dentry);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d7abaa00473a..6b0f7fe6bd1d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1671,8 +1671,7 @@ static void nfs4_clear_inode(struct inode *inode)
1671 struct nfs_inode *nfsi = NFS_I(inode); 1671 struct nfs_inode *nfsi = NFS_I(inode);
1672 1672
1673 /* If we are holding a delegation, return it! */ 1673 /* If we are holding a delegation, return it! */
1674 if (nfsi->delegation != NULL) 1674 nfs_inode_return_delegation(inode);
1675 nfs_inode_return_delegation(inode);
1676 /* First call standard NFS clear_inode() code */ 1675 /* First call standard NFS clear_inode() code */
1677 nfs_clear_inode(inode); 1676 nfs_clear_inode(inode);
1678 /* Now clear out any remaining state */ 1677 /* Now clear out any remaining state */