bug: linux 2.2.12 SMP NFS client directory entry race

Bruce Janson (bruce@cs.usyd.edu.au)
Wed, 13 Oct 1999 20:30:06 +1000


When executed on an otherwise idle Linux 2.2.12 kernel (SMP, on a dual
processor) in a directory on an NFS file system the following program should
be silent, but it eventually does produce output. Apparently after some
(alas, variable) number of attempts the ".." entry returned by readdir() in
two separate processes in two separate directories becomes confused (usually
swapped). I am using a Slackware 4.0 distribution. The NFS file server
is a SunOS 5.6 computer.

$ cat > 1.c <<EOF
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>

main()
{
char *r;
struct stat root_statb;
int tries;

switch (fork())
{
case -1:
perror("fork");
exit(1);

case 0: /* child */
r = "x";
break;

default: /* self */
r = "y";
break;
}

mkdir(r, 0700);
chdir(r);

lstat(".", &root_statb);

tries = 0;

for (;;)
{
DIR *d;
struct dirent *e;

tries++;

rmdir("0");
mkdir("0", 0700);

d = opendir("0");

while ((e = readdir(d)) != (struct dirent *)0)
{
if (e->d_ino == (long)0)
continue;

if (e->d_name[0] == '\0')
continue;

if (strcmp(&e->d_name[0], "..") == 0)
{
if (e->d_ino != root_statb.st_ino)
{
printf("readdir_inumber %ld, root_statb.st_ino %ld, %d tries\n", e->d_ino, root_statb.st_ino, tries);
exit(0);
}

break;
}
}

closedir(d);
}
}
EOF
$ cc -o 1 1.c
$ ./1
readdir_inumber 954631, root_statb.st_ino 358799, 48 tries
readdir_inumber 358799, root_statb.st_ino 954631, 50 tries
$ ldd ./1
libc.so.5 => /lib/libc.so.5 (0x4000b000)
$ cc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs
gcc version 2.7.2.3
$ uname -a
Linux citrix 2.2.12 #3 SMP Tue Oct 5 01:15:04 EST 1999 i686 unknown
$

Regards,
bruce.

-
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/