Re: NFS client write out corrupted file?

Sai-Lai Lo (S.Lo@orl.co.uk)
06 Jan 1999 10:22:57 +0000


Linus,

I have tested 2.2.0-pre4 against my test case with the Solaris server,
sadly it is still giving me the same corruption error.

I'll try to find out more about what are the exact sequence of nfs exchanges
between the linux client and the solaris server.

In the mean time, you may find the test code below useful for other people
working on the nfs code to track down the bug.

The interesting thing is the test code only produces file corruption on one
of the nfs partition but not others on the same nfs server. The corruption
occurs with a part of a 4K page shifted by 3 bytes. It seems like something
is wrong in sunrpc where the marshalled data on the wire is wrongly aligned
on 4 bytes boundary.

Sai-Lai

----------- cut here -------------
/* Test case extracted from a gcc run. */
/* gcc -o bug bug.c */
/* Run this program on a linux client and with the current working
directory on a NFS server. The program produces the file "dump".
Compare the output file with a similar run but with the current
working directory on the local disk.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>

int
main(int argc, char** argv)
{
int fd;
unsigned char* buf;
int i;

buf = (char*) malloc(4096);
for (i=0; i<4096; i++) {
buf[i] = i % 256;
}

if ((fd = open("dump",O_CREAT|O_RDWR)) < 0) {
fprintf(stderr, "Cannot open file\n");
return 1;
}

assert(lseek(fd,24144,SEEK_SET) == 24144);

assert(write(fd,buf,4096) == 4096);

assert(write(fd,buf, 1024) == 1024);

assert(lseek(fd, 52, SEEK_SET) == 52);

assert(write(fd,buf,4096) == 4096);

assert(write(fd,buf,4096) == 4096);

assert(write(fd,buf,4096) == 4096);

assert(write(fd,buf, 592) == 592);

assert(lseek(fd, 12960, SEEK_SET) == 12960);

assert(write(fd,buf, 3126) == 3126);

assert(lseek(fd, 16088, SEEK_SET) == 16088);

assert(write(fd,buf, 10) == 10);

assert(lseek(fd, 16100, SEEK_SET) == 16100);

assert(write(fd,buf, 10) == 10);

assert(lseek(fd, 16112, SEEK_SET) == 16112);

assert(write(fd,buf, 10) == 10);

assert(lseek(fd, 16124, SEEK_SET) == 16124);

assert(write(fd,buf,10) == 10);

assert(lseek(fd, 16136, SEEK_SET) == 16136);

assert(write(fd,buf, 22) == 22);

assert(lseek(fd, 16160, SEEK_SET) == 16160);

assert(write(fd,buf, 54) == 54);

assert(lseek(fd, 16216, SEEK_SET) == 16216);

assert(write(fd,buf, 22) == 22);

assert(lseek(fd, 16240, SEEK_SET) == 16240);

assert(write(fd,buf, 65) == 65);

assert(lseek(fd, 16308, SEEK_SET) == 16308);

assert(write(fd,buf, 50) == 50);

assert(lseek(fd, 16360, SEEK_SET) == 16360);

assert(write(fd,buf, 2095) == 2095);

assert(lseek(fd, 29264, SEEK_SET) == 29264);

assert(write(fd,buf, 4096) == 4096);

assert(write(fd,buf, 2648) == 2648);

assert(lseek(fd, 21232, SEEK_SET) == 21232);

assert(write(fd,buf, 2912) == 2912);

assert(lseek(fd, 18455, SEEK_SET) == 18455);

assert(write(fd,buf, 1257) == 1257);

assert(lseek(fd, 0, SEEK_SET) == 0);

assert(write(fd,buf, 52) == 52);

assert(lseek(fd, 19712, SEEK_SET) == 19712);

assert(write(fd,buf, 1520) == 1520);

close(fd);

return 0;

}

------------------------------------

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/