fs.h revision 50477
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1982, 1986, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 3. All advertising materials mentioning features or use of this software
141541Srgrimes *    must display the following acknowledgement:
151541Srgrimes *	This product includes software developed by the University of
161541Srgrimes *	California, Berkeley and its contributors.
171541Srgrimes * 4. Neither the name of the University nor the names of its contributors
181541Srgrimes *    may be used to endorse or promote products derived from this software
191541Srgrimes *    without specific prior written permission.
201541Srgrimes *
211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311541Srgrimes * SUCH DAMAGE.
321541Srgrimes *
3322521Sdyson *	@(#)fs.h	8.13 (Berkeley) 3/21/95
3450477Speter * $FreeBSD: head/sys/ufs/ffs/fs.h 50477 1999-08-28 01:08:13Z peter $
351541Srgrimes */
361541Srgrimes
372176Spaul#ifndef _UFS_FFS_FS_H_
382176Spaul#define _UFS_FFS_FS_H_
392176Spaul
401541Srgrimes/*
411541Srgrimes * Each disk drive contains some number of file systems.
421541Srgrimes * A file system consists of a number of cylinder groups.
431541Srgrimes * Each cylinder group has inodes and data.
441541Srgrimes *
451541Srgrimes * A file system is described by its super-block, which in turn
461541Srgrimes * describes the cylinder groups.  The super-block is critical
471541Srgrimes * data and is replicated in each cylinder group to protect against
481541Srgrimes * catastrophic loss.  This is done at `newfs' time and the critical
491541Srgrimes * super-block data does not change, so the copies need not be
501541Srgrimes * referenced further unless disaster strikes.
511541Srgrimes *
521541Srgrimes * For file system fs, the offsets of the various blocks of interest
531541Srgrimes * are given in the super block as:
541541Srgrimes *	[fs->fs_sblkno]		Super-block
551541Srgrimes *	[fs->fs_cblkno]		Cylinder group block
561541Srgrimes *	[fs->fs_iblkno]		Inode blocks
571541Srgrimes *	[fs->fs_dblkno]		Data blocks
581541Srgrimes * The beginning of cylinder group cg in fs, is given by
591541Srgrimes * the ``cgbase(fs, cg)'' macro.
601541Srgrimes *
611541Srgrimes * The first boot and super blocks are given in absolute disk addresses.
621541Srgrimes * The byte-offset forms are preferred, as they don't imply a sector size.
631541Srgrimes */
641541Srgrimes#define BBSIZE		8192
651541Srgrimes#define SBSIZE		8192
661541Srgrimes#define	BBOFF		((off_t)(0))
671541Srgrimes#define	SBOFF		((off_t)(BBOFF + BBSIZE))
6822521Sdyson#define	BBLOCK		((ufs_daddr_t)(0))
6922521Sdyson#define	SBLOCK		((ufs_daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
701541Srgrimes
711541Srgrimes/*
721541Srgrimes * Addresses stored in inodes are capable of addressing fragments
738876Srgrimes * of `blocks'. File system blocks of at most size MAXBSIZE can
741541Srgrimes * be optionally broken into 2, 4, or 8 pieces, each of which is
7513765Smpp * addressable; these pieces may be DEV_BSIZE, or some multiple of
761541Srgrimes * a DEV_BSIZE unit.
771541Srgrimes *
781541Srgrimes * Large files consist of exclusively large data blocks.  To avoid
791541Srgrimes * undue wasted disk space, the last data block of a small file may be
801541Srgrimes * allocated as only as many fragments of a large block as are
811541Srgrimes * necessary.  The file system format retains only a single pointer
821541Srgrimes * to such a fragment, which is a piece of a single large block that
831541Srgrimes * has been divided.  The size of such a fragment is determinable from
841541Srgrimes * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
851541Srgrimes *
861541Srgrimes * The file system records space availability at the fragment level;
871541Srgrimes * to determine block availability, aligned fragments are examined.
881541Srgrimes */
891541Srgrimes
901541Srgrimes/*
911541Srgrimes * MINBSIZE is the smallest allowable block size.
921541Srgrimes * In order to insure that it is possible to create files of size
931541Srgrimes * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
941541Srgrimes * MINBSIZE must be big enough to hold a cylinder group block,
951541Srgrimes * thus changes to (struct cg) must keep its size within MINBSIZE.
961541Srgrimes * Note that super blocks are always of size SBSIZE,
971541Srgrimes * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
981541Srgrimes */
991541Srgrimes#define MINBSIZE	4096
1001541Srgrimes
1011541Srgrimes/*
1021541Srgrimes * The path name on which the file system is mounted is maintained
1038876Srgrimes * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
1041541Srgrimes * the super block for this name.
10522521Sdyson */
10622521Sdyson#define MAXMNTLEN	512
10722521Sdyson
10822521Sdyson/*
1091541Srgrimes * The limit on the amount of summary information per file system
1101541Srgrimes * is defined by MAXCSBUFS. It is currently parameterized for a
11122521Sdyson * size of 128 bytes (2 million cylinder groups on machines with
11222521Sdyson * 32-bit pointers, and 1 million on 64-bit machines). One pointer
11322521Sdyson * is taken away to point to an array of cluster sizes that is
11422521Sdyson * computed as cylinder groups are inspected.
1151541Srgrimes */
11622521Sdyson#define	MAXCSBUFS	((128 / sizeof(void *)) - 1)
1171541Srgrimes
1181541Srgrimes/*
1191541Srgrimes * A summary of contiguous blocks of various sizes is maintained
1201541Srgrimes * in each cylinder group. Normally this is set by the initial
1211541Srgrimes * value of fs_maxcontig. To conserve space, a maximum summary size
1221541Srgrimes * is set by FS_MAXCONTIG.
1231541Srgrimes */
1241541Srgrimes#define FS_MAXCONTIG	16
1251541Srgrimes
1261541Srgrimes/*
1271541Srgrimes * MINFREE gives the minimum acceptable percentage of file system
1281541Srgrimes * blocks which may be free. If the freelist drops below this level
1291541Srgrimes * only the superuser may continue to allocate blocks. This may
1301541Srgrimes * be set to 0 if no reserve of free blocks is deemed necessary,
1311541Srgrimes * however throughput drops by fifty percent if the file system
1321541Srgrimes * is run at between 95% and 100% full; thus the minimum default
1331541Srgrimes * value of fs_minfree is 5%. However, to get good clustering
1341541Srgrimes * performance, 10% is a better choice. hence we use 10% as our
1351541Srgrimes * default value. With 10% free space, fragmentation is not a
1361541Srgrimes * problem, so we choose to optimize for time.
1371541Srgrimes */
1386994Sdg#define MINFREE		8
1391541Srgrimes#define DEFAULTOPT	FS_OPTTIME
1401541Srgrimes
1411541Srgrimes/*
1421541Srgrimes * Per cylinder group information; summarized in blocks allocated
1431541Srgrimes * from first cylinder group data blocks.  These blocks have to be
1441541Srgrimes * read in from fs_csaddr (size fs_cssize) in addition to the
1451541Srgrimes * super block.
1461541Srgrimes *
1471541Srgrimes * N.B. sizeof(struct csum) must be a power of two in order for
1481541Srgrimes * the ``fs_cs'' macro to work (see below).
1491541Srgrimes */
1501541Srgrimesstruct csum {
15122521Sdyson	int32_t	cs_ndir;		/* number of directories */
15222521Sdyson	int32_t	cs_nbfree;		/* number of free blocks */
15322521Sdyson	int32_t	cs_nifree;		/* number of free inodes */
15422521Sdyson	int32_t	cs_nffree;		/* number of free frags */
1551541Srgrimes};
1561541Srgrimes
1571541Srgrimes/*
15822521Sdyson * Super block for an FFS file system.
1591541Srgrimes */
1601541Srgrimesstruct fs {
16122521Sdyson	int32_t	 fs_firstfield;		/* historic file system linked list, */
16222521Sdyson	int32_t	 fs_unused_1;		/*     used for incore super blocks */
16322521Sdyson	ufs_daddr_t fs_sblkno;		/* addr of super-block in filesys */
16422521Sdyson	ufs_daddr_t fs_cblkno;		/* offset of cyl-block in filesys */
16522521Sdyson	ufs_daddr_t fs_iblkno;		/* offset of inode-blocks in filesys */
16622521Sdyson	ufs_daddr_t fs_dblkno;		/* offset of first data after cg */
16722521Sdyson	int32_t	 fs_cgoffset;		/* cylinder group offset in cylinder */
16822521Sdyson	int32_t	 fs_cgmask;		/* used to calc mod fs_ntrak */
16922521Sdyson	time_t 	 fs_time;		/* last time written */
17022521Sdyson	int32_t	 fs_size;		/* number of blocks in fs */
17122521Sdyson	int32_t	 fs_dsize;		/* number of data blocks in fs */
17222521Sdyson	int32_t	 fs_ncg;		/* number of cylinder groups */
17322521Sdyson	int32_t	 fs_bsize;		/* size of basic blocks in fs */
17422521Sdyson	int32_t	 fs_fsize;		/* size of frag blocks in fs */
17522521Sdyson	int32_t	 fs_frag;		/* number of frags in a block in fs */
1761541Srgrimes/* these are configuration parameters */
17722521Sdyson	int32_t	 fs_minfree;		/* minimum percentage of free blocks */
17822521Sdyson	int32_t	 fs_rotdelay;		/* num of ms for optimal next block */
17922521Sdyson	int32_t	 fs_rps;		/* disk revolutions per second */
1801541Srgrimes/* these fields can be computed from the others */
18122521Sdyson	int32_t	 fs_bmask;		/* ``blkoff'' calc of blk offsets */
18222521Sdyson	int32_t	 fs_fmask;		/* ``fragoff'' calc of frag offsets */
18322521Sdyson	int32_t	 fs_bshift;		/* ``lblkno'' calc of logical blkno */
18422521Sdyson	int32_t	 fs_fshift;		/* ``numfrags'' calc number of frags */
1851541Srgrimes/* these are configuration parameters */
18622521Sdyson	int32_t	 fs_maxcontig;		/* max number of contiguous blks */
18722521Sdyson	int32_t	 fs_maxbpg;		/* max number of blks per cyl group */
1881541Srgrimes/* these fields can be computed from the others */
18922521Sdyson	int32_t	 fs_fragshift;		/* block to frag shift */
19022521Sdyson	int32_t	 fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
19122521Sdyson	int32_t	 fs_sbsize;		/* actual size of super block */
19222521Sdyson	int32_t	 fs_csmask;		/* csum block offset */
19322521Sdyson	int32_t	 fs_csshift;		/* csum block number */
19422521Sdyson	int32_t	 fs_nindir;		/* value of NINDIR */
19522521Sdyson	int32_t	 fs_inopb;		/* value of INOPB */
19622521Sdyson	int32_t	 fs_nspf;		/* value of NSPF */
1971541Srgrimes/* yet another configuration parameter */
19822521Sdyson	int32_t	 fs_optim;		/* optimization preference, see below */
1991541Srgrimes/* these fields are derived from the hardware */
20022521Sdyson	int32_t	 fs_npsect;		/* # sectors/track including spares */
20122521Sdyson	int32_t	 fs_interleave;		/* hardware sector interleave */
20222521Sdyson	int32_t	 fs_trackskew;		/* sector 0 skew, per track */
20324171Sbde/* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */
20424171Sbde	int32_t	 fs_id[2];		/* unique filesystem id */
2051541Srgrimes/* sizes determined by number of cylinder groups and their sizes */
20622521Sdyson	ufs_daddr_t fs_csaddr;		/* blk addr of cyl grp summary area */
20722521Sdyson	int32_t	 fs_cssize;		/* size of cyl grp summary area */
20822521Sdyson	int32_t	 fs_cgsize;		/* cylinder group size */
2091541Srgrimes/* these fields are derived from the hardware */
21022521Sdyson	int32_t	 fs_ntrak;		/* tracks per cylinder */
21122521Sdyson	int32_t	 fs_nsect;		/* sectors per track */
21222521Sdyson	int32_t  fs_spc;			/* sectors per cylinder */
2131541Srgrimes/* this comes from the disk driver partitioning */
21422521Sdyson	int32_t	 fs_ncyl;		/* cylinders in file system */
2151541Srgrimes/* these fields can be computed from the others */
21622521Sdyson	int32_t	 fs_cpg;			/* cylinders per group */
21722521Sdyson	int32_t	 fs_ipg;			/* inodes per group */
21822521Sdyson	int32_t	 fs_fpg;			/* blocks per group * fs_frag */
2191541Srgrimes/* this data must be re-computed after crashes */
2201541Srgrimes	struct	csum fs_cstotal;	/* cylinder summary information */
2211541Srgrimes/* these fields are cleared at mount time */
22222521Sdyson	int8_t   fs_fmod;		/* super block modified flag */
22322521Sdyson	int8_t   fs_clean;		/* file system is clean flag */
22422521Sdyson	int8_t 	 fs_ronly;		/* mounted read-only flag */
22534266Sjulian	int8_t   fs_flags;		/* see FS_ flags below */
22622521Sdyson	u_char	 fs_fsmnt[MAXMNTLEN];	/* name mounted on */
2271541Srgrimes/* these fields retain the current block allocation info */
22822521Sdyson	int32_t	 fs_cgrotor;		/* last cg searched */
2291541Srgrimes	struct	csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
23022521Sdyson	int32_t	 *fs_maxcluster;	/* max cluster in each cyl group */
23122521Sdyson	int32_t	 fs_cpc;		/* cyl per cycle in postbl */
23222521Sdyson	int16_t	 fs_opostbl[16][8];	/* old rotation block list head */
23322521Sdyson	int32_t	 fs_sparecon[50];	/* reserved for future constants */
23422521Sdyson	int32_t	 fs_contigsumsize;	/* size of cluster summary array */
23522521Sdyson	int32_t	 fs_maxsymlinklen;	/* max length of an internal symlink */
23622521Sdyson	int32_t	 fs_inodefmt;		/* format of on-disk inodes */
23722521Sdyson	u_int64_t fs_maxfilesize;	/* maximum representable file size */
23822521Sdyson	int64_t	 fs_qbmask;		/* ~fs_bmask for use with 64-bit size */
23922521Sdyson	int64_t	 fs_qfmask;		/* ~fs_fmask for use with 64-bit size */
24022521Sdyson	int32_t	 fs_state;		/* validate fs_clean field */
24122521Sdyson	int32_t	 fs_postblformat;	/* format of positional layout tables */
24222521Sdyson	int32_t	 fs_nrpos;		/* number of rotational positions */
24322521Sdyson	int32_t	 fs_postbloff;		/* (u_int16) rotation block list head */
24422521Sdyson	int32_t	 fs_rotbloff;		/* (u_int8) blocks for each rotation */
24522521Sdyson	int32_t	 fs_magic;		/* magic number */
24622521Sdyson	u_int8_t fs_space[1];		/* list of blocks for each rotation */
2471541Srgrimes/* actually longer */
2481541Srgrimes};
24922521Sdyson
2501541Srgrimes/*
25113765Smpp * Filesystem identification
2521541Srgrimes */
2531541Srgrimes#define	FS_MAGIC	0x011954	/* the fast filesystem magic number */
2541541Srgrimes#define	FS_OKAY		0x7c269d38	/* superblock checksum */
2551541Srgrimes#define FS_42INODEFMT	-1		/* 4.2BSD inode format */
2561541Srgrimes#define FS_44INODEFMT	2		/* 4.4BSD inode format */
25734266Sjulian
2581541Srgrimes/*
2591541Srgrimes * Preference for optimization.
2601541Srgrimes */
2611541Srgrimes#define FS_OPTTIME	0	/* minimize allocation time */
2621541Srgrimes#define FS_OPTSPACE	1	/* minimize disk fragmentation */
2631541Srgrimes
2641541Srgrimes/*
26534266Sjulian * Filesystem flags.
26634266Sjulian */
26734266Sjulian#define FS_UNCLEAN    0x01    /* filesystem not clean at mount */
26834266Sjulian#define FS_DOSOFTDEP  0x02    /* filesystem using soft dependencies */
26934266Sjulian
27034266Sjulian/*
2711541Srgrimes * Rotational layout table format types
2721541Srgrimes */
2731541Srgrimes#define FS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
2741541Srgrimes#define FS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
2751541Srgrimes/*
2761541Srgrimes * Macros for access to superblock array structures
2771541Srgrimes */
2781541Srgrimes#define fs_postbl(fs, cylno) \
2791541Srgrimes    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
2801541Srgrimes    ? ((fs)->fs_opostbl[cylno]) \
28122521Sdyson    : ((int16_t *)((u_int8_t *)(fs) + \
28222521Sdyson	(fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
2831541Srgrimes#define fs_rotbl(fs) \
2841541Srgrimes    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
2851541Srgrimes    ? ((fs)->fs_space) \
28622521Sdyson    : ((u_int8_t *)((u_int8_t *)(fs) + (fs)->fs_rotbloff)))
2871541Srgrimes
2881541Srgrimes/*
2891541Srgrimes * The size of a cylinder group is calculated by CGSIZE. The maximum size
2901541Srgrimes * is limited by the fact that cylinder groups are at most one block.
2918876Srgrimes * Its size is derived from the size of the maps maintained in the
2921541Srgrimes * cylinder group and the (struct cg) size.
2931541Srgrimes */
2941541Srgrimes#define CGSIZE(fs) \
29522521Sdyson    /* base cg */	(sizeof(struct cg) + sizeof(int32_t) + \
29622521Sdyson    /* blktot size */	(fs)->fs_cpg * sizeof(int32_t) + \
29722521Sdyson    /* blks size */	(fs)->fs_cpg * (fs)->fs_nrpos * sizeof(int16_t) + \
2981541Srgrimes    /* inode map */	howmany((fs)->fs_ipg, NBBY) + \
2991541Srgrimes    /* block map */	howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY) +\
3001541Srgrimes    /* if present */	((fs)->fs_contigsumsize <= 0 ? 0 : \
30122521Sdyson    /* cluster sum */	(fs)->fs_contigsumsize * sizeof(int32_t) + \
3021541Srgrimes    /* cluster map */	howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY)))
3031541Srgrimes
3041541Srgrimes/*
3051541Srgrimes * Convert cylinder group to base address of its global summary info.
3061541Srgrimes *
3071541Srgrimes * N.B. This macro assumes that sizeof(struct csum) is a power of two.
3081541Srgrimes */
3091541Srgrimes#define fs_cs(fs, indx) \
3101541Srgrimes	fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
3111541Srgrimes
3121541Srgrimes/*
3131541Srgrimes * Cylinder group block for a file system.
3141541Srgrimes */
3151541Srgrimes#define	CG_MAGIC	0x090255
31622521Sdysonstruct cg {
31722521Sdyson	int32_t	 cg_firstfield;		/* historic cyl groups linked list */
31822521Sdyson	int32_t	 cg_magic;		/* magic number */
31922521Sdyson	time_t	 cg_time;		/* time last written */
32022521Sdyson	int32_t	 cg_cgx;		/* we are the cgx'th cylinder group */
32122521Sdyson	int16_t	 cg_ncyl;		/* number of cyl's this cg */
32222521Sdyson	int16_t	 cg_niblk;		/* number of inode blocks this cg */
32322521Sdyson	int32_t	 cg_ndblk;		/* number of data blocks this cg */
3241541Srgrimes	struct	csum cg_cs;		/* cylinder summary information */
32522521Sdyson	int32_t	 cg_rotor;		/* position of last used block */
32622521Sdyson	int32_t	 cg_frotor;		/* position of last used frag */
32722521Sdyson	int32_t	 cg_irotor;		/* position of last used inode */
32822521Sdyson	int32_t	 cg_frsum[MAXFRAG];	/* counts of available frags */
32922521Sdyson	int32_t	 cg_btotoff;		/* (int32) block totals per cylinder */
33022521Sdyson	int32_t	 cg_boff;		/* (u_int16) free block positions */
33122521Sdyson	int32_t	 cg_iusedoff;		/* (u_int8) used inode map */
33222521Sdyson	int32_t	 cg_freeoff;		/* (u_int8) free block map */
33322521Sdyson	int32_t	 cg_nextfreeoff;	/* (u_int8) next available space */
33422521Sdyson	int32_t	 cg_clustersumoff;	/* (u_int32) counts of avail clusters */
33522521Sdyson	int32_t	 cg_clusteroff;		/* (u_int8) free cluster map */
33622521Sdyson	int32_t	 cg_nclusterblks;	/* number of clusters this cg */
33722521Sdyson	int32_t	 cg_sparecon[13];	/* reserved for future use */
33822521Sdyson	u_int8_t cg_space[1];		/* space for cylinder group maps */
3391541Srgrimes/* actually longer */
3401541Srgrimes};
34122521Sdyson
3421541Srgrimes/*
3431541Srgrimes * Macros for access to cylinder group array structures
3441541Srgrimes */
3451541Srgrimes#define cg_blktot(cgp) \
3461541Srgrimes    (((cgp)->cg_magic != CG_MAGIC) \
3471541Srgrimes    ? (((struct ocg *)(cgp))->cg_btot) \
34822521Sdyson    : ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_btotoff)))
3491541Srgrimes#define cg_blks(fs, cgp, cylno) \
3501541Srgrimes    (((cgp)->cg_magic != CG_MAGIC) \
3511541Srgrimes    ? (((struct ocg *)(cgp))->cg_b[cylno]) \
35222521Sdyson    : ((int16_t *)((u_int8_t *)(cgp) + \
35322521Sdyson	(cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
3541541Srgrimes#define cg_inosused(cgp) \
3551541Srgrimes    (((cgp)->cg_magic != CG_MAGIC) \
3561541Srgrimes    ? (((struct ocg *)(cgp))->cg_iused) \
35722521Sdyson    : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff)))
3581541Srgrimes#define cg_blksfree(cgp) \
3591541Srgrimes    (((cgp)->cg_magic != CG_MAGIC) \
3601541Srgrimes    ? (((struct ocg *)(cgp))->cg_free) \
36122521Sdyson    : ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff)))
3621541Srgrimes#define cg_chkmagic(cgp) \
3631541Srgrimes    ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
3641541Srgrimes#define cg_clustersfree(cgp) \
36522521Sdyson    ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff))
3661541Srgrimes#define cg_clustersum(cgp) \
36722521Sdyson    ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_clustersumoff))
3681541Srgrimes
3691541Srgrimes/*
3701541Srgrimes * The following structure is defined
3711541Srgrimes * for compatibility with old file systems.
3721541Srgrimes */
37322521Sdysonstruct ocg {
37422521Sdyson	int32_t	 cg_firstfield;		/* historic linked list of cyl groups */
37522521Sdyson	int32_t	 cg_unused_1;		/*     used for incore cyl groups */
37622521Sdyson	time_t	 cg_time;		/* time last written */
37722521Sdyson	int32_t	 cg_cgx;		/* we are the cgx'th cylinder group */
37822521Sdyson	int16_t	 cg_ncyl;		/* number of cyl's this cg */
37922521Sdyson	int16_t	 cg_niblk;		/* number of inode blocks this cg */
38022521Sdyson	int32_t	 cg_ndblk;		/* number of data blocks this cg */
3811541Srgrimes	struct	csum cg_cs;		/* cylinder summary information */
38222521Sdyson	int32_t	 cg_rotor;		/* position of last used block */
38322521Sdyson	int32_t	 cg_frotor;		/* position of last used frag */
38422521Sdyson	int32_t	 cg_irotor;		/* position of last used inode */
38522521Sdyson	int32_t	 cg_frsum[8];		/* counts of available frags */
38622521Sdyson	int32_t	 cg_btot[32];		/* block totals per cylinder */
38722521Sdyson	int16_t	 cg_b[32][8];		/* positions of free blocks */
38822521Sdyson	u_int8_t cg_iused[256];		/* used inode map */
38922521Sdyson	int32_t	 cg_magic;		/* magic number */
39022521Sdyson	u_int8_t cg_free[1];		/* free block map */
3911541Srgrimes/* actually longer */
3921541Srgrimes};
3931541Srgrimes
3941541Srgrimes/*
3951541Srgrimes * Turn file system block numbers into disk block addresses.
3961541Srgrimes * This maps file system blocks to device size blocks.
3971541Srgrimes */
3981541Srgrimes#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
3991541Srgrimes#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
4001541Srgrimes
4011541Srgrimes/*
4021541Srgrimes * Cylinder group macros to locate things in cylinder groups.
4031541Srgrimes * They calc file system addresses of cylinder group data structures.
4041541Srgrimes */
40522521Sdyson#define	cgbase(fs, c)	((ufs_daddr_t)((fs)->fs_fpg * (c)))
4061541Srgrimes#define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */
4071541Srgrimes#define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
4081541Srgrimes#define	cgsblock(fs, c)	(cgstart(fs, c) + (fs)->fs_sblkno)	/* super blk */
4091541Srgrimes#define	cgtod(fs, c)	(cgstart(fs, c) + (fs)->fs_cblkno)	/* cg block */
4101541Srgrimes#define cgstart(fs, c)							\
4111541Srgrimes	(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
4121541Srgrimes
4131541Srgrimes/*
4141541Srgrimes * Macros for handling inode numbers:
4151541Srgrimes *     inode number to file system block offset.
4161541Srgrimes *     inode number to cylinder group number.
4171541Srgrimes *     inode number to file system block address.
4181541Srgrimes */
4191541Srgrimes#define	ino_to_cg(fs, x)	((x) / (fs)->fs_ipg)
4201541Srgrimes#define	ino_to_fsba(fs, x)						\
42122521Sdyson	((ufs_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +			\
4221541Srgrimes	    (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
4231541Srgrimes#define	ino_to_fsbo(fs, x)	((x) % INOPB(fs))
4241541Srgrimes
4251541Srgrimes/*
4261541Srgrimes * Give cylinder group number for a file system block.
4271541Srgrimes * Give cylinder group block number for a file system block.
4281541Srgrimes */
4291541Srgrimes#define	dtog(fs, d)	((d) / (fs)->fs_fpg)
4301541Srgrimes#define	dtogd(fs, d)	((d) % (fs)->fs_fpg)
4311541Srgrimes
4321541Srgrimes/*
4331541Srgrimes * Extract the bits for a block from a map.
4341541Srgrimes * Compute the cylinder and rotational position of a cyl block addr.
4351541Srgrimes */
4361541Srgrimes#define blkmap(fs, map, loc) \
4371541Srgrimes    (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
4381541Srgrimes#define cbtocylno(fs, bno) \
4391541Srgrimes    ((bno) * NSPF(fs) / (fs)->fs_spc)
4401541Srgrimes#define cbtorpos(fs, bno) \
4411541Srgrimes    (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
4421541Srgrimes     (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
4431541Srgrimes     (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
4441541Srgrimes
4451541Srgrimes/*
4461541Srgrimes * The following macros optimize certain frequently calculated
4471541Srgrimes * quantities by using shifts and masks in place of divisions
4481541Srgrimes * modulos and multiplications.
4491541Srgrimes */
4501541Srgrimes#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
4511541Srgrimes	((loc) & (fs)->fs_qbmask)
4521541Srgrimes#define fragoff(fs, loc)	/* calculates (loc % fs->fs_fsize) */ \
4531541Srgrimes	((loc) & (fs)->fs_qfmask)
45418899Sbde#define lblktosize(fs, blk)	/* calculates ((off_t)blk * fs->fs_bsize) */ \
45518899Sbde	((off_t)(blk) << (fs)->fs_bshift)
45618899Sbde/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
45718899Sbde#define smalllblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
4581541Srgrimes	((blk) << (fs)->fs_bshift)
4591541Srgrimes#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
4601541Srgrimes	((loc) >> (fs)->fs_bshift)
4611541Srgrimes#define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
4621541Srgrimes	((loc) >> (fs)->fs_fshift)
4631541Srgrimes#define blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
4641541Srgrimes	(((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
4651541Srgrimes#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
4661541Srgrimes	(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
4671541Srgrimes#define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
4681541Srgrimes	((frags) >> (fs)->fs_fragshift)
4691541Srgrimes#define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
4701541Srgrimes	((blks) << (fs)->fs_fragshift)
4711541Srgrimes#define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
4721541Srgrimes	((fsb) & ((fs)->fs_frag - 1))
4731541Srgrimes#define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
4741541Srgrimes	((fsb) &~ ((fs)->fs_frag - 1))
4751541Srgrimes
4761541Srgrimes/*
4771541Srgrimes * Determine the number of available frags given a
47822521Sdyson * percentage to hold in reserve.
4791541Srgrimes */
4801541Srgrimes#define freespace(fs, percentreserved) \
4811541Srgrimes	(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
4821541Srgrimes	(fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
4831541Srgrimes
4841541Srgrimes/*
4851541Srgrimes * Determining the size of a file block in the file system.
4861541Srgrimes */
4871541Srgrimes#define blksize(fs, ip, lbn) \
48818899Sbde	(((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
4891541Srgrimes	    ? (fs)->fs_bsize \
4901541Srgrimes	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
4911541Srgrimes#define dblksize(fs, dip, lbn) \
49218899Sbde	(((lbn) >= NDADDR || (dip)->di_size >= smalllblktosize(fs, (lbn) + 1)) \
4931541Srgrimes	    ? (fs)->fs_bsize \
4941541Srgrimes	    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
49534266Sjulian#define sblksize(fs, size, lbn) \
49634266Sjulian	(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
49734266Sjulian	  ? (fs)->fs_bsize \
49834266Sjulian	  : (fragroundup(fs, blkoff(fs, (size)))))
4991541Srgrimes
50034266Sjulian
5011541Srgrimes/*
50222521Sdyson * Number of disk sectors per block/fragment; assumes DEV_BSIZE byte
50322521Sdyson * sector size.
5041541Srgrimes */
5051541Srgrimes#define	NSPB(fs)	((fs)->fs_nspf << (fs)->fs_fragshift)
5061541Srgrimes#define	NSPF(fs)	((fs)->fs_nspf)
5071541Srgrimes
5081541Srgrimes/*
50922521Sdyson * Number of inodes in a secondary storage block/fragment.
5101541Srgrimes */
5111541Srgrimes#define	INOPB(fs)	((fs)->fs_inopb)
5121541Srgrimes#define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
5131541Srgrimes
5141541Srgrimes/*
51522521Sdyson * Number of indirects in a file system block.
5161541Srgrimes */
5171541Srgrimes#define	NINDIR(fs)	((fs)->fs_nindir)
5181541Srgrimes
5191541Srgrimesextern int inside[], around[];
5201541Srgrimesextern u_char *fragtbl[];
5212176Spaul
5222176Spaul#endif
523