1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS File System Recognizer 4 * FILE: drivers/filesystems/fs_rec/ffs.h 5 * PURPOSE: FFS Header File 6 * PROGRAMMER: Peter Hater 7 * Pierre Schweitzer (pierre@reactos.org) 8 */ 9 10 #include <pshpack1.h> 11 12 /* 13 * The path name on which the file system is mounted is maintained 14 * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in 15 * the super block for this name. 16 */ 17 #define MAXMNTLEN 468 18 19 /* 20 * The volume name for this filesystem is maintained in fs_volname. 21 * MAXVOLLEN defines the length of the buffer allocated. 22 * This space used to be part of of fs_fsmnt. 23 */ 24 #define MAXVOLLEN 32 25 26 /* 27 * Unused value currently, FreeBSD compat. 28 */ 29 #define FSMAXSNAP 20 30 31 /* 32 * There is a 128-byte region in the superblock reserved for in-core 33 * pointers to summary information. Originally this included an array 34 * of pointers to blocks of struct csum; now there are just four 35 * pointers and the remaining space is padded with fs_ocsp[]. 36 * NOCSPTRS determines the size of this padding. One pointer (fs_csp) 37 * is taken away to point to a contiguous array of struct csum for 38 * all cylinder groups; a second (fs_maxcluster) points to an array 39 * of cluster sizes that is computed as cylinder groups are inspected; 40 * the third (fs_contigdirs) points to an array that tracks the 41 * creation of new directories; and the fourth (fs_active) is used 42 * by snapshots. 43 */ 44 #define NOCSPTRS ((128 / sizeof(void *)) - 4) 45 46 /* 47 * Per cylinder group information; summarized in blocks allocated 48 * from first cylinder group data blocks. These blocks have to be 49 * read in from fs_csaddr (size fs_cssize) in addition to the 50 * super block. 51 */ 52 struct csum { 53 INT32 cs_ndir; /* number of directories */ 54 INT32 cs_nbfree; /* number of free blocks */ 55 INT32 cs_nifree; /* number of free inodes */ 56 INT32 cs_nffree; /* number of free frags */ 57 }; 58 59 struct csum_total { 60 INT64 cs_ndir; /* number of directories */ 61 INT64 cs_nbfree; /* number of free blocks */ 62 INT64 cs_nifree; /* number of free inodes */ 63 INT64 cs_nffree; /* number of free frags */ 64 INT64 cs_spare[4]; /* future expansion */ 65 }; 66 67 /* 68 * Super block for an FFS file system in memory. 69 */ 70 typedef struct fs { 71 INT32 fs_firstfield; /* historic file system linked list, */ 72 INT32 fs_unused_1; /* used for incore super blocks */ 73 INT32 fs_sblkno; /* addr of super-block in filesys */ 74 INT32 fs_cblkno; /* offset of cyl-block in filesys */ 75 INT32 fs_iblkno; /* offset of inode-blocks in filesys */ 76 INT32 fs_dblkno; /* offset of first data after cg */ 77 INT32 fs_old_cgoffset; /* cylinder group offset in cylinder */ 78 INT32 fs_old_cgmask; /* used to calc mod fs_ntrak */ 79 INT32 fs_old_time; /* last time written */ 80 INT32 fs_old_size; /* number of blocks in fs */ 81 INT32 fs_old_dsize; /* number of data blocks in fs */ 82 INT32 fs_ncg; /* number of cylinder groups */ 83 INT32 fs_bsize; /* size of basic blocks in fs */ 84 INT32 fs_fsize; /* size of frag blocks in fs */ 85 INT32 fs_frag; /* number of frags in a block in fs */ 86 /* these are configuration parameters */ 87 INT32 fs_minfree; /* minimum percentage of free blocks */ 88 INT32 fs_old_rotdelay; /* num of ms for optimal next block */ 89 INT32 fs_old_rps; /* disk revolutions per second */ 90 /* these fields can be computed from the others */ 91 INT32 fs_bmask; /* ``blkoff'' calc of blk offsets */ 92 INT32 fs_fmask; /* ``fragoff'' calc of frag offsets */ 93 INT32 fs_bshift; /* ``lblkno'' calc of logical blkno */ 94 INT32 fs_fshift; /* ``numfrags'' calc number of frags */ 95 /* these are configuration parameters */ 96 INT32 fs_maxcontig; /* max number of contiguous blks */ 97 INT32 fs_maxbpg; /* max number of blks per cyl group */ 98 /* these fields can be computed from the others */ 99 INT32 fs_fragshift; /* block to frag shift */ 100 INT32 fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 101 INT32 fs_sbsize; /* actual size of super block */ 102 INT32 fs_spare1[2]; /* old fs_csmask */ 103 /* old fs_csshift */ 104 INT32 fs_nindir; /* value of NINDIR */ 105 INT32 fs_inopb; /* value of INOPB */ 106 INT32 fs_old_nspf; /* value of NSPF */ 107 /* yet another configuration parameter */ 108 INT32 fs_optim; /* optimization preference, see below */ 109 /* these fields are derived from the hardware */ 110 INT32 fs_old_npsect; /* # sectors/track including spares */ 111 INT32 fs_old_interleave; /* hardware sector interleave */ 112 INT32 fs_old_trackskew; /* sector 0 skew, per track */ 113 /* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */ 114 INT32 fs_id[2]; /* unique file system id */ 115 /* sizes determined by number of cylinder groups and their sizes */ 116 INT32 fs_old_csaddr; /* blk addr of cyl grp summary area */ 117 INT32 fs_cssize; /* size of cyl grp summary area */ 118 INT32 fs_cgsize; /* cylinder group size */ 119 /* these fields are derived from the hardware */ 120 INT32 fs_spare2; /* old fs_ntrak */ 121 INT32 fs_old_nsect; /* sectors per track */ 122 INT32 fs_old_spc; /* sectors per cylinder */ 123 INT32 fs_old_ncyl; /* cylinders in file system */ 124 INT32 fs_old_cpg; /* cylinders per group */ 125 INT32 fs_ipg; /* inodes per group */ 126 INT32 fs_fpg; /* blocks per group * fs_frag */ 127 /* this data must be re-computed after crashes */ 128 struct csum fs_old_cstotal; /* cylinder summary information */ 129 /* these fields are cleared at mount time */ 130 INT8 fs_fmod; /* super block modified flag */ 131 INT8 fs_clean; /* file system is clean flag */ 132 INT8 fs_ronly; /* mounted read-only flag */ 133 UINT8 fs_old_flags; /* see FS_ flags below */ 134 UCHAR fs_fsmnt[MAXMNTLEN]; /* name mounted on */ 135 UCHAR fs_volname[MAXVOLLEN]; /* volume name */ 136 UINT64 fs_swuid; /* system-wide uid */ 137 INT32 fs_pad; 138 /* these fields retain the current block allocation info */ 139 INT32 fs_cgrotor; /* last cg searched (UNUSED) */ 140 void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */ 141 UINT8 *fs_contigdirs; /* # of contiguously allocated dirs */ 142 struct csum *fs_csp; /* cg summary info buffer for fs_cs */ 143 INT32 *fs_maxcluster; /* max cluster in each cyl group */ 144 INT32 *fs_active; /* used by snapshots to track fs */ 145 INT32 fs_old_cpc; /* cyl per cycle in postbl */ 146 /* this area is otherwise allocated unless fs_old_flags & FS_FLAGS_UPDATED */ 147 INT32 fs_maxbsize; /* maximum blocking factor permitted */ 148 INT64 fs_sparecon64[17]; /* old rotation block list head */ 149 INT64 fs_sblockloc; /* byte offset of standard superblock */ 150 struct csum_total fs_cstotal; /* cylinder summary information */ 151 INT64 fs_time; /* last time written */ 152 INT64 fs_size; /* number of blocks in fs */ 153 INT64 fs_dsize; /* number of data blocks in fs */ 154 INT64 fs_csaddr; /* blk addr of cyl grp summary area */ 155 INT64 fs_pendingblocks; /* blocks in process of being freed */ 156 INT32 fs_pendinginodes; /* inodes in process of being freed */ 157 INT32 fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ 158 /* back to stuff that has been around a while */ 159 INT32 fs_avgfilesize; /* expected average file size */ 160 INT32 fs_avgfpdir; /* expected # of files per directory */ 161 INT32 fs_save_cgsize; /* save real cg size to use fs_bsize */ 162 INT32 fs_sparecon32[26]; /* reserved for future constants */ 163 INT32 fs_flags; /* see FS_ flags below */ 164 /* back to stuff that has been around a while (again) */ 165 INT32 fs_contigsumsize; /* size of cluster summary array */ 166 INT32 fs_maxsymlinklen; /* max length of an internal symlink */ 167 INT32 fs_old_inodefmt; /* format of on-disk inodes */ 168 UINT64 fs_maxfilesize; /* maximum representable file size */ 169 INT64 fs_qbmask; /* ~fs_bmask for use with 64-bit size */ 170 INT64 fs_qfmask; /* ~fs_fmask for use with 64-bit size */ 171 INT32 fs_state; /* validate fs_clean field (UNUSED) */ 172 INT32 fs_old_postblformat; /* format of positional layout tables */ 173 INT32 fs_old_nrpos; /* number of rotational positions */ 174 INT32 fs_spare5[2]; /* old fs_postbloff */ 175 /* old fs_rotbloff */ 176 INT32 fs_magic; /* magic number */ 177 } FFSD_SUPER_BLOCK, *PFFSD_SUPER_BLOCK; 178 179 #define MAXPARTITIONS 16 /* number of partitions */ 180 #define NDDATA 5 181 #define NSPARE 5 182 183 typedef struct disklabel { 184 UINT32 d_magic; /* the magic number */ 185 UINT16 d_type; /* drive type */ 186 UINT16 d_subtype; /* controller/d_type specific */ 187 char d_typename[16]; /* type name, e.g. "eagle" */ 188 189 /* 190 * d_packname contains the pack identifier and is returned when 191 * the disklabel is read off the disk or in-core copy. 192 * d_boot0 and d_boot1 are the (optional) names of the 193 * primary (block 0) and secondary (block 1-15) bootstraps 194 * as found in /usr/mdec. These are returned when using 195 * getdiskbyname(3) to retrieve the values from /etc/disktab. 196 */ 197 union { 198 char un_d_packname[16]; /* pack identifier */ 199 struct { 200 char *un_d_boot0; /* primary bootstrap name */ 201 char *un_d_boot1; /* secondary bootstrap name */ 202 } un_b; 203 } d_un; 204 205 /* disk geometry: */ 206 UINT32 d_secsize; /* # of bytes per sector */ 207 UINT32 d_nsectors; /* # of data sectors per track */ 208 UINT32 d_ntracks; /* # of tracks per cylinder */ 209 UINT32 d_ncylinders; /* # of data cylinders per unit */ 210 UINT32 d_secpercyl; /* # of data sectors per cylinder */ 211 UINT32 d_secperunit; /* # of data sectors per unit */ 212 213 /* 214 * Spares (bad sector replacements) below are not counted in 215 * d_nsectors or d_secpercyl. Spare sectors are assumed to 216 * be physical sectors which occupy space at the end of each 217 * track and/or cylinder. 218 */ 219 UINT16 d_sparespertrack; /* # of spare sectors per track */ 220 UINT16 d_sparespercyl; /* # of spare sectors per cylinder */ 221 /* 222 * Alternative cylinders include maintenance, replacement, 223 * configuration description areas, etc. 224 */ 225 UINT32 d_acylinders; /* # of alt. cylinders per unit */ 226 227 /* hardware characteristics: */ 228 /* 229 * d_interleave, d_trackskew and d_cylskew describe perturbations 230 * in the media format used to compensate for a slow controller. 231 * Interleave is physical sector interleave, set up by the 232 * formatter or controller when formatting. When interleaving is 233 * in use, logically adjacent sectors are not physically 234 * contiguous, but instead are separated by some number of 235 * sectors. It is specified as the ratio of physical sectors 236 * traversed per logical sector. Thus an interleave of 1:1 237 * implies contiguous layout, while 2:1 implies that logical 238 * sector 0 is separated by one sector from logical sector 1. 239 * d_trackskew is the offset of sector 0 on track N relative to 240 * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew 241 * is the offset of sector 0 on cylinder N relative to sector 0 242 * on cylinder N-1. 243 */ 244 UINT16 d_rpm; /* rotational speed */ 245 UINT16 d_interleave; /* hardware sector interleave */ 246 UINT16 d_trackskew; /* sector 0 skew, per track */ 247 UINT16 d_cylskew; /* sector 0 skew, per cylinder */ 248 UINT32 d_headswitch; /* head switch time, usec */ 249 UINT32 d_trkseek; /* track-to-track seek, usec */ 250 UINT32 d_flags; /* generic flags */ 251 UINT32 d_drivedata[NDDATA]; /* drive-type specific information */ 252 UINT32 d_spare[NSPARE]; /* reserved for future use */ 253 UINT32 d_magic2; /* the magic number (again) */ 254 UINT16 d_checksum; /* xor of data incl. partitions */ 255 256 /* filesystem and partition information: */ 257 UINT16 d_npartitions; /* number of partitions in following */ 258 UINT32 d_bbsize; /* size of boot area at sn0, bytes */ 259 UINT32 d_sbsize; /* max size of fs superblock, bytes */ 260 struct partition { /* the partition table */ 261 UINT32 p_size; /* number of sectors in partition */ 262 UINT32 p_offset; /* starting sector */ 263 union { 264 UINT32 fsize; /* FFS, ADOS: 265 filesystem basic fragment size */ 266 UINT32 cdsession; /* ISO9660: session offset */ 267 } __partition_u2; 268 UINT8 p_fstype; /* filesystem type, see below */ 269 UINT8 p_frag; /* filesystem fragments per block */ 270 union { 271 UINT16 cpg; /* UFS: FS cylinders per group */ 272 UINT16 sgs; /* LFS: FS segment shift */ 273 } __partition_u1; 274 } d_partitions[MAXPARTITIONS]; /* actually may be more */ 275 } FFSD_DISKLABEL, *PFFSD_DISKLABEL; 276 #include <poppack.h> 277 278 C_ASSERT(FIELD_OFFSET(FFSD_SUPER_BLOCK, fs_cgsize) == 160); 279 C_ASSERT(FIELD_OFFSET(FFSD_SUPER_BLOCK, fs_fmod) == 208); 280 C_ASSERT(FIELD_OFFSET(FFSD_SUPER_BLOCK, fs_ocsp) == 728); 281 282 #define SBLOCK_UFS1 8192 283 #define SBLOCK_UFS2 65536 284 285 #define SBLOCKSIZE 8192 286 287 /* 288 * File system identification 289 */ 290 #define FS_UFS1_MAGIC 0x011954 /* UFS1 fast file system magic number */ 291 #define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast file system magic number */ 292 293 #define DISKMAGIC ((UINT32)0x82564557) /* The disk magic number */ 294 295 #define LABELSECTOR 1 /* sector containing label */ 296 297 #define FS_BSDFFS 7 /* 4.2BSD fast file system */ 298