xref: /illumos-gate/usr/src/uts/common/sys/fs/ufs_fs.h (revision 2d6eb4a5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*02ff05a9Svsakar  * Common Development and Distribution License (the "License").
6*02ff05a9Svsakar  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*02ff05a9Svsakar  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
317c478bd9Sstevel@tonic-gate  * The Regents of the University of California
327c478bd9Sstevel@tonic-gate  * All Rights Reserved
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
357c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
367c478bd9Sstevel@tonic-gate  * contributors.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #ifndef	_SYS_FS_UFS_FS_H
407c478bd9Sstevel@tonic-gate #define	_SYS_FS_UFS_FS_H
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
437c478bd9Sstevel@tonic-gate #include <sys/types32.h>
447c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>		/* for kmutex_t */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
477c478bd9Sstevel@tonic-gate extern "C" {
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * The following values are minor release values for UFS.
526451fdbcSvsakar  * The fs_version field in the superblock will equal one of them.
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #define		MTB_UFS_VERSION_MIN	1
567c478bd9Sstevel@tonic-gate #define		MTB_UFS_VERSION_1	1
576451fdbcSvsakar #define		UFS_VERSION_MIN	0
586451fdbcSvsakar #define		UFS_EFISTYLE4NONEFI_VERSION_2	2
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * Each disk drive contains some number of file systems.
627c478bd9Sstevel@tonic-gate  * A file system consists of a number of cylinder groups.
637c478bd9Sstevel@tonic-gate  * Each cylinder group has inodes and data.
647c478bd9Sstevel@tonic-gate  *
657c478bd9Sstevel@tonic-gate  * A file system is described by its super-block, which in turn
667c478bd9Sstevel@tonic-gate  * describes the cylinder groups.  The super-block is critical
677c478bd9Sstevel@tonic-gate  * data and is replicated in the first 10 cylinder groups and the
687c478bd9Sstevel@tonic-gate  * the last 10 cylinder groups to protect against
697c478bd9Sstevel@tonic-gate  * catastrophic loss.  This is done at mkfs time and the critical
707c478bd9Sstevel@tonic-gate  * super-block data does not change, so the copies need not be
717c478bd9Sstevel@tonic-gate  * referenced further unless disaster strikes.
727c478bd9Sstevel@tonic-gate  *
737c478bd9Sstevel@tonic-gate  * For file system fs, the offsets of the various blocks of interest
747c478bd9Sstevel@tonic-gate  * are given in the super block as:
757c478bd9Sstevel@tonic-gate  *	[fs->fs_sblkno]		Super-block
767c478bd9Sstevel@tonic-gate  *	[fs->fs_cblkno]		Cylinder group block
777c478bd9Sstevel@tonic-gate  *	[fs->fs_iblkno]		Inode blocks
787c478bd9Sstevel@tonic-gate  *	[fs->fs_dblkno]		Data blocks
797c478bd9Sstevel@tonic-gate  * The beginning of cylinder group cg in fs, is given by
807c478bd9Sstevel@tonic-gate  * the ``cgbase(fs, cg)'' macro.
817c478bd9Sstevel@tonic-gate  *
827c478bd9Sstevel@tonic-gate  * The first boot and super blocks are given in absolute disk addresses.
837c478bd9Sstevel@tonic-gate  * The byte-offset forms are preferred, as they don't imply a sector size.
847c478bd9Sstevel@tonic-gate  */
857c478bd9Sstevel@tonic-gate #define	BBSIZE		8192
867c478bd9Sstevel@tonic-gate #define	SBSIZE		8192
877c478bd9Sstevel@tonic-gate #define	BBOFF		((off_t)(0))
887c478bd9Sstevel@tonic-gate #define	SBOFF		((off_t)(BBOFF + BBSIZE))
897c478bd9Sstevel@tonic-gate #define	BBLOCK		((daddr32_t)(0))
907c478bd9Sstevel@tonic-gate #define	SBLOCK		((daddr32_t)(BBLOCK + BBSIZE / DEV_BSIZE))
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate  * Addresses stored in inodes are capable of addressing fragments
947c478bd9Sstevel@tonic-gate  * of `blocks'. File system blocks of at most size MAXBSIZE can
957c478bd9Sstevel@tonic-gate  * be optionally broken into 2, 4, or 8 pieces, each of which is
967c478bd9Sstevel@tonic-gate  * addressible; these pieces may be DEV_BSIZE, or some multiple of
977c478bd9Sstevel@tonic-gate  * a DEV_BSIZE unit.
987c478bd9Sstevel@tonic-gate  *
997c478bd9Sstevel@tonic-gate  * Large files consist of exclusively large data blocks.  To avoid
1007c478bd9Sstevel@tonic-gate  * undue wasted disk space, the last data block of a small file may be
1017c478bd9Sstevel@tonic-gate  * allocated as only as many fragments of a large block as are
1027c478bd9Sstevel@tonic-gate  * necessary.  The file system format retains only a single pointer
1037c478bd9Sstevel@tonic-gate  * to such a fragment, which is a piece of a single large block that
1047c478bd9Sstevel@tonic-gate  * has been divided.  The size of such a fragment is determinable from
1057c478bd9Sstevel@tonic-gate  * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  * The file system records space availability at the fragment level;
1087c478bd9Sstevel@tonic-gate  * to determine block availability, aligned fragments are examined.
1097c478bd9Sstevel@tonic-gate  *
1107c478bd9Sstevel@tonic-gate  * The root inode is the root of the file system.
1117c478bd9Sstevel@tonic-gate  * Inode 0 can't be used for normal purposes and
1127c478bd9Sstevel@tonic-gate  * historically bad blocks were linked to inode 1,
1137c478bd9Sstevel@tonic-gate  * thus the root inode is 2. (inode 1 is no longer used for
1147c478bd9Sstevel@tonic-gate  * this purpose, however numerous dump tapes make this
1157c478bd9Sstevel@tonic-gate  * assumption, so we are stuck with it)
1167c478bd9Sstevel@tonic-gate  * The lost+found directory is given the next available
1177c478bd9Sstevel@tonic-gate  * inode when it is created by ``mkfs''.
1187c478bd9Sstevel@tonic-gate  */
1197c478bd9Sstevel@tonic-gate #define	UFSROOTINO	((ino_t)2)	/* i number of all roots */
1207c478bd9Sstevel@tonic-gate #define	LOSTFOUNDINO    (UFSROOTINO + 1)
1217c478bd9Sstevel@tonic-gate #ifndef _LONGLONG_TYPE
1227c478bd9Sstevel@tonic-gate #define	UFS_MAXOFFSET_T	MAXOFF_T
1237c478bd9Sstevel@tonic-gate #define	UFS_FILESIZE_BITS	32
1247c478bd9Sstevel@tonic-gate #else
1257c478bd9Sstevel@tonic-gate #define	UFS_MAXOFFSET_T	((1LL << NBBY * sizeof (daddr32_t) + DEV_BSHIFT - 1) \
1267c478bd9Sstevel@tonic-gate 							- 1)
1277c478bd9Sstevel@tonic-gate #define	UFS_FILESIZE_BITS	41
1287c478bd9Sstevel@tonic-gate #endif /* _LONGLONG_TYPE */
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate /*
1317c478bd9Sstevel@tonic-gate  * MINBSIZE is the smallest allowable block size.
1327c478bd9Sstevel@tonic-gate  * In order to insure that it is possible to create files of size
1337c478bd9Sstevel@tonic-gate  * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
1347c478bd9Sstevel@tonic-gate  * MINBSIZE must be big enough to hold a cylinder group block,
1357c478bd9Sstevel@tonic-gate  * thus changes to (struct cg) must keep its size within MINBSIZE.
1367c478bd9Sstevel@tonic-gate  * Note that super blocks are always of size SBSIZE,
1377c478bd9Sstevel@tonic-gate  * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
1387c478bd9Sstevel@tonic-gate  */
1397c478bd9Sstevel@tonic-gate #define	MINBSIZE	4096
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * The path name on which the file system is mounted is maintained
1437c478bd9Sstevel@tonic-gate  * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
1447c478bd9Sstevel@tonic-gate  * the super block for this name.
1457c478bd9Sstevel@tonic-gate  * The limit on the amount of summary information per file system
1467c478bd9Sstevel@tonic-gate  * is defined by MAXCSBUFS. It is currently parameterized for a
1477c478bd9Sstevel@tonic-gate  * maximum of two million cylinders.
1487c478bd9Sstevel@tonic-gate  */
1497c478bd9Sstevel@tonic-gate #define	MAXMNTLEN 512
1507c478bd9Sstevel@tonic-gate #define	MAXCSBUFS 32
1517c478bd9Sstevel@tonic-gate 
1526451fdbcSvsakar #define	LABEL_TYPE_VTOC		1
1536451fdbcSvsakar #define	LABEL_TYPE_EFI		2
1546451fdbcSvsakar #define	LABEL_TYPE_OTHER	3
1556451fdbcSvsakar 
1566451fdbcSvsakar /*
1576451fdbcSvsakar  * The following constant is taken from the ANSI T13 ATA Specification
1586451fdbcSvsakar  * and defines the maximum size (in sectors) that an ATA disk can be
1596451fdbcSvsakar  * and still has to provide CHS translation. For a disk above this
1606451fdbcSvsakar  * size all sectors are to be accessed via their LBA address. This
1616451fdbcSvsakar  * makes a good cut off value to move from disk provided geometry
1626451fdbcSvsakar  * to the predefined defaults used in efi label disks.
1636451fdbcSvsakar  */
1646451fdbcSvsakar #define	CHSLIMIT	(63 * 256 * 1024)
1656451fdbcSvsakar 
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate  * Per cylinder group information; summarized in blocks allocated
1687c478bd9Sstevel@tonic-gate  * from first cylinder group data blocks.  These blocks have to be
1697c478bd9Sstevel@tonic-gate  * read in from fs_csaddr (size fs_cssize) in addition to the
1707c478bd9Sstevel@tonic-gate  * super block.
1717c478bd9Sstevel@tonic-gate  *
1727c478bd9Sstevel@tonic-gate  * N.B. sizeof (struct csum) must be a power of two in order for
1737c478bd9Sstevel@tonic-gate  * the ``fs_cs'' macro to work (see below).
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate struct csum {
1767c478bd9Sstevel@tonic-gate 	int32_t	cs_ndir;	/* number of directories */
1777c478bd9Sstevel@tonic-gate 	int32_t	cs_nbfree;	/* number of free blocks */
1787c478bd9Sstevel@tonic-gate 	int32_t	cs_nifree;	/* number of free inodes */
1797c478bd9Sstevel@tonic-gate 	int32_t	cs_nffree;	/* number of free frags */
1807c478bd9Sstevel@tonic-gate };
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate /*
1837c478bd9Sstevel@tonic-gate  * In the 5.0 release, the file system state flag in the superblock (fs_clean)
1847c478bd9Sstevel@tonic-gate  * is now used. The value of fs_clean can be:
1857c478bd9Sstevel@tonic-gate  *	FSACTIVE	file system may have fsck inconsistencies
1867c478bd9Sstevel@tonic-gate  *	FSCLEAN		file system has successfully unmounted (implies
1877c478bd9Sstevel@tonic-gate  *			everything is ok)
1887c478bd9Sstevel@tonic-gate  *	FSSTABLE	No fsck inconsistencies, no guarantee on user data
1897c478bd9Sstevel@tonic-gate  *	FSBAD		file system is mounted from a partition that is
1907c478bd9Sstevel@tonic-gate  *			neither FSCLEAN or FSSTABLE
1917c478bd9Sstevel@tonic-gate  *	FSSUSPEND	Clean flag processing is temporarily disabled
1927c478bd9Sstevel@tonic-gate  *	FSLOG		Logging file system
1937c478bd9Sstevel@tonic-gate  * Under this scheme, fsck can safely skip file systems that
1947c478bd9Sstevel@tonic-gate  * are FSCLEAN or FSSTABLE.  To provide additional safeguard,
1957c478bd9Sstevel@tonic-gate  * fs_clean information could be trusted only if
1967c478bd9Sstevel@tonic-gate  * fs_state == FSOKAY - fs_time, where FSOKAY is a constant
1977c478bd9Sstevel@tonic-gate  *
1987c478bd9Sstevel@tonic-gate  * Note: mount(2) will now return ENOSPC if fs_clean is neither FSCLEAN nor
1997c478bd9Sstevel@tonic-gate  * FSSTABLE, or fs_state is not valid.  The exceptions are the root or
2007c478bd9Sstevel@tonic-gate  * the read-only partitions
2017c478bd9Sstevel@tonic-gate  */
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate  * Super block for a file system.
2057c478bd9Sstevel@tonic-gate  *
2067c478bd9Sstevel@tonic-gate  * Most of the data in the super block is read-only data and needs
2077c478bd9Sstevel@tonic-gate  * no explicit locking to protect it. Exceptions are:
2087c478bd9Sstevel@tonic-gate  *	fs_time
2097c478bd9Sstevel@tonic-gate  *	fs_optim
2107c478bd9Sstevel@tonic-gate  *	fs_cstotal
2117c478bd9Sstevel@tonic-gate  *	fs_fmod
2127c478bd9Sstevel@tonic-gate  *	fs_cgrotor
2137c478bd9Sstevel@tonic-gate  *	fs_flags   (largefiles flag - set when a file grows large)
2147c478bd9Sstevel@tonic-gate  * These fields require the use of fs->fs_lock.
2157c478bd9Sstevel@tonic-gate  */
2167c478bd9Sstevel@tonic-gate #define	FS_MAGIC	0x011954
2177c478bd9Sstevel@tonic-gate #define	MTB_UFS_MAGIC	0xdecade
2187c478bd9Sstevel@tonic-gate #define	FSOKAY		(0x7c269d38)
2197c478bd9Sstevel@tonic-gate /*  #define	FSOKAY		(0x7c269d38 + 3) */
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate  * fs_clean values
2227c478bd9Sstevel@tonic-gate  */
2237c478bd9Sstevel@tonic-gate #define	FSACTIVE	((char)0)
2247c478bd9Sstevel@tonic-gate #define	FSCLEAN		((char)0x1)
2257c478bd9Sstevel@tonic-gate #define	FSSTABLE	((char)0x2)
2267c478bd9Sstevel@tonic-gate #define	FSBAD		((char)0xff)	/* mounted !FSCLEAN and !FSSTABLE */
2277c478bd9Sstevel@tonic-gate #define	FSSUSPEND	((char)0xfe)	/* temporarily suspended */
2287c478bd9Sstevel@tonic-gate #define	FSLOG		((char)0xfd)	/* logging fs */
2297c478bd9Sstevel@tonic-gate #define	FSFIX		((char)0xfc)	/* being repaired while mounted */
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate  * fs_flags values
2337c478bd9Sstevel@tonic-gate  */
2347c478bd9Sstevel@tonic-gate #define	FSLARGEFILES	((char)0x1)	/* largefiles exist on filesystem */
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate struct  fs {
2377c478bd9Sstevel@tonic-gate 	uint32_t fs_link;		/* linked list of file systems */
2387c478bd9Sstevel@tonic-gate 	uint32_t fs_rolled;		/* logging only: fs fully rolled */
2397c478bd9Sstevel@tonic-gate 	daddr32_t fs_sblkno;		/* addr of super-block in filesys */
2407c478bd9Sstevel@tonic-gate 	daddr32_t fs_cblkno;		/* offset of cyl-block in filesys */
2417c478bd9Sstevel@tonic-gate 	daddr32_t fs_iblkno;		/* offset of inode-blocks in filesys */
2427c478bd9Sstevel@tonic-gate 	daddr32_t fs_dblkno;		/* offset of first data after cg */
2437c478bd9Sstevel@tonic-gate 	int32_t	fs_cgoffset;		/* cylinder group offset in cylinder */
2447c478bd9Sstevel@tonic-gate 	int32_t	fs_cgmask;		/* used to calc mod fs_ntrak */
2457c478bd9Sstevel@tonic-gate 	time32_t fs_time;		/* last time written */
2467c478bd9Sstevel@tonic-gate 	int32_t	fs_size;		/* number of blocks in fs */
2477c478bd9Sstevel@tonic-gate 	int32_t	fs_dsize;		/* number of data blocks in fs */
2487c478bd9Sstevel@tonic-gate 	int32_t	fs_ncg;			/* number of cylinder groups */
2497c478bd9Sstevel@tonic-gate 	int32_t	fs_bsize;		/* size of basic blocks in fs */
2507c478bd9Sstevel@tonic-gate 	int32_t	fs_fsize;		/* size of frag blocks in fs */
2517c478bd9Sstevel@tonic-gate 	int32_t	fs_frag;		/* number of frags in a block in fs */
2527c478bd9Sstevel@tonic-gate /* these are configuration parameters */
2537c478bd9Sstevel@tonic-gate 	int32_t	fs_minfree;		/* minimum percentage of free blocks */
2547c478bd9Sstevel@tonic-gate 	int32_t	fs_rotdelay;		/* num of ms for optimal next block */
2557c478bd9Sstevel@tonic-gate 	int32_t	fs_rps;			/* disk revolutions per second */
2567c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
2577c478bd9Sstevel@tonic-gate 	int32_t	fs_bmask;		/* ``blkoff'' calc of blk offsets */
2587c478bd9Sstevel@tonic-gate 	int32_t	fs_fmask;		/* ``fragoff'' calc of frag offsets */
2597c478bd9Sstevel@tonic-gate 	int32_t	fs_bshift;		/* ``lblkno'' calc of logical blkno */
2607c478bd9Sstevel@tonic-gate 	int32_t	fs_fshift;		/* ``numfrags'' calc number of frags */
2617c478bd9Sstevel@tonic-gate /* these are configuration parameters */
2627c478bd9Sstevel@tonic-gate 	int32_t	fs_maxcontig;		/* max number of contiguous blks */
2637c478bd9Sstevel@tonic-gate 	int32_t	fs_maxbpg;		/* max number of blks per cyl group */
2647c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
2657c478bd9Sstevel@tonic-gate 	int32_t	fs_fragshift;		/* block to frag shift */
2667c478bd9Sstevel@tonic-gate 	int32_t	fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
2677c478bd9Sstevel@tonic-gate 	int32_t	fs_sbsize;		/* actual size of super block */
2687c478bd9Sstevel@tonic-gate 	int32_t	fs_csmask;		/* csum block offset */
2697c478bd9Sstevel@tonic-gate 	int32_t	fs_csshift;		/* csum block number */
2707c478bd9Sstevel@tonic-gate 	int32_t	fs_nindir;		/* value of NINDIR */
2717c478bd9Sstevel@tonic-gate 	int32_t	fs_inopb;		/* value of INOPB */
2727c478bd9Sstevel@tonic-gate 	int32_t	fs_nspf;		/* value of NSPF */
2737c478bd9Sstevel@tonic-gate /* yet another configuration parameter */
2747c478bd9Sstevel@tonic-gate 	int32_t	fs_optim;		/* optimization preference, see below */
2757c478bd9Sstevel@tonic-gate /* these fields are derived from the hardware */
2767c478bd9Sstevel@tonic-gate 	/* USL SVR4 compatibility */
2777c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
2787c478bd9Sstevel@tonic-gate 	/*
2797c478bd9Sstevel@tonic-gate 	 * USL SVR4 compatibility
2807c478bd9Sstevel@tonic-gate 	 *
2817c478bd9Sstevel@tonic-gate 	 * There was a significant divergence here between Solaris and
2827c478bd9Sstevel@tonic-gate 	 * SVR4 for x86.  By swapping these two members in the superblock,
2837c478bd9Sstevel@tonic-gate 	 * we get read-only compatibility of SVR4 filesystems.  Otherwise
2847c478bd9Sstevel@tonic-gate 	 * there would be no compatibility.  This change was introduced
2857c478bd9Sstevel@tonic-gate 	 * during bootstrapping of Solaris on x86.  By making this ifdef'ed
2867c478bd9Sstevel@tonic-gate 	 * on byte order, we provide ongoing compatibility across all
2877c478bd9Sstevel@tonic-gate 	 * platforms with the same byte order, the highest compatibility
2887c478bd9Sstevel@tonic-gate 	 * that can be achieved.
2897c478bd9Sstevel@tonic-gate 	 */
2907c478bd9Sstevel@tonic-gate 	int32_t	fs_state;		/* file system state time stamp */
2917c478bd9Sstevel@tonic-gate #else
2927c478bd9Sstevel@tonic-gate 	int32_t	fs_npsect;		/* # sectors/track including spares */
2937c478bd9Sstevel@tonic-gate #endif
2947c478bd9Sstevel@tonic-gate 	int32_t fs_si;			/* summary info state - lufs only */
2957c478bd9Sstevel@tonic-gate 	int32_t	fs_trackskew;		/* sector 0 skew, per track */
2967c478bd9Sstevel@tonic-gate /* a unique id for this filesystem (currently unused and unmaintained) */
2977c478bd9Sstevel@tonic-gate /* In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek */
2987c478bd9Sstevel@tonic-gate /* Neither of those fields is used in the Tahoe code right now but */
2997c478bd9Sstevel@tonic-gate /* there could be problems if they are.				*/
3007c478bd9Sstevel@tonic-gate 	int32_t	fs_id[2];		/* file system id */
3017c478bd9Sstevel@tonic-gate /* sizes determined by number of cylinder groups and their sizes */
3027c478bd9Sstevel@tonic-gate 	daddr32_t fs_csaddr;		/* blk addr of cyl grp summary area */
3037c478bd9Sstevel@tonic-gate 	int32_t	fs_cssize;		/* size of cyl grp summary area */
3047c478bd9Sstevel@tonic-gate 	int32_t	fs_cgsize;		/* cylinder group size */
3057c478bd9Sstevel@tonic-gate /* these fields are derived from the hardware */
3067c478bd9Sstevel@tonic-gate 	int32_t	fs_ntrak;		/* tracks per cylinder */
3077c478bd9Sstevel@tonic-gate 	int32_t	fs_nsect;		/* sectors per track */
3087c478bd9Sstevel@tonic-gate 	int32_t	fs_spc;			/* sectors per cylinder */
3097c478bd9Sstevel@tonic-gate /* this comes from the disk driver partitioning */
3107c478bd9Sstevel@tonic-gate 	int32_t	fs_ncyl;		/* cylinders in file system */
3117c478bd9Sstevel@tonic-gate /* these fields can be computed from the others */
3127c478bd9Sstevel@tonic-gate 	int32_t	fs_cpg;			/* cylinders per group */
3137c478bd9Sstevel@tonic-gate 	int32_t	fs_ipg;			/* inodes per group */
3147c478bd9Sstevel@tonic-gate 	int32_t	fs_fpg;			/* blocks per group * fs_frag */
3157c478bd9Sstevel@tonic-gate /* this data must be re-computed after crashes */
3167c478bd9Sstevel@tonic-gate 	struct	csum fs_cstotal;	/* cylinder summary information */
3177c478bd9Sstevel@tonic-gate /* these fields are cleared at mount time */
3187c478bd9Sstevel@tonic-gate 	char	fs_fmod;		/* super block modified flag */
3197c478bd9Sstevel@tonic-gate 	char	fs_clean;		/* file system state flag */
3207c478bd9Sstevel@tonic-gate 	char	fs_ronly;		/* mounted read-only flag */
3217c478bd9Sstevel@tonic-gate 	char	fs_flags;		/* largefiles flag, etc. */
3227c478bd9Sstevel@tonic-gate 	char	fs_fsmnt[MAXMNTLEN];	/* name mounted on */
3237c478bd9Sstevel@tonic-gate /* these fields retain the current block allocation info */
3247c478bd9Sstevel@tonic-gate 	int32_t	fs_cgrotor;		/* last cg searched */
3257c478bd9Sstevel@tonic-gate 	/*
3267c478bd9Sstevel@tonic-gate 	 * The following used to be fs_csp[MAXCSBUFS]. It was not
3277c478bd9Sstevel@tonic-gate 	 * used anywhere except in old utilities.  We removed this
3287c478bd9Sstevel@tonic-gate 	 * in 5.6 and expect fs_u.fs_csp to be used instead.
3297c478bd9Sstevel@tonic-gate 	 * We no longer limit fs_cssize based on MAXCSBUFS.
3307c478bd9Sstevel@tonic-gate 	 */
3317c478bd9Sstevel@tonic-gate 	union { 			/* fs_cs (csum) info */
3327c478bd9Sstevel@tonic-gate 		uint32_t fs_csp_pad[MAXCSBUFS];
3337c478bd9Sstevel@tonic-gate 		struct csum *fs_csp;
3347c478bd9Sstevel@tonic-gate 	} fs_u;
3357c478bd9Sstevel@tonic-gate 	int32_t	fs_cpc;			/* cyl per cycle in postbl */
3367c478bd9Sstevel@tonic-gate 	short	fs_opostbl[16][8];	/* old rotation block list head */
3377c478bd9Sstevel@tonic-gate 	int32_t	fs_sparecon[51];	/* reserved for future constants */
3386451fdbcSvsakar 	int32_t fs_version;		/* minor version of ufs */
3397c478bd9Sstevel@tonic-gate 	int32_t	fs_logbno;		/* block # of embedded log */
3407c478bd9Sstevel@tonic-gate 	int32_t fs_reclaim;		/* reclaim open, deleted files */
3417c478bd9Sstevel@tonic-gate 	int32_t	fs_sparecon2;		/* reserved for future constant */
3427c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
3437c478bd9Sstevel@tonic-gate 	/* USL SVR4 compatibility */
3447c478bd9Sstevel@tonic-gate 	int32_t	fs_npsect;		/* # sectors/track including spares */
3457c478bd9Sstevel@tonic-gate #else
3467c478bd9Sstevel@tonic-gate 	int32_t	fs_state;		/* file system state time stamp */
3477c478bd9Sstevel@tonic-gate #endif
3487c478bd9Sstevel@tonic-gate 	quad_t	fs_qbmask;		/* ~fs_bmask - for use with quad size */
3497c478bd9Sstevel@tonic-gate 	quad_t	fs_qfmask;		/* ~fs_fmask - for use with quad size */
3507c478bd9Sstevel@tonic-gate 	int32_t	fs_postblformat;	/* format of positional layout tables */
3517c478bd9Sstevel@tonic-gate 	int32_t	fs_nrpos;		/* number of rotaional positions */
3527c478bd9Sstevel@tonic-gate 	int32_t	fs_postbloff;		/* (short) rotation block list head */
3537c478bd9Sstevel@tonic-gate 	int32_t	fs_rotbloff;		/* (uchar_t) blocks for each rotation */
3547c478bd9Sstevel@tonic-gate 	int32_t	fs_magic;		/* magic number */
3557c478bd9Sstevel@tonic-gate 	uchar_t	fs_space[1];		/* list of blocks for each rotation */
3567c478bd9Sstevel@tonic-gate /* actually longer */
3577c478bd9Sstevel@tonic-gate };
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate /*
3607c478bd9Sstevel@tonic-gate  * values for fs_reclaim
3617c478bd9Sstevel@tonic-gate  */
3627c478bd9Sstevel@tonic-gate #define	FS_RECLAIM	(0x00000001)	/* run the reclaim-files thread */
3637c478bd9Sstevel@tonic-gate #define	FS_RECLAIMING	(0x00000002)	/* running the reclaim-files thread */
3647c478bd9Sstevel@tonic-gate #define	FS_CHECKCLEAN	(0x00000004)	/* checking for a clean file system */
3657c478bd9Sstevel@tonic-gate #define	FS_CHECKRECLAIM	(0x00000008)	/* checking for a reclaimable file */
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate /*
3687c478bd9Sstevel@tonic-gate  * values for fs_rolled
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate #define	FS_PRE_FLAG	0	/* old system, prior to fs_rolled flag */
3717c478bd9Sstevel@tonic-gate #define	FS_ALL_ROLLED	1
3727c478bd9Sstevel@tonic-gate #define	FS_NEED_ROLL	2
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate /*
3757c478bd9Sstevel@tonic-gate  * values for fs_si, logging only
3767c478bd9Sstevel@tonic-gate  * si is the summary of the summary - a copy of the cylinder group summary
3777c478bd9Sstevel@tonic-gate  * info held in an array for perf. On a mount if this is out of date
3787c478bd9Sstevel@tonic-gate  * (FS_SI_BAD) it can be re-constructed by re-reading the cgs.
3797c478bd9Sstevel@tonic-gate  */
3807c478bd9Sstevel@tonic-gate #define	FS_SI_OK	0	/* on-disk summary info ok */
3817c478bd9Sstevel@tonic-gate #define	FS_SI_BAD	1	/* out of date on-disk si */
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate  * Preference for optimization.
3857c478bd9Sstevel@tonic-gate  */
3867c478bd9Sstevel@tonic-gate #define	FS_OPTTIME	0	/* minimize allocation time */
3877c478bd9Sstevel@tonic-gate #define	FS_OPTSPACE	1	/* minimize disk fragmentation */
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate /*
3907c478bd9Sstevel@tonic-gate  * Rotational layout table format types
3917c478bd9Sstevel@tonic-gate  */
3927c478bd9Sstevel@tonic-gate #define	FS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
3937c478bd9Sstevel@tonic-gate #define	FS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate /*
3967c478bd9Sstevel@tonic-gate  * Macros for access to superblock array structures
3977c478bd9Sstevel@tonic-gate  */
3987c478bd9Sstevel@tonic-gate #ifdef _KERNEL
3997c478bd9Sstevel@tonic-gate #define	fs_postbl(ufsvfsp, cylno) \
4007c478bd9Sstevel@tonic-gate 	(((ufsvfsp)->vfs_fs->fs_postblformat != FS_DYNAMICPOSTBLFMT) \
4017c478bd9Sstevel@tonic-gate 	? ((ufsvfsp)->vfs_fs->fs_opostbl[cylno]) \
4027c478bd9Sstevel@tonic-gate 	: ((short *)((char *)(ufsvfsp)->vfs_fs + \
4037c478bd9Sstevel@tonic-gate 	(ufsvfsp)->vfs_fs->fs_postbloff) \
4047c478bd9Sstevel@tonic-gate 	+ (cylno) * (ufsvfsp)->vfs_nrpos))
4057c478bd9Sstevel@tonic-gate #else
4067c478bd9Sstevel@tonic-gate #define	fs_postbl(fs, cylno) \
4077c478bd9Sstevel@tonic-gate 	(((fs)->fs_postblformat != FS_DYNAMICPOSTBLFMT) \
4087c478bd9Sstevel@tonic-gate 	? ((fs)->fs_opostbl[cylno]) \
4097c478bd9Sstevel@tonic-gate 	: ((short *)((char *)(fs) + \
4107c478bd9Sstevel@tonic-gate 	(fs)->fs_postbloff) \
4117c478bd9Sstevel@tonic-gate 	+ (cylno) * (fs)->fs_nrpos))
4127c478bd9Sstevel@tonic-gate #endif
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate #define	fs_rotbl(fs) \
4157c478bd9Sstevel@tonic-gate 	(((fs)->fs_postblformat != FS_DYNAMICPOSTBLFMT) \
4167c478bd9Sstevel@tonic-gate 	? ((fs)->fs_space) \
4177c478bd9Sstevel@tonic-gate 	: ((uchar_t *)((char *)(fs) + (fs)->fs_rotbloff)))
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate /*
4207c478bd9Sstevel@tonic-gate  * Convert cylinder group to base address of its global summary info.
4217c478bd9Sstevel@tonic-gate  *
4227c478bd9Sstevel@tonic-gate  * N.B. This macro assumes that sizeof (struct csum) is a power of two.
4237c478bd9Sstevel@tonic-gate  * We just index off the first entry into one big array
4247c478bd9Sstevel@tonic-gate  */
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate #define	fs_cs(fs, indx) fs_u.fs_csp[(indx)]
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate /*
4297c478bd9Sstevel@tonic-gate  * Cylinder group block for a file system.
4307c478bd9Sstevel@tonic-gate  *
4317c478bd9Sstevel@tonic-gate  * Writable fields in the cylinder group are protected by the associated
4327c478bd9Sstevel@tonic-gate  * super block lock fs->fs_lock.
4337c478bd9Sstevel@tonic-gate  */
4347c478bd9Sstevel@tonic-gate #define	CG_MAGIC	0x090255
4357c478bd9Sstevel@tonic-gate struct	cg {
4367c478bd9Sstevel@tonic-gate 	uint32_t cg_link;		/* NOT USED linked list of cyl groups */
4377c478bd9Sstevel@tonic-gate 	int32_t	cg_magic;		/* magic number */
4387c478bd9Sstevel@tonic-gate 	time32_t cg_time;		/* time last written */
4397c478bd9Sstevel@tonic-gate 	int32_t	cg_cgx;			/* we are the cgx'th cylinder group */
4407c478bd9Sstevel@tonic-gate 	short	cg_ncyl;		/* number of cyl's this cg */
4417c478bd9Sstevel@tonic-gate 	short	cg_niblk;		/* number of inode blocks this cg */
4427c478bd9Sstevel@tonic-gate 	int32_t	cg_ndblk;		/* number of data blocks this cg */
4437c478bd9Sstevel@tonic-gate 	struct	csum cg_cs;		/* cylinder summary information */
4447c478bd9Sstevel@tonic-gate 	int32_t	cg_rotor;		/* position of last used block */
4457c478bd9Sstevel@tonic-gate 	int32_t	cg_frotor;		/* position of last used frag */
4467c478bd9Sstevel@tonic-gate 	int32_t	cg_irotor;		/* position of last used inode */
4477c478bd9Sstevel@tonic-gate 	int32_t	cg_frsum[MAXFRAG];	/* counts of available frags */
4487c478bd9Sstevel@tonic-gate 	int32_t	cg_btotoff;		/* (int32_t)block totals per cylinder */
4497c478bd9Sstevel@tonic-gate 	int32_t	cg_boff;		/* (short) free block positions */
4507c478bd9Sstevel@tonic-gate 	int32_t	cg_iusedoff;		/* (char) used inode map */
4517c478bd9Sstevel@tonic-gate 	int32_t	cg_freeoff;		/* (uchar_t) free block map */
4527c478bd9Sstevel@tonic-gate 	int32_t	cg_nextfreeoff;		/* (uchar_t) next available space */
4537c478bd9Sstevel@tonic-gate 	int32_t	cg_sparecon[16];	/* reserved for future use */
4547c478bd9Sstevel@tonic-gate 	uchar_t	cg_space[1];		/* space for cylinder group maps */
4557c478bd9Sstevel@tonic-gate /* actually longer */
4567c478bd9Sstevel@tonic-gate };
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate /*
4597c478bd9Sstevel@tonic-gate  * Macros for access to cylinder group array structures
4607c478bd9Sstevel@tonic-gate  */
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate #define	cg_blktot(cgp) \
4637c478bd9Sstevel@tonic-gate 	(((cgp)->cg_magic != CG_MAGIC) \
4647c478bd9Sstevel@tonic-gate 	? (((struct ocg *)(cgp))->cg_btot) \
4657c478bd9Sstevel@tonic-gate 	: ((int32_t *)((char *)(cgp) + (cgp)->cg_btotoff)))
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate #ifdef _KERNEL
4687c478bd9Sstevel@tonic-gate #define	cg_blks(ufsvfsp, cgp, cylno) \
4697c478bd9Sstevel@tonic-gate 	(((cgp)->cg_magic != CG_MAGIC) \
4707c478bd9Sstevel@tonic-gate 	? (((struct ocg *)(cgp))->cg_b[cylno]) \
4717c478bd9Sstevel@tonic-gate 	: ((short *)((char *)(cgp) + (cgp)->cg_boff) + \
4727c478bd9Sstevel@tonic-gate 	(cylno) * (ufsvfsp)->vfs_nrpos))
4737c478bd9Sstevel@tonic-gate #else
4747c478bd9Sstevel@tonic-gate #define	cg_blks(fs, cgp, cylno) \
4757c478bd9Sstevel@tonic-gate 	(((cgp)->cg_magic != CG_MAGIC) \
4767c478bd9Sstevel@tonic-gate 	? (((struct ocg *)(cgp))->cg_b[cylno]) \
4777c478bd9Sstevel@tonic-gate 	: ((short *)((char *)(cgp) + (cgp)->cg_boff) + \
4787c478bd9Sstevel@tonic-gate 	(cylno) * (fs)->fs_nrpos))
4797c478bd9Sstevel@tonic-gate #endif
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate #define	cg_inosused(cgp) \
4827c478bd9Sstevel@tonic-gate 	(((cgp)->cg_magic != CG_MAGIC) \
4837c478bd9Sstevel@tonic-gate 	? (((struct ocg *)(cgp))->cg_iused) \
4847c478bd9Sstevel@tonic-gate 	: ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate #define	cg_blksfree(cgp) \
4877c478bd9Sstevel@tonic-gate 	(((cgp)->cg_magic != CG_MAGIC) \
4887c478bd9Sstevel@tonic-gate 	? (((struct ocg *)(cgp))->cg_free) \
4897c478bd9Sstevel@tonic-gate 	: ((uchar_t *)((char *)(cgp) + (cgp)->cg_freeoff)))
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate #define	cg_chkmagic(cgp) \
4927c478bd9Sstevel@tonic-gate 	((cgp)->cg_magic == CG_MAGIC || \
4937c478bd9Sstevel@tonic-gate 	((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate /*
4967c478bd9Sstevel@tonic-gate  * The following structure is defined
4977c478bd9Sstevel@tonic-gate  * for compatibility with old file systems.
4987c478bd9Sstevel@tonic-gate  */
4997c478bd9Sstevel@tonic-gate struct	ocg {
5007c478bd9Sstevel@tonic-gate 	uint32_t cg_link;		/* NOT USED linked list of cyl groups */
5017c478bd9Sstevel@tonic-gate 	uint32_t cg_rlink;		/* NOT USED incore cyl groups */
5027c478bd9Sstevel@tonic-gate 	time32_t cg_time;		/* time last written */
5037c478bd9Sstevel@tonic-gate 	int32_t	cg_cgx;			/* we are the cgx'th cylinder group */
5047c478bd9Sstevel@tonic-gate 	short	cg_ncyl;		/* number of cyl's this cg */
5057c478bd9Sstevel@tonic-gate 	short	cg_niblk;		/* number of inode blocks this cg */
5067c478bd9Sstevel@tonic-gate 	int32_t	cg_ndblk;		/* number of data blocks this cg */
5077c478bd9Sstevel@tonic-gate 	struct	csum cg_cs;		/* cylinder summary information */
5087c478bd9Sstevel@tonic-gate 	int32_t	cg_rotor;		/* position of last used block */
5097c478bd9Sstevel@tonic-gate 	int32_t	cg_frotor;		/* position of last used frag */
5107c478bd9Sstevel@tonic-gate 	int32_t	cg_irotor;		/* position of last used inode */
5117c478bd9Sstevel@tonic-gate 	int32_t	cg_frsum[8];		/* counts of available frags */
5127c478bd9Sstevel@tonic-gate 	int32_t	cg_btot[32];		/* block totals per cylinder */
5137c478bd9Sstevel@tonic-gate 	short	cg_b[32][8];		/* positions of free blocks */
5147c478bd9Sstevel@tonic-gate 	char	cg_iused[256];		/* used inode map */
5157c478bd9Sstevel@tonic-gate 	int32_t	cg_magic;		/* magic number */
5167c478bd9Sstevel@tonic-gate 	uchar_t	cg_free[1];		/* free block map */
5177c478bd9Sstevel@tonic-gate /* actually longer */
5187c478bd9Sstevel@tonic-gate };
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate /*
5217c478bd9Sstevel@tonic-gate  * Turn frag offsets into disk block addresses.
5227c478bd9Sstevel@tonic-gate  * This maps frags to device size blocks.
5237c478bd9Sstevel@tonic-gate  * (In the names of these macros, "fsb" refers to "frags", not
5247c478bd9Sstevel@tonic-gate  * file system blocks.)
5257c478bd9Sstevel@tonic-gate  */
5267c478bd9Sstevel@tonic-gate #ifdef KERNEL
5277c478bd9Sstevel@tonic-gate #define	fsbtodb(fs, b)	(((daddr_t)(b)) << (fs)->fs_fsbtodb)
5287c478bd9Sstevel@tonic-gate #else /* KERNEL */
5297c478bd9Sstevel@tonic-gate #define	fsbtodb(fs, b)	(((diskaddr_t)(b)) << (fs)->fs_fsbtodb)
5307c478bd9Sstevel@tonic-gate #endif /* KERNEL */
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate #define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate /*
5357c478bd9Sstevel@tonic-gate  * Get the offset of the log, in either sectors, frags, or file system
5367c478bd9Sstevel@tonic-gate  * blocks.  The interpretation of the fs_logbno field depends on whether
5377c478bd9Sstevel@tonic-gate  * this is UFS or MTB UFS.  (UFS stores the value as sectors.  MTBUFS
5387c478bd9Sstevel@tonic-gate  * stores the value as frags.)
5397c478bd9Sstevel@tonic-gate  */
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate #ifdef KERNEL
5427c478bd9Sstevel@tonic-gate #define	logbtodb(fs, b)	((fs)->fs_magic == FS_MAGIC ? \
5437c478bd9Sstevel@tonic-gate 		(daddr_t)(b) : ((daddr_t)(b) << (fs)->fs_fsbtodb))
5447c478bd9Sstevel@tonic-gate #else /* KERNEL */
5457c478bd9Sstevel@tonic-gate #define	logbtodb(fs, b)	((fs)->fs_magic == FS_MAGIC ? \
5467c478bd9Sstevel@tonic-gate 		(diskaddr_t)(b) : ((diskaddr_t)(b) << (fs)->fs_fsbtodb))
5477c478bd9Sstevel@tonic-gate #endif /* KERNEL */
5487c478bd9Sstevel@tonic-gate #define	logbtofrag(fs, b)	((fs)->fs_magic == FS_MAGIC ? \
5497c478bd9Sstevel@tonic-gate 		(b) >> (fs)->fs_fsbtodb : (b))
5507c478bd9Sstevel@tonic-gate #define	logbtofsblk(fs, b) ((fs)->fs_magic == FS_MAGIC ? \
5517c478bd9Sstevel@tonic-gate 		(b) >> ((fs)->fs_fsbtodb + (fs)->fs_fragshift) : \
5527c478bd9Sstevel@tonic-gate 		(b) >> (fs)->fs_fragshift)
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate /*
5557c478bd9Sstevel@tonic-gate  * Cylinder group macros to locate things in cylinder groups.
5567c478bd9Sstevel@tonic-gate  * They calc file system addresses of cylinder group data structures.
5577c478bd9Sstevel@tonic-gate  */
5587c478bd9Sstevel@tonic-gate #define	cgbase(fs, c)	((daddr32_t)((fs)->fs_fpg * (c)))
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate #define	cgstart(fs, c) \
5617c478bd9Sstevel@tonic-gate 	(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate #define	cgsblock(fs, c)	(cgstart(fs, c) + (fs)->fs_sblkno)	/* super blk */
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate #define	cgtod(fs, c)	(cgstart(fs, c) + (fs)->fs_cblkno)	/* cg block */
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate #define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate #define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate /*
5727c478bd9Sstevel@tonic-gate  * Macros for handling inode numbers:
5737c478bd9Sstevel@tonic-gate  *	inode number to file system block offset.
5747c478bd9Sstevel@tonic-gate  *	inode number to cylinder group number.
5757c478bd9Sstevel@tonic-gate  *	inode number to file system block address.
5767c478bd9Sstevel@tonic-gate  */
5777c478bd9Sstevel@tonic-gate #define	itoo(fs, x)	((x) % (uint32_t)INOPB(fs))
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate #define	itog(fs, x)	((x) / (uint32_t)(fs)->fs_ipg)
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate #define	itod(fs, x) \
5827c478bd9Sstevel@tonic-gate 	((daddr32_t)(cgimin(fs, itog(fs, x)) + \
5837c478bd9Sstevel@tonic-gate 	(blkstofrags((fs), (((x)%(ulong_t)(fs)->fs_ipg)/(ulong_t)INOPB(fs))))))
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate /*
5867c478bd9Sstevel@tonic-gate  * Give cylinder group number for a file system block.
5877c478bd9Sstevel@tonic-gate  * Give cylinder group block number for a file system block.
5887c478bd9Sstevel@tonic-gate  */
5897c478bd9Sstevel@tonic-gate #define	dtog(fs, d)	((d) / (fs)->fs_fpg)
5907c478bd9Sstevel@tonic-gate #define	dtogd(fs, d)	((d) % (fs)->fs_fpg)
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate /*
5937c478bd9Sstevel@tonic-gate  * Extract the bits for a block from a map.
5947c478bd9Sstevel@tonic-gate  * Compute the cylinder and rotational position of a cyl block addr.
5957c478bd9Sstevel@tonic-gate  */
5967c478bd9Sstevel@tonic-gate #define	blkmap(fs, map, loc) \
5977c478bd9Sstevel@tonic-gate 	(((map)[(loc) / NBBY] >> ((loc) % NBBY)) & \
5987c478bd9Sstevel@tonic-gate 	(0xff >> (NBBY - (fs)->fs_frag)))
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate #define	cbtocylno(fs, bno) \
6017c478bd9Sstevel@tonic-gate 	((bno) * NSPF(fs) / (fs)->fs_spc)
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate #ifdef _KERNEL
6047c478bd9Sstevel@tonic-gate #define	cbtorpos(ufsvfsp, bno) \
6057c478bd9Sstevel@tonic-gate 	((((bno) * NSPF((ufsvfsp)->vfs_fs) % (ufsvfsp)->vfs_fs->fs_spc) % \
6067c478bd9Sstevel@tonic-gate 	(ufsvfsp)->vfs_fs->fs_nsect) * \
6077c478bd9Sstevel@tonic-gate 	(ufsvfsp)->vfs_nrpos) / (ufsvfsp)->vfs_fs->fs_nsect
6087c478bd9Sstevel@tonic-gate #else
6097c478bd9Sstevel@tonic-gate #define	cbtorpos(fs, bno) \
6107c478bd9Sstevel@tonic-gate 	((((bno) * NSPF(fs) % (fs)->fs_spc) % \
6117c478bd9Sstevel@tonic-gate 	(fs)->fs_nsect) * \
6127c478bd9Sstevel@tonic-gate 	(fs)->fs_nrpos) / (fs)->fs_nsect
6137c478bd9Sstevel@tonic-gate #endif
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate /*
6167c478bd9Sstevel@tonic-gate  * The following macros optimize certain frequently calculated
6177c478bd9Sstevel@tonic-gate  * quantities by using shifts and masks in place of divisions
6187c478bd9Sstevel@tonic-gate  * modulos and multiplications.
6197c478bd9Sstevel@tonic-gate  */
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate /*
6227c478bd9Sstevel@tonic-gate  * This macro works for 40 bit offset support in ufs because
6237c478bd9Sstevel@tonic-gate  * this calculates offset in the block and therefore no loss of
6247c478bd9Sstevel@tonic-gate  * information while casting to int.
6257c478bd9Sstevel@tonic-gate  */
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate #define	blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
6287c478bd9Sstevel@tonic-gate 	((int)((loc) & ~(fs)->fs_bmask))
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate /*
6317c478bd9Sstevel@tonic-gate  * This macro works for 40 bit offset support similar to blkoff
6327c478bd9Sstevel@tonic-gate  */
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate #define	fragoff(fs, loc)	/* calculates (loc % fs->fs_fsize) */ \
6357c478bd9Sstevel@tonic-gate 	((int)((loc) & ~(fs)->fs_fmask))
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate /*
6387c478bd9Sstevel@tonic-gate  * The cast to int32_t does not result in any loss of information because
6397c478bd9Sstevel@tonic-gate  * the number of logical blocks in the file system is limited to
6407c478bd9Sstevel@tonic-gate  * what fits in an int32_t anyway.
6417c478bd9Sstevel@tonic-gate  */
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate #define	lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
6447c478bd9Sstevel@tonic-gate 	((int32_t)((loc) >> (fs)->fs_bshift))
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate /*
6477c478bd9Sstevel@tonic-gate  * The same argument as above applies here.
6487c478bd9Sstevel@tonic-gate  */
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate #define	numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
6517c478bd9Sstevel@tonic-gate 	((int32_t)((loc) >> (fs)->fs_fshift))
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate /*
6547c478bd9Sstevel@tonic-gate  * Size can be a 64-bit value and therefore we sign extend fs_bmask
6557c478bd9Sstevel@tonic-gate  * to a 64-bit value too so that the higher 32 bits are masked
6567c478bd9Sstevel@tonic-gate  * properly. Note that the type of fs_bmask has to be signed. Otherwise
6577c478bd9Sstevel@tonic-gate  * compiler will set the higher 32 bits as zero and we don't want
6587c478bd9Sstevel@tonic-gate  * this to happen.
6597c478bd9Sstevel@tonic-gate  */
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate #define	blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
6627c478bd9Sstevel@tonic-gate 	(((size) + (fs)->fs_bsize - 1) & (offset_t)(fs)->fs_bmask)
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate /*
6657c478bd9Sstevel@tonic-gate  * Same argument as above.
6667c478bd9Sstevel@tonic-gate  */
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate #define	fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
6697c478bd9Sstevel@tonic-gate 	(((size) + (fs)->fs_fsize - 1) & (offset_t)(fs)->fs_fmask)
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate /*
6727c478bd9Sstevel@tonic-gate  * frags cannot exceed 32-bit value since we only support 40bit sizes.
6737c478bd9Sstevel@tonic-gate  */
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate #define	fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
6767c478bd9Sstevel@tonic-gate 	((frags) >> (fs)->fs_fragshift)
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate #define	blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
6797c478bd9Sstevel@tonic-gate 	((blks) << (fs)->fs_fragshift)
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate #define	fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
6827c478bd9Sstevel@tonic-gate 	((fsb) & ((fs)->fs_frag - 1))
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate #define	blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
6857c478bd9Sstevel@tonic-gate 	((fsb) &~ ((fs)->fs_frag - 1))
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate /*
6887c478bd9Sstevel@tonic-gate  * Determine the number of available frags given a
6897c478bd9Sstevel@tonic-gate  * percentage to hold in reserve
6907c478bd9Sstevel@tonic-gate  */
6917c478bd9Sstevel@tonic-gate #define	freespace(fs, ufsvfsp) \
6927c478bd9Sstevel@tonic-gate 	((blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
6937c478bd9Sstevel@tonic-gate 	(fs)->fs_cstotal.cs_nffree) - (ufsvfsp)->vfs_minfrags)
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate  * Determining the size of a file block in the file system.
6977c478bd9Sstevel@tonic-gate  */
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate #define	blksize(fs, ip, lbn) \
7007c478bd9Sstevel@tonic-gate 	(((lbn) >= NDADDR || \
7017c478bd9Sstevel@tonic-gate 	(ip)->i_size >= (offset_t)((lbn) + 1) << (fs)->fs_bshift) \
7027c478bd9Sstevel@tonic-gate 	    ? (fs)->fs_bsize \
7037c478bd9Sstevel@tonic-gate 	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate #define	dblksize(fs, dip, lbn) \
7067c478bd9Sstevel@tonic-gate 	(((lbn) >= NDADDR || \
7077c478bd9Sstevel@tonic-gate 	(dip)->di_size >= (offset_t)((lbn) + 1) << (fs)->fs_bshift) \
7087c478bd9Sstevel@tonic-gate 	    ? (fs)->fs_bsize \
7097c478bd9Sstevel@tonic-gate 	    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate /*
7127c478bd9Sstevel@tonic-gate  * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
7137c478bd9Sstevel@tonic-gate  */
7147c478bd9Sstevel@tonic-gate #define	NSPB(fs)	((fs)->fs_nspf << (fs)->fs_fragshift)
7157c478bd9Sstevel@tonic-gate #define	NSPF(fs)	((fs)->fs_nspf)
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate /*
7187c478bd9Sstevel@tonic-gate  * INOPB is the number of inodes in a secondary storage block.
7197c478bd9Sstevel@tonic-gate  */
7207c478bd9Sstevel@tonic-gate #define	INOPB(fs)	((fs)->fs_inopb)
7217c478bd9Sstevel@tonic-gate #define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate /*
7247c478bd9Sstevel@tonic-gate  * NINDIR is the number of indirects in a file system block.
7257c478bd9Sstevel@tonic-gate  */
7267c478bd9Sstevel@tonic-gate #define	NINDIR(fs)	((fs)->fs_nindir)
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate /*
7297c478bd9Sstevel@tonic-gate  * bit map related macros
7307c478bd9Sstevel@tonic-gate  */
7317c478bd9Sstevel@tonic-gate #define	bitloc(a, i)	((a)[(i)/NBBY])
7327c478bd9Sstevel@tonic-gate #define	setbit(a, i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
7337c478bd9Sstevel@tonic-gate #define	clrbit(a, i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
7347c478bd9Sstevel@tonic-gate #define	isset(a, i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
7357c478bd9Sstevel@tonic-gate #define	isclr(a, i)	(((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate #define	getfs(vfsp) \
7387c478bd9Sstevel@tonic-gate 	((struct fs *)((struct ufsvfs *)vfsp->vfs_data)->vfs_bufp->b_un.b_addr)
7397c478bd9Sstevel@tonic-gate 
740*02ff05a9Svsakar #define	RETRY_LOCK_DELAY 1
741*02ff05a9Svsakar 
742*02ff05a9Svsakar /*
743*02ff05a9Svsakar  * Macros to test and acquire i_rwlock:
744*02ff05a9Svsakar  * some vnops hold the target directory's i_rwlock after calling
745*02ff05a9Svsakar  * ufs_lockfs_begin but in many other operations (like ufs_readdir)
746*02ff05a9Svsakar  * VOP_RWLOCK is explicitly called by the filesystem independent code before
747*02ff05a9Svsakar  * calling the file system operation. In these cases the order is reversed
748*02ff05a9Svsakar  * (i.e i_rwlock is taken first and then ufs_lockfs_begin is called). This
749*02ff05a9Svsakar  * is fine as long as ufs_lockfs_begin acts as a VOP counter but with
750*02ff05a9Svsakar  * ufs_quiesce setting the SLOCK bit this becomes a synchronizing
751*02ff05a9Svsakar  * object which might lead to a deadlock. So we use rw_tryenter instead of
752*02ff05a9Svsakar  * rw_enter. If we fail to get this lock and find that SLOCK bit is set, we
753*02ff05a9Svsakar  * call ufs_lockfs_end and restart the operation.
754*02ff05a9Svsakar  */
755*02ff05a9Svsakar 
756*02ff05a9Svsakar #define	ufs_tryirwlock(lock, mode, label) \
757*02ff05a9Svsakar {\
758*02ff05a9Svsakar 	indeadlock = 0;\
759*02ff05a9Svsakar label:\
760*02ff05a9Svsakar 	if (!rw_tryenter(lock, mode))\
761*02ff05a9Svsakar 	{\
762*02ff05a9Svsakar 		if (ulp && ULOCKFS_IS_SLOCK(ulp)) {\
763*02ff05a9Svsakar 			indeadlock = 1;\
764*02ff05a9Svsakar 		} else {\
765*02ff05a9Svsakar 			delay(RETRY_LOCK_DELAY);\
766*02ff05a9Svsakar 			goto  label;\
767*02ff05a9Svsakar 		}\
768*02ff05a9Svsakar 	}\
769*02ff05a9Svsakar }
770*02ff05a9Svsakar 
771*02ff05a9Svsakar /*
772*02ff05a9Svsakar  * The macro ufs_tryirwlock_trans is used in functions which call
773*02ff05a9Svsakar  * TRANS_BEGIN_CSYNC and ufs_lockfs_begin, hence the need to call
774*02ff05a9Svsakar  * TRANS_END_CSYNC and ufs_lockfs_end.
775*02ff05a9Svsakar  */
776*02ff05a9Svsakar 
777*02ff05a9Svsakar #define	ufs_tryirwlock_trans(lock, mode, transmode, label) \
778*02ff05a9Svsakar {\
779*02ff05a9Svsakar 	indeadlock = 0;\
780*02ff05a9Svsakar label:\
781*02ff05a9Svsakar 	if (!rw_tryenter(lock, mode))\
782*02ff05a9Svsakar 	{\
783*02ff05a9Svsakar 		if (ulp && ULOCKFS_IS_SLOCK(ulp)) {\
784*02ff05a9Svsakar 			TRANS_END_CSYNC(ufsvfsp, error, issync,\
785*02ff05a9Svsakar 				transmode, trans_size);\
786*02ff05a9Svsakar 			ufs_lockfs_end(ulp);\
787*02ff05a9Svsakar 			indeadlock = 1;\
788*02ff05a9Svsakar 		} else {\
789*02ff05a9Svsakar 			delay(RETRY_LOCK_DELAY);\
790*02ff05a9Svsakar 			goto  label;\
791*02ff05a9Svsakar 		}\
792*02ff05a9Svsakar 	}\
793*02ff05a9Svsakar }
794*02ff05a9Svsakar 
7957c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
7967c478bd9Sstevel@tonic-gate }
7977c478bd9Sstevel@tonic-gate #endif
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate #endif	/* _SYS_FS_UFS_FS_H */
800