delegation.c | 2 +- delegation.h | 1 + nfs4proc.c | 21 ++++++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.7-16-delegation_cache/fs/nfs/delegation.c linux-2.6.7-17-delegation_reclaim/fs/nfs/delegation.c --- linux-2.6.7-16-delegation_cache/fs/nfs/delegation.c 2004-06-10 00:39:04.000000000 -0400 +++ linux-2.6.7-17-delegation_reclaim/fs/nfs/delegation.c 2004-06-10 01:00:39.000000000 -0400 @@ -67,7 +67,7 @@ again: /* * Inform the world that we no longer possess a delegation */ -static int nfs_inode_clear_delegation(struct inode *inode) +int nfs_inode_clear_delegation(struct inode *inode) { struct nfs_delegation *delegation = &NFS_I(inode)->delegation; struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; diff -u --recursive --new-file --show-c-function linux-2.6.7-16-delegation_cache/fs/nfs/delegation.h linux-2.6.7-17-delegation_reclaim/fs/nfs/delegation.h --- linux-2.6.7-16-delegation_cache/fs/nfs/delegation.h 2004-06-10 00:39:17.000000000 -0400 +++ linux-2.6.7-17-delegation_reclaim/fs/nfs/delegation.h 2004-06-10 01:01:19.000000000 -0400 @@ -11,6 +11,7 @@ #if defined(CONFIG_NFS_V4) void nfs_inode_set_delegation(struct inode *inode, struct nfs_openres *res, long generation); +int nfs_inode_clear_delegation(struct inode *inode); int nfs_inode_return_delegation(struct inode *inode); int nfs_async_inode_return_delegation(struct nfs4_client *clp, struct inode *inode); diff -u --recursive --new-file --show-c-function linux-2.6.7-16-delegation_cache/fs/nfs/nfs4proc.c linux-2.6.7-17-delegation_reclaim/fs/nfs/nfs4proc.c --- linux-2.6.7-16-delegation_cache/fs/nfs/nfs4proc.c 2004-06-10 00:39:11.000000000 -0400 +++ linux-2.6.7-17-delegation_reclaim/fs/nfs/nfs4proc.c 2004-06-10 00:59:52.000000000 -0400 @@ -191,8 +191,7 @@ static void update_changeattr(struct ino * reclaim state on the server after a reboot. * Assumes caller is holding the sp->so_sem */ -int -nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) +static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) { struct inode *inode = state->inode; struct nfs_inode *nfsi = NFS_I(inode); @@ -229,13 +228,29 @@ nfs4_open_reclaim(struct nfs4_state_owne /* Did the server issue an immediate delegation recall? */ if (o_res.do_recall) nfs_async_inode_return_delegation(server->nfs4_state, inode); - } + } else + nfs_inode_clear_delegation(inode); } + clear_bit(NFS_DELEGATED_STATE, &state->flags); /* Ensure we update the inode attributes */ NFS_CACHEINV(inode); return status; } +int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) +{ + struct inode *inode = state->inode; + struct nfs_delegation *delegation = &NFS_I(inode)->delegation; + + if (!nfs_have_delegation(inode, state->state) + || sp->so_generation != delegation->generation) + return nfs4_do_open_reclaim(sp, state); + memcpy(&state->stateid.data, delegation->stateid.data, + sizeof(state->stateid.data)); + set_bit(NFS_DELEGATED_STATE, &state->flags); + return 0; +} + static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) { struct nfs4_state_owner *sp = state->owner;