diff options
author | J. Bruce Fields <bfields@redhat.com> | 2017-05-05 17:09:37 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2017-08-24 22:12:48 -0400 |
commit | 34b1744c91ccd44811005822106945fa80ecbff2 (patch) | |
tree | bcfe6172004c09e2b0a5966fb6bb66855169bb32 /fs/nfsd | |
parent | f4f9ef4a1b0a1ca80b152e28e176d69515bdf7e8 (diff) |
nfsd4: define ->op_release for compound ops
Run a separate ->op_release function if necessary instead of depending
on the xdr encoder to do this.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 32 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 9 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 1 |
3 files changed, 36 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 01d7f2456f62..ac53ae2435c5 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -784,6 +784,14 @@ out: | |||
784 | return status; | 784 | return status; |
785 | } | 785 | } |
786 | 786 | ||
787 | |||
788 | static void | ||
789 | nfsd4_read_release(union nfsd4_op_u *u) | ||
790 | { | ||
791 | if (u->read.rd_filp) | ||
792 | fput(u->read.rd_filp); | ||
793 | } | ||
794 | |||
787 | static __be32 | 795 | static __be32 |
788 | nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 796 | nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
789 | union nfsd4_op_u *u) | 797 | union nfsd4_op_u *u) |
@@ -912,6 +920,13 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat | |||
912 | return nfs_ok; | 920 | return nfs_ok; |
913 | } | 921 | } |
914 | 922 | ||
923 | static void | ||
924 | nfsd4_secinfo_release(union nfsd4_op_u *u) | ||
925 | { | ||
926 | if (u->secinfo.si_exp) | ||
927 | exp_put(u->secinfo.si_exp); | ||
928 | } | ||
929 | |||
915 | static __be32 | 930 | static __be32 |
916 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 931 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
917 | union nfsd4_op_u *u) | 932 | union nfsd4_op_u *u) |
@@ -1335,6 +1350,12 @@ out: | |||
1335 | return nfserr; | 1350 | return nfserr; |
1336 | } | 1351 | } |
1337 | 1352 | ||
1353 | static void | ||
1354 | nfsd4_getdeviceinfo_release(union nfsd4_op_u *u) | ||
1355 | { | ||
1356 | kfree(u->getdeviceinfo.gd_device); | ||
1357 | } | ||
1358 | |||
1338 | static __be32 | 1359 | static __be32 |
1339 | nfsd4_layoutget(struct svc_rqst *rqstp, | 1360 | nfsd4_layoutget(struct svc_rqst *rqstp, |
1340 | struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) | 1361 | struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) |
@@ -1415,6 +1436,12 @@ out: | |||
1415 | return nfserr; | 1436 | return nfserr; |
1416 | } | 1437 | } |
1417 | 1438 | ||
1439 | static void | ||
1440 | nfsd4_layoutget_release(union nfsd4_op_u *u) | ||
1441 | { | ||
1442 | kfree(u->layoutget.lg_content); | ||
1443 | } | ||
1444 | |||
1418 | static __be32 | 1445 | static __be32 |
1419 | nfsd4_layoutcommit(struct svc_rqst *rqstp, | 1446 | nfsd4_layoutcommit(struct svc_rqst *rqstp, |
1420 | struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) | 1447 | struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) |
@@ -2192,6 +2219,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { | |||
2192 | }, | 2219 | }, |
2193 | [OP_READ] = { | 2220 | [OP_READ] = { |
2194 | .op_func = nfsd4_read, | 2221 | .op_func = nfsd4_read, |
2222 | .op_release = nfsd4_read_release, | ||
2195 | .op_name = "OP_READ", | 2223 | .op_name = "OP_READ", |
2196 | .op_rsize_bop = nfsd4_read_rsize, | 2224 | .op_rsize_bop = nfsd4_read_rsize, |
2197 | .op_get_currentstateid = nfsd4_get_readstateid, | 2225 | .op_get_currentstateid = nfsd4_get_readstateid, |
@@ -2241,6 +2269,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { | |||
2241 | }, | 2269 | }, |
2242 | [OP_SECINFO] = { | 2270 | [OP_SECINFO] = { |
2243 | .op_func = nfsd4_secinfo, | 2271 | .op_func = nfsd4_secinfo, |
2272 | .op_release = nfsd4_secinfo_release, | ||
2244 | .op_flags = OP_HANDLES_WRONGSEC, | 2273 | .op_flags = OP_HANDLES_WRONGSEC, |
2245 | .op_name = "OP_SECINFO", | 2274 | .op_name = "OP_SECINFO", |
2246 | .op_rsize_bop = nfsd4_secinfo_rsize, | 2275 | .op_rsize_bop = nfsd4_secinfo_rsize, |
@@ -2342,6 +2371,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { | |||
2342 | }, | 2371 | }, |
2343 | [OP_SECINFO_NO_NAME] = { | 2372 | [OP_SECINFO_NO_NAME] = { |
2344 | .op_func = nfsd4_secinfo_no_name, | 2373 | .op_func = nfsd4_secinfo_no_name, |
2374 | .op_release = nfsd4_secinfo_release, | ||
2345 | .op_flags = OP_HANDLES_WRONGSEC, | 2375 | .op_flags = OP_HANDLES_WRONGSEC, |
2346 | .op_name = "OP_SECINFO_NO_NAME", | 2376 | .op_name = "OP_SECINFO_NO_NAME", |
2347 | .op_rsize_bop = nfsd4_secinfo_rsize, | 2377 | .op_rsize_bop = nfsd4_secinfo_rsize, |
@@ -2362,12 +2392,14 @@ static const struct nfsd4_operation nfsd4_ops[] = { | |||
2362 | #ifdef CONFIG_NFSD_PNFS | 2392 | #ifdef CONFIG_NFSD_PNFS |
2363 | [OP_GETDEVICEINFO] = { | 2393 | [OP_GETDEVICEINFO] = { |
2364 | .op_func = nfsd4_getdeviceinfo, | 2394 | .op_func = nfsd4_getdeviceinfo, |
2395 | .op_release = nfsd4_getdeviceinfo_release, | ||
2365 | .op_flags = ALLOWED_WITHOUT_FH, | 2396 | .op_flags = ALLOWED_WITHOUT_FH, |
2366 | .op_name = "OP_GETDEVICEINFO", | 2397 | .op_name = "OP_GETDEVICEINFO", |
2367 | .op_rsize_bop = nfsd4_getdeviceinfo_rsize, | 2398 | .op_rsize_bop = nfsd4_getdeviceinfo_rsize, |
2368 | }, | 2399 | }, |
2369 | [OP_LAYOUTGET] = { | 2400 | [OP_LAYOUTGET] = { |
2370 | .op_func = nfsd4_layoutget, | 2401 | .op_func = nfsd4_layoutget, |
2402 | .op_release = nfsd4_layoutget_release, | ||
2371 | .op_flags = OP_MODIFIES_SOMETHING, | 2403 | .op_flags = OP_MODIFIES_SOMETHING, |
2372 | .op_name = "OP_LAYOUTGET", | 2404 | .op_name = "OP_LAYOUTGET", |
2373 | .op_rsize_bop = nfsd4_layoutget_rsize, | 2405 | .op_rsize_bop = nfsd4_layoutget_rsize, |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 40ed23fda814..7d683e3aebf0 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -3593,8 +3593,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
3593 | xdr_truncate_encode(xdr, starting_len); | 3593 | xdr_truncate_encode(xdr, starting_len); |
3594 | 3594 | ||
3595 | out: | 3595 | out: |
3596 | if (file) | ||
3597 | fput(file); | ||
3598 | return nfserr; | 3596 | return nfserr; |
3599 | } | 3597 | } |
3600 | 3598 | ||
@@ -3838,8 +3836,6 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, | |||
3838 | *flavorsp = htonl(supported); | 3836 | *flavorsp = htonl(supported); |
3839 | nfserr = 0; | 3837 | nfserr = 0; |
3840 | out: | 3838 | out: |
3841 | if (exp) | ||
3842 | exp_put(exp); | ||
3843 | return nfserr; | 3839 | return nfserr; |
3844 | } | 3840 | } |
3845 | 3841 | ||
@@ -4172,7 +4168,6 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
4172 | 4168 | ||
4173 | nfserr = 0; | 4169 | nfserr = 0; |
4174 | out: | 4170 | out: |
4175 | kfree(gdev->gd_device); | ||
4176 | dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr)); | 4171 | dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr)); |
4177 | return nfserr; | 4172 | return nfserr; |
4178 | 4173 | ||
@@ -4221,7 +4216,6 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
4221 | ops = nfsd4_layout_ops[lgp->lg_layout_type]; | 4216 | ops = nfsd4_layout_ops[lgp->lg_layout_type]; |
4222 | nfserr = ops->encode_layoutget(xdr, lgp); | 4217 | nfserr = ops->encode_layoutget(xdr, lgp); |
4223 | out: | 4218 | out: |
4224 | kfree(lgp->lg_content); | ||
4225 | return nfserr; | 4219 | return nfserr; |
4226 | } | 4220 | } |
4227 | 4221 | ||
@@ -4452,6 +4446,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) | |||
4452 | struct xdr_stream *xdr = &resp->xdr; | 4446 | struct xdr_stream *xdr = &resp->xdr; |
4453 | struct nfs4_stateowner *so = resp->cstate.replay_owner; | 4447 | struct nfs4_stateowner *so = resp->cstate.replay_owner; |
4454 | struct svc_rqst *rqstp = resp->rqstp; | 4448 | struct svc_rqst *rqstp = resp->rqstp; |
4449 | const struct nfsd4_operation *opdesc = op->opdesc; | ||
4455 | int post_err_offset; | 4450 | int post_err_offset; |
4456 | nfsd4_enc encoder; | 4451 | nfsd4_enc encoder; |
4457 | __be32 *p; | 4452 | __be32 *p; |
@@ -4470,6 +4465,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) | |||
4470 | !nfsd4_enc_ops[op->opnum]); | 4465 | !nfsd4_enc_ops[op->opnum]); |
4471 | encoder = nfsd4_enc_ops[op->opnum]; | 4466 | encoder = nfsd4_enc_ops[op->opnum]; |
4472 | op->status = encoder(resp, op->status, &op->u); | 4467 | op->status = encoder(resp, op->status, &op->u); |
4468 | if (opdesc && opdesc->op_release) | ||
4469 | opdesc->op_release(&op->u); | ||
4473 | xdr_commit_encode(xdr); | 4470 | xdr_commit_encode(xdr); |
4474 | 4471 | ||
4475 | /* nfsd4_check_resp_size guarantees enough room for error status */ | 4472 | /* nfsd4_check_resp_size guarantees enough room for error status */ |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 90b928006bc7..1e6274e0e066 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -783,6 +783,7 @@ enum nfsd4_op_flags { | |||
783 | struct nfsd4_operation { | 783 | struct nfsd4_operation { |
784 | __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, | 784 | __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, |
785 | union nfsd4_op_u *); | 785 | union nfsd4_op_u *); |
786 | void (*op_release)(union nfsd4_op_u *); | ||
786 | u32 op_flags; | 787 | u32 op_flags; |
787 | char *op_name; | 788 | char *op_name; |
788 | /* Try to get response size before operation */ | 789 | /* Try to get response size before operation */ |