I originally submitted this to the kde bugzilla: http://bugs.kde.org/show_bug.cgi?id=109918 Here is the detail from there again: If I use nfs:// to browse a TCP NFS file server, copying files TO the server larger than a certain length fails - it'll definitely happen with > 20k files. Other operations work fine. The server reports: RPC: bad TCP reclen 0x00000f9c (non-terminal) in dmesg. This is because the linux sunrpc implementation is incomplete and cannot handle fragmented sunrpc requests. If you look at the relevant code in net/sunrpc/svcsock.c/svc_tcp_recvfrom() in a recent kernel, you see the following: /* FIXME: technically, a record can be fragmented, * and non-terminal fragments will not have the top * bit set in the fragment length header. * But apparently no known nfs clients send fragmented * records. */ I can't figure out why KDE/glibc's sunrpc client implementation is sending fragmented records and I don't have the time to fix the kernel sunrpc implementation. A simple "fix" would be to disable TCP NFS support from kio_nfs completely, and rely on UDP only (UDP works fine BTW). But obviously this isn't great :( I'm using glibc 2.3.5 BTW. Recently someone contacted the NFS list for advice.. the reply was as follows: >>> >> I'm communicating with the linux NFS kernel server via RPC using the >>> >> sunrpc implementation in glibc. On certain RPC record sizes, glibc >>> >> starts to use record fragmentation (whereas the sunrpc kernel client >>> >> doesn't) and the sunrpc linux kernel server implementation lacks the RPC >>> >> record "defragmentation" functionality as can be seen in >>> >> net/sunrpc/svcsock.c: >>> >> >>> >> svsk->sk_reclen = ntohl(svsk->sk_reclen); >>> >> if (!(svsk->sk_reclen & 0x80000000)) { >>> >>
I originally submitted this to the kde bugzilla: http://bugs.kde.org/show_bug.cgi?id=109918 Here is the detail from there again: If I use nfs:// to browse a TCP NFS file server, copying files TO the server larger than a certain length fails - it'll definitely happen with > 20k files. Other operations work fine. The server reports: RPC: bad TCP reclen 0x00000f9c (non-terminal) in dmesg. This is because the linux sunrpc implementation is incomplete and cannot handle fragmented sunrpc requests. If you look at the relevant code in net/sunrpc/svcsock.c/svc_tcp_recvfrom() in a recent kernel, you see the following: /* FIXME: technically, a record can be fragmented, * and non-terminal fragments will not have the top * bit set in the fragment length header. * But apparently no known nfs clients send fragmented * records. */ I can't figure out why KDE/glibc's sunrpc client implementation is sending fragmented records and I don't have the time to fix the kernel sunrpc implementation. A simple "fix" would be to disable TCP NFS support from kio_nfs completely, and rely on UDP only (UDP works fine BTW). But obviously this isn't great :( I'm using glibc 2.3.5 BTW. Recently someone contacted the NFS list for advice.. the reply was as follows: >>> >> I'm communicating with the linux NFS kernel server via RPC using the >>> >> sunrpc implementation in glibc. On certain RPC record sizes, glibc >>> >> starts to use record fragmentation (whereas the sunrpc kernel client >>> >> doesn't) and the sunrpc linux kernel server implementation lacks the RPC >>> >> record "defragmentation" functionality as can be seen in >>> >> net/sunrpc/svcsock.c: >>> >> >>> >> svsk->sk_reclen = ntohl(svsk->sk_reclen); >>> >> if (!(svsk->sk_reclen & 0x80000000)) { >>> >> /* FIXME: technically, a record can be fragmented, >>> >> * and non-terminal fragments will not have the top >>> >> * bit set in the fragment length header. >>> >> * But apparently no known nfs clients send fragmented >>> >> * records. */ >>> >> printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (non-terminal)\n", >>> >> (unsigned long) svsk->sk_reclen); >>> >> goto err_delete; >>> >> } >>> >> >>> >> Unfortunately, I didn't find a way to disable the use of fragmentation >>> >> in glibc. Is there an existing patch for the kernel to support >>> >> fragmented records? >> > >> > Not that I am aware of, and it would be fairly non-trivial to >> > implement, for relatively little gain. >> > >> > You should be able to avoid fragmentation with glibc by setting >> > 'sendsz' large enough. >> > When you call clnttcp_create, pass a big number for the 5th arg. >> > >> > NeilBrown >> > > > Thanks, calling clnttcp_create with sendsz=65724 avoids the > fragmentation by the glibc and NFS "splits" the packets instead. A patch against kdelibs 3.5 is attached. I'm talking to the upstream maintainer about it also.
Created attachment 96249 [details, diff] kdelibs patch to fix kio_nfs
Hm, yes. But what made you chose the value you have chosen?
I didn't thats the value the guy who fixed the bugs used. Actually, have a look at the bug in kde bugzilla - someone's just added a further explanation there, with some more sensible defaults. -------- I'm not familiar with nfs, but it looks like someone simply copied the showmount(8) code from nfs-utils, not the connection code. In mnt_openclnt (conn.c in recent nfs-utils) 2048/1024 bytes for send/receive are used. --------
You quoted my comment. ;) Can't say that I do know what's best for nfs though. Committed with 3.5.4-r1.