diff options
author | Christoph Hellwig <hch@lst.de> | 2015-04-28 09:41:15 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2015-05-04 12:02:38 -0400 |
commit | ebe9cb3bb13e7b9b281969cd279ce70834f7500f (patch) | |
tree | 36b7416e6f7bcf4dd5c607fb1f6bbfe831420658 /fs/nfsd/nfs4state.c | |
parent | 40cdc7a530c7a075557651a071354bb42b99df08 (diff) |
nfsd: fix the check for confirmed openowner in nfs4_preprocess_stateid_op
If we find a non-confirmed openowner we jump to exit the function, but do
not set an error value. Fix this by factoring out a helper to do the
check and properly set the error from nfsd4_validate_stateid.
Cc: stable@vger.kernel.org
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 38f2d7abe3a7..fb8c66725035 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -4385,10 +4385,17 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s | |||
4385 | return nfserr_old_stateid; | 4385 | return nfserr_old_stateid; |
4386 | } | 4386 | } |
4387 | 4387 | ||
4388 | static __be32 nfsd4_check_openowner_confirmed(struct nfs4_ol_stateid *ols) | ||
4389 | { | ||
4390 | if (ols->st_stateowner->so_is_open_owner && | ||
4391 | !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) | ||
4392 | return nfserr_bad_stateid; | ||
4393 | return nfs_ok; | ||
4394 | } | ||
4395 | |||
4388 | static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) | 4396 | static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) |
4389 | { | 4397 | { |
4390 | struct nfs4_stid *s; | 4398 | struct nfs4_stid *s; |
4391 | struct nfs4_ol_stateid *ols; | ||
4392 | __be32 status = nfserr_bad_stateid; | 4399 | __be32 status = nfserr_bad_stateid; |
4393 | 4400 | ||
4394 | if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) | 4401 | if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) |
@@ -4418,13 +4425,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) | |||
4418 | break; | 4425 | break; |
4419 | case NFS4_OPEN_STID: | 4426 | case NFS4_OPEN_STID: |
4420 | case NFS4_LOCK_STID: | 4427 | case NFS4_LOCK_STID: |
4421 | ols = openlockstateid(s); | 4428 | status = nfsd4_check_openowner_confirmed(openlockstateid(s)); |
4422 | if (ols->st_stateowner->so_is_open_owner | ||
4423 | && !(openowner(ols->st_stateowner)->oo_flags | ||
4424 | & NFS4_OO_CONFIRMED)) | ||
4425 | status = nfserr_bad_stateid; | ||
4426 | else | ||
4427 | status = nfs_ok; | ||
4428 | break; | 4429 | break; |
4429 | default: | 4430 | default: |
4430 | printk("unknown stateid type %x\n", s->sc_type); | 4431 | printk("unknown stateid type %x\n", s->sc_type); |
@@ -4516,8 +4517,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate, | |||
4516 | status = nfs4_check_fh(current_fh, stp); | 4517 | status = nfs4_check_fh(current_fh, stp); |
4517 | if (status) | 4518 | if (status) |
4518 | goto out; | 4519 | goto out; |
4519 | if (stp->st_stateowner->so_is_open_owner | 4520 | status = nfsd4_check_openowner_confirmed(stp); |
4520 | && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED)) | 4521 | if (status) |
4521 | goto out; | 4522 | goto out; |
4522 | status = nfs4_check_openmode(stp, flags); | 4523 | status = nfs4_check_openmode(stp, flags); |
4523 | if (status) | 4524 | if (status) |