Subject: port-mvme68k/14197: NFS client broken on mvme68k
To: None <gnats-bugs@gnats.netbsd.org>
From: None <steve@mctavish.co.uk>
List: netbsd-bugs
Date: 10/09/2001 20:43:50
>Number:         14197
>Category:       port-mvme68k
>Synopsis:       NFS client broken on mvme68k
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-mvme68k-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 09 12:44:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD-current Oct 6 2001
>Organization:
None at all
>Environment:
System: NetBSD soapy 1.5Y NetBSD 1.5Y (SOAPY) #1: Mon Oct 8 18:16:31 BST 2001 root@soapy:/usr/src/sys/arch/mvme68k/compile/SOAPY mvme68k
Architecture: m68k
Machine: mvme68k
>Description:
There is a subtle NFS client problem on mvme68k which under certain
circumstances can truncates files down to a multiple of 8192 bytes.
(Lengths less than 8192 are truncated to zero).

The problem was noticed when mv(1)ing files from a local filesystem
onto an NFS mounted filesystem. The destination filesize ended up
being truncated as described above. A test case is shown below. A raw
tcpdump(8) is available at ftp.netbsd.org:~scw/nfs-dump.

I suspect this may be some form of pmap bug, however I'm not familiar
enough with nfs to speculate further. The problem does not exist on
at least i386, pmap and alpha.
>How-To-Repeat:
The following program illustrates the bug:

#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


#define CHUNK	10000	/* Something which is not a multiple of 0x2000 */

int
main(int argc, char **argv)
{
	struct timeval tval[2];
	void *mem;
	int ofd;

	if (argc != 2) {
		fprintf(stderr, "usage: %s <nfs-scratch-file>\n", argv[0]);
		exit(1);
	}

	if ((mem = calloc(1, CHUNK)) == NULL) {
		perror("calloc");
		exit(1);
	}

	/*
	 * Create the dummy file
	 */
	ofd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0644);
	if (ofd < 0) {
		perror(argv[1]);
		exit(1);
	}

	/*
	 * Write some junk into it
	 */
	if (write(ofd, mem, CHUNK) < 0) {
		perror("write");
		exit(1);
	}

	/*
	 * At this point, the client's view of the file (according to ls(1))
	 * is correct, ie. CHUNK bytes in length. The NFS server still has
	 * CHUNK & ~(0x2000 - 1) bytes...
	 */

	tval[0].tv_sec = tval[1].tv_sec = (long) time(NULL);
	tval[0].tv_usec = tval[1].tv_usec = 0;

	/*
	 * Tweak the modified/accessed times on the file
	 */
	if (futimes(ofd, tval) < 0) {
		perror("futimes");
		exit(1);
	}

	/*
	 * Boom!
	 * Both client and server show the file truncated as per the
	 * following formula: CHUNK & ~(0x2000 - 1).
	 */

	close(ofd);

	exit(0);
}

>Fix:
Unknown.
>Release-Note:
>Audit-Trail:
>Unformatted: