Date: Thu, 29 Jul 1999 14:11:36 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Bill Paul <wpaul@skynet.ctr.columbia.edu> Cc: peter@netplex.com.au, crossd@cs.rpi.edu, current@FreeBSD.ORG Subject: Re: IRIX 6.5.4 NFS v3 TCP client + FreeBSD server = bewm Message-ID: <199907292111.OAA78730@apollo.backplane.com> References: <199907292044.QAA17186@skynet.ctr.columbia.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
I counted it all up. It definitely needs to be 8 * NFSX_UNSIGNED. See my count below. -Matt :In /sys/nfs/nfs_serv.c:nfsrv_readdirplus(), we have the following :code: : : /* : * If either the dircount or maxcount will be : * exceeded, get out now. Both of these lengths : * are calculated conservatively, including all : * XDR overheads. : */ : len += (7 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH + : NFSX_V3POSTOPATTR); : dirlen += (6 * NFSX_UNSIGNED + nlen + rem); : :I observed that the value of "len" didn't agree with the actual amount :of data beong consumed in the mbuf chain. It turns out that each :time through the loop, len is being incremented by 4 bytes too little. :In other words, 7 * NFSX_UNSIGNED should really be 8 * NFSX_UNSIGNED. :When I change 7 to 8, I no longer get oversized replies and everything :adds up. :... : :Unfortunately I haven't been able to wrap my brain around how this is :being counted up for the "len" calculation. Whatever it's doing, it's :off by 4 bytes. Possibly somebody forgot that "filename3" is a string, :which in XDR format consists of a string bytes, plus padding to a longword :boundary, *plus* a longword length value. Some comments would have been :useful here. (Hint, hint.) : :What I don't know is whether or not the calculation for dirlen is :wrong or not. Hopefully now that I've shown everyone the light, maybe :somebody can tell me for sure. : :-Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu :... : len += (7 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH + : NFSX_V3POSTOPATTR); nfsm_clget; *tl = nfs_true; bp += NFSX_UNSIGNED; (one) nfsm_clget; *tl = 0; bp += NFSX_UNSIGNED; (two) nfsm_clget; *tl = txdr_unsigned(dp->d_fileno); bp += NFSX_UNSIGNED; (three) nfsm_clget; *tl = txdr_unsigned(nlen); bp += NFSX_UNSIGNED; (four) ... xfer = nlen; (nlen) while (xfer > 0) { nfsm_clget; if ((bp + xfer) > be) tsiz = be - bp; else tsiz = xfer; bcopy(cp, bp, tsiz); bp += tsiz; xfer -= tsiz; if (xfer > 0) cp += tsiz; } /* And null pad to a int32_t boundary */ for (i = 0; i < rem; i++) (rem) *bp++ = '\0'; /* * Now copy the flrep structure out. */ xfer = sizeof (struct flrep); >>>>>>> 8 + 4 + NFSX_V3FATTR + 4 + 4 + NFSX_V3FH note: NFSX_V3POSTOPATTR eats an extra 32 bit int because it is defined as: #define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) (NFSX_V3POSTOPATTR) (NFSX_V3FATTR) (NFSX_V3FH) 20 remaining, remove 4 to take into account NFSX_UNSIGNED in NFSX_V3POSTOPATTR, leaving 16. (five) (six) (seven) (eight) ************* struct flrep { nfsuint64 fl_off; u_int32_t fl_postopok; u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)]; u_int32_t fl_fhok; u_int32_t fl_fhsize; u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)]; }; cp = (caddr_t)&fl; while (xfer > 0) { nfsm_clget; if ((bp + xfer) > be) tsiz = be - bp; else tsiz = xfer; bcopy(cp, bp, tsiz); bp += tsiz; xfer -= tsiz; if (xfer > 0) cp += tsiz; } -Matt Matthew Dillon <dillon@backplane.com> To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199907292111.OAA78730>