mjy@sdti.sdti.com (Michael J. Young) (12/07/88)
Posting-number: Volume 5, Issue 70 Submitted-by: "Michael J. Young" <mjy@sdti.sdti.com> Archive-name: fsanalyze4.1/[art03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 3)." # Contents: chkfile.c fsconfig.h # Wrapped by mjy@sdti on Wed Nov 30 15:54:17 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f chkfile.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"chkfile.c\" else echo shar: Extracting \"chkfile.c\" \(15316 characters\) sed "s/^X//" >chkfile.c <<'END_OF_chkfile.c' Xstatic char sccsid[] = "@(#)$Id: chkfile.c, V4.1 88/11/16 17:29:30 $"; X X/* X * chkfile.c - analyze file X * Version : 4.1 - 88/11/16 17:29:30 X * X * Author : Michael J. Young X * USmail : Software Development Technologies, Inc. X * 375 Dutton Rd X * Sudbury MA 01776 X * UUCP : harvard!sdti!mjy X * Internet : mjy@sdti.SDTI.COM X * X * ========================================================================= X * Note : This program has been placed in the public domain to permit X * unrestricted distribution and use. I have placed no copyright on it, but X * I request that you keep me informed about any enhancements and bug fixes X * you make so I can keep an up-to-date copy for further distribution. X * X * This program is being provided "as is", with no warrantee as to safety or X * accuracy of results. Use at your own risk. X * ========================================================================= X */ X X/* X * Modification History: X * X * Thu Jul 28 15:00:44 EDT 1988 - M. Young (mjy@sdti.SDTI.COM), X * Extracted from fsanalyze.c X * X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy@sdti.SDTI.COM), X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts X * X * Fri Nov 11 16:25:44 EST 1988 - M. Young (mjy@sdti.SDTI.COM), X * Fixed boundary condition error in scan(). X * X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy@sdti.SDTI.COM), X * Placed under SCCS X */ X X#include "fsconfig.h" X#include "fsanalyze.h" X X/* X * chk_indirects : scans a block containing data block numbers, looking X * for block numbers that are not sequential. X */ Xdaddr_t chk_indirects (block, cur_pos, data, inode, lbn) Xdaddr_t block; /* indirect block to check */ Xdaddr_t cur_pos; /* current block offset */ Xstruct file_data *data; /* current file statistics */ Xstruct dinode *inode; /* inode being processed */ Xdaddr_t lbn; /* logical blk_no of 1st data block */ X{ X daddr_t ind_blk[MAXINDIR]; /* holds an indirect block */ X int num_blocks; /* number of data blocks in X * an indirect block */ X daddr_t pos; /* current data block */ X daddr_t new_pos; /* next data block */ X int i; /* loop counter */ X boolean sparse; /* potential sparse X * file detected */ X X num_blocks = nindir(fil_sys); X data->total_blocks += (bsize(fil_sys) / fsize(fil_sys)); X X /* X * the indirect block itself should be in the correct sequence X * with the data blocks X */ X test_fragmentation (block, cur_pos, data); X X /* X * get the indirect block X */ X if (fseek (fsys, block * block_size, 0)){ X error (errno, "\nerror seeking indirect block %ld\n", block); X /* NOTREACHED */ X } X if (fread (ind_blk, sizeof (daddr_t), num_blocks, fsys) != num_blocks){ X error (errno, "\nerror reading indirect block %ld\n", block); X /* NOTREACHED */ X } X pos = block; X X /* X * scan the data blocks looking for numbers out of sequence X */ X sparse = FALSE; X for (i = 0; i < num_blocks; i++){ X new_pos = ind_blk [i]; X if (new_pos == 0){ X sparse = TRUE; X continue; X } X if (sparse){ X data->sparse++; X } X data->data_blocks += (blk_size (fil_sys, inode, lbn+i) / fsize(fil_sys)); X data->total_blocks+= (blk_size (fil_sys, inode, lbn+i) / fsize(fil_sys)); X test_fragmentation (new_pos, pos, data); X pos = new_pos; X } X return pos; X } X X/* X * chk_double_indirects : scans a block containing a list of indirect X * blocks, checking for data block numbers that are out of sequence. X */ Xdaddr_t chk_double_indirects (block, cur_pos, data, inode, lbn) Xdaddr_t block; /* indirect block to check */ Xdaddr_t cur_pos; /* current block offset */ Xstruct file_data *data; /* current file statistics */ Xstruct dinode *inode; /* inode being processed */ Xdaddr_t lbn; /* logical blk_no of 1st data block */ X{ X daddr_t dindirect_blk[MAXINDIR]; /* holds a double-indirect X * block */ X int i; /* loop counter */ X int num_blocks; /* number of indirect blocks X * in a d-i block */ X boolean sparse; /* potential sparse file X * detected */ X X num_blocks = nindir(fil_sys); X data->total_blocks += (bsize(fil_sys) / fsize(fil_sys)); X X /* X * the double-indirect block itself should be in sequence with the X * data blocks X */ X test_fragmentation (block, cur_pos, data); X X /* X * get the d-i block X */ X if (fseek (fsys, block * block_size, 0)){ X error (errno, "\nerror seeking double indirect block %ld\n", X block); X /* NOTREACHED */ X } X if (fread (dindirect_blk, sizeof (daddr_t), num_blocks, fsys) != num_blocks){ X error (errno, "\nerror reading double indirect block %ld\n", X block); X /* NOTREACHED */ X } X X /* X * scan through the d-i block X */ X cur_pos = block; X sparse = FALSE; X for (i = 0; i < num_blocks; i++){ X if (dindirect_blk[i] == 0){ X sparse = TRUE; X continue; X } X if (sparse){ X data->sparse++; X } X cur_pos = chk_indirects (dindirect_blk[i], X cur_pos, X data, X inode, X lbn + (i * nindir(fil_sys))); X } X return cur_pos; X } X X/* X * chk_triple_indirects : scans a block containing a list of double X * indirect blocks, looking for data block numbers that are out of sequence. X */ Xdaddr_t chk_triple_indirects (block, cur_pos, data, inode, lbn) Xdaddr_t block; /* indirect block to check */ Xdaddr_t cur_pos; /* current block offset */ Xstruct file_data *data; /* current file statistics */ Xstruct dinode *inode; /* inode being processed */ Xdaddr_t lbn; /* log. blk_no of 1st data block */ X{ X daddr_t tindirect_blk[MAXINDIR]; /* holds a triple-indirect X * block */ X int i; /* loop counter */ X int num_blocks; /* number of double-indirect X * blocks in a triple-i blk */ X boolean sparse; /* potential sparse file X * detected */ X X X num_blocks = nindir(fil_sys); X data->total_blocks += (bsize(fil_sys) / fsize(fil_sys)); X X /* X * the triple-indirect block itself should be in sequence with the X * data blocks X */ X test_fragmentation (block, cur_pos, data); X X /* X * get the t-i block X */ X if (fseek (fsys, block * block_size, 0)){ X error (errno, "\nerror seeking triple indirect block %ld\n", X block); X /* NOTREACHED */ X } X if (fread (tindirect_blk, sizeof (daddr_t), num_blocks, fsys) != num_blocks){ X error (errno, "\nerror reading triple indirect block %ld\n", X block); X /* NOTREACHED */ X } X X /* X * scan through the t-i block X */ X cur_pos = block; X sparse = FALSE; X for (i = 0; i < num_blocks; i++){ X if (tindirect_blk[i] == 0){ X sparse = TRUE; X continue; X } X if (sparse){ X data->sparse++; X } X cur_pos = chk_double_indirects (tindirect_blk[i], X cur_pos, X data, X inode, X lbn + (i * nindir (fil_sys) * nindir (fil_sys))); X } X return cur_pos; X } X X/* X * chk_file : scans the data block numbers of an i-node, looking for X * block numbers that are out of sequence, and would thus result in excess X * track-to-track seeking. This function also checks directory files for X * indirection, and performs a simple consistency check on all file sizes. X */ Xvoid chk_file (inode, inode_number, data) Xstruct dinode *inode; /* inode info structure */ Xint inode_number; /* inode number to be X * checked */ Xstruct file_data *data; /* current file statistics */ X{ X daddr_t pos; /* current block */ X daddr_t new_pos; /* next block in file */ X int i; /* loop counter */ X long file_size; /* file size computed by X * actual byte count */ X boolean sparse; /* potential sparse file X * detected */ X X pos = blk_no (dta_blk (inode, 0)); /* first data block */ X X /* X * do some simple-minded statistics gathering X */ X if (inode->di_nlink > 1){ /* multi-linked files */ X linked_files++; X } X X if (FILE_TYPE (inode) == S_IFDIR){ /* got a directory */ X num_directories++; X } X X /* X * no fragmentation checks for special files or 0-length files X */ X if (IS_SPECIAL (inode->di_mode)){ X num_specials++; X if (debug)printf ("inode %d is special\n", inode_number); X return; X } X X if (inode->di_size == 0){ X if (debug)printf ("inode %d is empty\n", inode_number); X return; /* ignore 0-size files */ X } X X data->data_blocks = data->total_blocks = (blk_size(fil_sys, inode, 1) / fsize (fil_sys)); X if (debug)printf ("blk_size returns %ld\n", blk_size (fil_sys, inode, 1)); X X /* X * scan the data blocks looking for numbers out of sequence X */ X sparse = FALSE; X for (i = 1; i < NDADDR; i++){ X new_pos = blk_no (dta_blk (inode, i)); X if (new_pos == 0){ /* end of file */ X sparse = TRUE; X continue; X } X if (sparse){ X data->sparse++; X } X data->data_blocks += (blk_size (fil_sys, inode, i) / fsize (fil_sys)); X data->total_blocks += (blk_size (fil_sys, inode, i) / fsize (fil_sys)); X if (debug)printf (" blk_size returns %ld\n", blk_size(fil_sys,inode,i)); X test_fragmentation (new_pos, pos, data); X pos = new_pos; X } X X /* X * Indirect block 0, if non-zero, is the number of the block X * which contains the next NINDIR data block numbers. It should X * also be in sequence with the data blocks. X */ X if (blk_no (indir_blk (inode, 0))){ X indirects++; X /* X * if a directory contains indirection, it is too large for X * efficient access. Report it. X */ X if (FILE_TYPE (inode) == S_IFDIR){ X printf ("inode %d is a large directory\n", inode_number); X big_directories++; X } X pos = chk_indirects (blk_no (indir_blk (inode, 0)), X pos, X data, X inode, X NDADDR); X } X X /* X * Indirect block 1, if non-zero, is the number of the block which contains X * the next NINDIR INDIRECT block numbers. It should also be X * in sequence with the data blocks. This block is called a "double- X * indirect" block. X */ X if (blk_no (indir_blk (inode, 1))){ X double_indirects++; X if (rpt_indirects){ X printf ("double indirection : %d\n", inode_number); X } X pos = chk_double_indirects (blk_no (indir_blk (inode, 1)), X pos, X data, X inode, X NDADDR+nindir(fil_sys)); X } X X /* X * Indirect block 2, if non-zero, is the number of the block which contains X * the next NINDIR DOUBLE-INDIRECT block numbers. It should X * also be in sequence with the data blocks. This block is called a X * "triple-indirect" block. X */ X if (blk_no (indir_blk (inode, 2))){ X triple_indirects++; X if (rpt_indirects){ X printf ("triple indirection : %d\n", inode_number); X } X pos = chk_triple_indirects (blk_no (indir_blk (inode, 2)), X pos, X data, X inode, X NDADDR + (nindir (fil_sys) * nindir (fil_sys))); X } X X /* X * detect and display sparse files X */ X if (data->sparse){ X printf ("inode %d is sparse\n", inode_number); X sparse_files++; X } X X /* X * do a simple check to detect possible file-size errors (a la X * fsck phase 1) X */ X file_size = (inode->di_size + (block_size - 1)) / block_size; X data->wasted = (block_size - (inode->di_size % block_size)); X if (file_size != data->data_blocks){ X size_errors++; X if (rpt_errors){ X printf ("inode %d, inconsistent file size : actual blocks = %ld, computed = %ld (%ld bytes)\n", X inode_number, data->data_blocks, X file_size, inode->di_size); X } X } X } X X/* X * scan : scan through each i-node of a file system, compiling statistics X * regarding fragmentation and indirection. X */ Xvoid scan (){ X int i, j; /* loop counters */ X struct dinode i_node[MAXINOPB]; /* holds a block of inodes */ X struct file_data data; /* per-inode statistics */ X X for (i = first_inode; i < num_inodes(fil_sys); i+=inopb(fil_sys)){ X X /* X * for efficiency, read a block of i-nodes at a time X */ X get_inodes (i, i_node, inopb(fil_sys)); X X /* X * scan through each i-node that was read in X */ X for (j = 0; i+j <= num_inodes(fil_sys) && j < inopb(fil_sys); j++){ X if (debug){ X printf ("inode %d = mode %o\r", i+j, i_node[j].di_mode); X } X if (i+j <= 1)continue; /* don't scan i-node 1 */ X if (i_node[j].di_mode != 0){ /* unused i-node ? */ X init_stats (&data, i+j, i_node[j].di_size); X chk_file (&i_node[j], i+j, &data); /* scan blocks in file */ X log_stats (&data); X } X else { X free_inodes++; X } X } X } X } X X/* X * anal_file : analyzes a single file for fragmentation. X */ Xvoid anal_file (ino, fname) Xint ino; /* i-node number */ Xchar *fname; /* filename of this inode */ X{ X struct file_data data; /* current file statistics */ X X struct dinode i_node; /* current inode data */ X X get_inodes (ino, &i_node, 1); X init_stats(&data, ino, i_node.di_size); X chk_file (&i_node, ino, &data); X log_stats (&data); X printf (" %-14s\t%6d %6ld %6ld %6.2f%% %6.1f %ld\n", X fname, data.inode, data.seeks+1, X data.total_blocks, data.fragm*100, X data.rel_cost, data.wasted); X } END_OF_chkfile.c if test 15316 -ne `wc -c <chkfile.c`; then echo shar: \"chkfile.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f fsconfig.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"fsconfig.h\" else echo shar: Extracting \"fsconfig.h\" \(12938 characters\) sed "s/^X//" >fsconfig.h <<'END_OF_fsconfig.h' X/* @(#)$Id: fsconfig.h, V4.1.1.1 88/11/18 17:38:35 $ */ X X/* X * fsconfig.h - fsanalyze configuration-specific definitions X * Version : 4.1.1.1 - 88/11/18 17:38:35 X * X * Author : Michael J. Young X * USmail : Software Development Technologies, Inc. X * 375 Dutton Rd X * Sudbury MA 01776 X * UUCP : harvard!sdti!mjy X * Internet : mjy@sdti.SDTI.COM X * X * ========================================================================= X * Note : This program has been placed in the public domain to permit X * unrestricted distribution and use. I have placed no copyright on it, but X * I request that you keep me informed about any enhancements and bug fixes X * you make so I can keep an up-to-date copy for further distribution. X * ========================================================================= X */ X X/* X * Modification History: X * X * Date Author Description X * ----------- -------- ----------------------------------------------- X * Wed Mar 9 17:51:38 EST 1988 - M. Young (mjy@sdti.SDTI.COM) X * Originated. X * X * Wed Apr 13 17:18:06 EDT 1988 - M. Young (mjy@sdti.SDTI.COM) X * Completed port to BSD. Added fsize(), first_inode, and Sec_per_blk X * macros. X * X * Wed Jun 15 14:06:35 EDT 1988 - M. Young (mjy@sdti.SDTI.COM) X * Added NUMOFFEND macro. X * X * Tue Jul 26 15:27:52 EDT 1988 - M. Young (mjy@sdti.SDTI.COM) X * Modified Opt_interleave and cyl_pos macros to more closely reflect BSD X * placement algorithm (still unsure of this!). X * X * Thu Jul 28 16:43:20 EDT 1988 - M. Young (mjy@sdti.SDTI.COM) X * Opt_interleave formula now makes sense. X * X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy@sdti.SDTI.COM), X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts X * X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy@sdti.SDTI.COM), X * Placed under SCCS X * X * Fri Nov 18 17:37:08 EST 1988 - M. Young (mjy@sdti.SDTI.COM), X * Removed #defines for SUPERBOFF for all but XENIX/286 X */ X X/* X * One of the things fsanalyze displays is a list of the most fragmented X * files. The macro NUMOFFEND determines how many of those files to report. X * The report is in double column format, so the number should be divisible X * by 2. Ideally, this number should be set so that the report fits on X * a single screen. For a 24-line display, the suggested number is 10 X * (5 lines). X */ X#ifndef NUMOFFEND X# define NUMOFFEND 10 /* number of top offenders to report */ X#endif X X/* X * File System types - define _FS_TYPE accordingly X */ X#define FS_ATT 1 /* AT&T File system derivatives, incl Version 7, X * System III, & System V (sVr2 & sVr3) */ X#define FS_BSD 2 /* BSD fast file system derivatives */ X#define FS_BSD_NFS 3 /* BSD fast file system with NFS support */ X X/* X * OS-types -- although the basic structure of the file system remains X * constant, many ports of Unix contain minor modifications. Eventually, X * the following should contain a complete list of special cases. Those X * OS's which do not contain special cases should be referred to as OS_ATT X * or OS_BSD. X */ X#define OS_ATT 1 /* Generic AT&T OS, no special cases */ X#define OS_BSD 2 /* Generic BSD 4.2 or later FFS, no special X * cases */ X#define OS_XENIX_286 4 /* XENIX/286 */ X#define OS_UPORT_286 5 /* Microport System V/AT */ X X#ifndef FS_TYPE X# define FS_TYPE FS_ATT X#endif X X#ifndef OS_TYPE X# define OS_TYPE OS_ATT X#endif X X X/*************************************************************************** X * file system macros * X ***************************************************************************/ X X/* X * File systems based on Version 7 Unix (System III and System V) are X * significantly different than those based on the BSD Fast File System. X * The following macros are defined to facilitate portable access to the X * superblock and inode information. Where possible, macro names X * the BSD <sys/fs.h> are used, and these macros must be created for non X * BSD file systems. X * X * SUPERBOFF Byte offset of the superblock X * DEV_BSIZE Physical device block size (sector size) X * MAXBSIZE Maximum block size of any file system X * MAXINOPB Maximum number of inodes per block (based X * on largest possible block size of any file X * system X * MAXINDIR Maximum number of indirect blocks per block X * (based on largest possible block size of any X * file system) X * inopb(fs) Number of inodes per block of a given file X * system X * nindir(fs) Number of indirect blocks per block in a X * given file system X * bsize(fs) Block size (in bytes) of a given file system X * fsize(fs) Fragment size (in bytes) -- same as bsize() X * in non-BSD file systems X * fssize(fs) Total size of a file system (in blocks of X * bsize(fs) bytes) X * dsize(fs) Number of data blocks in the file system X * isize(fs) Total number of blocks reserved for inode info X * num_inodes(fs) Number of inodes supported by the file system X * first_inode number of first inode in file system X * iblkno(fs) Block number of the first inode in a file X * system (or cylinder group) X * sec_per_cyl(fs) Number of physical sectors per cylinder in X * a given file system X * is_ok(fs) TRUE if the file system is not in need of X * checking (with fsck(1M)) X * opt_interleave(fs) The optimum sector interleave which will result X * in minimum rotational delay. X * Sec_per_blk Number of sectors per logical block X * freespace(fs,res) Total number of free blocks in a file system, X * given a percentage that must be held in reserve X * inode_block(fs,inode) Computes block number which contains inode info X * inode_offset(fs,inode) Computes offset of an inode within its block X * blk_size(fs,inode,lbn) Computes the size of a data block in bytes X * cylinder(fs,blk) Computes cylinder which contains specified X * block X * cyl_pos(fs,blk) Computes relative sector position of the X * specified block in its cylinder. X * NDADDR Number of direct data blocks within inode X * NIADDR Number of indirect data blocks within inode X * dta_blk(blk) Returns pointer to data block within inode X * cast as (char *) for compatibility with X * AT&T file systems. X * indir_blk(blk) Returns pointer to indirect block within inode X * cast as (char *) for compatibility with X * AT&T file systems. X */ X X/* X * Sec_per_blk : Number of physical sectors (size DEV_BSIZE) per logical block. X */ X#define Sec_per_blk (block_size / DEV_BSIZE) X X#if (FS_TYPE == FS_ATT) X X/* X * The following definitions provide the above-listed macros for a X * "conventional" Unix file system. Any versions of Unix that use a X * file system structure that was derived directly from Version 7 Unix X * (e.g., System III, System V, XENIX) use these definitions. X */ X Xtypedef struct filsys superblk_t; /* superblock structure definition */ X X/* SCO XENIX doesn't have SUPERBOFF, so we must set it explicitly. Note X * that XENIX/286 seems to want the value BSIZE*SUPERB (==1024L), yet X * XENIX/386 is "normal" SystemV (512L). X */ X# if (OS_TYPE == OS_XENIX_286) X# define SUPERBOFF (BSIZE*SUPERB) X# endif X X# define DEV_BSIZE 512 X X/* X * MAXBSIZE is defined as the largest possible BSIZE for any file system. X * The largest I have come across in System V ports is 2048. If a larger X * one is encountered, MAXBSIZE should be increased accordingly. X */ X# define MAXBSIZE 2048 X# define MAXINOPB (MAXBSIZE / sizeof (struct dinode)) X# define MAXINDIR (MAXBSIZE / sizeof (daddr_t)) X# ifdef FsINOPB X# define inopb(fs) FsINOPB(fs) X# else X# define inopb(fs) INOPB X# endif X# ifdef FsNINDIR X# define nindir(fs) FsNINDIR(fs) X# else X# define nindir(fs) NINDIR X# endif X X/* X * The following definition is used to determine the logical block size for X * a particular file system. Normally, SBUFSIZE == BSIZE == the logical X * block size. However, in systems that have dual file system support X * enabled (rare), BSIZE is usually set to the block size of the smaller X * file system, whereas SBUFSIZE is set to the larger. If this is X * different in your system, change the following macro accordingly. X */ X# ifdef Fs2b X# define bsize(fs) ((fs)->s_type == Fs2b ? SBUFSIZE : BSIZE) X# else X# define bsize(fs) (BSIZE) X# endif X# define fsize(fs) (bsize(fs)) X X# define fssize(fs) ((fs)->s_fsize) X# define dsize(fs) ((fs)->s_fsize - (fs)->s_isize) X# define isize(fs) ((fs)->s_isize) X# define num_inodes(fs) (((fs)->s_isize-ROOTINO) * inopb(fs)) X# define first_inode 1 X# define iblkno(fs) 2 X# define sec_per_cyl(fs) ((fs)->s_dinfo[1]) X X/* X * Note that the standard check for file system integrity does not work X * on Microport systems because a clean, unmounted file system is not set X * to FsOKAY, but some other undocumented constant. It is therefore X * strongly recommended that the HAVE_FSSTAT macro be defined for Microport X * systems. X */ X# if (OS_TYPE == OS_UPORT_286) X# define is_ok(fs) (TRUE) X# ifndef HAVE_FSSTAT X# define HAVE_FSSTAT X# endif X# else X# if (OS_TYPE == OS_XENIX_286) X# define is_ok(fs) (TRUE) X# else X# define is_ok(fs) ((fs)->s_state == FsOKAY) || ((fs)->s_state == FsACTIVE) X# endif X# endif X X# define opt_interleave(fs) ((fs)->s_dinfo[0]) X# define freespace(fs,reserved) ((fs)->s_tfree) X# define inode_block(fs,inode) (iblkno(fs) + (((inode)-1) / inopb(fs))) X# define inode_offset(fs,inode) (((inode)-1) % inopb(fs)) X# define blk_size(fs, inode, lbn) (bsize(fs)) X# define cylinder(fs,blk) ((daddr_t)(blk) * Sec_per_blk / cyl_size) X# define cyl_pos(fs,blk) ((daddr_t)(blk) * Sec_per_blk % cyl_size) X X/* X * inode data/indirect block access X */ X# define NDADDR 10 /* direct addresses in inode */ X# define NIADDR 3 /* indirect addresses in inode */ X X# define dta_blk(ino, blk) (&(ino)->di_addr[(blk)*3]) X# define indir_blk(ino, blk) (&(ino)->di_addr[((blk)+10)*3]) X X#endif /* FS_TYPE == FS_ATT */ X X#if ((FS_TYPE == FS_BSD) || (FS_TYPE == FS_BSD_NFS)) X X/* X * The following definitions provide the above-listed macros for a derivative X * of the BSD Fast File System. X */ X Xtypedef struct fs superblk_t; /* superblock structure definition */ X X# define SUPERBOFF (SBLOCK * DEV_BSIZE) X/* DEV_BSIZE is defined in <sys/fs.h> */ X/* MAXBSIZE is defined in <sys/fs.h> */ X# define MAXINOPB (MAXBSIZE / sizeof (struct dinode)) X# define MAXINDIR (MAXBSIZE / sizeof (daddr_t)) X# define inopb(fs) INOPB(fs) X# define nindir(fs) NINDIR(fs) X# define bsize(fs) ((fs)->fs_bsize) X# define fsize(fs) (bsize(fs) / (fs)->fs_frag) X# define fssize(fs) ((fs)->fs_size) X# define dsize(fs) ((fs)->fs_dsize) X# define isize(fs) ((fs)->fs_ncg * (fs)->fs_ipg / inopb(fs)) X# define num_inodes(fs) (isize(fs) * inopb(fs)) X# define first_inode 0 X# define iblkno(fs) ((fs)->fs_iblkno) X# define sec_per_cyl(fs) ((fs)->fs_spc) X X/* X * How do we determine file system integrity on a BSD file system? X */ X# define is_ok(fs) (TRUE) X X# define opt_interleave(fs) \ X (((fs)->fs_rps * (fs)->fs_nsect * (fs)->fs_rotdelay /* sectors */\ X + ((NSPB(fs)*1000)-1)) / 1000) /* round up */ X X/* freespace(fs,res) is defined in <sys/fs.h> */ X# define inode_block(fs,inode) itod((fs),(inode)) X# define inode_offset(fs,inode) itoo((fs),(inode)) X# define cylinder(fs,blk) cbtocylno((fs),(blk)) X# define cyl_pos(fs,blk) (cbtorpos((fs),(blk)) * NRPOS) X X# define blk_size(fs, inode, lbn) (dblksize (fs, inode, lbn)) X X/* X * inode data/indirect block access X */ X/* NDADDR is defined in inode.h */ X/* NIADDR is defined in inode.h */ X# define dta_blk(ino,blk) ((char *)&((ino)->di_db[blk])) X# define indir_blk(ino,blk) ((char *)&((ino)->di_ib[blk])) X X# endif /* FS_TYPE == FS_BSD || FS_TYPE == FS_BSD_NFS */ END_OF_fsconfig.h if test 12938 -ne `wc -c <fsconfig.h`; then echo shar: \"fsconfig.h\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 3 \(of 3\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Young Software Development Technologies, Inc., Sudbury MA Tel: +1 508 443 5779 Internet: mjy@sdti.sdti.com UUCP: {harvard,mit-eddie}!sdti!mjy