@@ -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
3743
- * after encoding the current operation with pad.
3742
+ * Calculate whether we still have space to encode repsize bytes.
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()
3746
- * which was specified at nfsd4_operation, else pad is zero.
3747
- *
3748
- * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached.
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.
3749
+ * This is called before the operation is processed, so can only provide
3750
+ * an upper estimate. For some nonidempotent operations (such as
3751
+ * getattr), it's not necessarily a problem if that estimate is wrong,
3752
+ * as we can fail it after processing without significant side effects.
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
3756
struct xdr_buf * buf = & resp -> rqstp -> rq_res ;
3756
3757
struct nfsd4_session * session = resp -> cstate .session ;
3757
- struct nfsd4_slot * slot = resp -> cstate .slot ;
3758
3758
int slack_bytes = (char * )resp -> xdr .end - (char * )resp -> xdr .p ;
3759
3759
3760
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
3764
return nfserr_rep_too_big ;
3764
3765
3765
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
3768
return nfserr_rep_too_big_to_cache ;
3768
3769
}
3769
3770
3770
- if (pad > slack_bytes ) {
3771
+ if (respsize > slack_bytes ) {
3771
3772
WARN_ON_ONCE (nfsd4_has_session (& resp -> cstate ));
3772
3773
return nfserr_resource ;
3773
3774
}
0 commit comments