NFS nfsStBlksize and buffer overflows (NFS RPC: Timed out)

Peter Dufault dufault at
Thu Sep 11 11:47:11 UTC 2014

On Sep 10, 2014, at 09:53 , Peter Dufault <dufault at> wrote:

> My client is having problems similar to that described here:
> I don't understand the details, or why one needs to limit the I/O size based on the ethernet chip set, but I did verify that cpukit/libfs/src/nfsclient/src/nfs.c does not have changes described in the email and that changing nfs.c and then setting nfsStBlksize to 4096 before calling nfsInit() works around the issue. This is on the phycore_mpc5554 BSP with the smc91111 ethernet chip.

According to mounting the file system with a smaller rsize and wsize should address the problem:

"If the network adapter on an NFS client cannot handle full frames and back-to-back packets, reduce the NFS read and write transfer sizes below the default of 8KB. To do this, specify the mount(ADM) option modifiersrsize and wsize for each mounted filesystem. These must be added to the options defined for the mntopts keyword in the file /etc/default/filesys (see filesys(F) for more information). The following is an example of such an entry reducing the read and write transfer sizes to 1KB (1024 bytes):

"   bdev=nfs_svr:/remote \
          mountdir=/remote_mnt fstyp=NFS \
          fsck=no fsckflags= \
          init=yes initcmd="sleep 2" \
          mntopts="bg,soft,rsize=1024,wsize=1024" \
          rcmount=yes rcfsck=no mountflags=..."

Note that nfs.c already sets the blocksize based on nfsStBlksize:

    /* Set to "preferred size" of this NFS client implementation */
    buf->st_blksize = nfsStBlksize ? nfsStBlksize : fa->blocksize;

The existing code limits I/O transfers to nfsStBlksize or NFS_MAXDATA and not the file system blocks size.  Is there a way to get back to the buf->st_blksize given the "rtems_libio_t *iop" in the NFS I/O routines?  Then the file system blocksize could be used as the limit.

The above code-quote has an additional bug.  nfsStBlksize has a default value of DEFAULT_NFS_ST_BLKSIZE which is NFS_MAXDATA which is 8K, so the default RTEMS behavior is that buf->st_blksize is always 8K even if fa->blocksize is 4K.

So currently:
- I/O is not limited to the file system block size;
- The mounted block size is ignored and nfsStBlksize is used, which defaults to 4K.

The first problem can be fixed by getting from the iop back to the block size and then limiting the transfer at that size.  The second can be fixed by initializing nfsStBlksize to 0 instead of NFS_MAXDATA.

Peter Dufault
HD Associates, Inc.      Software and System Engineering

More information about the devel mailing list