xref: /illumos-gate/usr/src/grub/grub-0.97/stage2/fs.h (revision 1b8adde7)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Mach Operating System
37c478bd9Sstevel@tonic-gate  * Copyright (c) 1991,1990 Carnegie Mellon University
47c478bd9Sstevel@tonic-gate  * All Rights Reserved.
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify and distribute this software and its
77c478bd9Sstevel@tonic-gate  * documentation is hereby granted, provided that both the copyright
87c478bd9Sstevel@tonic-gate  * notice and this permission notice appear in all copies of the
97c478bd9Sstevel@tonic-gate  * software, derivative works or modified versions, and any portions
107c478bd9Sstevel@tonic-gate  * thereof, and that both notices appear in supporting documentation.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
137c478bd9Sstevel@tonic-gate  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
147c478bd9Sstevel@tonic-gate  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  * Carnegie Mellon requests users of this software to return to
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
197c478bd9Sstevel@tonic-gate  *  School of Computer Science
207c478bd9Sstevel@tonic-gate  *  Carnegie Mellon University
217c478bd9Sstevel@tonic-gate  *  Pittsburgh PA 15213-3890
227c478bd9Sstevel@tonic-gate  *
237c478bd9Sstevel@tonic-gate  * any improvements or extensions that they make and grant Carnegie Mellon
247c478bd9Sstevel@tonic-gate  * the rights to redistribute these changes.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * Copyright (c) 1982, 1986 Regents of the University of California.
287c478bd9Sstevel@tonic-gate  * All rights reserved.
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
317c478bd9Sstevel@tonic-gate  * provided that the above copyright notice and this paragraph are
327c478bd9Sstevel@tonic-gate  * duplicated in all such forms and that any documentation,
337c478bd9Sstevel@tonic-gate  * advertising materials, and other materials related to such
347c478bd9Sstevel@tonic-gate  * distribution and use acknowledge that the software was developed
357c478bd9Sstevel@tonic-gate  * by the University of California, Berkeley.  The name of the
367c478bd9Sstevel@tonic-gate  * University may not be used to endorse or promote products derived
377c478bd9Sstevel@tonic-gate  * from this software without specific prior written permission.
387c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
397c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
407c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  *	@(#)fs.h	7.7 (Berkeley) 5/9/89
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * Each disk drive contains some number of file systems.
477c478bd9Sstevel@tonic-gate  * A file system consists of a number of cylinder groups.
487c478bd9Sstevel@tonic-gate  * Each cylinder group has inodes and data.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * A file system is described by its super-block, which in turn
517c478bd9Sstevel@tonic-gate  * describes the cylinder groups.  The super-block is critical
527c478bd9Sstevel@tonic-gate  * data and is replicated in each cylinder group to protect against
537c478bd9Sstevel@tonic-gate  * catastrophic loss.  This is done at `newfs' time and the critical
547c478bd9Sstevel@tonic-gate  * super-block data does not change, so the copies need not be
557c478bd9Sstevel@tonic-gate  * referenced further unless disaster strikes.
567c478bd9Sstevel@tonic-gate  *
577c478bd9Sstevel@tonic-gate  * For file system fs, the offsets of the various blocks of interest
587c478bd9Sstevel@tonic-gate  * are given in the super block as:
597c478bd9Sstevel@tonic-gate  *	[fs->fs_sblkno]		Super-block
607c478bd9Sstevel@tonic-gate  *	[fs->fs_cblkno]		Cylinder group block
617c478bd9Sstevel@tonic-gate  *	[fs->fs_iblkno]		Inode blocks
627c478bd9Sstevel@tonic-gate  *	[fs->fs_dblkno]		Data blocks
637c478bd9Sstevel@tonic-gate  * The beginning of cylinder group cg in fs, is given by
647c478bd9Sstevel@tonic-gate  * the ``cgbase(fs, cg)'' macro.
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  * The first boot and super blocks are given in absolute disk addresses.
677c478bd9Sstevel@tonic-gate  * The byte-offset forms are preferred, as they don't imply a sector size.
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate #define BBSIZE		8192
707c478bd9Sstevel@tonic-gate #define SBSIZE		8192
717c478bd9Sstevel@tonic-gate #define	BBOFF		((mach_off_t)(0))
727c478bd9Sstevel@tonic-gate #define	SBOFF		((mach_off_t)(BBOFF + BBSIZE))
737c478bd9Sstevel@tonic-gate #define	BBLOCK		((mach_daddr_t)(0))
747c478bd9Sstevel@tonic-gate #define	SBLOCK		((mach_daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate /*
777c478bd9Sstevel@tonic-gate  * Addresses stored in inodes are capable of addressing fragments
787c478bd9Sstevel@tonic-gate  * of `blocks'. File system blocks of at most size MAXBSIZE can
797c478bd9Sstevel@tonic-gate  * be optionally broken into 2, 4, or 8 pieces, each of which is
807c478bd9Sstevel@tonic-gate  * addressible; these pieces may be DEV_BSIZE, or some multiple of
817c478bd9Sstevel@tonic-gate  * a DEV_BSIZE unit.
827c478bd9Sstevel@tonic-gate  *
837c478bd9Sstevel@tonic-gate  * Large files consist of exclusively large data blocks.  To avoid
847c478bd9Sstevel@tonic-gate  * undue wasted disk space, the last data block of a small file may be
857c478bd9Sstevel@tonic-gate  * allocated as only as many fragments of a large block as are
867c478bd9Sstevel@tonic-gate  * necessary.  The file system format retains only a single pointer
877c478bd9Sstevel@tonic-gate  * to such a fragment, which is a piece of a single large block that
887c478bd9Sstevel@tonic-gate  * has been divided.  The size of such a fragment is determinable from
897c478bd9Sstevel@tonic-gate  * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * The file system records space availability at the fragment level;
927c478bd9Sstevel@tonic-gate  * to determine block availability, aligned fragments are examined.
937c478bd9Sstevel@tonic-gate  *
947c478bd9Sstevel@tonic-gate  * The root inode is the root of the file system.
957c478bd9Sstevel@tonic-gate  * Inode 0 can't be used for normal purposes and
967c478bd9Sstevel@tonic-gate  * historically bad blocks were linked to inode 1,
977c478bd9Sstevel@tonic-gate  * thus the root inode is 2. (inode 1 is no longer used for
987c478bd9Sstevel@tonic-gate  * this purpose, however numerous dump tapes make this
997c478bd9Sstevel@tonic-gate  * assumption, so we are stuck with it)
1007c478bd9Sstevel@tonic-gate  */
1017c478bd9Sstevel@tonic-gate #define	ROOTINO		((mach_ino_t)2)	/* i number of all roots */
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate  * MINBSIZE is the smallest allowable block size.
1057c478bd9Sstevel@tonic-gate  * In order to insure that it is possible to create files of size
1067c478bd9Sstevel@tonic-gate  * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
1077c478bd9Sstevel@tonic-gate  * MINBSIZE must be big enough to hold a cylinder group block,
1087c478bd9Sstevel@tonic-gate  * thus changes to (struct cg) must keep its size within MINBSIZE.
1097c478bd9Sstevel@tonic-gate  * Note that super blocks are always of size SBSIZE,
1107c478bd9Sstevel@tonic-gate  * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
1117c478bd9Sstevel@tonic-gate  */
1127c478bd9Sstevel@tonic-gate #define MINBSIZE	4096
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate /*
1157c478bd9Sstevel@tonic-gate  * The path name on which the file system is mounted is maintained
1167c478bd9Sstevel@tonic-gate  * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
1177c478bd9Sstevel@tonic-gate  * the super block for this name.
1187c478bd9Sstevel@tonic-gate  * The limit on the amount of summary information per file system
1197c478bd9Sstevel@tonic-gate  * is defined by MAXCSBUFS. It is currently parameterized for a
1207c478bd9Sstevel@tonic-gate  * maximum of two million cylinders.
1217c478bd9Sstevel@tonic-gate  */
1227c478bd9Sstevel@tonic-gate #define MAXMNTLEN 512
1237c478bd9Sstevel@tonic-gate #define MAXCSBUFS 32
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate  * Per cylinder group information; summarized in blocks allocated
1277c478bd9Sstevel@tonic-gate  * from first cylinder group data blocks.  These blocks have to be
1287c478bd9Sstevel@tonic-gate  * read in from fs_csaddr (size fs_cssize) in addition to the
1297c478bd9Sstevel@tonic-gate  * super block.
1307c478bd9Sstevel@tonic-gate  *
1317c478bd9Sstevel@tonic-gate  * N.B. sizeof(struct csum) must be a power of two in order for
1327c478bd9Sstevel@tonic-gate  * the ``fs_cs'' macro to work (see below).
1337c478bd9Sstevel@tonic-gate  */
1347c478bd9Sstevel@tonic-gate struct csum
1357c478bd9Sstevel@tonic-gate   {
1367c478bd9Sstevel@tonic-gate     int cs_ndir;		/* number of directories */
1377c478bd9Sstevel@tonic-gate     int cs_nbfree;		/* number of free blocks */
1387c478bd9Sstevel@tonic-gate     int cs_nifree;		/* number of free inodes */
1397c478bd9Sstevel@tonic-gate     int cs_nffree;		/* number of free frags */
1407c478bd9Sstevel@tonic-gate   };
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate  * Super block for a file system.
1447c478bd9Sstevel@tonic-gate  */
1457c478bd9Sstevel@tonic-gate #define	FS_MAGIC	0x011954
1467c478bd9Sstevel@tonic-gate struct fs
1477c478bd9Sstevel@tonic-gate   {
1487c478bd9Sstevel@tonic-gate     int xxx1;			/* struct       fs *fs_link; */
1497c478bd9Sstevel@tonic-gate     int xxx2;			/* struct       fs *fs_rlink; */
1507c478bd9Sstevel@tonic-gate     mach_daddr_t fs_sblkno;	/* addr of super-block in filesys */
1517c478bd9Sstevel@tonic-gate     mach_daddr_t fs_cblkno;	/* offset of cyl-block in filesys */
1527c478bd9Sstevel@tonic-gate     mach_daddr_t fs_iblkno;	/* offset of inode-blocks in filesys */
1537c478bd9Sstevel@tonic-gate     mach_daddr_t fs_dblkno;	/* offset of first data after cg */
1547c478bd9Sstevel@tonic-gate     int fs_cgoffset;		/* cylinder group offset in cylinder */
1557c478bd9Sstevel@tonic-gate     int fs_cgmask;		/* used to calc mod fs_ntrak */
1567c478bd9Sstevel@tonic-gate     mach_time_t fs_time;	/* last time written */
1577c478bd9Sstevel@tonic-gate     int fs_size;		/* number of blocks in fs */
1587c478bd9Sstevel@tonic-gate     int fs_dsize;		/* number of data blocks in fs */
1597c478bd9Sstevel@tonic-gate     int fs_ncg;			/* number of cylinder groups */
1607c478bd9Sstevel@tonic-gate     int fs_bsize;		/* size of basic blocks in fs */
1617c478bd9Sstevel@tonic-gate     int fs_fsize;		/* size of frag blocks in fs */
1627c478bd9Sstevel@tonic-gate     int fs_frag;		/* number of frags in a block in fs */
1637c478bd9Sstevel@tonic-gate /* these are configuration parameters */
1647c478bd9Sstevel@tonic-gate     int fs_minfree;		/* minimum percentage of free blocks */
1657c478bd9Sstevel@tonic-gate     int fs_rotdelay;		/* num of ms for optimal next block */
1667c478bd9Sstevel@tonic-gate     int fs_rps;			/* disk revolutions per second */
1677c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
1687c478bd9Sstevel@tonic-gate     int fs_bmask;		/* ``blkoff'' calc of blk offsets */
1697c478bd9Sstevel@tonic-gate     int fs_fmask;		/* ``fragoff'' calc of frag offsets */
1707c478bd9Sstevel@tonic-gate     int fs_bshift;		/* ``lblkno'' calc of logical blkno */
1717c478bd9Sstevel@tonic-gate     int fs_fshift;		/* ``numfrags'' calc number of frags */
1727c478bd9Sstevel@tonic-gate /* these are configuration parameters */
1737c478bd9Sstevel@tonic-gate     int fs_maxcontig;		/* max number of contiguous blks */
1747c478bd9Sstevel@tonic-gate     int fs_maxbpg;		/* max number of blks per cyl group */
1757c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
1767c478bd9Sstevel@tonic-gate     int fs_fragshift;		/* block to frag shift */
1777c478bd9Sstevel@tonic-gate     int fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
1787c478bd9Sstevel@tonic-gate     int fs_sbsize;		/* actual size of super block */
1797c478bd9Sstevel@tonic-gate     int fs_csmask;		/* csum block offset */
1807c478bd9Sstevel@tonic-gate     int fs_csshift;		/* csum block number */
1817c478bd9Sstevel@tonic-gate     int fs_nindir;		/* value of NINDIR */
1827c478bd9Sstevel@tonic-gate     int fs_inopb;		/* value of INOPB */
1837c478bd9Sstevel@tonic-gate     int fs_nspf;		/* value of NSPF */
1847c478bd9Sstevel@tonic-gate /* yet another configuration parameter */
1857c478bd9Sstevel@tonic-gate     int fs_optim;		/* optimization preference, see below */
1867c478bd9Sstevel@tonic-gate /* these fields are derived from the hardware */
1877c478bd9Sstevel@tonic-gate     int fs_npsect;		/* # sectors/track including spares */
1887c478bd9Sstevel@tonic-gate     int fs_interleave;		/* hardware sector interleave */
1897c478bd9Sstevel@tonic-gate     int fs_trackskew;		/* sector 0 skew, per track */
1907c478bd9Sstevel@tonic-gate     int fs_headswitch;		/* head switch time, usec */
1917c478bd9Sstevel@tonic-gate     int fs_trkseek;		/* track-to-track seek, usec */
1927c478bd9Sstevel@tonic-gate /* sizes determined by number of cylinder groups and their sizes */
1937c478bd9Sstevel@tonic-gate     mach_daddr_t fs_csaddr;	/* blk addr of cyl grp summary area */
1947c478bd9Sstevel@tonic-gate     int fs_cssize;		/* size of cyl grp summary area */
1957c478bd9Sstevel@tonic-gate     int fs_cgsize;		/* cylinder group size */
1967c478bd9Sstevel@tonic-gate /* these fields are derived from the hardware */
1977c478bd9Sstevel@tonic-gate     int fs_ntrak;		/* tracks per cylinder */
1987c478bd9Sstevel@tonic-gate     int fs_nsect;		/* sectors per track */
1997c478bd9Sstevel@tonic-gate     int fs_spc;			/* sectors per cylinder */
2007c478bd9Sstevel@tonic-gate /* this comes from the disk driver partitioning */
2017c478bd9Sstevel@tonic-gate     int fs_ncyl;		/* cylinders in file system */
2027c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
2037c478bd9Sstevel@tonic-gate     int fs_cpg;			/* cylinders per group */
2047c478bd9Sstevel@tonic-gate     int fs_ipg;			/* inodes per group */
2057c478bd9Sstevel@tonic-gate     int fs_fpg;			/* blocks per group * fs_frag */
2067c478bd9Sstevel@tonic-gate /* this data must be re-computed after crashes */
2077c478bd9Sstevel@tonic-gate     struct csum fs_cstotal;	/* cylinder summary information */
2087c478bd9Sstevel@tonic-gate /* these fields are cleared at mount time */
2097c478bd9Sstevel@tonic-gate     char fs_fmod;		/* super block modified flag */
2107c478bd9Sstevel@tonic-gate     char fs_clean;		/* file system is clean flag */
2117c478bd9Sstevel@tonic-gate     char fs_ronly;		/* mounted read-only flag */
2127c478bd9Sstevel@tonic-gate     char fs_flags;		/* currently unused flag */
2137c478bd9Sstevel@tonic-gate     char fs_fsmnt[MAXMNTLEN];	/* name mounted on */
2147c478bd9Sstevel@tonic-gate /* these fields retain the current block allocation info */
2157c478bd9Sstevel@tonic-gate     int fs_cgrotor;		/* last cg searched */
2167c478bd9Sstevel@tonic-gate #if 1
2177c478bd9Sstevel@tonic-gate     int was_fs_csp[MAXCSBUFS];
2187c478bd9Sstevel@tonic-gate #else
2197c478bd9Sstevel@tonic-gate     struct csum *fs_csp[MAXCSBUFS];	/* list of fs_cs info buffers */
2207c478bd9Sstevel@tonic-gate #endif
2217c478bd9Sstevel@tonic-gate     int fs_cpc;			/* cyl per cycle in postbl */
2227c478bd9Sstevel@tonic-gate     short fs_opostbl[16][8];	/* old rotation block list head */
2237c478bd9Sstevel@tonic-gate     long fs_sparecon[50];	/* reserved for future constants */
2247c478bd9Sstevel@tonic-gate     long fs_contigsumsize;	/* size of cluster summary array */
2257c478bd9Sstevel@tonic-gate     long fs_maxsymlinklen;	/* max length of an internal symlink */
2267c478bd9Sstevel@tonic-gate     long fs_inodefmt;		/* format of on-disk inodes */
2277c478bd9Sstevel@tonic-gate     quad fs_maxfilesize;	/* maximum representable file size */
2287c478bd9Sstevel@tonic-gate     quad fs_qbmask;		/* ~fs_bmask - for use with quad size */
2297c478bd9Sstevel@tonic-gate     quad fs_qfmask;		/* ~fs_fmask - for use with quad size */
2307c478bd9Sstevel@tonic-gate     long fs_state;		/* validate fs_clean field */
2317c478bd9Sstevel@tonic-gate     int fs_postblformat;	/* format of positional layout tables */
2327c478bd9Sstevel@tonic-gate     int fs_nrpos;		/* number of rotaional positions */
2337c478bd9Sstevel@tonic-gate     int fs_postbloff;		/* (short) rotation block list head */
2347c478bd9Sstevel@tonic-gate     int fs_rotbloff;		/* (u_char) blocks for each rotation */
2357c478bd9Sstevel@tonic-gate     int fs_magic;		/* magic number */
2367c478bd9Sstevel@tonic-gate     u_char fs_space[1];		/* list of blocks for each rotation */
2377c478bd9Sstevel@tonic-gate /* actually longer */
2387c478bd9Sstevel@tonic-gate   };
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate  * Preference for optimization.
2417c478bd9Sstevel@tonic-gate  */
2427c478bd9Sstevel@tonic-gate #define FS_OPTTIME	0	/* minimize allocation time */
2437c478bd9Sstevel@tonic-gate #define FS_OPTSPACE	1	/* minimize disk fragmentation */
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate /*
2467c478bd9Sstevel@tonic-gate  * Rotational layout table format types
2477c478bd9Sstevel@tonic-gate  */
2487c478bd9Sstevel@tonic-gate #define FS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
2497c478bd9Sstevel@tonic-gate #define FS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
2507c478bd9Sstevel@tonic-gate /*
2517c478bd9Sstevel@tonic-gate  * Macros for access to superblock array structures
2527c478bd9Sstevel@tonic-gate  */
2537c478bd9Sstevel@tonic-gate #define fs_postbl(fs, cylno) \
2547c478bd9Sstevel@tonic-gate     (((fs)->fs_postblformat == FS_42POSTBLFMT) \
2557c478bd9Sstevel@tonic-gate     ? ((fs)->fs_opostbl[cylno]) \
2567c478bd9Sstevel@tonic-gate     : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
2577c478bd9Sstevel@tonic-gate #define fs_rotbl(fs) \
2587c478bd9Sstevel@tonic-gate     (((fs)->fs_postblformat == FS_42POSTBLFMT) \
2597c478bd9Sstevel@tonic-gate     ? ((fs)->fs_space) \
2607c478bd9Sstevel@tonic-gate     : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate  * Convert cylinder group to base address of its global summary info.
2647c478bd9Sstevel@tonic-gate  *
2657c478bd9Sstevel@tonic-gate  * N.B. This macro assumes that sizeof(struct csum) is a power of two.
2667c478bd9Sstevel@tonic-gate  */
2677c478bd9Sstevel@tonic-gate #define fs_cs(fs, indx) \
2687c478bd9Sstevel@tonic-gate 	fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate  * Cylinder group block for a file system.
2727c478bd9Sstevel@tonic-gate  */
2737c478bd9Sstevel@tonic-gate #define	CG_MAGIC	0x090255
2747c478bd9Sstevel@tonic-gate struct cg
2757c478bd9Sstevel@tonic-gate   {
2767c478bd9Sstevel@tonic-gate     int xxx1;			/* struct       cg *cg_link; */
2777c478bd9Sstevel@tonic-gate     int cg_magic;		/* magic number */
2787c478bd9Sstevel@tonic-gate     mach_time_t cg_time;		/* time last written */
2797c478bd9Sstevel@tonic-gate     int cg_cgx;			/* we are the cgx'th cylinder group */
2807c478bd9Sstevel@tonic-gate     short cg_ncyl;		/* number of cyl's this cg */
2817c478bd9Sstevel@tonic-gate     short cg_niblk;		/* number of inode blocks this cg */
2827c478bd9Sstevel@tonic-gate     int cg_ndblk;		/* number of data blocks this cg */
2837c478bd9Sstevel@tonic-gate     struct csum cg_cs;		/* cylinder summary information */
2847c478bd9Sstevel@tonic-gate     int cg_rotor;		/* position of last used block */
2857c478bd9Sstevel@tonic-gate     int cg_frotor;		/* position of last used frag */
2867c478bd9Sstevel@tonic-gate     int cg_irotor;		/* position of last used inode */
2877c478bd9Sstevel@tonic-gate     int cg_frsum[MAXFRAG];	/* counts of available frags */
2887c478bd9Sstevel@tonic-gate     int cg_btotoff;		/* (long) block totals per cylinder */
2897c478bd9Sstevel@tonic-gate     int cg_boff;		/* (short) free block positions */
2907c478bd9Sstevel@tonic-gate     int cg_iusedoff;		/* (char) used inode map */
2917c478bd9Sstevel@tonic-gate     int cg_freeoff;		/* (u_char) free block map */
2927c478bd9Sstevel@tonic-gate     int cg_nextfreeoff;		/* (u_char) next available space */
2937c478bd9Sstevel@tonic-gate     int cg_sparecon[16];	/* reserved for future use */
2947c478bd9Sstevel@tonic-gate     u_char cg_space[1];		/* space for cylinder group maps */
2957c478bd9Sstevel@tonic-gate /* actually longer */
2967c478bd9Sstevel@tonic-gate   };
2977c478bd9Sstevel@tonic-gate /*
2987c478bd9Sstevel@tonic-gate  * Macros for access to cylinder group array structures
2997c478bd9Sstevel@tonic-gate  */
3007c478bd9Sstevel@tonic-gate #define cg_blktot(cgp) \
3017c478bd9Sstevel@tonic-gate     (((cgp)->cg_magic != CG_MAGIC) \
3027c478bd9Sstevel@tonic-gate     ? (((struct ocg *)(cgp))->cg_btot) \
3037c478bd9Sstevel@tonic-gate     : ((int *)((char *)(cgp) + (cgp)->cg_btotoff)))
3047c478bd9Sstevel@tonic-gate #define cg_blks(fs, cgp, cylno) \
3057c478bd9Sstevel@tonic-gate     (((cgp)->cg_magic != CG_MAGIC) \
3067c478bd9Sstevel@tonic-gate     ? (((struct ocg *)(cgp))->cg_b[cylno]) \
3077c478bd9Sstevel@tonic-gate     : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
3087c478bd9Sstevel@tonic-gate #define cg_inosused(cgp) \
3097c478bd9Sstevel@tonic-gate     (((cgp)->cg_magic != CG_MAGIC) \
3107c478bd9Sstevel@tonic-gate     ? (((struct ocg *)(cgp))->cg_iused) \
3117c478bd9Sstevel@tonic-gate     : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
3127c478bd9Sstevel@tonic-gate #define cg_blksfree(cgp) \
3137c478bd9Sstevel@tonic-gate     (((cgp)->cg_magic != CG_MAGIC) \
3147c478bd9Sstevel@tonic-gate     ? (((struct ocg *)(cgp))->cg_free) \
3157c478bd9Sstevel@tonic-gate     : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
3167c478bd9Sstevel@tonic-gate #define cg_chkmagic(cgp) \
3177c478bd9Sstevel@tonic-gate     ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate /*
3207c478bd9Sstevel@tonic-gate  * The following structure is defined
3217c478bd9Sstevel@tonic-gate  * for compatibility with old file systems.
3227c478bd9Sstevel@tonic-gate  */
3237c478bd9Sstevel@tonic-gate struct ocg
3247c478bd9Sstevel@tonic-gate   {
3257c478bd9Sstevel@tonic-gate     int xxx1;			/* struct       ocg *cg_link; */
3267c478bd9Sstevel@tonic-gate     int xxx2;			/* struct       ocg *cg_rlink; */
3277c478bd9Sstevel@tonic-gate     mach_time_t cg_time;	/* time last written */
3287c478bd9Sstevel@tonic-gate     int cg_cgx;			/* we are the cgx'th cylinder group */
3297c478bd9Sstevel@tonic-gate     short cg_ncyl;		/* number of cyl's this cg */
3307c478bd9Sstevel@tonic-gate     short cg_niblk;		/* number of inode blocks this cg */
3317c478bd9Sstevel@tonic-gate     int cg_ndblk;		/* number of data blocks this cg */
3327c478bd9Sstevel@tonic-gate     struct csum cg_cs;		/* cylinder summary information */
3337c478bd9Sstevel@tonic-gate     int cg_rotor;		/* position of last used block */
3347c478bd9Sstevel@tonic-gate     int cg_frotor;		/* position of last used frag */
3357c478bd9Sstevel@tonic-gate     int cg_irotor;		/* position of last used inode */
3367c478bd9Sstevel@tonic-gate     int cg_frsum[8];		/* counts of available frags */
3377c478bd9Sstevel@tonic-gate     int cg_btot[32];		/* block totals per cylinder */
3387c478bd9Sstevel@tonic-gate     short cg_b[32][8];		/* positions of free blocks */
3397c478bd9Sstevel@tonic-gate     char cg_iused[256];		/* used inode map */
3407c478bd9Sstevel@tonic-gate     int cg_magic;		/* magic number */
3417c478bd9Sstevel@tonic-gate     u_char cg_free[1];		/* free block map */
3427c478bd9Sstevel@tonic-gate /* actually longer */
3437c478bd9Sstevel@tonic-gate   };
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate /*
3467c478bd9Sstevel@tonic-gate  * Turn file system block numbers into disk block addresses.
3477c478bd9Sstevel@tonic-gate  * This maps file system blocks to device size blocks.
3487c478bd9Sstevel@tonic-gate  */
3497c478bd9Sstevel@tonic-gate #define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
3507c478bd9Sstevel@tonic-gate #define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate /*
3537c478bd9Sstevel@tonic-gate  * Cylinder group macros to locate things in cylinder groups.
3547c478bd9Sstevel@tonic-gate  * They calc file system addresses of cylinder group data structures.
3557c478bd9Sstevel@tonic-gate  */
3567c478bd9Sstevel@tonic-gate #define	cgbase(fs, c)	((mach_daddr_t)((fs)->fs_fpg * (c)))
3577c478bd9Sstevel@tonic-gate #define cgstart(fs, c) \
3587c478bd9Sstevel@tonic-gate 	(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
3597c478bd9Sstevel@tonic-gate #define	cgsblock(fs, c)	(cgstart(fs, c) + (fs)->fs_sblkno)	/* super blk */
3607c478bd9Sstevel@tonic-gate #define	cgtod(fs, c)	(cgstart(fs, c) + (fs)->fs_cblkno)	/* cg block */
3617c478bd9Sstevel@tonic-gate #define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
3627c478bd9Sstevel@tonic-gate #define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate /*
3657c478bd9Sstevel@tonic-gate  * Macros for handling inode numbers:
3667c478bd9Sstevel@tonic-gate  *     inode number to file system block offset.
3677c478bd9Sstevel@tonic-gate  *     inode number to cylinder group number.
3687c478bd9Sstevel@tonic-gate  *     inode number to file system block address.
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate #define	itoo(fs, x)	((x) % INOPB(fs))
3717c478bd9Sstevel@tonic-gate #define	itog(fs, x)	((x) / (fs)->fs_ipg)
3727c478bd9Sstevel@tonic-gate #define	itod(fs, x) \
3737c478bd9Sstevel@tonic-gate 	((mach_daddr_t)(cgimin(fs, itog(fs, x)) + \
3747c478bd9Sstevel@tonic-gate 	(blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate /*
3777c478bd9Sstevel@tonic-gate  * Give cylinder group number for a file system block.
3787c478bd9Sstevel@tonic-gate  * Give cylinder group block number for a file system block.
3797c478bd9Sstevel@tonic-gate  */
3807c478bd9Sstevel@tonic-gate #define	dtog(fs, d)	((d) / (fs)->fs_fpg)
3817c478bd9Sstevel@tonic-gate #define	dtogd(fs, d)	((d) % (fs)->fs_fpg)
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate  * Extract the bits for a block from a map.
3857c478bd9Sstevel@tonic-gate  * Compute the cylinder and rotational position of a cyl block addr.
3867c478bd9Sstevel@tonic-gate  */
3877c478bd9Sstevel@tonic-gate #define blkmap(fs, map, loc) \
3887c478bd9Sstevel@tonic-gate     (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
3897c478bd9Sstevel@tonic-gate #define cbtocylno(fs, bno) \
3907c478bd9Sstevel@tonic-gate     ((bno) * NSPF(fs) / (fs)->fs_spc)
3917c478bd9Sstevel@tonic-gate #define cbtorpos(fs, bno) \
3927c478bd9Sstevel@tonic-gate     (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
3937c478bd9Sstevel@tonic-gate      (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
3947c478bd9Sstevel@tonic-gate      (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate /*
3977c478bd9Sstevel@tonic-gate  * The following macros optimize certain frequently calculated
3987c478bd9Sstevel@tonic-gate  * quantities by using shifts and masks in place of divisions
3997c478bd9Sstevel@tonic-gate  * modulos and multiplications.
4007c478bd9Sstevel@tonic-gate  */
4017c478bd9Sstevel@tonic-gate #define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
4027c478bd9Sstevel@tonic-gate 	((loc) & ~(fs)->fs_bmask)
4037c478bd9Sstevel@tonic-gate #define fragoff(fs, loc)	/* calculates (loc % fs->fs_fsize) */ \
4047c478bd9Sstevel@tonic-gate 	((loc) & ~(fs)->fs_fmask)
4057c478bd9Sstevel@tonic-gate #define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
4067c478bd9Sstevel@tonic-gate 	((loc) >> (fs)->fs_bshift)
4077c478bd9Sstevel@tonic-gate #define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
4087c478bd9Sstevel@tonic-gate 	((loc) >> (fs)->fs_fshift)
4097c478bd9Sstevel@tonic-gate #define blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
4107c478bd9Sstevel@tonic-gate 	(((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
4117c478bd9Sstevel@tonic-gate #define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
4127c478bd9Sstevel@tonic-gate 	(((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
4137c478bd9Sstevel@tonic-gate #define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
4147c478bd9Sstevel@tonic-gate 	((frags) >> (fs)->fs_fragshift)
4157c478bd9Sstevel@tonic-gate #define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
4167c478bd9Sstevel@tonic-gate 	((blks) << (fs)->fs_fragshift)
4177c478bd9Sstevel@tonic-gate #define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
4187c478bd9Sstevel@tonic-gate 	((fsb) & ((fs)->fs_frag - 1))
4197c478bd9Sstevel@tonic-gate #define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
4207c478bd9Sstevel@tonic-gate 	((fsb) &~ ((fs)->fs_frag - 1))
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate /*
4237c478bd9Sstevel@tonic-gate  * Determine the number of available frags given a
4247c478bd9Sstevel@tonic-gate  * percentage to hold in reserve
4257c478bd9Sstevel@tonic-gate  */
4267c478bd9Sstevel@tonic-gate #define freespace(fs, percentreserved) \
4277c478bd9Sstevel@tonic-gate 	(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
4287c478bd9Sstevel@tonic-gate 	(fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate /*
4317c478bd9Sstevel@tonic-gate  * Determining the size of a file block in the file system.
4327c478bd9Sstevel@tonic-gate  */
4337c478bd9Sstevel@tonic-gate #define blksize(fs, ip, lbn) \
4347c478bd9Sstevel@tonic-gate 	(((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \
4357c478bd9Sstevel@tonic-gate 	    ? (fs)->fs_bsize \
4367c478bd9Sstevel@tonic-gate 	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
4377c478bd9Sstevel@tonic-gate #define dblksize(fs, dip, lbn) \
4387c478bd9Sstevel@tonic-gate 	(((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
4397c478bd9Sstevel@tonic-gate 	    ? (fs)->fs_bsize \
4407c478bd9Sstevel@tonic-gate 	    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate /*
4437c478bd9Sstevel@tonic-gate  * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
4447c478bd9Sstevel@tonic-gate  */
4457c478bd9Sstevel@tonic-gate #define	NSPB(fs)	((fs)->fs_nspf << (fs)->fs_fragshift)
4467c478bd9Sstevel@tonic-gate #define	NSPF(fs)	((fs)->fs_nspf)
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate /*
4497c478bd9Sstevel@tonic-gate  * INOPB is the number of inodes in a secondary storage block.
4507c478bd9Sstevel@tonic-gate  */
4517c478bd9Sstevel@tonic-gate #define	INOPB(fs)	((fs)->fs_inopb)
4527c478bd9Sstevel@tonic-gate #define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate /*
4557c478bd9Sstevel@tonic-gate  * NINDIR is the number of indirects in a file system block.
4567c478bd9Sstevel@tonic-gate  */
4577c478bd9Sstevel@tonic-gate #define	NINDIR(fs)	((fs)->fs_nindir)
458