NFSv4: Recover locks too when returning a delegation
Delegations allow us to cache posix and BSD locks, however when the delegation is recalled, we need to "flush the cache" and send the cached LOCK requests to the server. This patch sets up the mechanism for doing so. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
@ -31,11 +31,42 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
|
||||
kfree(delegation);
|
||||
}
|
||||
|
||||
static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
|
||||
{
|
||||
struct inode *inode = state->inode;
|
||||
struct file_lock *fl;
|
||||
int status;
|
||||
|
||||
for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
|
||||
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
|
||||
continue;
|
||||
if ((struct nfs_open_context *)fl->fl_file->private_data != ctx)
|
||||
continue;
|
||||
status = nfs4_lock_delegation_recall(state, fl);
|
||||
if (status >= 0)
|
||||
continue;
|
||||
switch (status) {
|
||||
default:
|
||||
printk(KERN_ERR "%s: unhandled error %d.\n",
|
||||
__FUNCTION__, status);
|
||||
case -NFS4ERR_EXPIRED:
|
||||
/* kill_proc(fl->fl_pid, SIGLOST, 1); */
|
||||
case -NFS4ERR_STALE_CLIENTID:
|
||||
nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state);
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
out_err:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void nfs_delegation_claim_opens(struct inode *inode)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct nfs_open_context *ctx;
|
||||
struct nfs4_state *state;
|
||||
int err;
|
||||
|
||||
again:
|
||||
spin_lock(&inode->i_lock);
|
||||
@ -47,9 +78,12 @@ again:
|
||||
continue;
|
||||
get_nfs_open_context(ctx);
|
||||
spin_unlock(&inode->i_lock);
|
||||
if (nfs4_open_delegation_recall(ctx->dentry, state) < 0)
|
||||
return;
|
||||
err = nfs4_open_delegation_recall(ctx->dentry, state);
|
||||
if (err >= 0)
|
||||
err = nfs_delegation_claim_locks(ctx, state);
|
||||
put_nfs_open_context(ctx);
|
||||
if (err != 0)
|
||||
return;
|
||||
goto again;
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
Reference in New Issue
Block a user