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