[comp.protocols.appletalk] AUFS patch to get v_free from super block

john@trigraph.UUCP (John Chew) (05/20/89)

The subject pretty much says it all.  I had to patch AUFS here
to give accurate volume free space information even without
fancy system calls like statfs() or getmnt(), so that I could
do a huuuge finder copy without the finder complaining that there
was insufficient space on the destination device.

The information is in the super block of the appropriate raw disk 
device.  If you (i.e. the user as which you've logged into AUFS)
do not have permission to read these devices, the usual bogus 
16 384K figure is returned.

The patch is short, might be useful to someone out there, and
applies to just one file (afpos.c), so I have included it here.

John
----- CUT HERE -----
*** afpos.c.orig     Fri May 19 17:40:10 1989
--- afpos.c	Thu May 18 17:59:02 1989
***************
*** 40,45 ****
--- 40,46 ----
   *   information doesn't tell us how much space is there -- only
   *   how much is free and we need both
   *  USESTATFS - statfs is the Sun NFS solution to volume information.
+  *  USESBINFO - use superblock information to get free space
   *
   *  aux has a couple of "ifdefs".
   *   - one to set full BSD compatibility
***************
*** 128,133 ****
--- 129,140 ----
  # include <sys/utsname.h>
  #endif
  
+ #ifdef USESBINFO
+ # include <sys/fs.h>
+ # include <fstab.h>
+ # include <mtab.h>
+ #endif
+ 
  #include <netat/afp.h>
  #include <netat/afpcmd.h>		/* flags should be in misc  */
  #include "afps.h"			/* common includes */
***************
*** 347,352 ****
--- 354,362 ----
  #ifdef USESUNQUOTA
    log(" Configured: SUN quota system");
  #endif
+ #ifdef USESBINFO
+   log(" Configured: Volume space information: super block info");
+ #endif
  #ifndef USESUNQUOTA
  /* sunquota turns on usequota */
  # ifdef USEQUOTA
***************
*** 1834,1842 ****
      return(noErr);
    }
  #endif
!   v->v_size = 0x1000000;		/* some random number */
!   v->v_free = 0x1000000;		/* same random number */
!   return(noErr);			/* all ok */
  }
  
  #ifdef USEGETMNT
--- 1844,1894 ----
      return(noErr);
    }
  #endif
! #ifdef USESBINFO
!   {
!   int fd;			/* file descriptor */
!   long availblks, used;
!   struct stat stb;
!   struct fstab *fsp;
!   union {			/* the super block */
!     struct fs iu_fs;
!     char dummy[SBSIZE];
!     } sb;
! #  define sblock sb.iu_fs
! 
!   sync();
! 
!   /* find the file system entry corresponding to our device */
!   (void) setfsent();
!   while (fsp = getfsent()) 
!     if (unix_stat(fsp->fs_spec, &stb) == noErr && stb.st_rdev == buf.st_dev)
!       break;
!   (void) endfsent();
!   if (fsp == NULL) goto sbabort;
! 
!   /* open special file and read super block */
!   if (noErr != unix_open(fsp->fs_spec, 0, &fd)) goto sbabort;
!   (void) lseek(fd, (long) (SBLOCK * DEV_BSIZE), 0);
!   if (SBSIZE != read(fd, (char *)&sblock, SBSIZE))
!     {
!     (void) unix_close(fd);
!     goto sbabort;
!     }
! 
!   v->v_size = sblock.fs_dsize * sblock.fs_fsize;
!   used = sblock.fs_dsize - sblock.fs_cstotal.cs_nbfree * sblock.fs_frag 
! 	 - sblock.fs_cstotal.cs_nffree;
!   availblks = sblock.fs_dsize * (100 - sblock.fs_minfree) / 100;
!   v->v_free = (availblks > used ? availblks - used : 0) * sblock.fs_fsize;
! 
!   (void) unix_close(fd);
!   return noErr;
! sbabort: ;
!   }
! #endif
!   v->v_size = 0x1000000;    /* some random number */
!   v->v_free = 0x1000000;    /* same random number */
!   return(noErr);      /* all ok */
  }
  
  #ifdef USEGETMNT
----- CUT HERE -----
-- 
john j. chew, iii   		  phone: +1 416 425 3818     AppleLink: CDA0329
trigraph, inc., toronto, canada   {uunet!utai!utcsri,utgpu,utzoo}!trigraph!john
dept. of math., u. of toronto     poslfit@{utorgpu.bitnet,gpu.utcs.utoronto.ca}