Patch #:	none yet
Type:		operational change
Priority:	none
Modification:	add support for AFP2.2 extended 8-byte size/free fields
Modification:	add support for AFP2.2 (late edition) allocation block size
IMPORTANT:
IMPORTANT:	This patch assumes CAP at patch level 198 plus asip.patch
IMPORTANT:	plus cicon.patch
IMPORTANT:
IMPORTANT:	This is an interim patch only. You will need to keep this
IMPORTANT:	patch file in order to reverse the code changes before patch
IMPORTANT:	199 can be applied without error.
IMPORTANT:
File:		cap60/applications/aufs/afpvols.h
File:		cap60/applications/aufs/afpvols.c
File:		cap60/applications/aufs/afpos.c


*** applications/aufs/afpvols.h.orig	Thu Dec 11 17:00:38 1997
--- applications/aufs/afpvols.h		Fri Aug  7 11:54:04 1998
***************
*** 40,45 ****
--- 40,48 ----
    sdword v_bdate;		/* volume backup date */
    dword v_size;			/* size of volume in bytes */
    dword v_free;			/* free bytes on volume */
+   byte v_esize[8];		/* size of volume in bytes */
+   byte v_efree[8];		/* free bytes on volume */
+   dword v_allocb;		/* allocation block size */
  } VolEntry, *VolPtr;		/* user volume table */
  
  #define NILVOL ((VolPtr) 0)
*** applications/aufs/afpvols.c.orig	Thu Dec 11 16:57:43 1997
--- applications/aufs/afpvols.c		Fri Aug  7 12:18:50 1998
***************
*** 70,75 ****
--- 70,78 ----
    PAKB(VolPtr,P_DWRD,v_free,VP_FREE),	/* free bytes */
    PAKB(VolPtr,P_DWRD,v_size,VP_SIZE),	/* size in bytes */
    PKSB(VolPtr,P_OSTR,v_name,VP_NAME),	/* name of volume */
+   PKSB(VolPtr,P_BYTS,v_efree,VP_EFREE), /* extended free bytes */
+   PKSB(VolPtr,P_BYTS,v_esize,VP_ESIZE), /* extended total bytes */
+   PAKB(VolPtr,P_DWRD,v_allocb,VP_ALLOC),/* allocation block size */
    PACKEND()
  };
  
***************
*** 871,876 ****
--- 874,891 ----
  	    fprintf(dbg, "Volume Name");
  	    j++;
  	    break;
+ 	  case 9:
+ 	    fprintf(dbg, "Extnd Bytes Free");
+ 	    j++;
+ 	    break;
+ 	  case 10:
+ 	    fprintf(dbg, "Extnd Bytes Totl");
+ 	    j++;
+ 	    break;
+ 	  case 11:
+ 	    fprintf(dbg, "Alloc Blk Sz");
+ 	    j++;
+ 	    break;
  	  default:
  	    fprintf(dbg, "Unknwn Bit");
  	    j++;
***************
*** 967,972 ****
--- 982,1002 ----
  	    fprintf(dbg, "\"\n");
  	    rl -= 2;
  	    r += 2;
+ 	    break;
+ 	  case 9:
+ 	    fprintf(dbg, "\tExtended Bytes Free: %08x%08x\n",get4(r),get4(r+4));
+ 	    rl -= 8;
+ 	    r += 8;
+ 	    break;
+ 	  case 10:
+ 	    fprintf(dbg, "\tExtended Bytes Totl: %08x%08x\n",get4(r),get4(r+4));
+ 	    rl -= 8;
+ 	    r += 8;
+ 	    break;
+ 	  case 11:
+ 	    fprintf(dbg, "\tAlloc Blk Sz: %d\n", get4(r));
+ 	    rl -= 4;
+ 	    r += 4;
  	    break;
  	  default:
  	    fprintf(dbg, "\tUnknwn Bit: %d\n", i);
*** applications/aufs/afpos.c.orig	Thu Dec 11 17:01:58 1997
--- applications/aufs/afpos.c		Fri Aug  7 12:21:39 1998
***************
*** 2410,2415 ****
--- 2410,2518 ----
  }
  
  /*
+  * set the extended volume size and allocation block size
+  * parameters defined by AFP 2.2
+  *
+  * size, free and blocks are 32-bit numbers.
+  * We want to end up with a 64-bit number in
+  * network-byte-order.
+  *
+  * For the moment we note that block-sizes
+  * are usually a simple power of two so we
+  * just bit-shift the original numbers.
+  *
+  */
+ 
+ void
+ extendedVolSize(v, size, free, blk)
+ VolPtr v;
+ dword size, free, blk;
+ {
+   int off;
+   int i, j;
+   int shift;
+ 
+   v->v_allocb = blk;
+ 
+   bzero((char *)v->v_esize, sizeof(v->v_esize));
+   bzero((char *)v->v_efree, sizeof(v->v_efree));
+ 
+   switch (blk) {
+     case 1:
+     case 2:
+     case 4:
+     case 8:
+     case 16:
+     case 32:
+     case 64:
+     case 128:
+       off = 0;
+       break;
+     case 256:
+     case 512:
+     case 1024:
+     case 2048:
+     case 4096:
+     case 8192:
+     case 16384:
+     case 32768:
+       off = 1;
+       break;
+     case 65536:
+     case 131072:
+     case 262144:
+       off = 2;
+       break;
+     default:
+       /* set some arbitrary number */
+       v->v_esize[4] = 0x80;
+       v->v_efree[4] = 0x40;
+       return;
+       break;
+   }
+ 
+   /*
+    * initialize the array in network byte
+    * order. If the multiplier is 1, 256 or
+    * 65536 there is nothing else to do.
+    *
+    */
+   v->v_esize[7-off] = size & 0xff;
+   v->v_esize[6-off] = (size >> 8) & 0xff;
+   v->v_esize[5-off] = (size >> 16) & 0xff;
+   v->v_esize[4-off] = (size >> 24) & 0xff;
+ 
+   v->v_efree[7-off] = free & 0xff;
+   v->v_efree[6-off] = (free >> 8) & 0xff;
+   v->v_efree[5-off] = (free >> 16) & 0xff;
+   v->v_efree[4-off] = (free >> 24) & 0xff;
+ 
+   if (blk == 1 || blk == 256 || blk == 65536)
+     return;
+ 
+   /*
+    * now bit shift each group of bytes
+    *
+    */
+   shift = (blk < 256) ? blk : ((blk < 65536) ? (blk/256) : (blk/65536));
+ 
+   for (i = 1; i < 20; i++) {
+     for (j = 0 ; j < 8; j++) {
+       v->v_esize[j] <<= 1;
+       v->v_efree[j] <<= 1;
+       if (j < 7 && (v->v_esize[j+1] & 0x80))
+         v->v_esize[j] |= 1;
+       if (j < 7 && (v->v_efree[j+1] & 0x80))
+         v->v_efree[j] |= 1;
+     }
+     if (shift == (0x0001 << i))
+       break;
+   }
+ 
+   return;
+ }
+ 
+ /*
   * OSErr OSVolInfo(VolPtr v)
   *
   * Update volume information for volume pointed to by v.
***************
*** 2448,2459 ****
--- 2551,2565 ----
  # endif SOLARIS
  #endif USESTATFS
    time_t sometime;
+   void extendedVolSize();
    void scaleVolSize();
  
    if (stat(path,&buf) != 0)	/* directory exists? */
      return(aeObjectNotFound);	/* no... */
    if (!(S_ISDIR(buf.st_mode)))	/* check for directory */  
      return(aeParamErr);		/* not a directory! */
+   if (bitmap & ~VP_ALL)
+     return(aeBitMapErr);	/* unknown request bit */
      
    if (bitmap & VP_CDATE) {
      /* pick out the earliest date for mac creation time */
***************
*** 2484,2490 ****
        v->v_attr &= ~V_RONLY;	/* clear read-only */
    }
  
!   if ((bitmap & (VP_FREE|VP_SIZE)) == 0)
      return(noErr);		/* naught else to do */
  
    /* All the following is good and fine unless: (a) the volume */
--- 2590,2596 ----
        v->v_attr &= ~V_RONLY;	/* clear read-only */
    }
  
!   if ((bitmap & (VP_FREE|VP_SIZE|VP_EFREE|VP_ESIZE|VP_ALLOC)) == 0)
      return(noErr);		/* naught else to do */
  
    /* All the following is good and fine unless: (a) the volume */
***************
*** 2516,2521 ****
--- 2622,2629 ----
        dqblk.dqb_bhardlimit != 0) { /* make sure not unlimited */
      v->v_size = dqblk.dqb_bhardlimit*512;
      v->v_free = (dqblk.dqb_bhardlimit-dqblk.dqb_curblocks)*512;
+     extendedVolSize(v, dqblk.dqb_bhardlimit,
+       dqblk.dqb_bhardlimit-dqblk.dqb_curblocks, 512);
      scaleVolSize(v);
      return(noErr);
    }
***************
*** 2532,2537 ****
--- 2640,2647 ----
           dqblk.dqb_bhardlimit != 0) {
          v->v_size = dqblk.dqb_bhardlimit*512;
          v->v_free = (dqblk.dqb_bhardlimit-dqblk.dqb_curblocks)*512;
+ 	extendedVolSize(v, dqblk.dqb_bhardlimit,
+ 	  dqblk.dqb_bhardlimit-dqblk.dqb_curblocks, 512);
  	scaleVolSize(v);
          return(noErr);
      }
***************
*** 2548,2553 ****
--- 2658,2664 ----
        v->v_size = ubuf.f_tfree*1024;
      }
      v->v_free = ubuf.f_tfree*1024;
+     extendedVolSize(v, ubuf.f_tfree, ubuf.f_tfree, 1024);
      scaleVolSize(v);
      return(noErr);
    }
***************
*** 2558,2563 ****
--- 2669,2675 ----
      v->v_size = fsbuf.f_frsize * fsbuf.f_blocks;
      /* limiting factor: cannot report on overutilization of a volume */
      v->v_free = (fsbuf.f_bavail < 0) ? 0 : fsbuf.f_frsize * fsbuf.f_bavail;
+     extendedVolSize(v, fsbuf.f_blocks, fsbuf.f_bavail, fsbuf.f_frsize);
      scaleVolSize(v);
      return(noErr);
    }
***************
*** 2567,2572 ****
--- 2679,2685 ----
      v->v_size = fsbuf.f_bsize * fsbuf.f_blocks;
      /* limiting factor: cannot report on overutilization of a volume */
      v->v_free = (fsbuf.f_bfree < 0) ? 0 : fsbuf.f_bsize * fsbuf.f_bfree;
+     extendedVolSize(v, fsbuf.f_blocks, fsbuf.f_bfree, fsbuf.f_bsize);
      scaleVolSize(v);
      return(noErr);
    }
***************
*** 2581,2590 ****
--- 2694,2705 ----
      v->v_size = fsbuf.f_fsize * fsbuf.f_blocks;
      /* limiting factor: cannot report on overutilization of a volume */
      v->v_free = (fsbuf.f_bavail < 0) ? 0 : fsbuf.f_fsize * fsbuf.f_bavail;
+     extendedVolSize(v, fsbuf.f_blocks, fsbuf.f_bavail, fsbuf.f_fsize);
  #else  /* __386BSD__ || __osf__ */
      v->v_size = fsbuf.f_bsize * fsbuf.f_blocks;
      /* limiting factor: cannot report on overutilization of a volume */
      v->v_free = (fsbuf.f_bavail < 0) ? 0 : fsbuf.f_bsize * fsbuf.f_bavail;
+     extendedVolSize(v, fsbuf.f_blocks, fsbuf.f_bavail, fsbuf.f_bsize);
  #endif /* __386BSD__ || __osf__ */
      scaleVolSize(v);
      return(noErr);
***************
*** 2598,2603 ****
--- 2713,2719 ----
    v->v_size = 0x1000000;		/* some random number */
    v->v_free = 0x1000000;		/* same random number */
  #endif SIZESERVER
+   extendedVolSize(v, 0x1000000, 0x1000000, 512);
    scaleVolSize(v);
    return(noErr);			/* all ok */
  }
***************
*** 2694,2699 ****
--- 2810,2816 ----
    struct fs_data buffer[NUMGETMNTBUF];
    struct fs_data *bp;
    int nbytes = sizeof(struct fs_data)*NUMGETMNTBUF;
+   void extendedVolSize();
    void scaleVolSize();
  
    if (!oldgetmnt) {
***************
*** 2723,2728 ****
--- 2840,2847 ----
    /* bfreen must be "good" in that it cannot go below 0 when */
    /* out of space -- it is unsigned! */
    v->v_free = ((getuid() == 0) ? bp->fd_req.bfree : bp->fd_req.bfreen) * 1024;
+   extendedVolSize(v, bp->fd_req.btot,
+     (getuid() == 0) ? bp->fd_req.bfree : bp->fd_req.bfreen, 1024);
    scaleVolSize(v);
    return(noErr);
  }
