Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / i386 / boot / dosboot / fs.h
1 /*\r
2  * Copyright (c) 1982, 1986 Regents of the University of California.\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  * 1. Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  * 2. Redistributions in binary form must reproduce the above copyright\r
11  *    notice, this list of conditions and the following disclaimer in the\r
12  *    documentation and/or other materials provided with the distribution.\r
13  * 3. All advertising materials mentioning features or use of this software\r
14  *    must display the following acknowledgement:\r
15  *      This product includes software developed by the University of\r
16  *      California, Berkeley and its contributors.\r
17  * 4. Neither the name of the University nor the names of its contributors\r
18  *    may be used to endorse or promote products derived from this software\r
19  *    without specific prior written permission.\r
20  *\r
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
31  * SUCH DAMAGE.\r
32  *\r
33  *      from: @(#)fs.h  7.12 (Berkeley) 5/8/91\r
34  * $FreeBSD: src/sys/i386/boot/dosboot/fs.h,v 1.6 1999/12/29 04:32:50 peter Exp $\r
35  */\r
36 \r
37 #ifndef _UFS_FS_H_\r
38 #define _UFS_FS_H_ 1\r
39 \r
40 #define MAXFRAG 8\r
41 \r
42 /*\r
43  * Each disk drive contains some number of file systems.\r
44  * A file system consists of a number of cylinder groups.\r
45  * Each cylinder group has inodes and data.\r
46  *\r
47  * A file system is described by its super-block, which in turn\r
48  * describes the cylinder groups.  The super-block is critical\r
49  * data and is replicated in each cylinder group to protect against\r
50  * catastrophic loss.  This is done at `newfs' time and the critical\r
51  * super-block data does not change, so the copies need not be\r
52  * referenced further unless disaster strikes.\r
53  *\r
54  * For file system fs, the offsets of the various blocks of interest\r
55  * are given in the super block as:\r
56  *      [fs->fs_sblkno]         Super-block\r
57  *      [fs->fs_cblkno]         Cylinder group block\r
58  *      [fs->fs_iblkno]         Inode blocks\r
59  *      [fs->fs_dblkno]         Data blocks\r
60  * The beginning of cylinder group cg in fs, is given by\r
61  * the ``cgbase(fs, cg)'' macro.\r
62  *\r
63  * The first boot and super blocks are given in absolute disk addresses.\r
64  * The byte-offset forms are preferred, as they don't imply a sector size.\r
65  */\r
66 #define BBSIZE          8192\r
67 #define SBSIZE          8192\r
68 #define BBOFF           ((off_t)(0))\r
69 #define SBOFF           ((off_t)(BBOFF + BBSIZE))\r
70 #define BBLOCK          ((daddr_t)(0))\r
71 #define SBLOCK          ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))\r
72 \r
73 /*\r
74  * Addresses stored in inodes are capable of addressing fragments\r
75  * of `blocks'. File system blocks of at most size MAXBSIZE can \r
76  * be optionally broken into 2, 4, or 8 pieces, each of which is\r
77  * addressible; these pieces may be DEV_BSIZE, or some multiple of\r
78  * a DEV_BSIZE unit.\r
79  *\r
80  * Large files consist of exclusively large data blocks.  To avoid\r
81  * undue wasted disk space, the last data block of a small file may be\r
82  * allocated as only as many fragments of a large block as are\r
83  * necessary.  The file system format retains only a single pointer\r
84  * to such a fragment, which is a piece of a single large block that\r
85  * has been divided.  The size of such a fragment is determinable from\r
86  * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.\r
87  *\r
88  * The file system records space availability at the fragment level;\r
89  * to determine block availability, aligned fragments are examined.\r
90  *\r
91  * The root inode is the root of the file system.\r
92  * Inode 0 can't be used for normal purposes and\r
93  * historically bad blocks were linked to inode 1,\r
94  * thus the root inode is 2. (inode 1 is no longer used for\r
95  * this purpose, however numerous dump tapes make this\r
96  * assumption, so we are stuck with it)\r
97  */\r
98 #define ROOTINO         ((ino_t)2)\r
99 \r
100 /*\r
101  * MINBSIZE is the smallest allowable block size.\r
102  * In order to insure that it is possible to create files of size\r
103  * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.\r
104  * MINBSIZE must be big enough to hold a cylinder group block,\r
105  * thus changes to (struct cg) must keep its size within MINBSIZE.\r
106  * Note that super blocks are always of size SBSIZE,\r
107  * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.\r
108  */\r
109 #define MINBSIZE        4096\r
110 \r
111 /*\r
112  * The path name on which the file system is mounted is maintained\r
113  * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in \r
114  * the super block for this name.\r
115  * The limit on the amount of summary information per file system\r
116  * is defined by MAXCSBUFS. It is currently parameterized for a\r
117  * maximum of two million cylinders.\r
118  */\r
119 #define MAXMNTLEN 512\r
120 #define MAXCSBUFS 32\r
121 \r
122 /*\r
123  * Per cylinder group information; summarized in blocks allocated\r
124  * from first cylinder group data blocks.  These blocks have to be\r
125  * read in from fs_csaddr (size fs_cssize) in addition to the\r
126  * super block.\r
127  *\r
128  * N.B. sizeof(struct csum) must be a power of two in order for\r
129  * the ``fs_cs'' macro to work (see below).\r
130  */\r
131 struct csum {\r
132         long    cs_ndir;        /* number of directories */\r
133         long    cs_nbfree;      /* number of free blocks */\r
134         long    cs_nifree;      /* number of free inodes */\r
135         long    cs_nffree;      /* number of free frags */\r
136 };\r
137 \r
138 /*\r
139  * Super block for a file system.\r
140  */\r
141 #define FS_MAGIC        0x011954\r
142 #define FSOKAY          0x7c269d38\r
143 struct  fs\r
144 {\r
145         struct  fs *fs_link;            /* linked list of file systems */\r
146         struct  fs *fs_rlink;           /*     used for incore super blocks */\r
147         daddr_t fs_sblkno;              /* addr of super-block in filesys */\r
148         daddr_t fs_cblkno;              /* offset of cyl-block in filesys */\r
149         daddr_t fs_iblkno;              /* offset of inode-blocks in filesys */\r
150         daddr_t fs_dblkno;              /* offset of first data after cg */\r
151         long    fs_cgoffset;            /* cylinder group offset in cylinder */\r
152         long    fs_cgmask;              /* used to calc mod fs_ntrak */\r
153         time_t  fs_time;                /* last time written */\r
154         long    fs_size;                /* number of blocks in fs */\r
155         long    fs_dsize;               /* number of data blocks in fs */\r
156         long    fs_ncg;                 /* number of cylinder groups */\r
157         long    fs_bsize;               /* size of basic blocks in fs */\r
158         long    fs_fsize;               /* size of frag blocks in fs */\r
159         long    fs_frag;                /* number of frags in a block in fs */\r
160 /* these are configuration parameters */\r
161         long    fs_minfree;             /* minimum percentage of free blocks */\r
162         long    fs_rotdelay;            /* num of ms for optimal next block */\r
163         long    fs_rps;                 /* disk revolutions per second */\r
164 /* these fields can be computed from the others */\r
165         long    fs_bmask;               /* ``blkoff'' calc of blk offsets */\r
166         long    fs_fmask;               /* ``fragoff'' calc of frag offsets */\r
167         long    fs_bshift;              /* ``lblkno'' calc of logical blkno */\r
168         long    fs_fshift;              /* ``numfrags'' calc number of frags */\r
169 /* these are configuration parameters */\r
170         long    fs_maxcontig;           /* max number of contiguous blks */\r
171         long    fs_maxbpg;              /* max number of blks per cyl group */\r
172 /* these fields can be computed from the others */\r
173         long    fs_fragshift;           /* block to frag shift */\r
174         long    fs_fsbtodb;             /* fsbtodb and dbtofsb shift constant */\r
175         long    fs_sbsize;              /* actual size of super block */\r
176         long    fs_csmask;              /* csum block offset */\r
177         long    fs_csshift;             /* csum block number */\r
178         long    fs_nindir;              /* value of NINDIR */\r
179         long    fs_inopb;               /* value of INOPB */\r
180         long    fs_nspf;                /* value of NSPF */\r
181 /* yet another configuration parameter */\r
182         long    fs_optim;               /* optimization preference, see below */\r
183 /* these fields are derived from the hardware */\r
184         long    fs_npsect;              /* # sectors/track including spares */\r
185         long    fs_interleave;          /* hardware sector interleave */\r
186         long    fs_trackskew;           /* sector 0 skew, per track */\r
187         long    fs_headswitch;          /* head switch time, usec */\r
188         long    fs_trkseek;             /* track-to-track seek, usec */\r
189 /* sizes determined by number of cylinder groups and their sizes */\r
190         daddr_t fs_csaddr;              /* blk addr of cyl grp summary area */\r
191         long    fs_cssize;              /* size of cyl grp summary area */\r
192         long    fs_cgsize;              /* cylinder group size */\r
193 /* these fields are derived from the hardware */\r
194         long    fs_ntrak;               /* tracks per cylinder */\r
195         long    fs_nsect;               /* sectors per track */\r
196         long    fs_spc;                 /* sectors per cylinder */\r
197 /* this comes from the disk driver partitioning */\r
198         long    fs_ncyl;                /* cylinders in file system */\r
199 /* these fields can be computed from the others */\r
200         long    fs_cpg;                 /* cylinders per group */\r
201         long    fs_ipg;                 /* inodes per group */\r
202         long    fs_fpg;                 /* blocks per group * fs_frag */\r
203 /* this data must be re-computed after crashes */\r
204         struct  csum fs_cstotal;        /* cylinder summary information */\r
205 /* these fields are cleared at mount time */\r
206         char    fs_fmod;                /* super block modified flag */\r
207         char    fs_clean;               /* file system is clean flag */\r
208         char    fs_ronly;               /* mounted read-only flag */\r
209         char    fs_flags;               /* currently unused flag */\r
210         char    fs_fsmnt[MAXMNTLEN];    /* name mounted on */\r
211 /* these fields retain the current block allocation info */\r
212         long    fs_cgrotor;             /* last cg searched */\r
213         struct  csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */\r
214         long    fs_cpc;                 /* cyl per cycle in postbl */\r
215         short   fs_opostbl[16][8];      /* old rotation block list head */\r
216         long    fs_sparecon[55];        /* reserved for future constants */\r
217         long    fs_state;               /* validate fs_clean field */\r
218         union {\r
219 /*              quad_t v;*/\r
220                 long val[2];\r
221         }       fs_qbmask;              /* ~fs_bmask - for use with quad size */\r
222         union {\r
223 /*              quad_t v;*/\r
224                 long val[2];\r
225         }       fs_qfmask;              /* ~fs_fmask - for use with quad size */\r
226         long    fs_postblformat;        /* format of positional layout tables */\r
227         long    fs_nrpos;               /* number of rotaional positions */\r
228         long    fs_postbloff;           /* (short) rotation block list head */\r
229         long    fs_rotbloff;            /* (u_char) blocks for each rotation */\r
230         long    fs_magic;               /* magic number */\r
231         u_char  fs_space[1];            /* list of blocks for each rotation */\r
232 /* actually longer */\r
233 };\r
234 /*\r
235  * Preference for optimization.\r
236  */\r
237 #define FS_OPTTIME      0       /* minimize allocation time */\r
238 #define FS_OPTSPACE     1       /* minimize disk fragmentation */\r
239 \r
240 /*\r
241  * Rotational layout table format types\r
242  */\r
243 #define FS_42POSTBLFMT          -1      /* 4.2BSD rotational table format */\r
244 #define FS_DYNAMICPOSTBLFMT     1       /* dynamic rotational table format */\r
245 /*\r
246  * Macros for access to superblock array structures\r
247  */\r
248 #define fs_postbl(fs, cylno) \\r
249     (((fs)->fs_postblformat == FS_42POSTBLFMT) \\r
250     ? ((fs)->fs_opostbl[cylno]) \\r
251     : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))\r
252 #define fs_rotbl(fs) \\r
253     (((fs)->fs_postblformat == FS_42POSTBLFMT) \\r
254     ? ((fs)->fs_space) \\r
255     : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))\r
256 \r
257 /*\r
258  * Convert cylinder group to base address of its global summary info.\r
259  *\r
260  * N.B. This macro assumes that sizeof(struct csum) is a power of two.\r
261  */\r
262 #define fs_cs(fs, indx) \\r
263         fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]\r
264 \r
265 /*\r
266  * Cylinder group block for a file system.\r
267  */\r
268 #define CG_MAGIC        0x090255\r
269 struct  cg {\r
270         struct  cg *cg_link;            /* linked list of cyl groups */\r
271         long    cg_magic;               /* magic number */\r
272         time_t  cg_time;                /* time last written */\r
273         long    cg_cgx;                 /* we are the cgx'th cylinder group */\r
274         short   cg_ncyl;                /* number of cyl's this cg */\r
275         short   cg_niblk;               /* number of inode blocks this cg */\r
276         long    cg_ndblk;               /* number of data blocks this cg */\r
277         struct  csum cg_cs;             /* cylinder summary information */\r
278         long    cg_rotor;               /* position of last used block */\r
279         long    cg_frotor;              /* position of last used frag */\r
280         long    cg_irotor;              /* position of last used inode */\r
281         long    cg_frsum[MAXFRAG];      /* counts of available frags */\r
282         long    cg_btotoff;             /* (long) block totals per cylinder */\r
283         long    cg_boff;                /* (short) free block positions */\r
284         long    cg_iusedoff;            /* (char) used inode map */\r
285         long    cg_freeoff;             /* (u_char) free block map */\r
286         long    cg_nextfreeoff;         /* (u_char) next available space */\r
287         long    cg_sparecon[16];        /* reserved for future use */\r
288         u_char  cg_space[1];            /* space for cylinder group maps */\r
289 /* actually longer */\r
290 };\r
291 /*\r
292  * Macros for access to cylinder group array structures\r
293  */\r
294 #define cg_blktot(cgp) \\r
295     (((cgp)->cg_magic != CG_MAGIC) \\r
296     ? (((struct ocg *)(cgp))->cg_btot) \\r
297     : ((long *)((char *)(cgp) + (cgp)->cg_btotoff)))\r
298 #define cg_blks(fs, cgp, cylno) \\r
299     (((cgp)->cg_magic != CG_MAGIC) \\r
300     ? (((struct ocg *)(cgp))->cg_b[cylno]) \\r
301     : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))\r
302 #define cg_inosused(cgp) \\r
303     (((cgp)->cg_magic != CG_MAGIC) \\r
304     ? (((struct ocg *)(cgp))->cg_iused) \\r
305     : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))\r
306 #define cg_blksfree(cgp) \\r
307     (((cgp)->cg_magic != CG_MAGIC) \\r
308     ? (((struct ocg *)(cgp))->cg_free) \\r
309     : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))\r
310 #define cg_chkmagic(cgp) \\r
311     ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)\r
312 \r
313 /*\r
314  * The following structure is defined\r
315  * for compatibility with old file systems.\r
316  */\r
317 struct  ocg {\r
318         struct  ocg *cg_link;           /* linked list of cyl groups */\r
319         struct  ocg *cg_rlink;          /*     used for incore cyl groups */\r
320         time_t  cg_time;                /* time last written */\r
321         long    cg_cgx;                 /* we are the cgx'th cylinder group */\r
322         short   cg_ncyl;                /* number of cyl's this cg */\r
323         short   cg_niblk;               /* number of inode blocks this cg */\r
324         long    cg_ndblk;               /* number of data blocks this cg */\r
325         struct  csum cg_cs;             /* cylinder summary information */\r
326         long    cg_rotor;               /* position of last used block */\r
327         long    cg_frotor;              /* position of last used frag */\r
328         long    cg_irotor;              /* position of last used inode */\r
329         long    cg_frsum[8];            /* counts of available frags */\r
330         long    cg_btot[32];            /* block totals per cylinder */\r
331         short   cg_b[32][8];            /* positions of free blocks */\r
332         char    cg_iused[256];          /* used inode map */\r
333         long    cg_magic;               /* magic number */\r
334         u_char  cg_free[1];             /* free block map */\r
335 /* actually longer */\r
336 };\r
337 \r
338 /*\r
339  * Turn file system block numbers into disk block addresses.\r
340  * This maps file system blocks to device size blocks.\r
341  */\r
342 #define fsbtodb(fs, b)  ((b) << (fs)->fs_fsbtodb)\r
343 #define dbtofsb(fs, b)  ((b) >> (fs)->fs_fsbtodb)\r
344 \r
345 /*\r
346  * Cylinder group macros to locate things in cylinder groups.\r
347  * They calc file system addresses of cylinder group data structures.\r
348  */\r
349 #define cgbase(fs, c)   ((daddr_t)((fs)->fs_fpg * (c)))\r
350 #define cgstart(fs, c) \\r
351         (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))\r
352 #define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno)      /* super blk */\r
353 #define cgtod(fs, c)    (cgstart(fs, c) + (fs)->fs_cblkno)      /* cg block */\r
354 #define cgimin(fs, c)   (cgstart(fs, c) + (fs)->fs_iblkno)      /* inode blk */\r
355 #define cgdmin(fs, c)   (cgstart(fs, c) + (fs)->fs_dblkno)      /* 1st data */\r
356 \r
357 /*\r
358  * Macros for handling inode numbers:\r
359  *     inode number to file system block offset.\r
360  *     inode number to cylinder group number.\r
361  *     inode number to file system block address.\r
362  */\r
363 #define itoo(fs, x)     ((x) % INOPB(fs))\r
364 #define itog(fs, x)     ((x) / (fs)->fs_ipg)\r
365 #define itod(fs, x) \\r
366         ((daddr_t)(cgimin(fs, itog(fs, x)) + \\r
367         (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))\r
368 \r
369 /*\r
370  * Give cylinder group number for a file system block.\r
371  * Give cylinder group block number for a file system block.\r
372  */\r
373 #define dtog(fs, d)     ((d) / (fs)->fs_fpg)\r
374 #define dtogd(fs, d)    ((d) % (fs)->fs_fpg)\r
375 \r
376 /*\r
377  * Extract the bits for a block from a map.\r
378  * Compute the cylinder and rotational position of a cyl block addr.\r
379  */\r
380 #define blkmap(fs, map, loc) \\r
381     (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))\r
382 #define cbtocylno(fs, bno) \\r
383     ((bno) * NSPF(fs) / (fs)->fs_spc)\r
384 #define cbtorpos(fs, bno) \\r
385     (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \\r
386      (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \\r
387      (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)\r
388 \r
389 /*\r
390  * The following macros optimize certain frequently calculated\r
391  * quantities by using shifts and masks in place of divisions\r
392  * modulos and multiplications.\r
393  */\r
394 #define blkoff(fs, loc)         /* calculates (loc % fs->fs_bsize) */ \\r
395         ((loc) & ~(fs)->fs_bmask)\r
396 #define fragoff(fs, loc)        /* calculates (loc % fs->fs_fsize) */ \\r
397         ((loc) & ~(fs)->fs_fmask)\r
398 #define lblktosize(fs, blk)     /* calculates (blk * fs->fs_bsize) */ \\r
399         ((blk) << (fs)->fs_bshift)\r
400 #define lblkno(fs, loc)         /* calculates (loc / fs->fs_bsize) */ \\r
401         ((loc) >> (fs)->fs_bshift)\r
402 #define numfrags(fs, loc)       /* calculates (loc / fs->fs_fsize) */ \\r
403         ((loc) >> (fs)->fs_fshift)\r
404 #define blkroundup(fs, size)    /* calculates roundup(size, fs->fs_bsize) */ \\r
405         (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)\r
406 #define fragroundup(fs, size)   /* calculates roundup(size, fs->fs_fsize) */ \\r
407         (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)\r
408 #define fragstoblks(fs, frags)  /* calculates (frags / fs->fs_frag) */ \\r
409         ((frags) >> (fs)->fs_fragshift)\r
410 #define blkstofrags(fs, blks)   /* calculates (blks * fs->fs_frag) */ \\r
411         ((blks) << (fs)->fs_fragshift)\r
412 #define fragnum(fs, fsb)        /* calculates (fsb % fs->fs_frag) */ \\r
413         ((fsb) & ((fs)->fs_frag - 1))\r
414 #define blknum(fs, fsb)         /* calculates rounddown(fsb, fs->fs_frag) */ \\r
415         ((fsb) &~ ((fs)->fs_frag - 1))\r
416 \r
417 /*\r
418  * Determine the number of available frags given a\r
419  * percentage to hold in reserve\r
420  */\r
421 #define freespace(fs, percentreserved) \\r
422         (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \\r
423         (fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))\r
424 \r
425 /*\r
426  * Determining the size of a file block in the file system.\r
427  */\r
428 #define blksize(fs, ip, lbn) \\r
429         (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \\r
430             ? (fs)->fs_bsize \\r
431             : (fragroundup(fs, blkoff(fs, (ip)->i_size))))\r
432 #define dblksize(fs, dip, lbn) \\r
433         (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \\r
434             ? (fs)->fs_bsize \\r
435             : (fragroundup(fs, blkoff(fs, (dip)->di_size))))\r
436 \r
437 /*\r
438  * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.\r
439  */\r
440 #define NSPB(fs)        ((fs)->fs_nspf << (fs)->fs_fragshift)\r
441 #define NSPF(fs)        ((fs)->fs_nspf)\r
442 \r
443 /*\r
444  * INOPB is the number of inodes in a secondary storage block.\r
445  */\r
446 #define INOPB(fs)       ((fs)->fs_inopb)\r
447 #define INOPF(fs)       ((fs)->fs_inopb >> (fs)->fs_fragshift)\r
448 \r
449 /*\r
450  * NINDIR is the number of indirects in a file system block.\r
451  */\r
452 #define NINDIR(fs)      ((fs)->fs_nindir)\r
453 \r
454 #ifdef KERNEL\r
455 \r
456 extern void fserr(struct fs *, int /*uid_t*/, const char *);\r
457 extern void fragacct(struct fs *, int, long *, int);\r
458 extern int isblock(struct fs *, u_char *, daddr_t);\r
459 extern void clrblock(struct fs *, u_char *, daddr_t);\r
460 extern void setblock(struct fs *, u_char *, daddr_t);\r
461 extern ino_t dirpref(struct fs *);\r
462 extern daddr_t mapsearch(struct fs *, struct cg *, daddr_t, int);\r
463 \r
464 #endif /* _KERNEL */\r
465 #endif /* _UFS_FS_H_ */\r