diff -r fails on some NFS partitions under Linux 2.0.36pre6

Chris Siebenmann (cks@hawkwind.utcs.toronto.edu)
Thu, 27 Aug 1998 21:52:42 -0500


Environment: diffutils 2.7 on a RedHat 5.1 (glibc 2.0.7-based) Linux
machine running kernel 2.0.36pre6.

I have some NFS-mounted partitions that I cannot run diff -r against,
because diff -r reports
diff: /local/newsrc/cks: Invalid argument
strace reveals that the reason it returns this is the sequence:
open("/local/newsrc/cks", O_RDONLY|O_NONBLOCK) = 3
[...]
lseek(3, 0, SEEK_CUR) = 0
getdents(3, /* 35 entries */, 7865) = 704
lseek(3, 0, SEEK_CUR) = -1 EINVAL (Invalid argument)
getdents(3, /* 0 entries */, 7865) = 0
This is from repeated readdir() calls; eventually one hits the end
(there are 35 entries in that directory), readdir() calls lseek() on the
directory, lseek() returns EINVAL for some reason, and when the next
readdir() call returns NULL, dir.c:dir_sort() sees errno set to EINVAL
and dies.

The lseek() failure only happens when the NFS-mounted filesystem is
an SGI XFS filesystem (mounted from an SGI server, obvious); SGI EFS
filesystems, and other filesystems mounted from other machines, do not
have the lseek() fail in similar situations. (I have a simple readdir()
loop that shows this.)

I am not sure where the bug should be considered to be. Perhaps the
kernel should be making the lseek() work; possibly glibc should be
fixing errno to be 0 as it returns from readdir() in this situation;
possibly diff is being overzealous in checking errno (or not checking it
only against EBADF, which a couple of manpages claim is the only thing
errno can be if it's non-zero). Perhaps several of these.

-- 
		"there used to be two moons
		 then one of them
		 discovered coffee."		- Curtis Yarvin
cks@hawkwind.utcs.toronto.edu	           ...!{utgpu,utzoo,watmath}!utgpu!cks

- 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.altern.org/andrebalsa/doc/lkml-faq.html