Skip to content

Commit 2282cd2

Browse files
kinglongmeeJ. Bruce Fields
authored andcommitted
NFSD: Get response size before operation for all RPCs
NFSD usess PAGE_SIZE as the reply size estimate for RPCs which don't support op_rsize_bop(), A PAGE_SIZE (4096) is larger than many real response sizes, eg, access (op_encode_hdr_size + 2), seek (op_encode_hdr_size + 3). This patch just adds op_rsize_bop() for all RPCs getting response size. An overestimate is generally safe but the tighter estimates are probably better. Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 8274338 commit 2282cd2

File tree

1 file changed

+63
-6
lines changed

1 file changed

+63
-6
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,12 @@ static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd
18421842
return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
18431843
}
18441844

1845+
static inline u32 nfsd4_access_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1846+
{
1847+
/* ac_supported, ac_resp_access */
1848+
return (op_encode_hdr_size + 2)* sizeof(__be32);
1849+
}
1850+
18451851
static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
18461852
{
18471853
return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
@@ -1896,6 +1902,11 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
18961902
return ret;
18971903
}
18981904

1905+
static inline u32 nfsd4_getfh_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1906+
{
1907+
return (op_encode_hdr_size + 1) * sizeof(__be32) + NFS4_FHSIZE;
1908+
}
1909+
18991910
static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
19001911
{
19011912
return (op_encode_hdr_size + op_encode_change_info_maxsz)
@@ -1937,6 +1948,11 @@ static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o
19371948
XDR_QUADLEN(rlen)) * sizeof(__be32);
19381949
}
19391950

1951+
static inline u32 nfsd4_readlink_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1952+
{
1953+
return (op_encode_hdr_size + 1) * sizeof(__be32) + PAGE_SIZE;
1954+
}
1955+
19401956
static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
19411957
{
19421958
return (op_encode_hdr_size + op_encode_change_info_maxsz)
@@ -1956,11 +1972,23 @@ static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
19561972
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) * sizeof(__be32);
19571973
}
19581974

1975+
static inline u32 nfsd4_test_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1976+
{
1977+
return (op_encode_hdr_size + 1 + op->u.test_stateid.ts_num_ids)
1978+
* sizeof(__be32);
1979+
}
1980+
19591981
static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
19601982
{
19611983
return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
19621984
}
19631985

1986+
static inline u32 nfsd4_secinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1987+
{
1988+
return (op_encode_hdr_size + RPC_AUTH_MAXFLAVOR *
1989+
(4 + XDR_QUADLEN(GSS_OID_MAX_LEN))) * sizeof(__be32);
1990+
}
1991+
19641992
static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
19651993
{
19661994
return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) *
@@ -2015,6 +2043,19 @@ static inline u32 nfsd4_copy_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
20152043
}
20162044

20172045
#ifdef CONFIG_NFSD_PNFS
2046+
static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
2047+
{
2048+
u32 maxcount = 0, rlen = 0;
2049+
2050+
maxcount = svc_max_payload(rqstp);
2051+
rlen = min(op->u.getdeviceinfo.gd_maxcount, maxcount);
2052+
2053+
return (op_encode_hdr_size +
2054+
1 /* gd_layout_type*/ +
2055+
XDR_QUADLEN(rlen) +
2056+
2 /* gd_notify_types */) * sizeof(__be32);
2057+
}
2058+
20182059
/*
20192060
* At this stage we don't really know what layout driver will handle the request,
20202061
* so we need to define an arbitrary upper bound here.
@@ -2044,10 +2085,17 @@ static inline u32 nfsd4_layoutreturn_rsize(struct svc_rqst *rqstp, struct nfsd4_
20442085
}
20452086
#endif /* CONFIG_NFSD_PNFS */
20462087

2088+
2089+
static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
2090+
{
2091+
return (op_encode_hdr_size + 3) * sizeof(__be32);
2092+
}
2093+
20472094
static struct nfsd4_operation nfsd4_ops[] = {
20482095
[OP_ACCESS] = {
20492096
.op_func = (nfsd4op_func)nfsd4_access,
20502097
.op_name = "OP_ACCESS",
2098+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_access_rsize,
20512099
},
20522100
[OP_CLOSE] = {
20532101
.op_func = (nfsd4op_func)nfsd4_close,
@@ -2085,6 +2133,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
20852133
[OP_GETFH] = {
20862134
.op_func = (nfsd4op_func)nfsd4_getfh,
20872135
.op_name = "OP_GETFH",
2136+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_getfh_rsize,
20882137
},
20892138
[OP_LINK] = {
20902139
.op_func = (nfsd4op_func)nfsd4_link,
@@ -2103,6 +2152,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
21032152
[OP_LOCKT] = {
21042153
.op_func = (nfsd4op_func)nfsd4_lockt,
21052154
.op_name = "OP_LOCKT",
2155+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
21062156
},
21072157
[OP_LOCKU] = {
21082158
.op_func = (nfsd4op_func)nfsd4_locku,
@@ -2115,15 +2165,18 @@ static struct nfsd4_operation nfsd4_ops[] = {
21152165
.op_func = (nfsd4op_func)nfsd4_lookup,
21162166
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
21172167
.op_name = "OP_LOOKUP",
2168+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
21182169
},
21192170
[OP_LOOKUPP] = {
21202171
.op_func = (nfsd4op_func)nfsd4_lookupp,
21212172
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
21222173
.op_name = "OP_LOOKUPP",
2174+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
21232175
},
21242176
[OP_NVERIFY] = {
21252177
.op_func = (nfsd4op_func)nfsd4_nverify,
21262178
.op_name = "OP_NVERIFY",
2179+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
21272180
},
21282181
[OP_OPEN] = {
21292182
.op_func = (nfsd4op_func)nfsd4_open,
@@ -2181,6 +2234,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
21812234
[OP_READLINK] = {
21822235
.op_func = (nfsd4op_func)nfsd4_readlink,
21832236
.op_name = "OP_READLINK",
2237+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_readlink_rsize,
21842238
},
21852239
[OP_REMOVE] = {
21862240
.op_func = (nfsd4op_func)nfsd4_remove,
@@ -2219,6 +2273,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
22192273
.op_func = (nfsd4op_func)nfsd4_secinfo,
22202274
.op_flags = OP_HANDLES_WRONGSEC,
22212275
.op_name = "OP_SECINFO",
2276+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize,
22222277
},
22232278
[OP_SETATTR] = {
22242279
.op_func = (nfsd4op_func)nfsd4_setattr,
@@ -2244,6 +2299,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
22442299
[OP_VERIFY] = {
22452300
.op_func = (nfsd4op_func)nfsd4_verify,
22462301
.op_name = "OP_VERIFY",
2302+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
22472303
},
22482304
[OP_WRITE] = {
22492305
.op_func = (nfsd4op_func)nfsd4_write,
@@ -2318,11 +2374,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
23182374
.op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
23192375
.op_flags = OP_HANDLES_WRONGSEC,
23202376
.op_name = "OP_SECINFO_NO_NAME",
2377+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize,
23212378
},
23222379
[OP_TEST_STATEID] = {
23232380
.op_func = (nfsd4op_func)nfsd4_test_stateid,
23242381
.op_flags = ALLOWED_WITHOUT_FH,
23252382
.op_name = "OP_TEST_STATEID",
2383+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_test_stateid_rsize,
23262384
},
23272385
[OP_FREE_STATEID] = {
23282386
.op_func = (nfsd4op_func)nfsd4_free_stateid,
@@ -2336,6 +2394,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
23362394
.op_func = (nfsd4op_func)nfsd4_getdeviceinfo,
23372395
.op_flags = ALLOWED_WITHOUT_FH,
23382396
.op_name = "OP_GETDEVICEINFO",
2397+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_getdeviceinfo_rsize,
23392398
},
23402399
[OP_LAYOUTGET] = {
23412400
.op_func = (nfsd4op_func)nfsd4_layoutget,
@@ -2385,6 +2444,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
23852444
[OP_SEEK] = {
23862445
.op_func = (nfsd4op_func)nfsd4_seek,
23872446
.op_name = "OP_SEEK",
2447+
.op_rsize_bop = (nfsd4op_rsize)nfsd4_seek_rsize,
23882448
},
23892449
};
23902450

@@ -2429,14 +2489,11 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
24292489

24302490
int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
24312491
{
2432-
struct nfsd4_operation *opdesc;
2433-
nfsd4op_rsize estimator;
2434-
24352492
if (op->opnum == OP_ILLEGAL)
24362493
return op_encode_hdr_size * sizeof(__be32);
2437-
opdesc = OPDESC(op);
2438-
estimator = opdesc->op_rsize_bop;
2439-
return estimator ? estimator(rqstp, op) : PAGE_SIZE;
2494+
2495+
BUG_ON(OPDESC(op)->op_rsize_bop == NULL);
2496+
return OPDESC(op)->op_rsize_bop(rqstp, op);
24402497
}
24412498

24422499
void warn_on_nonidempotent_op(struct nfsd4_op *op)

0 commit comments

Comments
 (0)