Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / ufs / ffs / fs.h @ 13

History | View | Annotate | Download (31.1 KB)

1
/*        $NetBSD: fs.h,v 1.66 2015/02/14 09:06:11 maxv Exp $        */
2

    
3
/*
4
 * Copyright (c) 1982, 1986, 1993
5
 *        The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 * 3. Neither the name of the University nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 *
31
 *        @(#)fs.h        8.13 (Berkeley) 3/21/95
32
 */
33

    
34
/*
35
 * NOTE: COORDINATE ON-DISK FORMAT CHANGES WITH THE FREEBSD PROJECT.
36
 */
37

    
38
#ifndef        _UFS_FFS_FS_H_
39
#define        _UFS_FFS_FS_H_
40

    
41
/*
42
 * Each disk drive contains some number of file systems.
43
 * A file system consists of a number of cylinder groups.
44
 * Each cylinder group has inodes and data.
45
 *
46
 * A file system is described by its super-block, which in turn
47
 * describes the cylinder groups.  The super-block is critical
48
 * data and is replicated in each cylinder group to protect against
49
 * catastrophic loss.  This is done at `newfs' time and the critical
50
 * super-block data does not change, so the copies need not be
51
 * referenced further unless disaster strikes.
52
 *
53
 * For file system fs, the offsets of the various blocks of interest
54
 * are given in the super block as:
55
 *        [fs->fs_sblkno]                Super-block
56
 *        [fs->fs_cblkno]                Cylinder group block
57
 *        [fs->fs_iblkno]                Inode blocks
58
 *        [fs->fs_dblkno]                Data blocks
59
 * The beginning of cylinder group cg in fs, is given by
60
 * the ``cgbase(fs, cg)'' macro.
61
 *
62
 * Depending on the architecture and the media, the superblock may
63
 * reside in any one of four places. For tiny media where every block
64
 * counts, it is placed at the very front of the partition. Historically,
65
 * UFS1 placed it 8K from the front to leave room for the disk label and
66
 * a small bootstrap. For UFS2 it got moved to 64K from the front to leave
67
 * room for the disk label and a bigger bootstrap, and for really piggy
68
 * systems we check at 256K from the front if the first three fail. In
69
 * all cases the size of the superblock will be SBLOCKSIZE. All values are
70
 * given in byte-offset form, so they do not imply a sector size. The
71
 * SBLOCKSEARCH specifies the order in which the locations should be searched.
72
 *
73
 * Unfortunately the UFS2/FFSv2 change was done without adequate consideration
74
 * of backward compatibility.  In particular 'newfs' for a FFSv2 partition
75
 * must overwrite any old FFSv1 superblock at 8k, and preferably as many
76
 * of the alternates as it can find - otherwise attempting to mount on a
77
 * system that only supports FFSv1 is likely to succeed!.
78
 * For a small FFSv1 filesystem, an old FFSv2 superblock can be left on
79
 * the disk, and a system that tries to find an FFSv2 filesystem in preference
80
 * to and FFSv1 one (as NetBSD does) can mount the old FFSv2 filesystem.
81
 * As a added bonus, the 'first alternate' superblock of a FFSv1 filesystem
82
 * with 64k blocks is at 64k - just where the code looks first when playing
83
 * 'hunt the superblock'.
84
 *
85
 * The ffsv2 superblock layout (which might contain an ffsv1 filesystem)
86
 * can be detected by checking for sb->fs_old_flags & FS_FLAGS_UPDATED.
87
 * This is the default superblock type for NetBSD since ffsv2 support was added.
88
 */
89
#define        BBSIZE                8192
90
#define        BBOFF                ((off_t)(0))
91
#define        BBLOCK                ((daddr_t)(0))
92

    
93
#define        SBLOCK_FLOPPY      0
94
#define        SBLOCK_UFS1     8192
95
#define        SBLOCK_UFS2    65536
96
#define        SBLOCK_PIGGY  262144
97
#define        SBLOCKSIZE      8192
98
/*
99
 * NB: Do not, under any circumstances, look for an ffsv1 filesystem at
100
 * SBLOCK_UFS2.  Doing so will find the wrong superblock for filesystems
101
 * with a 64k block size.
102
 */
103
#define        SBLOCKSEARCH \
104
        { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
105

    
106
/*
107
 * Max number of fragments per block. This value is NOT tweakable.
108
 */
109
#define        MAXFRAG                8
110

    
111

    
112

    
113
/*
114
 * Addresses stored in inodes are capable of addressing fragments
115
 * of `blocks'. File system blocks of at most size MAXBSIZE can
116
 * be optionally broken into 2, 4, or 8 pieces, each of which is
117
 * addressable; these pieces may be DEV_BSIZE, or some multiple of
118
 * a DEV_BSIZE unit.
119
 *
120
 * Large files consist of exclusively large data blocks.  To avoid
121
 * undue wasted disk space, the last data block of a small file may be
122
 * allocated as only as many fragments of a large block as are
123
 * necessary.  The file system format retains only a single pointer
124
 * to such a fragment, which is a piece of a single large block that
125
 * has been divided.  The size of such a fragment is determinable from
126
 * information in the inode, using the ``ffs_blksize(fs, ip, lbn)'' macro.
127
 *
128
 * The file system records space availability at the fragment level;
129
 * to determine block availability, aligned fragments are examined.
130
 */
131

    
132
/*
133
 * MINBSIZE is the smallest allowable block size.
134
 * In order to insure that it is possible to create files of size
135
 * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
136
 * MINBSIZE must be big enough to hold a cylinder group block,
137
 * thus changes to (struct cg) must keep its size within MINBSIZE.
138
 * Note that super blocks are always of size SBSIZE,
139
 * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
140
 */
141
#define        MINBSIZE        4096
142

    
143
/*
144
 * The path name on which the file system is mounted is maintained
145
 * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
146
 * the super block for this name.
147
 */
148
#define        MAXMNTLEN        468
149

    
150
/*
151
 * The volume name for this filesystem is maintained in fs_volname.
152
 * MAXVOLLEN defines the length of the buffer allocated.
153
 * This space used to be part of of fs_fsmnt.
154
 */
155
#define        MAXVOLLEN        32
156

    
157
/*
158
 * There is a 128-byte region in the superblock reserved for in-core
159
 * pointers to summary information. Originally this included an array
160
 * of pointers to blocks of struct csum; now there are just four
161
 * pointers and the remaining space is padded with fs_ocsp[].
162
 * NOCSPTRS determines the size of this padding. One pointer (fs_csp)
163
 * is taken away to point to a contiguous array of struct csum for
164
 * all cylinder groups; a second (fs_maxcluster) points to an array
165
 * of cluster sizes that is computed as cylinder groups are inspected;
166
 * the third (fs_contigdirs) points to an array that tracks the
167
 * creation of new directories; and the fourth (fs_active) is used
168
 * by snapshots.
169
 */
170
#define        NOCSPTRS        ((128 / sizeof(void *)) - 4)
171

    
172
/*
173
 * A summary of contiguous blocks of various sizes is maintained
174
 * in each cylinder group. Normally this is set by the initial
175
 * value of fs_maxcontig. To conserve space, a maximum summary size
176
 * is set by FS_MAXCONTIG.
177
 */
178
#define        FS_MAXCONTIG        16
179

    
180
/*
181
 * The maximum number of snapshot nodes that can be associated
182
 * with each filesystem. This limit affects only the number of
183
 * snapshot files that can be recorded within the superblock so
184
 * that they can be found when the filesystem is mounted. However,
185
 * maintaining too many will slow the filesystem performance, so
186
 * having this limit is a good idea.
187
 */
188
#define        FSMAXSNAP 20
189

    
190
/*
191
 * Used to identify special blocks in snapshots:
192
 *
193
 * BLK_NOCOPY - A block that was unallocated at the time the snapshot
194
 *      was taken, hence does not need to be copied when written.
195
 * BLK_SNAP - A block held by another snapshot that is not needed by this
196
 *      snapshot. When the other snapshot is freed, the BLK_SNAP entries
197
 *      are converted to BLK_NOCOPY. These are needed to allow fsck to
198
 *      identify blocks that are in use by other snapshots (which are
199
 *      expunged from this snapshot).
200
 */
201
#define        BLK_NOCOPY        ((daddr_t)(1))
202
#define        BLK_SNAP        ((daddr_t)(2))
203

    
204
/*
205
 * MINFREE gives the minimum acceptable percentage of file system
206
 * blocks which may be free. If the freelist drops below this level
207
 * only the superuser may continue to allocate blocks. This may
208
 * be set to 0 if no reserve of free blocks is deemed necessary,
209
 * however throughput drops by fifty percent if the file system
210
 * is run at between 95% and 100% full; thus the minimum default
211
 * value of fs_minfree is 5%. However, to get good clustering
212
 * performance, 10% is a better choice. This value is used only
213
 * when creating a file system and can be overridden from the
214
 * command line. By default we choose to optimize for time.
215
 */
216
#define        MINFREE                5
217
#define        DEFAULTOPT        FS_OPTTIME
218

    
219
/*
220
 * Grigoriy Orlov <gluk@ptci.ru> has done some extensive work to fine
221
 * tune the layout preferences for directories within a filesystem.
222
 * His algorithm can be tuned by adjusting the following parameters
223
 * which tell the system the average file size and the average number
224
 * of files per directory. These defaults are well selected for typical
225
 * filesystems, but may need to be tuned for odd cases like filesystems
226
 * being used for squid caches or news spools.
227
 */
228
#define        AVFILESIZ        16384        /* expected average file size */
229
#define        AFPDIR                64        /* expected number of files per directory */
230

    
231
/*
232
 * Per cylinder group information; summarized in blocks allocated
233
 * from first cylinder group data blocks.  These blocks have to be
234
 * read in from fs_csaddr (size fs_cssize) in addition to the
235
 * super block.
236
 */
237
struct csum {
238
        int32_t        cs_ndir;                /* number of directories */
239
        int32_t        cs_nbfree;                /* number of free blocks */
240
        int32_t        cs_nifree;                /* number of free inodes */
241
        int32_t        cs_nffree;                /* number of free frags */
242
};
243

    
244
struct csum_total {
245
        int64_t cs_ndir;                /* number of directories */
246
        int64_t cs_nbfree;                /* number of free blocks */
247
        int64_t cs_nifree;                /* number of free inodes */
248
        int64_t cs_nffree;                /* number of free frags */
249
        int64_t cs_spare[4];                /* future expansion */
250
};
251

    
252

    
253
/*
254
 * Super block for an FFS file system in memory.
255
 */
256
struct fs {
257
        int32_t         fs_firstfield;                /* historic file system linked list, */
258
        int32_t         fs_unused_1;                /*     used for incore super blocks */
259
        int32_t  fs_sblkno;                /* addr of super-block in filesys */
260
        int32_t  fs_cblkno;                /* offset of cyl-block in filesys */
261
        int32_t  fs_iblkno;                /* offset of inode-blocks in filesys */
262
        int32_t  fs_dblkno;                /* offset of first data after cg */
263
        int32_t         fs_old_cgoffset;        /* cylinder group offset in cylinder */
264
        int32_t         fs_old_cgmask;                /* used to calc mod fs_ntrak */
265
        int32_t         fs_old_time;                /* last time written */
266
        int32_t         fs_old_size;                /* number of blocks in fs */
267
        int32_t         fs_old_dsize;                /* number of data blocks in fs */
268
        int32_t         fs_ncg;                /* number of cylinder groups */
269
        int32_t         fs_bsize;                /* size of basic blocks in fs */
270
        int32_t         fs_fsize;                /* size of frag blocks in fs */
271
        int32_t         fs_frag;                /* number of frags in a block in fs */
272
/* these are configuration parameters */
273
        int32_t         fs_minfree;                /* minimum percentage of free blocks */
274
        int32_t         fs_old_rotdelay;        /* num of ms for optimal next block */
275
        int32_t         fs_old_rps;                /* disk revolutions per second */
276
/* these fields can be computed from the others */
277
        int32_t         fs_bmask;                /* ``blkoff'' calc of blk offsets */
278
        int32_t         fs_fmask;                /* ``fragoff'' calc of frag offsets */
279
        int32_t         fs_bshift;                /* ``lblkno'' calc of logical blkno */
280
        int32_t         fs_fshift;                /* ``numfrags'' calc number of frags */
281
/* these are configuration parameters */
282
        int32_t         fs_maxcontig;                /* max number of contiguous blks */
283
        int32_t         fs_maxbpg;                /* max number of blks per cyl group */
284
/* these fields can be computed from the others */
285
        int32_t         fs_fragshift;                /* block to frag shift */
286
        int32_t         fs_fsbtodb;                /* fsbtodb and dbtofsb shift constant */
287
        int32_t         fs_sbsize;                /* actual size of super block */
288
        int32_t         fs_spare1[2];                /* old fs_csmask */
289
                                        /* old fs_csshift */
290
        int32_t         fs_nindir;                /* value of FFS_NINDIR */
291
        int32_t         fs_inopb;                /* value of FFS_INOPB */
292
        int32_t         fs_old_nspf;                /* value of NSPF */
293
/* yet another configuration parameter */
294
        int32_t         fs_optim;                /* optimization preference, see below */
295
/* these fields are derived from the hardware */
296
        int32_t         fs_old_npsect;                /* # sectors/track including spares */
297
        int32_t         fs_old_interleave;        /* hardware sector interleave */
298
        int32_t         fs_old_trackskew;        /* sector 0 skew, per track */
299
/* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */
300
        int32_t         fs_id[2];                /* unique file system id */
301
/* sizes determined by number of cylinder groups and their sizes */
302
        int32_t  fs_old_csaddr;                /* blk addr of cyl grp summary area */
303
        int32_t         fs_cssize;                /* size of cyl grp summary area */
304
        int32_t         fs_cgsize;                /* cylinder group size */
305
/* these fields are derived from the hardware */
306
        int32_t         fs_spare2;                /* old fs_ntrak */
307
        int32_t         fs_old_nsect;                /* sectors per track */
308
        int32_t         fs_old_spc;                /* sectors per cylinder */
309
        int32_t         fs_old_ncyl;                /* cylinders in file system */
310
        int32_t         fs_old_cpg;                /* cylinders per group */
311
        int32_t         fs_ipg;                /* inodes per group */
312
        int32_t         fs_fpg;                /* blocks per group * fs_frag */
313
/* this data must be re-computed after crashes */
314
        struct        csum fs_old_cstotal;        /* cylinder summary information */
315
/* these fields are cleared at mount time */
316
        int8_t         fs_fmod;                /* super block modified flag */
317
        uint8_t         fs_clean;                /* file system is clean flag */
318
        int8_t         fs_ronly;                /* mounted read-only flag */
319
        uint8_t         fs_old_flags;                /* see FS_ flags below */
320
        u_char         fs_fsmnt[MAXMNTLEN];        /* name mounted on */
321
        u_char   fs_volname[MAXVOLLEN];        /* volume name */
322
        uint64_t fs_swuid;                /* system-wide uid */
323
        int32_t         fs_pad;
324
/* these fields retain the current block allocation info */
325
        int32_t         fs_cgrotor;                /* last cg searched (UNUSED) */
326
        void         *fs_ocsp[NOCSPTRS];        /* padding; was list of fs_cs buffers */
327
        u_int8_t *fs_contigdirs;        /* # of contiguously allocated dirs */
328
        struct csum *fs_csp;                /* cg summary info buffer for fs_cs */
329
        int32_t        *fs_maxcluster;                /* max cluster in each cyl group */
330
        u_char        *fs_active;                /* used by snapshots to track fs */
331
        int32_t         fs_old_cpc;                /* cyl per cycle in postbl */
332
/* this area is otherwise allocated unless fs_old_flags & FS_FLAGS_UPDATED */
333
        int32_t         fs_maxbsize;                /* maximum blocking factor permitted */
334
        uint8_t         fs_journal_version;        /* journal format version */
335
        uint8_t         fs_journal_location;        /* journal location type */
336
        uint8_t         fs_journal_reserved[2];/* reserved for future use */
337
        uint32_t fs_journal_flags;        /* journal flags */
338
        uint64_t fs_journallocs[4];        /* location info for journal */
339
        uint32_t fs_quota_magic;        /* see quota2.h */
340
        uint8_t  fs_quota_flags;        /* see quota2.h */
341
        uint8_t  fs_quota_reserved[3];        
342
        uint64_t fs_quotafile[2];        /* pointer to quota inodes */
343
        int64_t         fs_sparecon64[9];        /* reserved for future use */
344
        int64_t         fs_sblockloc;                /* byte offset of standard superblock */
345
        struct        csum_total fs_cstotal;        /* cylinder summary information */
346
        int64_t  fs_time;                /* last time written */
347
        int64_t         fs_size;                /* number of blocks in fs */
348
        int64_t         fs_dsize;                /* number of data blocks in fs */
349
        int64_t  fs_csaddr;                /* blk addr of cyl grp summary area */
350
        int64_t         fs_pendingblocks;        /* blocks in process of being freed */
351
        int32_t         fs_pendinginodes;        /* inodes in process of being freed */
352
        int32_t         fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
353
/* back to stuff that has been around a while */
354
        int32_t         fs_avgfilesize;        /* expected average file size */
355
        int32_t         fs_avgfpdir;                /* expected # of files per directory */
356
        int32_t         fs_save_cgsize;        /* save real cg size to use fs_bsize */
357
        int32_t         fs_sparecon32[26];        /* reserved for future constants */
358
        uint32_t fs_flags;                /* see FS_ flags below */
359
/* back to stuff that has been around a while (again) */
360
        int32_t         fs_contigsumsize;        /* size of cluster summary array */
361
        int32_t         fs_maxsymlinklen;        /* max length of an internal symlink */
362
        int32_t         fs_old_inodefmt;        /* format of on-disk inodes */
363
        u_int64_t fs_maxfilesize;        /* maximum representable file size */
364
        int64_t         fs_qbmask;                /* ~fs_bmask for use with 64-bit size */
365
        int64_t         fs_qfmask;                /* ~fs_fmask for use with 64-bit size */
366
        int32_t         fs_state;                /* validate fs_clean field (UNUSED) */
367
        int32_t         fs_old_postblformat;        /* format of positional layout tables */
368
        int32_t         fs_old_nrpos;                /* number of rotational positions */
369
        int32_t  fs_spare5[2];                /* old fs_postbloff */
370
                                        /* old fs_rotbloff */
371
        int32_t         fs_magic;                /* magic number */
372
};
373

    
374
#define        fs_old_postbloff        fs_spare5[0]
375
#define        fs_old_rotbloff                fs_spare5[1]
376
#define        fs_old_postbl_start        fs_maxbsize
377
#define        fs_old_headswitch        fs_id[0]
378
#define        fs_old_trkseek        fs_id[1]
379
#define        fs_old_csmask        fs_spare1[0]
380
#define        fs_old_csshift        fs_spare1[1]
381

    
382
#define        FS_42POSTBLFMT                -1        /* 4.2BSD rotational table format */
383
#define        FS_DYNAMICPOSTBLFMT        1        /* dynamic rotational table format */
384

    
385
#define        old_fs_postbl(fs_, cylno, opostblsave) \
386
    ((((fs_)->fs_old_postblformat == FS_42POSTBLFMT) || \
387
     ((fs_)->fs_old_postbloff == offsetof(struct fs, fs_old_postbl_start))) \
388
    ? ((int16_t *)(opostblsave) + (cylno) * (fs_)->fs_old_nrpos) \
389
    : ((int16_t *)((uint8_t *)(fs_) + \
390
        (fs_)->fs_old_postbloff) + (cylno) * (fs_)->fs_old_nrpos))
391
#define        old_fs_rotbl(fs) \
392
    (((fs)->fs_old_postblformat == FS_42POSTBLFMT) \
393
    ? ((uint8_t *)(&(fs)->fs_magic+1)) \
394
    : ((uint8_t *)((uint8_t *)(fs) + (fs)->fs_old_rotbloff)))
395

    
396
/*
397
 * File system identification
398
 */
399
#define        FS_UFS1_MAGIC        0x011954        /* UFS1 fast file system magic number */
400
#define        FS_UFS2_MAGIC        0x19540119        /* UFS2 fast file system magic number */
401
#define        FS_UFS1_MAGIC_SWAPPED        0x54190100
402
#define        FS_UFS2_MAGIC_SWAPPED        0x19015419
403
#define        FS_OKAY                0x7c269d38        /* superblock checksum */
404
#define        FS_42INODEFMT        -1                /* 4.2BSD inode format */
405
#define        FS_44INODEFMT        2                /* 4.4BSD inode format */
406

    
407
/*
408
 * File system clean flags
409
 */
410
#define        FS_ISCLEAN        0x01
411
#define        FS_WASCLEAN        0x02
412

    
413
/*
414
 * Preference for optimization.
415
 */
416
#define        FS_OPTTIME        0        /* minimize allocation time */
417
#define        FS_OPTSPACE        1        /* minimize disk fragmentation */
418

    
419
/*
420
 * File system flags
421
 */
422
#define        FS_UNCLEAN        0x001        /* file system not clean at mount (unused) */
423
#define        FS_DOSOFTDEP        0x002        /* file system using soft dependencies */
424
#define        FS_NEEDSFSCK        0x004        /* needs sync fsck (FreeBSD compat, unused) */
425
#define        FS_SUJ                0x008        /* file system using journaled softupdates */
426
#define        FS_ACLS                0x010        /* file system has ACLs enabled */
427
#define        FS_MULTILABEL        0x020        /* file system is MAC multi-label */
428
#define        FS_GJOURNAL        0x40        /* gjournaled file system */
429
#define        FS_FLAGS_UPDATED 0x80        /* flags have been moved to new location */
430
#define        FS_DOWAPBL        0x100        /* Write ahead physical block logging */
431
/*             FS_NFS4ACLS        0x100           file system has NFSv4 ACLs enabled (FBSD) */
432
#define        FS_DOQUOTA2        0x200        /* in-filesystem quotas */
433
/*             FS_INDEXDIRS        0x200           kernel supports indexed directories (FBSD)*/
434
#define        FS_TRIM                0x400        /* discard deleted blocks in storage layer */
435

    
436
/* File system flags that are ok for NetBSD if set in fs_flags */
437
#define        FS_KNOWN_FLAGS        (FS_DOSOFTDEP | FS_DOWAPBL | FS_DOQUOTA2)
438

    
439
/*
440
 * File system internal flags, also in fs_flags.
441
 * (Pick highest number to avoid conflicts with others)
442
 */
443
#define        FS_SWAPPED        0x80000000        /* file system is endian swapped */
444
#define        FS_INTERNAL        0x80000000        /* mask for internal flags */
445

    
446
/*
447
 * Macros to access bits in the fs_active array.
448
 */
449
#define        ACTIVECG_SET(fs, cg)                                \
450
        do {                                                \
451
                if ((fs)->fs_active != NULL)                \
452
                        setbit((fs)->fs_active, (cg));        \
453
        } while (/*CONSTCOND*/ 0)
454
#define        ACTIVECG_CLR(fs, cg)                                \
455
        do {                                                \
456
                if ((fs)->fs_active != NULL)                \
457
                        clrbit((fs)->fs_active, (cg));        \
458
        } while (/*CONSTCOND*/ 0)
459
#define        ACTIVECG_ISSET(fs, cg)                                \
460
        ((fs)->fs_active != NULL && isset((fs)->fs_active, (cg)))
461

    
462
/*
463
 * The size of a cylinder group is calculated by CGSIZE. The maximum size
464
 * is limited by the fact that cylinder groups are at most one block.
465
 * Its size is derived from the size of the maps maintained in the
466
 * cylinder group and the (struct cg) size.
467
 */
468
#define        CGSIZE_IF(fs, ipg, fpg) \
469
    /* base cg */        (sizeof(struct cg) + sizeof(int32_t) + \
470
    /* old btotoff */        (fs)->fs_old_cpg * sizeof(int32_t) + \
471
    /* old boff */        (fs)->fs_old_cpg * sizeof(u_int16_t) + \
472
    /* inode map */        howmany((ipg), NBBY) + \
473
    /* block map */        howmany((fpg), NBBY) +\
474
    /* if present */        ((fs)->fs_contigsumsize <= 0 ? 0 : \
475
    /* cluster sum */        (fs)->fs_contigsumsize * sizeof(int32_t) + \
476
    /* cluster map */        howmany(ffs_fragstoblks(fs, (fpg)), NBBY)))
477

    
478
#define        CGSIZE(fs) CGSIZE_IF((fs), (fs)->fs_ipg, (fs)->fs_fpg)
479

    
480
/*
481
 * The minimal number of cylinder groups that should be created.
482
 */
483
#define        MINCYLGRPS        4
484

    
485

    
486
/*
487
 * Convert cylinder group to base address of its global summary info.
488
 */
489
#define        fs_cs(fs, indx)        fs_csp[indx]
490

    
491
/*
492
 * Cylinder group block for a file system.
493
 */
494
#define        CG_MAGIC        0x090255
495
struct cg {
496
        int32_t         cg_firstfield;                /* historic cyl groups linked list */
497
        int32_t         cg_magic;                /* magic number */
498
        int32_t         cg_old_time;                /* time last written */
499
        int32_t         cg_cgx;                /* we are the cgx'th cylinder group */
500
        int16_t         cg_old_ncyl;                /* number of cyl's this cg */
501
        int16_t         cg_old_niblk;                /* number of inode blocks this cg */
502
        int32_t         cg_ndblk;                /* number of data blocks this cg */
503
        struct        csum cg_cs;                /* cylinder summary information */
504
        int32_t         cg_rotor;                /* position of last used block */
505
        int32_t         cg_frotor;                /* position of last used frag */
506
        int32_t         cg_irotor;                /* position of last used inode */
507
        int32_t         cg_frsum[MAXFRAG];        /* counts of available frags */
508
        int32_t         cg_old_btotoff;        /* (int32) block totals per cylinder */
509
        int32_t         cg_old_boff;                /* (u_int16) free block positions */
510
        int32_t         cg_iusedoff;                /* (u_int8) used inode map */
511
        int32_t         cg_freeoff;                /* (u_int8) free block map */
512
        int32_t         cg_nextfreeoff;        /* (u_int8) next available space */
513
        int32_t         cg_clustersumoff;        /* (u_int32) counts of avail clusters */
514
        int32_t         cg_clusteroff;                /* (u_int8) free cluster map */
515
        int32_t         cg_nclusterblks;        /* number of clusters this cg */
516
        int32_t  cg_niblk;                /* number of inode blocks this cg */
517
        int32_t  cg_initediblk;                /* last initialized inode */
518
        int32_t         cg_sparecon32[3];        /* reserved for future use */
519
        int64_t  cg_time;                /* time last written */
520
        int64_t  cg_sparecon64[3];        /* reserved for future use */
521
        u_int8_t cg_space[1];                /* space for cylinder group maps */
522
/* actually longer */
523
};
524

    
525
/*
526
 * The following structure is defined
527
 * for compatibility with old file systems.
528
 */
529
struct ocg {
530
        int32_t  cg_firstfield;                /* historic linked list of cyl groups */
531
        int32_t  cg_unused_1;                /*     used for incore cyl groups */
532
        int32_t  cg_time;                /* time last written */
533
        int32_t  cg_cgx;                /* we are the cgx'th cylinder group */
534
        int16_t  cg_ncyl;                /* number of cyl's this cg */
535
        int16_t  cg_niblk;                /* number of inode blocks this cg */
536
        int32_t  cg_ndblk;                /* number of data blocks this cg */
537
        struct  csum cg_cs;                /* cylinder summary information */
538
        int32_t  cg_rotor;                /* position of last used block */
539
        int32_t  cg_frotor;                /* position of last used frag */
540
        int32_t  cg_irotor;                /* position of last used inode */
541
        int32_t  cg_frsum[8];                /* counts of available frags */
542
        int32_t  cg_btot[32];                /* block totals per cylinder */
543
        int16_t  cg_b[32][8];                /* positions of free blocks */
544
        u_int8_t cg_iused[256];                /* used inode map */
545
        int32_t  cg_magic;                /* magic number */
546
        u_int8_t cg_free[1];                /* free block map */
547
/* actually longer */
548
};
549

    
550

    
551
/*
552
 * Macros for access to cylinder group array structures.
553
 */
554
#define        old_cg_blktot_old(cgp, ns) \
555
    (((struct ocg *)(cgp))->cg_btot)
556
#define        old_cg_blks_old(fs, cgp, cylno, ns) \
557
    (((struct ocg *)(cgp))->cg_b[cylno])
558

    
559
#define        old_cg_blktot_new(cgp, ns) \
560
    ((int32_t *)((u_int8_t *)(cgp) + \
561
        ufs_rw32((cgp)->cg_old_btotoff, (ns))))
562
#define        old_cg_blks_new(fs, cgp, cylno, ns) \
563
    ((int16_t *)((u_int8_t *)(cgp) + \
564
        ufs_rw32((cgp)->cg_old_boff, (ns))) + (cylno) * (fs)->fs_old_nrpos)
565

    
566
#define        old_cg_blktot(cgp, ns) \
567
    ((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
568
      old_cg_blktot_old(cgp, ns) : old_cg_blktot_new(cgp, ns))
569
#define        old_cg_blks(fs, cgp, cylno, ns) \
570
    ((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
571
      old_cg_blks_old(fs, cgp, cylno, ns) : old_cg_blks_new(fs, cgp, cylno, ns))
572

    
573
#define        cg_inosused_new(cgp, ns) \
574
    ((u_int8_t *)((u_int8_t *)(cgp) + \
575
        ufs_rw32((cgp)->cg_iusedoff, (ns))))
576
#define        cg_blksfree_new(cgp, ns) \
577
    ((u_int8_t *)((u_int8_t *)(cgp) + \
578
        ufs_rw32((cgp)->cg_freeoff, (ns))))
579
#define        cg_chkmagic_new(cgp, ns) \
580
    (ufs_rw32((cgp)->cg_magic, (ns)) == CG_MAGIC)
581

    
582
#define        cg_inosused_old(cgp, ns) \
583
    (((struct ocg *)(cgp))->cg_iused)
584
#define        cg_blksfree_old(cgp, ns) \
585
    (((struct ocg *)(cgp))->cg_free)
586
#define        cg_chkmagic_old(cgp, ns) \
587
    (ufs_rw32(((struct ocg *)(cgp))->cg_magic, (ns)) == CG_MAGIC)
588

    
589
#define        cg_inosused(cgp, ns) \
590
    ((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
591
      cg_inosused_old(cgp, ns) : cg_inosused_new(cgp, ns))
592
#define        cg_blksfree(cgp, ns) \
593
    ((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
594
      cg_blksfree_old(cgp, ns) : cg_blksfree_new(cgp, ns))
595
#define        cg_chkmagic(cgp, ns) \
596
    (cg_chkmagic_new(cgp, ns) || cg_chkmagic_old(cgp, ns))
597

    
598
#define        cg_clustersfree(cgp, ns) \
599
    ((u_int8_t *)((u_int8_t *)(cgp) + \
600
        ufs_rw32((cgp)->cg_clusteroff, (ns))))
601
#define        cg_clustersum(cgp, ns) \
602
    ((int32_t *)((u_int8_t *)(cgp) + \
603
        ufs_rw32((cgp)->cg_clustersumoff, (ns))))
604

    
605

    
606
/*
607
 * Turn file system block numbers into disk block addresses.
608
 * This maps file system blocks to device size blocks.
609
 */
610
#if defined (_KERNEL)
611
#define        FFS_FSBTODB(fs, b)        ((b) << ((fs)->fs_fshift - DEV_BSHIFT))
612
#define        FFS_DBTOFSB(fs, b)        ((b) >> ((fs)->fs_fshift - DEV_BSHIFT))
613
#else
614
#define        FFS_FSBTODB(fs, b)        ((b) << (fs)->fs_fsbtodb)
615
#define        FFS_DBTOFSB(fs, b)        ((b) >> (fs)->fs_fsbtodb)
616
#endif
617

    
618
/*
619
 * Cylinder group macros to locate things in cylinder groups.
620
 * They calc file system addresses of cylinder group data structures.
621
 */
622
#define        cgbase(fs, c)        (((daddr_t)(fs)->fs_fpg) * (c))
623
#define        cgstart_ufs1(fs, c) \
624
    (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask)))
625
#define        cgstart_ufs2(fs, c) cgbase((fs), (c))
626
#define        cgstart(fs, c) ((fs)->fs_magic == FS_UFS2_MAGIC \
627
                            ? cgstart_ufs2((fs), (c)) : cgstart_ufs1((fs), (c)))
628
#define        cgdmin(fs, c)        (cgstart(fs, c) + (fs)->fs_dblkno)        /* 1st data */
629
#define        cgimin(fs, c)        (cgstart(fs, c) + (fs)->fs_iblkno)        /* inode blk */
630
#define        cgsblock(fs, c)        (cgstart(fs, c) + (fs)->fs_sblkno)        /* super blk */
631
#define        cgtod(fs, c)        (cgstart(fs, c) + (fs)->fs_cblkno)        /* cg block */
632

    
633
/*
634
 * Macros for handling inode numbers:
635
 *     inode number to file system block offset.
636
 *     inode number to cylinder group number.
637
 *     inode number to file system block address.
638
 */
639
#define        ino_to_cg(fs, x)        ((x) / (fs)->fs_ipg)
640
#define        ino_to_fsba(fs, x)                                                \
641
        ((daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +                        \
642
            (ffs_blkstofrags((fs), (((x) % (fs)->fs_ipg) / FFS_INOPB(fs))))))
643
#define        ino_to_fsbo(fs, x)        ((x) % FFS_INOPB(fs))
644

    
645
/*
646
 * Give cylinder group number for a file system block.
647
 * Give cylinder group block number for a file system block.
648
 */
649
#define        dtog(fs, d)        ((d) / (fs)->fs_fpg)
650
#define        dtogd(fs, d)        ((d) % (fs)->fs_fpg)
651

    
652
/*
653
 * Extract the bits for a block from a map.
654
 * Compute the cylinder and rotational position of a cyl block addr.
655
 */
656
#define        blkmap(fs, map, loc) \
657
    (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
658
#define        old_cbtocylno(fs, bno) \
659
    (FFS_FSBTODB(fs, bno) / (fs)->fs_old_spc)
660
#define        old_cbtorpos(fs, bno) \
661
    ((fs)->fs_old_nrpos <= 1 ? 0 : \
662
     (FFS_FSBTODB(fs, bno) % (fs)->fs_old_spc / (fs)->fs_old_nsect * (fs)->fs_old_trackskew + \
663
      FFS_FSBTODB(fs, bno) % (fs)->fs_old_spc % (fs)->fs_old_nsect * (fs)->fs_old_interleave) % \
664
     (fs)->fs_old_nsect * (fs)->fs_old_nrpos / (fs)->fs_old_npsect)
665

    
666
/*
667
 * The following macros optimize certain frequently calculated
668
 * quantities by using shifts and masks in place of divisions
669
 * modulos and multiplications.
670
 */
671
#define        ffs_blkoff(fs, loc)        /* calculates (loc % fs->fs_bsize) */ \
672
        ((loc) & (fs)->fs_qbmask)
673
#define        ffs_fragoff(fs, loc)        /* calculates (loc % fs->fs_fsize) */ \
674
        ((loc) & (fs)->fs_qfmask)
675
#define        ffs_lfragtosize(fs, frag) /* calculates ((off_t)frag * fs->fs_fsize) */ \
676
        (((off_t)(frag)) << (fs)->fs_fshift)
677
#define        ffs_lblktosize(fs, blk)        /* calculates ((off_t)blk * fs->fs_bsize) */ \
678
        ((uint64_t)(((off_t)(blk)) << (fs)->fs_bshift))
679
#define        ffs_lblkno(fs, loc)        /* calculates (loc / fs->fs_bsize) */ \
680
        ((loc) >> (fs)->fs_bshift)
681
#define        ffs_numfrags(fs, loc)        /* calculates (loc / fs->fs_fsize) */ \
682
        ((loc) >> (fs)->fs_fshift)
683
#define        ffs_blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
684
        (((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
685
#define        ffs_fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
686
        (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
687
#define        ffs_fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
688
        ((frags) >> (fs)->fs_fragshift)
689
#define        ffs_blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
690
        ((blks) << (fs)->fs_fragshift)
691
#define        ffs_fragnum(fs, fsb)        /* calculates (fsb % fs->fs_frag) */ \
692
        ((fsb) & ((fs)->fs_frag - 1))
693
#define        ffs_blknum(fs, fsb)        /* calculates rounddown(fsb, fs->fs_frag) */ \
694
        ((fsb) &~ ((fs)->fs_frag - 1))
695

    
696
/*
697
 * Determine the number of available frags given a
698
 * percentage to hold in reserve.
699
 */
700
#define        freespace(fs, percentreserved) \
701
        (ffs_blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
702
        (fs)->fs_cstotal.cs_nffree - \
703
        (((off_t)((fs)->fs_dsize)) * (percentreserved) / 100))
704

    
705
/*
706
 * Determining the size of a file block in the file system.
707
 */
708
#define        ffs_blksize(fs, ip, lbn) \
709
        (((lbn) >= UFS_NDADDR || (ip)->i_size >= ffs_lblktosize(fs, (lbn) + 1)) \
710
            ? (fs)->fs_bsize \
711
            : ((int32_t)ffs_fragroundup(fs, ffs_blkoff(fs, (ip)->i_size))))
712

    
713
#define        ffs_sblksize(fs, size, lbn) \
714
        (((lbn) >= UFS_NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
715
          ? (fs)->fs_bsize \
716
          : ((int32_t)ffs_fragroundup(fs, ffs_blkoff(fs, (uint64_t)(size)))))
717

    
718

    
719
/*
720
 * Number of inodes in a secondary storage block/fragment.
721
 */
722
#define        FFS_INOPB(fs)        ((fs)->fs_inopb)
723
#define        FFS_INOPF(fs)        ((fs)->fs_inopb >> (fs)->fs_fragshift)
724

    
725
/*
726
 * Number of indirects in a file system block.
727
 */
728
#define        FFS_NINDIR(fs)        ((fs)->fs_nindir)
729

    
730
/*
731
 * Apple UFS Label:
732
 *  We check for this to decide to use APPLEUFS_DIRBLKSIZ
733
 */
734
#define        APPLEUFS_LABEL_MAGIC                0x4c41424c /* LABL */
735
#define        APPLEUFS_LABEL_SIZE                1024
736
#define        APPLEUFS_LABEL_OFFSET        (BBSIZE - APPLEUFS_LABEL_SIZE) /* located at 7k */
737
#define        APPLEUFS_LABEL_VERSION        1
738
#define        APPLEUFS_MAX_LABEL_NAME        512
739

    
740
struct appleufslabel {
741
        u_int32_t        ul_magic;
742
        u_int16_t        ul_checksum;
743
        u_int16_t        ul_unused0;
744
        u_int32_t        ul_version;
745
        u_int32_t        ul_time;
746
        u_int16_t        ul_namelen;
747
        u_char        ul_name[APPLEUFS_MAX_LABEL_NAME]; /* Warning: may not be null terminated */
748
        u_int16_t        ul_unused1;
749
        u_int64_t        ul_uuid;        /* Note this is only 4 byte aligned */
750
        u_char        ul_reserved[24];
751
        u_char        ul_unused[460];
752
} __packed;
753

    
754

    
755
#endif /* !_UFS_FFS_FS_H_ */