Commit db4f2e63 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Clean up delegation recall error handling

Unify the error handling in nfs4_open_delegation_recall and
nfs4_lock_delegation_recall.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent be76b5b6
...@@ -64,7 +64,7 @@ int nfs4_have_delegation(struct inode *inode, fmode_t flags) ...@@ -64,7 +64,7 @@ int nfs4_have_delegation(struct inode *inode, fmode_t flags)
return ret; return ret;
} }
static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
{ {
struct inode *inode = state->inode; struct inode *inode = state->inode;
struct file_lock *fl; struct file_lock *fl;
...@@ -83,7 +83,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ ...@@ -83,7 +83,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
if (nfs_file_open_context(fl->fl_file) != ctx) if (nfs_file_open_context(fl->fl_file) != ctx)
continue; continue;
unlock_flocks(); unlock_flocks();
status = nfs4_lock_delegation_recall(state, fl); status = nfs4_lock_delegation_recall(fl, state, stateid);
if (status < 0) if (status < 0)
goto out; goto out;
lock_flocks(); lock_flocks();
...@@ -120,7 +120,7 @@ static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *s ...@@ -120,7 +120,7 @@ static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *s
seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
err = nfs4_open_delegation_recall(ctx, state, stateid); err = nfs4_open_delegation_recall(ctx, state, stateid);
if (!err) if (!err)
err = nfs_delegation_claim_locks(ctx, state); err = nfs_delegation_claim_locks(ctx, state, stateid);
if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
err = -EAGAIN; err = -EAGAIN;
mutex_unlock(&sp->so_delegreturn_mutex); mutex_unlock(&sp->so_delegreturn_mutex);
......
...@@ -53,7 +53,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp); ...@@ -53,7 +53,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
/* NFSv4 delegation-related procedures */ /* NFSv4 delegation-related procedures */
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync);
int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid);
bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags); bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_t flags);
void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
......
...@@ -1379,19 +1379,8 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta ...@@ -1379,19 +1379,8 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
return ret; return ret;
} }
int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct nfs4_state *state, const nfs4_stateid *stateid, int err)
{ {
struct nfs_server *server = NFS_SERVER(state->inode);
struct nfs4_opendata *opendata;
int err;
opendata = nfs4_open_recoverdata_alloc(ctx, state,
NFS4_OPEN_CLAIM_DELEG_CUR_FH);
if (IS_ERR(opendata))
return PTR_ERR(opendata);
nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
err = nfs4_open_recover(opendata, state);
nfs4_opendata_put(opendata);
switch (err) { switch (err) {
default: default:
printk(KERN_ERR "NFS: %s: unhandled error " printk(KERN_ERR "NFS: %s: unhandled error "
...@@ -1418,20 +1407,40 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state ...@@ -1418,20 +1407,40 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
case -NFS4ERR_DELEG_REVOKED: case -NFS4ERR_DELEG_REVOKED:
case -NFS4ERR_ADMIN_REVOKED: case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_BAD_STATEID: case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_OPENMODE:
nfs_inode_find_state_and_recover(state->inode, nfs_inode_find_state_and_recover(state->inode,
stateid); stateid);
nfs4_schedule_stateid_recovery(server, state); nfs4_schedule_stateid_recovery(server, state);
case -ENOMEM:
return 0; return 0;
case -NFS4ERR_DELAY: case -NFS4ERR_DELAY:
case -NFS4ERR_GRACE: case -NFS4ERR_GRACE:
set_bit(NFS_DELEGATED_STATE, &state->flags); set_bit(NFS_DELEGATED_STATE, &state->flags);
ssleep(1); ssleep(1);
return -EAGAIN; return -EAGAIN;
case -ENOMEM:
case -NFS4ERR_DENIED:
/* kill_proc(fl->fl_pid, SIGLOST, 1); */
return 0;
} }
return err; return err;
} }
int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
{
struct nfs_server *server = NFS_SERVER(state->inode);
struct nfs4_opendata *opendata;
int err;
opendata = nfs4_open_recoverdata_alloc(ctx, state,
NFS4_OPEN_CLAIM_DELEG_CUR_FH);
if (IS_ERR(opendata))
return PTR_ERR(opendata);
nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
err = nfs4_open_recover(opendata, state);
nfs4_opendata_put(opendata);
return nfs4_handle_delegation_recall_error(server, state, stateid, err);
}
static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
{ {
struct nfs4_opendata *data = calldata; struct nfs4_opendata *data = calldata;
...@@ -5127,54 +5136,16 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) ...@@ -5127,54 +5136,16 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
return status; return status;
} }
int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid)
{ {
struct nfs_server *server = NFS_SERVER(state->inode); struct nfs_server *server = NFS_SERVER(state->inode);
int err; int err;
err = nfs4_set_lock_state(state, fl); err = nfs4_set_lock_state(state, fl);
if (err != 0) if (err != 0)
goto out;
err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
switch (err) {
default:
printk(KERN_ERR "NFS: %s: unhandled error "
"%d.\n", __func__, err);
case 0:
case -ESTALE:
goto out;
case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_STALE_STATEID:
set_bit(NFS_DELEGATED_STATE, &state->flags);
case -NFS4ERR_EXPIRED:
nfs4_schedule_lease_recovery(server->nfs_client);
return -EAGAIN;
case -NFS4ERR_BADSESSION:
case -NFS4ERR_BADSLOT:
case -NFS4ERR_BAD_HIGH_SLOT:
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
case -NFS4ERR_DEADSESSION:
set_bit(NFS_DELEGATED_STATE, &state->flags);
nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
return -EAGAIN;
case -NFS4ERR_DELEG_REVOKED:
case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_OPENMODE:
nfs4_schedule_stateid_recovery(server, state);
return 0;
case -NFS4ERR_DELAY:
case -NFS4ERR_GRACE:
set_bit(NFS_DELEGATED_STATE, &state->flags);
ssleep(1);
return -EAGAIN;
case -ENOMEM:
case -NFS4ERR_DENIED:
/* kill_proc(fl->fl_pid, SIGLOST, 1); */
return 0;
}
out:
return err; return err;
err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
return nfs4_handle_delegation_recall_error(server, state, stateid, err);
} }
struct nfs_release_lockowner_data { struct nfs_release_lockowner_data {
......
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