diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-12-03 17:24:41 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-12-04 07:51:12 -0500 |
commit | 9b2ef62b1541f176ea1b1f6e13b16df14bb16e99 (patch) | |
tree | 29ffd5f501ba69dee44679e78b8e3dbd1cde91cc /fs/nfsd/nfs4state.c | |
parent | 836fbadb96a8308e6283eee5c7b3bdae818b58ca (diff) |
nfsd4: lockt, release_lockowner should renew clients
Fix nfsd4_lockt and release_lockowner to lookup the referenced client,
so that it can renew it, or correctly return "expired", as appropriate.
Also share some code while we're here.
Reported-by: Frank Filz <ffilzlnx@us.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index eff734033437..16e954c1c911 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -3132,6 +3132,18 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) | |||
3132 | free_generic_stateid(open->op_stp); | 3132 | free_generic_stateid(open->op_stp); |
3133 | } | 3133 | } |
3134 | 3134 | ||
3135 | static __be32 lookup_clientid(clientid_t *clid, bool session, struct nfsd_net *nn, struct nfs4_client **clp) | ||
3136 | { | ||
3137 | struct nfs4_client *found; | ||
3138 | |||
3139 | if (STALE_CLIENTID(clid, nn)) | ||
3140 | return nfserr_stale_clientid; | ||
3141 | found = find_confirmed_client(clid, session, nn); | ||
3142 | if (clp) | ||
3143 | *clp = found; | ||
3144 | return found ? nfs_ok : nfserr_expired; | ||
3145 | } | ||
3146 | |||
3135 | __be32 | 3147 | __be32 |
3136 | nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 3148 | nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
3137 | clientid_t *clid) | 3149 | clientid_t *clid) |
@@ -3143,16 +3155,9 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3143 | nfs4_lock_state(); | 3155 | nfs4_lock_state(); |
3144 | dprintk("process_renew(%08x/%08x): starting\n", | 3156 | dprintk("process_renew(%08x/%08x): starting\n", |
3145 | clid->cl_boot, clid->cl_id); | 3157 | clid->cl_boot, clid->cl_id); |
3146 | status = nfserr_stale_clientid; | 3158 | status = lookup_clientid(clid, cstate->minorversion, nn, &clp); |
3147 | if (STALE_CLIENTID(clid, nn)) | 3159 | if (status) |
3148 | goto out; | ||
3149 | clp = find_confirmed_client(clid, cstate->minorversion, nn); | ||
3150 | status = nfserr_expired; | ||
3151 | if (clp == NULL) { | ||
3152 | /* We assume the client took too long to RENEW. */ | ||
3153 | dprintk("nfsd4_renew: clientid not found!\n"); | ||
3154 | goto out; | 3160 | goto out; |
3155 | } | ||
3156 | status = nfserr_cb_path_down; | 3161 | status = nfserr_cb_path_down; |
3157 | if (!list_empty(&clp->cl_delegations) | 3162 | if (!list_empty(&clp->cl_delegations) |
3158 | && clp->cl_cb_state != NFSD4_CB_UP) | 3163 | && clp->cl_cb_state != NFSD4_CB_UP) |
@@ -4293,9 +4298,11 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
4293 | 4298 | ||
4294 | nfs4_lock_state(); | 4299 | nfs4_lock_state(); |
4295 | 4300 | ||
4296 | status = nfserr_stale_clientid; | 4301 | if (!nfsd4_has_session(cstate)) { |
4297 | if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid, nn)) | 4302 | status = lookup_clientid(&lockt->lt_clientid, false, nn, NULL); |
4298 | goto out; | 4303 | if (status) |
4304 | goto out; | ||
4305 | } | ||
4299 | 4306 | ||
4300 | if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) | 4307 | if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) |
4301 | goto out; | 4308 | goto out; |
@@ -4466,14 +4473,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, | |||
4466 | dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", | 4473 | dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", |
4467 | clid->cl_boot, clid->cl_id); | 4474 | clid->cl_boot, clid->cl_id); |
4468 | 4475 | ||
4469 | /* XXX check for lease expiration */ | ||
4470 | |||
4471 | status = nfserr_stale_clientid; | ||
4472 | if (STALE_CLIENTID(clid, nn)) | ||
4473 | return status; | ||
4474 | |||
4475 | nfs4_lock_state(); | 4476 | nfs4_lock_state(); |
4476 | 4477 | ||
4478 | status = lookup_clientid(clid, cstate->minorversion, nn, NULL); | ||
4479 | if (status) | ||
4480 | goto out; | ||
4481 | |||
4477 | status = nfserr_locks_held; | 4482 | status = nfserr_locks_held; |
4478 | INIT_LIST_HEAD(&matches); | 4483 | INIT_LIST_HEAD(&matches); |
4479 | 4484 | ||