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