summaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2017-05-05 17:09:37 -0400
committerJ. Bruce Fields <bfields@redhat.com>2017-08-24 22:12:48 -0400
commit34b1744c91ccd44811005822106945fa80ecbff2 (patch)
treebcfe6172004c09e2b0a5966fb6bb66855169bb32 /fs/nfsd
parentf4f9ef4a1b0a1ca80b152e28e176d69515bdf7e8 (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.c32
-rw-r--r--fs/nfsd/nfs4xdr.c9
-rw-r--r--fs/nfsd/xdr4.h1
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
788static void
789nfsd4_read_release(union nfsd4_op_u *u)
790{
791 if (u->read.rd_filp)
792 fput(u->read.rd_filp);
793}
794
787static __be32 795static __be32
788nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 796nfsd4_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
923static void
924nfsd4_secinfo_release(union nfsd4_op_u *u)
925{
926 if (u->secinfo.si_exp)
927 exp_put(u->secinfo.si_exp);
928}
929
915static __be32 930static __be32
916nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 931nfsd4_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
1353static void
1354nfsd4_getdeviceinfo_release(union nfsd4_op_u *u)
1355{
1356 kfree(u->getdeviceinfo.gd_device);
1357}
1358
1338static __be32 1359static __be32
1339nfsd4_layoutget(struct svc_rqst *rqstp, 1360nfsd4_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
1439static void
1440nfsd4_layoutget_release(union nfsd4_op_u *u)
1441{
1442 kfree(u->layoutget.lg_content);
1443}
1444
1418static __be32 1445static __be32
1419nfsd4_layoutcommit(struct svc_rqst *rqstp, 1446nfsd4_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
3595out: 3595out:
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;
3840out: 3838out:
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;
4174out: 4170out:
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);
4223out: 4218out:
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 {
783struct nfsd4_operation { 783struct 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 */