提交 2282cd2c 编写于 作者: K Kinglong Mee 提交者: J. Bruce Fields

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: NKinglong Mee <kinglongmee@gmail.com>
Signed-off-by: NJ. Bruce Fields <bfields@redhat.com>
上级 82743380
...@@ -1842,6 +1842,12 @@ static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd ...@@ -1842,6 +1842,12 @@ static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd
return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32); return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
} }
static inline u32 nfsd4_access_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
/* ac_supported, ac_resp_access */
return (op_encode_hdr_size + 2)* sizeof(__be32);
}
static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 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, ...@@ -1896,6 +1902,11 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
return ret; return ret;
} }
static inline u32 nfsd4_getfh_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
return (op_encode_hdr_size + 1) * sizeof(__be32) + NFS4_FHSIZE;
}
static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
return (op_encode_hdr_size + op_encode_change_info_maxsz) 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 ...@@ -1937,6 +1948,11 @@ static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o
XDR_QUADLEN(rlen)) * sizeof(__be32); XDR_QUADLEN(rlen)) * sizeof(__be32);
} }
static inline u32 nfsd4_readlink_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
return (op_encode_hdr_size + 1) * sizeof(__be32) + PAGE_SIZE;
}
static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
return (op_encode_hdr_size + op_encode_change_info_maxsz) return (op_encode_hdr_size + op_encode_change_info_maxsz)
...@@ -1956,11 +1972,23 @@ static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp, ...@@ -1956,11 +1972,23 @@ static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) * sizeof(__be32); + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) * sizeof(__be32);
} }
static inline u32 nfsd4_test_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
return (op_encode_hdr_size + 1 + op->u.test_stateid.ts_num_ids)
* sizeof(__be32);
}
static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
} }
static inline u32 nfsd4_secinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
return (op_encode_hdr_size + RPC_AUTH_MAXFLAVOR *
(4 + XDR_QUADLEN(GSS_OID_MAX_LEN))) * sizeof(__be32);
}
static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) * 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) ...@@ -2015,6 +2043,19 @@ static inline u32 nfsd4_copy_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
} }
#ifdef CONFIG_NFSD_PNFS #ifdef CONFIG_NFSD_PNFS
static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
u32 maxcount = 0, rlen = 0;
maxcount = svc_max_payload(rqstp);
rlen = min(op->u.getdeviceinfo.gd_maxcount, maxcount);
return (op_encode_hdr_size +
1 /* gd_layout_type*/ +
XDR_QUADLEN(rlen) +
2 /* gd_notify_types */) * sizeof(__be32);
}
/* /*
* At this stage we don't really know what layout driver will handle the request, * At this stage we don't really know what layout driver will handle the request,
* so we need to define an arbitrary upper bound here. * 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_ ...@@ -2044,10 +2085,17 @@ static inline u32 nfsd4_layoutreturn_rsize(struct svc_rqst *rqstp, struct nfsd4_
} }
#endif /* CONFIG_NFSD_PNFS */ #endif /* CONFIG_NFSD_PNFS */
static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
{
return (op_encode_hdr_size + 3) * sizeof(__be32);
}
static struct nfsd4_operation nfsd4_ops[] = { static struct nfsd4_operation nfsd4_ops[] = {
[OP_ACCESS] = { [OP_ACCESS] = {
.op_func = (nfsd4op_func)nfsd4_access, .op_func = (nfsd4op_func)nfsd4_access,
.op_name = "OP_ACCESS", .op_name = "OP_ACCESS",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_access_rsize,
}, },
[OP_CLOSE] = { [OP_CLOSE] = {
.op_func = (nfsd4op_func)nfsd4_close, .op_func = (nfsd4op_func)nfsd4_close,
...@@ -2085,6 +2133,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2085,6 +2133,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
[OP_GETFH] = { [OP_GETFH] = {
.op_func = (nfsd4op_func)nfsd4_getfh, .op_func = (nfsd4op_func)nfsd4_getfh,
.op_name = "OP_GETFH", .op_name = "OP_GETFH",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_getfh_rsize,
}, },
[OP_LINK] = { [OP_LINK] = {
.op_func = (nfsd4op_func)nfsd4_link, .op_func = (nfsd4op_func)nfsd4_link,
...@@ -2103,6 +2152,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2103,6 +2152,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
[OP_LOCKT] = { [OP_LOCKT] = {
.op_func = (nfsd4op_func)nfsd4_lockt, .op_func = (nfsd4op_func)nfsd4_lockt,
.op_name = "OP_LOCKT", .op_name = "OP_LOCKT",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
}, },
[OP_LOCKU] = { [OP_LOCKU] = {
.op_func = (nfsd4op_func)nfsd4_locku, .op_func = (nfsd4op_func)nfsd4_locku,
...@@ -2115,15 +2165,18 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2115,15 +2165,18 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_func = (nfsd4op_func)nfsd4_lookup, .op_func = (nfsd4op_func)nfsd4_lookup,
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
.op_name = "OP_LOOKUP", .op_name = "OP_LOOKUP",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
}, },
[OP_LOOKUPP] = { [OP_LOOKUPP] = {
.op_func = (nfsd4op_func)nfsd4_lookupp, .op_func = (nfsd4op_func)nfsd4_lookupp,
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
.op_name = "OP_LOOKUPP", .op_name = "OP_LOOKUPP",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
}, },
[OP_NVERIFY] = { [OP_NVERIFY] = {
.op_func = (nfsd4op_func)nfsd4_nverify, .op_func = (nfsd4op_func)nfsd4_nverify,
.op_name = "OP_NVERIFY", .op_name = "OP_NVERIFY",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
}, },
[OP_OPEN] = { [OP_OPEN] = {
.op_func = (nfsd4op_func)nfsd4_open, .op_func = (nfsd4op_func)nfsd4_open,
...@@ -2181,6 +2234,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2181,6 +2234,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
[OP_READLINK] = { [OP_READLINK] = {
.op_func = (nfsd4op_func)nfsd4_readlink, .op_func = (nfsd4op_func)nfsd4_readlink,
.op_name = "OP_READLINK", .op_name = "OP_READLINK",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_readlink_rsize,
}, },
[OP_REMOVE] = { [OP_REMOVE] = {
.op_func = (nfsd4op_func)nfsd4_remove, .op_func = (nfsd4op_func)nfsd4_remove,
...@@ -2219,6 +2273,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2219,6 +2273,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_func = (nfsd4op_func)nfsd4_secinfo, .op_func = (nfsd4op_func)nfsd4_secinfo,
.op_flags = OP_HANDLES_WRONGSEC, .op_flags = OP_HANDLES_WRONGSEC,
.op_name = "OP_SECINFO", .op_name = "OP_SECINFO",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize,
}, },
[OP_SETATTR] = { [OP_SETATTR] = {
.op_func = (nfsd4op_func)nfsd4_setattr, .op_func = (nfsd4op_func)nfsd4_setattr,
...@@ -2244,6 +2299,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2244,6 +2299,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
[OP_VERIFY] = { [OP_VERIFY] = {
.op_func = (nfsd4op_func)nfsd4_verify, .op_func = (nfsd4op_func)nfsd4_verify,
.op_name = "OP_VERIFY", .op_name = "OP_VERIFY",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
}, },
[OP_WRITE] = { [OP_WRITE] = {
.op_func = (nfsd4op_func)nfsd4_write, .op_func = (nfsd4op_func)nfsd4_write,
...@@ -2318,11 +2374,13 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2318,11 +2374,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_func = (nfsd4op_func)nfsd4_secinfo_no_name, .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
.op_flags = OP_HANDLES_WRONGSEC, .op_flags = OP_HANDLES_WRONGSEC,
.op_name = "OP_SECINFO_NO_NAME", .op_name = "OP_SECINFO_NO_NAME",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize,
}, },
[OP_TEST_STATEID] = { [OP_TEST_STATEID] = {
.op_func = (nfsd4op_func)nfsd4_test_stateid, .op_func = (nfsd4op_func)nfsd4_test_stateid,
.op_flags = ALLOWED_WITHOUT_FH, .op_flags = ALLOWED_WITHOUT_FH,
.op_name = "OP_TEST_STATEID", .op_name = "OP_TEST_STATEID",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_test_stateid_rsize,
}, },
[OP_FREE_STATEID] = { [OP_FREE_STATEID] = {
.op_func = (nfsd4op_func)nfsd4_free_stateid, .op_func = (nfsd4op_func)nfsd4_free_stateid,
...@@ -2336,6 +2394,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2336,6 +2394,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_func = (nfsd4op_func)nfsd4_getdeviceinfo, .op_func = (nfsd4op_func)nfsd4_getdeviceinfo,
.op_flags = ALLOWED_WITHOUT_FH, .op_flags = ALLOWED_WITHOUT_FH,
.op_name = "OP_GETDEVICEINFO", .op_name = "OP_GETDEVICEINFO",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_getdeviceinfo_rsize,
}, },
[OP_LAYOUTGET] = { [OP_LAYOUTGET] = {
.op_func = (nfsd4op_func)nfsd4_layoutget, .op_func = (nfsd4op_func)nfsd4_layoutget,
...@@ -2385,6 +2444,7 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -2385,6 +2444,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
[OP_SEEK] = { [OP_SEEK] = {
.op_func = (nfsd4op_func)nfsd4_seek, .op_func = (nfsd4op_func)nfsd4_seek,
.op_name = "OP_SEEK", .op_name = "OP_SEEK",
.op_rsize_bop = (nfsd4op_rsize)nfsd4_seek_rsize,
}, },
}; };
...@@ -2429,14 +2489,11 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp) ...@@ -2429,14 +2489,11 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op) int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
{ {
struct nfsd4_operation *opdesc;
nfsd4op_rsize estimator;
if (op->opnum == OP_ILLEGAL) if (op->opnum == OP_ILLEGAL)
return op_encode_hdr_size * sizeof(__be32); return op_encode_hdr_size * sizeof(__be32);
opdesc = OPDESC(op);
estimator = opdesc->op_rsize_bop; BUG_ON(OPDESC(op)->op_rsize_bop == NULL);
return estimator ? estimator(rqstp, op) : PAGE_SIZE; return OPDESC(op)->op_rsize_bop(rqstp, op);
} }
void warn_on_nonidempotent_op(struct nfsd4_op *op) void warn_on_nonidempotent_op(struct nfsd4_op *op)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册