[alt.sources.patches] [comp.protocols.appletalk] cap patches

Dan@dna.lth.se (Dan Oscarsson) (02/07/90)

Archive-name: cap/dan@dna.lth.se
Original-posting-by: Dan@dna.lth.se (Dan Oscarsson)
Original-subject: cap patches
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[This is a patch to  from comp.protocols.appletalk.]


Here is a shar containg the patches I have done to aufs to make it faster.

    Dan

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

#!/bin/sh
# This is a shell archive.  Remove anything before the "#!/bin/sh" line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
#	./README
#	./README.FIRST
#	./afpspd.c
#	./patches
#
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\Rogue\Monster\'
This code has been enhanced to make aufs faster. Also the file afpdt.c has
an error corrected.

Here are a few comments to make aufs faster:

The code here also have a lot of patches applied at Rutgers where I fetched
the code, but if you want speed do not enable SIZESERVER or NOCASEMATCH.

Also check in the makefile after you have configured cap so that
SMART_UNIX_FINDERINFO is not defined. It slows down looking at unix
directories in the finder.

If you are using a Sun, when you check the m4.setup file in the cap50 directory
STATFS should be defined and not SUNQUOTA.

------------
What have I done?

When one checks what aufs is doing, one finds that it is doing a lot
of stat calls. Very often on the same file several times. Also aufs uses
full pathnames.

Most of my new code is in the file afpspd.c. 

The routines in afpspd.c handles caching of stats of files and allows
open and stat to work relative to current working directory instead of
using full path names. My redefined stat and open calls are used in some of the
other files to speed things up.
Note: not all stat and open calls are replaced. Only the most important ones.
And I have avoided to change stat calls where modifications to files are
done.

The stats cached are expired after 2 minutes and are immediately invalidated
on requests that modify the filesystem.

The working directory is changed by some of the requests, this means that
if aufs core dumps it will probably do that in one of the base directories
of the volumes mounted on the Mac.


      Please send bug reports to Dan@dna.lth.se


    Dan
\Rogue\Monster\
else
  echo "will not over write ./README"
fi
if `test ! -s ./README.FIRST`
then
echo "writing ./README.FIRST"
cat > ./README.FIRST << '\Rogue\Monster\'
Here are my patches to make aufs faster.
As my cap sources is derived from what I fetched from Rugers and there
were several other patches already applied to the code, you may have
some difficulties to apply them. But it should not be very difficult
to find where those that fails should go in.

The README file explains what I have done. afpspd.c goes into the
aufs directory (and the patches should be applied there too).

   Dan                          email: Dan@dna.lth.se
\Rogue\Monster\
else
  echo "will not over write ./README.FIRST"
fi
if `test ! -s ./afpspd.c`
then
echo "writing ./afpspd.c"
cat > ./afpspd.c << '\Rogue\Monster\'
/*
   Speedup routines

   Author: Dan Oscarsson    (Dan@dna.lth.se)
*/

#include <sys/param.h>
#ifndef _TYPES
 /* assume included by param.h */
# include <sys/types.h>
#endif
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <netat/appletalk.h>
#include <netat/compat.h>
#include "afps.h" 


struct statobj {
	char * NAME;
	struct stat STAT;
	int FN,RS;
	time_t	VAL_TIME;
};

#define VAL_OK 1
#define VAL_NO 0
#define VAL_INVALID 2

#define MAX_LEVEL 20

private struct statobj STATS[MAX_LEVEL+1];

private time_t CUR_TIME;


#define EXP_TIME 120;

private char CUR_DIR_STR[1024];
private char * CUR_DIR = NULL;
private int CUR_DIR_LEN;

OScd(path)
	char * path;
{
	if (CUR_DIR != NULL && strlen(path) == CUR_DIR_LEN-1 && strncmp(path,CUR_DIR,CUR_DIR_LEN-1) == 0)
		return;
	if (chdir(path) < 0)
		return;
	CUR_DIR = CUR_DIR_STR;
	strcpy(CUR_DIR,path);
	strcat(CUR_DIR,"/");
	CUR_DIR_LEN = strlen(CUR_DIR);
	if (DBOSI)
		printf("OScd=%s\n",CUR_DIR);
}

cwd_stat(path,buf)
	char * path;
	struct stat *buf;
{
	if (CUR_DIR != NULL && strncmp(path,CUR_DIR,CUR_DIR_LEN) == 0) {
		if (DBOSI)
			printf("OScwd_stat=%s\n",path+CUR_DIR_LEN);
		return(stat(path+CUR_DIR_LEN,buf));
	}
	if (DBOSI)
		printf("OScwd_stat=%s\n",path);
	return(stat(path,buf));
}

cwd_open(path,flags,mode)
	char * path;
	int flags,mode;
{
	if (CUR_DIR != NULL && strncmp(path,CUR_DIR,CUR_DIR_LEN) == 0)
		return(open(path+CUR_DIR_LEN,flags,mode));
	return(open(path,flags,mode));
}

char * cwd_path(path)
	char * path;
{
	if (DBOSI)
		printf("OScwd_path=%s\n",path+CUR_DIR_LEN);
	if (CUR_DIR != NULL && strncmp(path,CUR_DIR,CUR_DIR_LEN) == 0) {
		if (DBOSI)
			printf("OScwd_path=%s\n",path+CUR_DIR_LEN);
		return path+CUR_DIR_LEN;
	} else
		return path;
}

private release_stats(K)
	int K;
{
	int P;

	if (DBOSI)
		printf("release_stats=%d\n",K);

	for (P = K; STATS[P].NAME != NULL; P++) {
		free(STATS[P].NAME);
		STATS[P].STAT.st_nlink = -1;
		STATS[P].FN = VAL_INVALID;
		STATS[P].RS = VAL_INVALID;
		STATS[P].NAME = NULL;
	}
}

private int EXPIRE_REQ;

private expire_stats(K)
	int K;
{
	if (!EXPIRE_REQ)
		return;
	EXPIRE_REQ = 0;
	for (K = 0; STATS[K].NAME != NULL; K++) {
		if (STATS[K].VAL_TIME > CUR_TIME) {
			STATS[K].STAT.st_nlink = -1;
			STATS[K].FN = VAL_INVALID;
			STATS[K].RS = VAL_INVALID;
			if (DBOSI)
				printf("expired=%d(%s)\n",K,STATS[K].NAME);
		}
	}
}

private char * newstr(STR)
	char * STR;
{
	char * P;

	P = (char *) malloc(strlen(STR)+1);
	if (P != NULL) {
		strcpy(P,STR);
		return P;
	}
	return NULL;
}

private struct statobj * locate_statobj(path)
	char * path;
{
	char STR[1024];
	char * PART[20];
	int K,P,LC;
	char * S;

	if (*path != '/' || strcmp(path,"/") == 0)
		return NULL;
	strcpy(STR,path);
	S = STR+1;
	K = 0;
	PART[K] = S;
	while ((S = (char*)index(S,'/')) != NULL) {
		*S++ = NULL;
		PART[++K] = S;
		if (K >= MAX_LEVEL)
			return NULL;
	}
	LC = K+1;
	expire_stats();
	
	for (K = 0; K < LC && STATS[K].NAME != NULL && strcmp(STATS[K].NAME,PART[K]) == 0; K++);
	if (K == LC) {
		K--;
		return &STATS[K];
	} else {
		release_stats(K);
		for (P = K; P < LC; P++) {
			STATS[P].NAME = newstr(PART[P]);
			STATS[P].STAT.st_nlink = -1;
			STATS[P].FN = VAL_INVALID;
			STATS[P].RS = VAL_INVALID;
		}
		return &STATS[LC-1];
	}
}
	
OSstat(path,buf)
	char * path;
	struct stat *buf;
{
	struct stat B;
	struct statobj * CE;

	if (DBOSI)
		printf("OSstat=%s\n",path);

	CE = locate_statobj(path);
	if (CE != NULL) {
		if (CE->STAT.st_nlink != -1) {
			if (DBOSI)
				printf("OSstat=cache path\n");
			bcopy(&CE->STAT,buf,sizeof(struct stat));
			return 0;
		}
		if (cwd_stat(path,&B) == 0) {
			if (DBOSI)
				printf("OSstat=caching path\n");
			bcopy(&B,&CE->STAT,sizeof(struct stat));
			CE->VAL_TIME = CUR_TIME+EXP_TIME;
			bcopy(&B,buf,sizeof(struct stat));
			return 0;
		}
		return -1;
	}
	if (DBOSI)
		printf("OSstat=not cached\n");
	return cwd_stat(path,buf);
}

OSfinderinfo(path)
	char * path;
{
	char pp[MAXPATHLEN];
	struct stat S;
	struct statobj * CE;

	CE = locate_statobj(path);
	if (CE != NULL) {
		if (CE->FN != VAL_INVALID)
			return CE->FN;
		strcpy(pp,path);
		toFinderInfo(pp,"");
		if (cwd_stat(pp,&S) < 0 || !S_ISDIR(S.st_mode))
			CE->FN = VAL_NO;
		else
			CE->FN = VAL_OK;
		CE->VAL_TIME = CUR_TIME+EXP_TIME;
		return CE->FN;
	}
	strcpy(pp,path);
	toFinderInfo(pp,"");
	if (cwd_stat(pp,&S) < 0 || !S_ISDIR(S.st_mode))
		return 0;
	else
		return 1;
}

OSresourcedir(path)
	char * path;
{
	char pp[MAXPATHLEN];
	struct stat S;
	struct statobj * CE;

	CE = locate_statobj(path);
	if (CE != NULL) {
		if (CE->RS != VAL_INVALID)
			return CE->RS;
		strcpy(pp,path);
		toResFork(pp,"");
		if (cwd_stat(pp,&S) < 0 || !S_ISDIR(S.st_mode))
			CE->RS = VAL_NO;
		else
			CE->RS = VAL_OK;
		CE->VAL_TIME = CUR_TIME+EXP_TIME;
		return CE->RS;
	}
	strcpy(pp,path);
	toResFork(pp,"");
	if (cwd_stat(pp,&S) < 0 || !S_ISDIR(S.st_mode))
		return 0;
	else
		return 1;
}

OSflush_stat()
{
	time(&CUR_TIME);
	if (DBOSI)
		printf("OSflush_stat\n");
	release_stats(0);
}

OSstat_cache_update()
{
	time(&CUR_TIME);
	EXPIRE_REQ = 1;
}
\Rogue\Monster\
else
  echo "will not over write ./afpspd.c"
fi
if `test ! -s ./patches`
then
echo "writing ./patches"
cat > ./patches << '\Rogue\Monster\'
*** afpdt.c.prespd	Mon Jan 15 11:16:17 1990
--- afpdt.c	Tue Jan 16 15:46:23 1990
***************
*** 207,212 ****
--- 207,214 ----
    dt->dt_afd = -1;
    dt->dt_rootd = VolRootD(dt->dt_ivol);
  
+   OScd(pathstr(dt->dt_rootd));
+ 
    dt->dt_afd = OpenDesk(dt,DESKTOP_APPL,FALSE,APPLFILEMODE,&wok); /* open or create */
    if (dt->dt_afd >= 0) {		/* success on open? */
      OSLockFileforRead(dt->dt_afd);
***************
*** 230,235 ****
--- 232,238 ----
      OSUnlockFile(dt->dt_ifd);
      if (err < 0) {
        close(dt->dt_ifd);
+       dt->dt_ifd = -1;
        DeskRemove(dt, REMOVEICONIDB);
        if (wok)
  	dt->dt_ifd = OpenDesk(dt,DESKTOP_ICON, TRUE,ICONFILEMODE,&wok);
***************
*** 770,775 ****
--- 773,779 ----
  					/* need to write out stuff */
    if (dt->dt_ifd >= 0)			/* if open, then */
      (void)close(dt->dt_ifd);		/* close desktop file */
+     dt->dt_ifd = -1;
  #ifdef notdef
    /* really need to map thorugh and release all storage */
    free((char *)dt);			/* release desktop storage */
***************
*** 1426,1431 ****
--- 1430,1436 ----
        return;
      if (!wok) {
        (void)close(dt->dt_afd);
+       dt->dt_afd = -1;
        return;
      }
    }
*** afpos.c.org	Thu Dec 14 13:26:26 1989
--- afpos.c	Mon Jan 15 13:43:34 1990
***************
*** 1182,1191 ****
    if (DBOSI)
      printf("OSFileDirInfo on %s\n",path);
  
!   if (stat(path,&buf) != 0) {		/* file exists? */
  #ifdef NOCASEMATCH
      noCaseFind(path);			/* case-insensitive */
!     if (stat(path,&buf) != 0) {		/* file exists? */
        if (idir)				/* was in directory tree? */
          Idrdirid(ipdir, idir);		/* invalidate the entry then */
        return(aeObjectNotFound);		/* no... */
--- 1182,1191 ----
    if (DBOSI)
      printf("OSFileDirInfo on %s\n",path);
  
!   if (OSstat(path,&buf) != 0) {		/* file exists? */
  #ifdef NOCASEMATCH
      noCaseFind(path);			/* case-insensitive */
!     if (OSstat(path,&buf) != 0) {		/* file exists? */
        if (idir)				/* was in directory tree? */
          Idrdirid(ipdir, idir);		/* invalidate the entry then */
        return(aeObjectNotFound);		/* no... */
***************
*** 1290,1300 ****
    int i;
  
    OSfname(p_ath,idirid,"",F_DATA);
!   i = stat(p_ath, &stb);
  #ifdef NOCASEMATCH
    if(i != 0) {
      noCaseFind(p_ath);
!     i = stat(p_ath, &stb);
    }
  #endif NOCASEMATCH
    if (i == 0) {
--- 1290,1300 ----
    int i;
  
    OSfname(p_ath,idirid,"",F_DATA);
!   i = OSstat(p_ath, &stb);
  #ifdef NOCASEMATCH
    if(i != 0) {
      noCaseFind(p_ath);
!     i = OSstat(p_ath, &stb);
    }
  #endif NOCASEMATCH
    if (i == 0) {
***************
*** 1301,1306 ****
--- 1301,1307 ----
      if (S_ISDIR(stb.st_mode))
        idirid->flags |= DID_DATA;
  #ifndef NOLSTAT
+ #ifdef notdef
      if (lstat(p_ath, &stb) != 0) { /* shouldn't fail! */
        idirid->flags = DID_VALID;
        return;
***************
*** 1318,1345 ****
--- 1319,1361 ----
        /* really shouldn't need to mask it - means we are overinc'ed */
        idirid->flags |= ((i << DID_SYMLINKS_SHIFT) & DID_SYMLINKS);
      }
+ #endif notdef
      /* don't follow symbolic links here! */
+    if (idirid->flags & DID_DATA) {  /* Dan */
      strcpy(path,p_ath);
      toFinderInfo(path,"");
+ #ifdef notdef
      if (lstat(path, &stb) == 0)
        if (S_ISDIR(stb.st_mode))
+ #endif notdef
+     if (OSfinderinfo(p_ath))
  	idirid->flags |= DID_FINDERINFO;
      strcpy(path,p_ath);
      toResFork(path,"");
+ #ifdef notdef
      if (lstat(path, &stb) == 0)
        if (S_ISDIR(stb.st_mode))
+ #endif notdef
+     if (OSresourcedir(p_ath))
  	idirid->flags |= DID_RESOURCE;
+    }
  #else
      /* no symolic links then */
      strcpy(path,p_ath);
      toFinderInfo(path,"");
+ #ifdef notdef
      if (stat(path, &stb) == 0)
        if (S_ISDIR(stb.st_mode))
+ #endif notdef
+     if (OSfinderinfo(p_ath)
  	idirid->flags |= DID_FINDERINFO;
      strcpy(path,p_ath);
      toResFork(path,"");
+ #ifdef notdef
      if (stat(path, &stb) == 0)
        if (S_ISDIR(stb.st_mode))
+ #endif notdef
+     if (OSresourcedir(p_ath)
  	idirid->flags |= DID_RESOURCE;
  #endif
    }
***************
*** 1372,1378 ****
    fdp->fdp_parms.fp_parms.fp_dflen = buf->st_size;
    fdp->fdp_parms.fp_parms.fp_rflen = 0;
  
!   if (bm & FP_RFLEN) {
      toResFork(rpath,fn);		/* convert to rsrc name */
      if (stat(rpath,&stb) != 0)		/* to figure size of resource fork */
        return(noErr);
--- 1388,1394 ----
    fdp->fdp_parms.fp_parms.fp_dflen = buf->st_size;
    fdp->fdp_parms.fp_parms.fp_rflen = 0;
  
!   if ((bm & FP_RFLEN) && ipdir != NULL && (ipdir->flags & DID_RESOURCE)) {  /* Dan */
      toResFork(rpath,fn);		/* convert to rsrc name */
      if (stat(rpath,&stb) != 0)		/* to figure size of resource fork */
        return(noErr);
*** afposenum.c.prespd	Wed Jan 17 10:12:27 1990
--- afposenum.c	Wed Jan 17 10:17:46 1990
***************
*** 256,262 ****
    if (ec != NILECE && ec->ece_lock)	/* found and locked? */
      return(ec);				/* then being enumerated, return */
  
!   if (stat(pathstr(dirid),&stb) != 0) {	/* else do a stat for checks */
      Idrdirid(Ipdirid(dirid),dirid);	/* unlink from directory tree */
      return(NILECE);			/* nothing there... */
    }
--- 256,262 ----
    if (ec != NILECE && ec->ece_lock)	/* found and locked? */
      return(ec);				/* then being enumerated, return */
  
!   if (OSstat(pathstr(dirid),&stb) != 0) {	/* else do a stat for checks */
      Idrdirid(Ipdirid(dirid),dirid);	/* unlink from directory tree */
      return(NILECE);			/* nothing there... */
    }
***************
*** 289,298 ****
  struct stat *stb;
  {
    char *path = pathstr(dirid);
  
    if (DBENU)
      printf("EC_Load: adding %s\n",path);
!   
    ec->ece_cnt = scandir(path,&ec->ece_nlst,iselect,0);
  
    if (ec->ece_cnt < 0) {
--- 289,300 ----
  struct stat *stb;
  {
    char *path = pathstr(dirid);
+   extern char * cwd_path();
  
    if (DBENU)
      printf("EC_Load: adding %s\n",path);
!   path = cwd_path(path);
! 
    ec->ece_cnt = scandir(path,&ec->ece_nlst,iselect,0);
  
    if (ec->ece_cnt < 0) {
*** afposfi.c.prespd	Mon Jan 15 11:13:25 1990
--- afposfi.c	Mon Jan 15 11:15:58 1990
***************
*** 278,284 ****
      if (DBOSI)
        printf("fc_readent: reading %s\n",path);
  
!     fd = open(path,O_RDONLY);
  #ifdef NOCASEMATCH
      if(fd < 0) {
        noCaseFind(path);
--- 278,284 ----
      if (DBOSI)
        printf("fc_readent: reading %s\n",path);
  
!     fd = cwd_open(path,O_RDONLY);
  #ifdef NOCASEMATCH
      if(fd < 0) {
        noCaseFind(path);
***************
*** 342,354 ****
    /* convert name to internal name */
    OSfname(path,fe->fe_pdir,fe->fe_fnam,F_DATA); /* create plain name */
  #ifdef NOCASEMATCH
!   if (stat(path,&stb) != 0) {		/* check if it exists */
      noCaseFind(path);
!     if (stat(path,&stb) != 0)		/* check if it exists */
        return(aeObjectNotFound);		/* no... */
    }
  #else NOCASEMATCH
!   if (stat(path,&stb) != 0)		/* check if it exists */
      return(aeObjectNotFound);		/* no... */
  #endif NOCASEMATCH
    if (S_ISDIR(stb.st_mode)) {
--- 342,354 ----
    /* convert name to internal name */
    OSfname(path,fe->fe_pdir,fe->fe_fnam,F_DATA); /* create plain name */
  #ifdef NOCASEMATCH
!   if (OSstat(path,&stb) != 0) {		/* check if it exists */
      noCaseFind(path);
!     if (OSstat(path,&stb) != 0)		/* check if it exists */
        return(aeObjectNotFound);		/* no... */
    }
  #else NOCASEMATCH
!   if (OSstat(path,&stb) != 0)		/* check if it exists */
      return(aeObjectNotFound);		/* no... */
  #endif NOCASEMATCH
    if (S_ISDIR(stb.st_mode)) {
*** afpserver.c.prespd	Mon Jan 15 11:21:33 1990
--- afpserver.c	Mon Jan 15 13:39:02 1990
***************
*** 68,73 ****
--- 68,74 ----
  #define DSPF_DMPOUT 02
  #define DSPF_DOESSPWRITE 0x4	/* needs more args.. */
  #define DSPF_DMPBOTH (DSPF_DMPIN | DSPF_DMPOUT)
+ #define DSPF_FSTAT 0x8
    int   dsp_cnt;
  #ifndef NORUSAGE
    struct timeval dsp_utime;
***************
*** 123,136 ****
    {AFPChgPasswd, FPChgPasswd, "ChangePassword", 0, 0},
    {AFPCloseVol,FPCloseVol,"CloseVol",0,0},
    {AFPCloseDir,FPCloseDir,"CloseDir",0,0},
!   {AFPCloseFork,FPCloseFork,"CloseFork",0,0},
!   {AFPCopyFile,FPCopyFile,"CopyFile",0,0},
    {AFPCreateDir,FPCreateDir,"CreateDir",0,0},
!   {AFPCreateFile,FPCreateFile,"CreateFile",0,0},
!   {AFPDelete,FPDelete,"Delete",0,0},
    {AFPEnumerate,FPEnumerate,"Enumerate",0,0},
!   {AFPFlush,FPFlush,"Flush",0,0},
!   {AFPFlushFork,FPFlushFork,"FlushFork",0,0},
    {AFPGetForkParms,FPGetForkParms,"GetForkParms",0,0},
    {AFPGetSrvrParms,FPGetSrvrParms,"GetSrvrParms",0,0},
    {AFPGetVolParms,FPGetVolParms,"GetVolParms",0,0},
--- 124,137 ----
    {AFPChgPasswd, FPChgPasswd, "ChangePassword", 0, 0},
    {AFPCloseVol,FPCloseVol,"CloseVol",0,0},
    {AFPCloseDir,FPCloseDir,"CloseDir",0,0},
!   {AFPCloseFork,FPCloseFork,"CloseFork",DSPF_FSTAT,0},
!   {AFPCopyFile,FPCopyFile,"CopyFile",DSPF_FSTAT,0},
    {AFPCreateDir,FPCreateDir,"CreateDir",0,0},
!   {AFPCreateFile,FPCreateFile,"CreateFile",DSPF_FSTAT,0},
!   {AFPDelete,FPDelete,"Delete",DSPF_FSTAT,0},
    {AFPEnumerate,FPEnumerate,"Enumerate",0,0},
!   {AFPFlush,FPFlush,"Flush",DSPF_FSTAT,0},
!   {AFPFlushFork,FPFlushFork,"FlushFork",DSPF_FSTAT,0},
    {AFPGetForkParms,FPGetForkParms,"GetForkParms",0,0},
    {AFPGetSrvrParms,FPGetSrvrParms,"GetSrvrParms",0,0},
    {AFPGetVolParms,FPGetVolParms,"GetVolParms",0,0},
***************
*** 139,157 ****
    {AFPLogout,FPLogout,"Logout",0,0},
    {AFPMapID,FPMapID,"MapID",0,0},
    {AFPMapName,FPMapName,"MapName",0,0},
!   {AFPMove,FPMove,"Move",0,0},
    {AFPOpenVol,FPOpenVol,"OpenVol",0,0},
    {AFPOpenDir,FPOpenDir,"OpenDir",0,0},
!   {AFPOpenFork,FPOpenFork,"OpenFork",0,0},
    {AFPRead,FPRead,"Read",0,0},
!   {AFPRename,FPRename,"Rename",0,0},
!   {AFPSetDirParms,FPSetDirParms,"SetDirParms",0,0},
!   {AFPSetFileParms,FPSetFileParms,"SetFileParms",0,0},
!   {AFPSetForkParms,FPSetForkParms,"SetForkParms",0,0},
!   {AFPSetVolParms,FPSetVolParms,"SetVolParms",0,0},
!   {AFPWrite,FPWrite,"Write",DSPF_DOESSPWRITE,0},
    {AFPGetFileDirParms,FPGetFileDirParms,"GetFileDirParms",0,0},
!   {AFPSetFileDirParms,FPSetFileDirParms,"SetFileDirParms",0,0},
    {AFPOpenDT,FPOpenDT,"OpenDT",0,0},
    {AFPCloseDT,FPCloseDT,"CloseDT",0,0},
    {AFPGetIcon,FPGetIcon,"GetIcon",0,0},
--- 140,158 ----
    {AFPLogout,FPLogout,"Logout",0,0},
    {AFPMapID,FPMapID,"MapID",0,0},
    {AFPMapName,FPMapName,"MapName",0,0},
!   {AFPMove,FPMove,"Move",DSPF_FSTAT,0},
    {AFPOpenVol,FPOpenVol,"OpenVol",0,0},
    {AFPOpenDir,FPOpenDir,"OpenDir",0,0},
!   {AFPOpenFork,FPOpenFork,"OpenFork",DSPF_FSTAT,0},
    {AFPRead,FPRead,"Read",0,0},
!   {AFPRename,FPRename,"Rename",DSPF_FSTAT,0},
!   {AFPSetDirParms,FPSetDirParms,"SetDirParms",DSPF_FSTAT,0},
!   {AFPSetFileParms,FPSetFileParms,"SetFileParms",DSPF_FSTAT,0},
!   {AFPSetForkParms,FPSetForkParms,"SetForkParms",DSPF_FSTAT,0},
!   {AFPSetVolParms,FPSetVolParms,"SetVolParms",DSPF_FSTAT,0},
!   {AFPWrite,FPWrite,"Write",DSPF_DOESSPWRITE|DSPF_FSTAT,0},
    {AFPGetFileDirParms,FPGetFileDirParms,"GetFileDirParms",0,0},
!   {AFPSetFileDirParms,FPSetFileDirParms,"SetFileDirParms",DSPF_FSTAT,0},
    {AFPOpenDT,FPOpenDT,"OpenDT",0,0},
    {AFPCloseDT,FPCloseDT,"CloseDT",0,0},
    {AFPGetIcon,FPGetIcon,"GetIcon",0,0},
***************
*** 244,249 ****
--- 245,255 ----
  
    if (statflg) 
      clockend(d);
+ 
+   if (d->dsp_flg & DSPF_FSTAT)
+      OSflush_stat();
+   else
+      OSstat_cache_update();
  
    if (d->dsp_flg & DSPF_DMPOUT)
      DumpBuf(rsp,*rlen,d->dsp_name,cmd);
*** aufs.c.prespd	Wed Jan 17 10:16:06 1990
--- aufs.c	Wed Jan 17 10:17:17 1990
***************
*** 168,174 ****
--- 168,176 ----
    fprintf(stderr,"\t-G <username> to set guest id for <anonymous> logins\n");
    fprintf(stderr,"\t-P LookAsidePasswordFile for scrambled transactions\n");
    fprintf(stderr,"\t-U <number> to allow <number> sessions\n");
+ #ifdef notdef
    fprintf(stderr,"\t-c directory to specify a directory to coredump to\n");
+ #endif notdef
    fprintf(stderr,"\t-l file to send logfile to other than <servername>.log\n");
    fprintf(stderr,"\t-S <n> limit responses to <n> packets\n");
    fprintf(stderr,"\t-R <n> limit remote to sending <n> packets\n");
***************
*** 443,448 ****
--- 445,451 ----
      allowrandnum(passwdlookaside);
  
  
+ #ifdef notdef
    if (coredir)
      if (chdir(coredir) < 0) {
        perror("chdir for coredumps");
***************
*** 449,454 ****
--- 452,458 ----
        log("chdir to %s for coredumps failed",coredir);
      } else
        log("***CORE DUMPS WILL BE IN %s",coredir);
+ #endif notdef
      
    /* Get server info once and stash away*/
    srvinfolen = GetSrvrInfo(rspbuf,srvrname,aufsicon,aufsiconsize);
*** /usr/local/src/Mac.rutgers/cap/cap50/applications/aufs/Makefile.m4	Mon Oct 16 19:07:50 1989
--- Makefile.m4	Mon Jan 15 13:42:39 1990
***************
*** 44,55 ****
  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
  	afpdt.c afpdid.c afposenum.c  afpavl.c \
  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! 	afpudb.c afposncs.c
  OBJS=afpos.o afpvols.o afpfile.o \
  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
  	afposfi.o afpgc.o afppasswd.o aufsv.o \
! 	afpudb.o afposncs.o
  SYMLINKS=att_getopt.c
  
  all:	aufs 
--- 44,55 ----
  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
  	afpdt.c afpdid.c afposenum.c  afpavl.c \
  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! 	afpudb.c afposncs.c afpspd.c
  OBJS=afpos.o afpvols.o afpfile.o \
  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
  	afposfi.o afpgc.o afppasswd.o aufsv.o \
! 	afpudb.o afposncs.o afpspd.o
  SYMLINKS=att_getopt.c
  
  all:	aufs 
*** /usr/local/src/Mac.rutgers/cap/cap50/applications/aufs/Makefile	Mon Oct 16 19:07:41 1989
--- Makefile	Mon Jan 15 13:42:02 1990
***************
*** 53,64 ****
  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
  	afpdt.c afpdid.c afposenum.c  afpavl.c \
  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! 	afpudb.c afposncs.c
  OBJS=afpos.o afpvols.o afpfile.o \
  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
  	afposfi.o afpgc.o afppasswd.o aufsv.o \
! 	afpudb.o afposncs.o
  SYMLINKS=att_getopt.c
  
  all:	aufs 
--- 53,64 ----
  	afpmisc.c afpserver.c aufsicon.c abmisc2.c \
  	afpdt.c afpdid.c afposenum.c  afpavl.c \
  	afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! 	afpudb.c afposncs.c afpspd.c
  OBJS=afpos.o afpvols.o afpfile.o \
  	afpmisc.o afpserver.o aufsicon.o abmisc2.o \
  	afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
  	afposfi.o afpgc.o afppasswd.o aufsv.o \
! 	afpudb.o afposncs.o afpspd.o
  SYMLINKS=att_getopt.c
  
  all:	aufs 
\Rogue\Monster\
else
  echo "will not over write ./patches"
fi
echo "Finished archive 1 of 1"
# if you want to concatenate archives, remove anything after this line
exit