On Mon, Oct 06, 2003 at 11:59:08AM -0400, Chris Shenton wrote:
> > After renaming 40 or so files, the readdir() terminates, probably because
> > the state of the directory is being changed while it is being read. Arguably
> > this is a Netapp bug,
> 
> This doesn't occur if you mount some UNIX box via NFS? What version
> of DataOntap are you running?

6.4R1

Well, I thought it was a Netapp problem, but now it looks like NFS and/or
FreeBSD. The attached program replicates it:

bash-2.05a# ./testnfs /na0/testdir
Transferred 169 out of 200 files

That was with a FreeBSD-4.8p3 frontend with the Netapp backend. However
re-running it with FreeBSD-4.7 talking to a Solaris-2.8 NFS backend gives
exactly the same result :-(

So perhaps if you could try it on your platform that would be a useful
comparison...

Cheers,

Brian.
/* Demonstrate problem with NFS readdir */

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h> /* for mkdir */
#include <sys/stat.h>  /* for mkdir */
#include <dirent.h>    /* opendir/readdir etc */

#define TESTSIZE 200
    
int main(int argc, char *argv[])
{
  int i;
  char fnbuf[1024], fnbuf2[1024];
  char *dir = argv[1];
  int count;
  DIR *dp;
  struct dirent *de;
  
  if (argc < 2 || !dir || !dir[0])
    dir = ".";

  sprintf(fnbuf, "%s/new", dir);
  mkdir(fnbuf, 0777);
  sprintf(fnbuf, "%s/cur", dir);
  mkdir(fnbuf, 0777);
    
  for (i=0; i<TESTSIZE; i++) {
    FILE *f;
    sprintf(fnbuf, "%s/new/MYTESTFILE%d", dir, i);
    f = fopen(fnbuf, "w");
    if (!f) { perror("fopen"); exit(1); }
    fprintf(f, "Some dummy content\n");
    fclose(f);
  }

  sprintf(fnbuf, "%s/new", dir);
  dp = opendir(fnbuf);
  if (!dp) { perror("opendir"); exit(1); }
  count = 0;
  while ((de = readdir(dp))) {
    if (de->d_name[0] == '.') continue;
    sprintf(fnbuf, "%s/new/%s", dir, de->d_name);
    sprintf(fnbuf2,"%s/cur/%s:2,S", dir, de->d_name);
    if (rename(fnbuf, fnbuf2) < 0) {
      perror("rename");
      fprintf(stderr, "(from %s to %s)\n", fnbuf, fnbuf2);
      continue;
    }
    count++;
  }  

  fprintf(stderr, "Transferred %d out of %d files\n", count, TESTSIZE);
  return count != TESTSIZE;
}

Reply via email to