v05i070: Fsanalyze Version 4.1, Part 3/3
Michael J. Young
mjy at sdti.sdti.com
Wed Dec 7 10:11:37 AEST 1988
Posting-number: Volume 5, Issue 70
Submitted-by: "Michael J. Young" <mjy at 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 at 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 at 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 at sdti.SDTI.COM),
X * Extracted from fsanalyze.c
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at 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 at sdti.SDTI.COM),
X * Fixed boundary condition error in scan().
X *
X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy at 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 at 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 at sdti.SDTI.COM)
X * Originated.
X *
X * Wed Apr 13 17:18:06 EDT 1988 - M. Young (mjy at 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 at sdti.SDTI.COM)
X * Added NUMOFFEND macro.
X *
X * Tue Jul 26 15:27:52 EDT 1988 - M. Young (mjy at 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 at sdti.SDTI.COM)
X * Opt_interleave formula now makes sense.
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at 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 at sdti.SDTI.COM),
X * Placed under SCCS
X *
X * Fri Nov 18 17:37:08 EST 1988 - M. Young (mjy at 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 at sdti.sdti.com UUCP: {harvard,mit-eddie}!sdti!mjy
More information about the Comp.sources.misc
mailing list