if (npages < len / AFSDIR_PAGESIZE) npages = len / AFSDIR_PAGESIZE;
adir_readdir (VenusFid dir,	      void (*func)(VenusFid *, const char *, void *), 	      void *arg,	      CredCacheEntry *ce){     int fd;     fbuf the_fbuf;     DirPage0 *page0;     unsigned i;     FCacheEntry *centry;     int ret;     unsigned ind, dotind, dotdotind;     VenusFid fid;     unsigned len;     struct stat sb;     ret = fcache_get (&centry, dir, ce);     if (ret)	 return ret;     ret = fcache_get_data (centry, ce);     if (ret) {	 ReleaseWriteLock (&centry->lock);	 return ret;     }     if (centry->status.FileType != TYPE_DIR) {	 ReleaseWriteLock (&centry->lock);	 return ENOTDIR;     }     fd = fcache_open_file (centry, O_RDONLY, 0);     if (fd < 0) {	 ReleaseWriteLock (&centry->lock);	 return errno;     }     if (fstat (fd, &sb)) {	 ReleaseWriteLock (&centry->lock);	 close (fd);	 return errno;     }     len = sb.st_size;     ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ);     if (ret) {	 ReleaseWriteLock (&centry->lock);	 close (fd);	 return ret;     }     page0 = (DirPage0 *)(the_fbuf.buf);     /*      * Begin with placing `.' and `..' first. (some system seem to need that)      */     dotind = find_by_name (page0, ".", &fid, &dir);     assert (dotind != 0);     (*func)(&fid, ".", arg);     dotdotind = find_by_name (page0, "..", &fid, &dir);     assert (dotind != 0);     (*func)(&fid, "..", arg);     for (i = 0; i < ADIRHASHSIZE; ++i) {	  const DirEntry *entry;	  for(ind = ntohs(page0->dheader.hash[i]);	      ind;	      ind = ntohs(entry->next)) {	      entry = getentry (page0, ind - 1);	      	      fid.Cell = dir.Cell;	      fid.fid.Volume = dir.fid.Volume;	      fid.fid.Vnode  = ntohl (entry->fid.Vnode);	      fid.fid.Unique = ntohl (entry->fid.Unique);	      if (ind != dotind && ind != dotdotind) /* already did them */		  (*func)(&fid, entry->name, arg);	  }     }     fbuf_end (&the_fbuf);     ReleaseWriteLock (&centry->lock);     return 0;}