diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-03-11 17:54:34 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-05-30 17:31:53 -0400 |
commit | a8095f7e80fbf3e0efe4ee5cd3f509113c56290f (patch) | |
tree | d44c77ac05bd42e6e054bd8b4cf356d5703d14a8 /fs/nfsd/nfs4xdr.c | |
parent | ea8d7720b274607f48fb524337254a9c43dbc2df (diff) |
nfsd4: size-checking cleanup
Better variable name, some comments, etc.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index df643e0fb6b3..bd529e523087 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -3739,35 +3739,36 @@ static nfsd4_enc nfsd4_enc_ops[] = { | |||
3739 | }; | 3739 | }; |
3740 | 3740 | ||
3741 | /* | 3741 | /* |
3742 | * Calculate the total amount of memory that the compound response has taken | 3742 | * Calculate whether we still have space to encode repsize bytes. |
3743 | * after encoding the current operation with pad. | 3743 | * There are two considerations: |
3744 | * - For NFS versions >=4.1, the size of the reply must stay within | ||
3745 | * session limits | ||
3746 | * - For all NFS versions, we must stay within limited preallocated | ||
3747 | * buffer space. | ||
3744 | * | 3748 | * |
3745 | * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop() | 3749 | * This is called before the operation is processed, so can only provide |
3746 | * which was specified at nfsd4_operation, else pad is zero. | 3750 | * an upper estimate. For some nonidempotent operations (such as |
3747 | * | 3751 | * getattr), it's not necessarily a problem if that estimate is wrong, |
3748 | * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached. | 3752 | * as we can fail it after processing without significant side effects. |
3749 | * | ||
3750 | * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so | ||
3751 | * will be at least a page and will therefore hold the xdr_buf head. | ||
3752 | */ | 3753 | */ |
3753 | __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) | 3754 | __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize) |
3754 | { | 3755 | { |
3755 | struct xdr_buf *buf = &resp->rqstp->rq_res; | 3756 | struct xdr_buf *buf = &resp->rqstp->rq_res; |
3756 | struct nfsd4_session *session = resp->cstate.session; | 3757 | struct nfsd4_session *session = resp->cstate.session; |
3757 | struct nfsd4_slot *slot = resp->cstate.slot; | ||
3758 | int slack_bytes = (char *)resp->xdr.end - (char *)resp->xdr.p; | 3758 | int slack_bytes = (char *)resp->xdr.end - (char *)resp->xdr.p; |
3759 | 3759 | ||
3760 | if (nfsd4_has_session(&resp->cstate)) { | 3760 | if (nfsd4_has_session(&resp->cstate)) { |
3761 | struct nfsd4_slot *slot = resp->cstate.slot; | ||
3761 | 3762 | ||
3762 | if (buf->len + pad > session->se_fchannel.maxresp_sz) | 3763 | if (buf->len + respsize > session->se_fchannel.maxresp_sz) |
3763 | return nfserr_rep_too_big; | 3764 | return nfserr_rep_too_big; |
3764 | 3765 | ||
3765 | if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) && | 3766 | if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) && |
3766 | buf->len + pad > session->se_fchannel.maxresp_cached) | 3767 | buf->len + respsize > session->se_fchannel.maxresp_cached) |
3767 | return nfserr_rep_too_big_to_cache; | 3768 | return nfserr_rep_too_big_to_cache; |
3768 | } | 3769 | } |
3769 | 3770 | ||
3770 | if (pad > slack_bytes) { | 3771 | if (respsize > slack_bytes) { |
3771 | WARN_ON_ONCE(nfsd4_has_session(&resp->cstate)); | 3772 | WARN_ON_ONCE(nfsd4_has_session(&resp->cstate)); |
3772 | return nfserr_resource; | 3773 | return nfserr_resource; |
3773 | } | 3774 | } |