1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1982, 1986, 1989, 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 32 #include <sys/param.h> 33 #include <sys/endian.h> 34 #include <sys/limits.h> 35 36 #ifndef _KERNEL 37 #include <stdio.h> 38 #include <string.h> 39 #include <stdlib.h> 40 #include <time.h> 41 #include <sys/errno.h> 42 #include <ufs/ufs/dinode.h> 43 #include <ufs/ffs/fs.h> 44 45 uint32_t calculate_crc32c(uint32_t, const void *, size_t); 46 uint32_t ffs_calc_sbhash(struct fs *); 47 struct malloc_type; 48 #define UFS_MALLOC(size, type, flags) malloc(size) 49 #define UFS_FREE(ptr, type) free(ptr) 50 #define maxphys MAXPHYS 51 52 #else /* _KERNEL */ 53 #include <sys/systm.h> 54 #include <sys/gsb_crc32.h> 55 #include <sys/lock.h> 56 #include <sys/malloc.h> 57 #include <sys/mount.h> 58 #include <sys/vnode.h> 59 #include <sys/bio.h> 60 #include <sys/buf.h> 61 #include <sys/ucred.h> 62 63 #include <ufs/ufs/quota.h> 64 #include <ufs/ufs/inode.h> 65 #include <ufs/ufs/extattr.h> 66 #include <ufs/ufs/ufsmount.h> 67 #include <ufs/ufs/ufs_extern.h> 68 #include <ufs/ffs/ffs_extern.h> 69 #include <ufs/ffs/fs.h> 70 71 #define UFS_MALLOC(size, type, flags) malloc(size, type, flags) 72 #define UFS_FREE(ptr, type) free(ptr, type) 73 74 #endif /* _KERNEL */ 75 76 /* 77 * Verify an inode check-hash. 78 */ 79 int 80 ffs_verify_dinode_ckhash(struct fs *fs, struct ufs2_dinode *dip) 81 { 82 uint32_t ckhash, save_ckhash; 83 84 /* 85 * Return success if unallocated or we are not doing inode check-hash. 86 */ 87 if (dip->di_mode == 0 || (fs->fs_metackhash & CK_INODE) == 0) 88 return (0); 89 /* 90 * Exclude di_ckhash from the crc32 calculation, e.g., always use 91 * a check-hash value of zero when calculating the check-hash. 92 */ 93 save_ckhash = dip->di_ckhash; 94 dip->di_ckhash = 0; 95 ckhash = calculate_crc32c(~0L, (void *)dip, sizeof(*dip)); 96 dip->di_ckhash = save_ckhash; 97 if (save_ckhash == ckhash) 98 return (0); 99 return (EINVAL); 100 } 101 102 /* 103 * Update an inode check-hash. 104 */ 105 void 106 ffs_update_dinode_ckhash(struct fs *fs, struct ufs2_dinode *dip) 107 { 108 109 if (dip->di_mode == 0 || (fs->fs_metackhash & CK_INODE) == 0) 110 return; 111 /* 112 * Exclude old di_ckhash from the crc32 calculation, e.g., always use 113 * a check-hash value of zero when calculating the new check-hash. 114 */ 115 dip->di_ckhash = 0; 116 dip->di_ckhash = calculate_crc32c(~0L, (void *)dip, sizeof(*dip)); 117 } 118 119 /* 120 * These are the low-level functions that actually read and write 121 * the superblock and its associated data. 122 */ 123 static off_t sblock_try[] = SBLOCKSEARCH; 124 static int readsuper(void *, struct fs **, off_t, int, 125 int (*)(void *, off_t, void **, int)); 126 static void ffs_oldfscompat_read(struct fs *, ufs2_daddr_t); 127 static int validate_sblock(struct fs *, int); 128 129 /* 130 * Read a superblock from the devfd device. 131 * 132 * If an alternate superblock is specified, it is read. Otherwise the 133 * set of locations given in the SBLOCKSEARCH list is searched for a 134 * superblock. Memory is allocated for the superblock by the readfunc and 135 * is returned. If filltype is non-NULL, additional memory is allocated 136 * of type filltype and filled in with the superblock summary information. 137 * All memory is freed when any error is returned. 138 * 139 * If a superblock is found, zero is returned. Otherwise one of the 140 * following error values is returned: 141 * EIO: non-existent or truncated superblock. 142 * EIO: error reading summary information. 143 * ENOENT: no usable known superblock found. 144 * EILSEQ: filesystem with wrong byte order found. 145 * ENOMEM: failed to allocate space for the superblock. 146 * EINVAL: The previous newfs operation on this volume did not complete. 147 * The administrator must complete newfs before using this volume. 148 */ 149 int 150 ffs_sbget(void *devfd, struct fs **fsp, off_t sblock, int flags, 151 struct malloc_type *filltype, 152 int (*readfunc)(void *devfd, off_t loc, void **bufp, int size)) 153 { 154 struct fs *fs; 155 struct fs_summary_info *fs_si; 156 int i, error; 157 uint64_t size, blks; 158 uint8_t *space; 159 int32_t *lp; 160 char *buf; 161 162 fs = NULL; 163 *fsp = NULL; 164 if (sblock != UFS_STDSB) { 165 if ((error = readsuper(devfd, &fs, sblock, 166 flags | UFS_ALTSBLK, readfunc)) != 0) { 167 if (fs != NULL) 168 UFS_FREE(fs, filltype); 169 return (error); 170 } 171 } else { 172 for (i = 0; sblock_try[i] != -1; i++) { 173 if ((error = readsuper(devfd, &fs, sblock_try[i], 174 flags, readfunc)) == 0) { 175 if ((flags & UFS_NOCSUM) != 0) { 176 *fsp = fs; 177 return (0); 178 } 179 break; 180 } 181 if (fs != NULL) { 182 UFS_FREE(fs, filltype); 183 fs = NULL; 184 } 185 if (error == ENOENT) 186 continue; 187 return (error); 188 } 189 if (sblock_try[i] == -1) 190 return (ENOENT); 191 } 192 /* 193 * Read in the superblock summary information. 194 */ 195 size = fs->fs_cssize; 196 blks = howmany(size, fs->fs_fsize); 197 if (fs->fs_contigsumsize > 0) 198 size += fs->fs_ncg * sizeof(int32_t); 199 size += fs->fs_ncg * sizeof(uint8_t); 200 if ((fs_si = UFS_MALLOC(sizeof(*fs_si), filltype, M_NOWAIT)) == NULL) { 201 UFS_FREE(fs, filltype); 202 return (ENOMEM); 203 } 204 bzero(fs_si, sizeof(*fs_si)); 205 fs->fs_si = fs_si; 206 if ((space = UFS_MALLOC(size, filltype, M_NOWAIT)) == NULL) { 207 UFS_FREE(fs->fs_si, filltype); 208 UFS_FREE(fs, filltype); 209 return (ENOMEM); 210 } 211 fs->fs_csp = (struct csum *)space; 212 for (i = 0; i < blks; i += fs->fs_frag) { 213 size = fs->fs_bsize; 214 if (i + fs->fs_frag > blks) 215 size = (blks - i) * fs->fs_fsize; 216 buf = NULL; 217 error = (*readfunc)(devfd, 218 dbtob(fsbtodb(fs, fs->fs_csaddr + i)), (void **)&buf, size); 219 if (error) { 220 if (buf != NULL) 221 UFS_FREE(buf, filltype); 222 UFS_FREE(fs->fs_csp, filltype); 223 UFS_FREE(fs->fs_si, filltype); 224 UFS_FREE(fs, filltype); 225 return (error); 226 } 227 memcpy(space, buf, size); 228 UFS_FREE(buf, filltype); 229 space += size; 230 } 231 if (fs->fs_contigsumsize > 0) { 232 fs->fs_maxcluster = lp = (int32_t *)space; 233 for (i = 0; i < fs->fs_ncg; i++) 234 *lp++ = fs->fs_contigsumsize; 235 space = (uint8_t *)lp; 236 } 237 size = fs->fs_ncg * sizeof(uint8_t); 238 fs->fs_contigdirs = (uint8_t *)space; 239 bzero(fs->fs_contigdirs, size); 240 *fsp = fs; 241 return (0); 242 } 243 244 /* 245 * Try to read a superblock from the location specified by sblockloc. 246 * Return zero on success or an errno on failure. 247 */ 248 static int 249 readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int flags, 250 int (*readfunc)(void *devfd, off_t loc, void **bufp, int size)) 251 { 252 struct fs *fs; 253 int error, res; 254 uint32_t ckhash; 255 256 error = (*readfunc)(devfd, sblockloc, (void **)fsp, SBLOCKSIZE); 257 if (error != 0) 258 return (error); 259 fs = *fsp; 260 if (fs->fs_magic == FS_BAD_MAGIC) 261 return (EINVAL); 262 /* 263 * For UFS1 with a 65536 block size, the first backup superblock 264 * is at the same location as the UFS2 superblock. Since SBLOCK_UFS2 265 * is the first location checked, the first backup is the superblock 266 * that will be accessed. Here we fail the lookup so that we can 267 * retry with the correct location for the UFS1 superblock. 268 */ 269 if (fs->fs_magic == FS_UFS1_MAGIC && (flags & UFS_ALTSBLK) == 0 && 270 fs->fs_bsize == SBLOCK_UFS2 && sblockloc == SBLOCK_UFS2) 271 return (ENOENT); 272 ffs_oldfscompat_read(fs, sblockloc); 273 if ((error = validate_sblock(fs, flags)) > 0) 274 return (error); 275 /* 276 * If the filesystem has been run on a kernel without 277 * metadata check hashes, disable them. 278 */ 279 if ((fs->fs_flags & FS_METACKHASH) == 0) 280 fs->fs_metackhash = 0; 281 /* 282 * Clear any check-hashes that are not maintained 283 * by this kernel. Also clear any unsupported flags. 284 */ 285 fs->fs_metackhash &= CK_SUPPORTED; 286 fs->fs_flags &= FS_SUPPORTED; 287 if (fs->fs_ckhash != (ckhash = ffs_calc_sbhash(fs))) { 288 if ((flags & (UFS_NOMSG | UFS_NOHASHFAIL)) == 289 (UFS_NOMSG | UFS_NOHASHFAIL)) 290 return (0); 291 if ((flags & UFS_NOMSG) != 0) 292 return (EINTEGRITY); 293 #ifdef _KERNEL 294 res = uprintf("Superblock check-hash failed: recorded " 295 "check-hash 0x%x != computed check-hash 0x%x%s\n", 296 fs->fs_ckhash, ckhash, 297 (flags & UFS_NOHASHFAIL) != 0 ? " (Ignored)" : ""); 298 #else 299 res = 0; 300 #endif 301 /* 302 * Print check-hash failure if no controlling terminal 303 * in kernel or always if in user-mode (libufs). 304 */ 305 if (res == 0) 306 printf("Superblock check-hash failed: recorded " 307 "check-hash 0x%x != computed check-hash " 308 "0x%x%s\n", fs->fs_ckhash, ckhash, 309 (flags & UFS_NOHASHFAIL) ? " (Ignored)" : ""); 310 if ((flags & UFS_NOHASHFAIL) != 0) 311 return (0); 312 return (EINTEGRITY); 313 } 314 /* Have to set for old filesystems that predate this field */ 315 fs->fs_sblockactualloc = sblockloc; 316 /* Not yet any summary information */ 317 fs->fs_si = NULL; 318 return (0); 319 } 320 321 /* 322 * Sanity checks for loading old filesystem superblocks. 323 * See ffs_oldfscompat_write below for unwound actions. 324 * 325 * XXX - Parts get retired eventually. 326 * Unfortunately new bits get added. 327 */ 328 static void 329 ffs_oldfscompat_read(struct fs *fs, ufs2_daddr_t sblockloc) 330 { 331 uint64_t maxfilesize; 332 333 /* 334 * If not yet done, update fs_flags location and value of fs_sblockloc. 335 */ 336 if ((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { 337 fs->fs_flags = fs->fs_old_flags; 338 fs->fs_old_flags |= FS_FLAGS_UPDATED; 339 fs->fs_sblockloc = sblockloc; 340 } 341 /* 342 * If not yet done, update UFS1 superblock with new wider fields. 343 */ 344 if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_maxbsize != fs->fs_bsize) { 345 fs->fs_maxbsize = fs->fs_bsize; 346 fs->fs_time = fs->fs_old_time; 347 fs->fs_size = fs->fs_old_size; 348 fs->fs_dsize = fs->fs_old_dsize; 349 fs->fs_csaddr = fs->fs_old_csaddr; 350 fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir; 351 fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree; 352 fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree; 353 fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree; 354 } 355 if (fs->fs_magic == FS_UFS1_MAGIC && 356 fs->fs_old_inodefmt < FS_44INODEFMT) { 357 fs->fs_maxfilesize = ((uint64_t)1 << 31) - 1; 358 fs->fs_qbmask = ~fs->fs_bmask; 359 fs->fs_qfmask = ~fs->fs_fmask; 360 } 361 if (fs->fs_magic == FS_UFS1_MAGIC) { 362 fs->fs_save_maxfilesize = fs->fs_maxfilesize; 363 maxfilesize = (uint64_t)0x80000000 * fs->fs_bsize - 1; 364 if (fs->fs_maxfilesize > maxfilesize) 365 fs->fs_maxfilesize = maxfilesize; 366 } 367 /* Compatibility for old filesystems */ 368 if (fs->fs_avgfilesize <= 0) 369 fs->fs_avgfilesize = AVFILESIZ; 370 if (fs->fs_avgfpdir <= 0) 371 fs->fs_avgfpdir = AFPDIR; 372 } 373 374 /* 375 * Unwinding superblock updates for old filesystems. 376 * See ffs_oldfscompat_read above for details. 377 * 378 * XXX - Parts get retired eventually. 379 * Unfortunately new bits get added. 380 */ 381 void 382 ffs_oldfscompat_write(struct fs *fs) 383 { 384 385 /* 386 * Copy back UFS2 updated fields that UFS1 inspects. 387 */ 388 if (fs->fs_magic == FS_UFS1_MAGIC) { 389 fs->fs_old_time = fs->fs_time; 390 fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir; 391 fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree; 392 fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree; 393 fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree; 394 fs->fs_maxfilesize = fs->fs_save_maxfilesize; 395 } 396 } 397 398 /* 399 * Verify the filesystem values. 400 */ 401 #define ILOG2(num) (fls(num) - 1) 402 #ifdef STANDALONE_SMALL 403 #define MPRINT(...) do { } while (0) 404 #else 405 #define MPRINT(...) if (prtmsg) printf(__VA_ARGS__) 406 #endif 407 #define FCHK(lhs, op, rhs, fmt) \ 408 if (lhs op rhs) { \ 409 MPRINT("UFS%d superblock failed: %s (" #fmt ") %s %s (" \ 410 #fmt ")\n", fs->fs_magic == FS_UFS1_MAGIC ? 1 : 2, \ 411 #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs); \ 412 if (error < 0) \ 413 return (ENOENT); \ 414 if (error == 0) \ 415 error = ENOENT; \ 416 } 417 #define WCHK(lhs, op, rhs, fmt) \ 418 if (lhs op rhs) { \ 419 MPRINT("UFS%d superblock failed: %s (" #fmt ") %s %s (" \ 420 #fmt ")%s\n", fs->fs_magic == FS_UFS1_MAGIC ? 1 : 2,\ 421 #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs, wmsg);\ 422 if (error == 0) \ 423 error = warnerr; \ 424 if (warnerr == 0) \ 425 lhs = rhs; \ 426 } 427 #define FCHK2(lhs1, op1, rhs1, lhs2, op2, rhs2, fmt) \ 428 if (lhs1 op1 rhs1 && lhs2 op2 rhs2) { \ 429 MPRINT("UFS%d superblock failed: %s (" #fmt ") %s %s (" \ 430 #fmt ") && %s (" #fmt ") %s %s (" #fmt ")\n", \ 431 fs->fs_magic == FS_UFS1_MAGIC ? 1 : 2, #lhs1, \ 432 (intmax_t)lhs1, #op1, #rhs1, (intmax_t)rhs1, #lhs2, \ 433 (intmax_t)lhs2, #op2, #rhs2, (intmax_t)rhs2); \ 434 if (error < 0) \ 435 return (ENOENT); \ 436 if (error == 0) \ 437 error = ENOENT; \ 438 } 439 440 static int 441 validate_sblock(struct fs *fs, int flags) 442 { 443 uint64_t i, sectorsize; 444 uint64_t maxfilesize, sizepb; 445 int error, prtmsg, warnerr; 446 char *wmsg; 447 448 error = 0; 449 sectorsize = dbtob(1); 450 prtmsg = ((flags & UFS_NOMSG) == 0); 451 warnerr = (flags & UFS_NOWARNFAIL) == UFS_NOWARNFAIL ? 0 : ENOENT; 452 wmsg = warnerr ? "" : " (Ignored)"; 453 /* 454 * Check for endian mismatch between machine and filesystem. 455 */ 456 if (((fs->fs_magic != FS_UFS2_MAGIC) && 457 (bswap32(fs->fs_magic) == FS_UFS2_MAGIC)) || 458 ((fs->fs_magic != FS_UFS1_MAGIC) && 459 (bswap32(fs->fs_magic) == FS_UFS1_MAGIC))) { 460 MPRINT("UFS superblock failed due to endian mismatch " 461 "between machine and filesystem\n"); 462 return(EILSEQ); 463 } 464 /* 465 * If just validating for recovery, then do just the minimal 466 * checks needed for the superblock fields needed to find 467 * alternate superblocks. 468 */ 469 if ((flags & UFS_FSRONLY) == UFS_FSRONLY && 470 (fs->fs_magic == FS_UFS1_MAGIC || fs->fs_magic == FS_UFS2_MAGIC)) { 471 error = -1; /* fail on first error */ 472 if (fs->fs_magic == FS_UFS2_MAGIC) { 473 FCHK(fs->fs_sblockloc, !=, SBLOCK_UFS2, %#jx); 474 } else if (fs->fs_magic == FS_UFS1_MAGIC) { 475 FCHK(fs->fs_sblockloc, <, 0, %jd); 476 FCHK(fs->fs_sblockloc, >, SBLOCK_UFS1, %jd); 477 } 478 FCHK(fs->fs_frag, <, 1, %jd); 479 FCHK(fs->fs_frag, >, MAXFRAG, %jd); 480 FCHK(fs->fs_bsize, <, MINBSIZE, %jd); 481 FCHK(fs->fs_bsize, >, MAXBSIZE, %jd); 482 FCHK(fs->fs_bsize, <, roundup(sizeof(struct fs), DEV_BSIZE), 483 %jd); 484 FCHK(fs->fs_fsize, <, sectorsize, %jd); 485 FCHK(fs->fs_fsize * fs->fs_frag, !=, fs->fs_bsize, %jd); 486 FCHK(powerof2(fs->fs_fsize), ==, 0, %jd); 487 FCHK(fs->fs_sbsize, >, SBLOCKSIZE, %jd); 488 FCHK(fs->fs_sbsize, <, (signed)sizeof(struct fs), %jd); 489 FCHK(fs->fs_sbsize % sectorsize, !=, 0, %jd); 490 FCHK(fs->fs_fpg, <, 3 * fs->fs_frag, %jd); 491 FCHK(fs->fs_ncg, <, 1, %jd); 492 FCHK(fs->fs_fsbtodb, !=, ILOG2(fs->fs_fsize / sectorsize), %jd); 493 FCHK(fs->fs_old_cgoffset, <, 0, %jd); 494 FCHK2(fs->fs_old_cgoffset, >, 0, ~fs->fs_old_cgmask, <, 0, %jd); 495 FCHK(fs->fs_old_cgoffset * (~fs->fs_old_cgmask), >, fs->fs_fpg, 496 %jd); 497 FCHK(fs->fs_sblkno, !=, roundup( 498 howmany(fs->fs_sblockloc + SBLOCKSIZE, fs->fs_fsize), 499 fs->fs_frag), %jd); 500 FCHK(CGSIZE(fs), >, fs->fs_bsize, %jd); 501 /* Only need to validate these if reading in csum data */ 502 if ((flags & UFS_NOCSUM) != 0) 503 return (error); 504 FCHK((uint64_t)fs->fs_ipg * fs->fs_ncg, >, 505 (((int64_t)(1)) << 32) - INOPB(fs), %jd); 506 FCHK(fs->fs_cstotal.cs_nifree, <, 0, %jd); 507 FCHK(fs->fs_cstotal.cs_nifree, >, 508 (uint64_t)fs->fs_ipg * fs->fs_ncg, %jd); 509 FCHK(fs->fs_cstotal.cs_ndir, >, 510 ((uint64_t)fs->fs_ipg * fs->fs_ncg) - 511 fs->fs_cstotal.cs_nifree, %jd); 512 FCHK(fs->fs_size, <, 8 * fs->fs_frag, %jd); 513 FCHK(fs->fs_size, <=, ((int64_t)fs->fs_ncg - 1) * fs->fs_fpg, 514 %jd); 515 FCHK(fs->fs_size, >, (int64_t)fs->fs_ncg * fs->fs_fpg, %jd); 516 FCHK(fs->fs_csaddr, <, 0, %jd); 517 FCHK(fs->fs_cssize, !=, 518 fragroundup(fs, fs->fs_ncg * sizeof(struct csum)), %jd); 519 FCHK(fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize), >, 520 fs->fs_size, %jd); 521 FCHK(fs->fs_csaddr, <, cgdmin(fs, dtog(fs, fs->fs_csaddr)), 522 %jd); 523 FCHK(dtog(fs, fs->fs_csaddr + howmany(fs->fs_cssize, 524 fs->fs_fsize)), >, dtog(fs, fs->fs_csaddr), %jd); 525 return (error); 526 } 527 if (fs->fs_magic == FS_UFS2_MAGIC) { 528 if ((flags & UFS_ALTSBLK) == 0) 529 FCHK2(fs->fs_sblockactualloc, !=, SBLOCK_UFS2, 530 fs->fs_sblockactualloc, !=, 0, %jd); 531 FCHK(fs->fs_sblockloc, !=, SBLOCK_UFS2, %#jx); 532 FCHK(fs->fs_maxsymlinklen, !=, ((UFS_NDADDR + UFS_NIADDR) * 533 sizeof(ufs2_daddr_t)), %jd); 534 FCHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs2_daddr_t), 535 %jd); 536 FCHK(fs->fs_inopb, !=, 537 fs->fs_bsize / sizeof(struct ufs2_dinode), %jd); 538 } else if (fs->fs_magic == FS_UFS1_MAGIC) { 539 if ((flags & UFS_ALTSBLK) == 0) 540 FCHK(fs->fs_sblockactualloc, >, SBLOCK_UFS1, %jd); 541 FCHK(fs->fs_sblockloc, <, 0, %jd); 542 FCHK(fs->fs_sblockloc, >, SBLOCK_UFS1, %jd); 543 FCHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs1_daddr_t), 544 %jd); 545 FCHK(fs->fs_inopb, !=, 546 fs->fs_bsize / sizeof(struct ufs1_dinode), %jd); 547 FCHK(fs->fs_maxsymlinklen, !=, ((UFS_NDADDR + UFS_NIADDR) * 548 sizeof(ufs1_daddr_t)), %jd); 549 WCHK(fs->fs_old_inodefmt, !=, FS_44INODEFMT, %jd); 550 WCHK(fs->fs_old_rotdelay, !=, 0, %jd); 551 WCHK(fs->fs_old_rps, !=, 60, %jd); 552 WCHK(fs->fs_old_nspf, !=, fs->fs_fsize / sectorsize, %jd); 553 WCHK(fs->fs_old_interleave, !=, 1, %jd); 554 WCHK(fs->fs_old_trackskew, !=, 0, %jd); 555 WCHK(fs->fs_old_cpc, !=, 0, %jd); 556 WCHK(fs->fs_old_postblformat, !=, 1, %jd); 557 FCHK(fs->fs_old_nrpos, !=, 1, %jd); 558 WCHK(fs->fs_old_nsect, !=, fs->fs_old_spc, %jd); 559 WCHK(fs->fs_old_npsect, !=, fs->fs_old_spc, %jd); 560 } else { 561 /* Bad magic number, so assume not a superblock */ 562 return (ENOENT); 563 } 564 FCHK(fs->fs_bsize, <, MINBSIZE, %jd); 565 FCHK(fs->fs_bsize, >, MAXBSIZE, %jd); 566 FCHK(fs->fs_bsize, <, roundup(sizeof(struct fs), DEV_BSIZE), %jd); 567 FCHK(powerof2(fs->fs_bsize), ==, 0, %jd); 568 FCHK(fs->fs_frag, <, 1, %jd); 569 FCHK(fs->fs_frag, >, MAXFRAG, %jd); 570 FCHK(fs->fs_frag, !=, numfrags(fs, fs->fs_bsize), %jd); 571 FCHK(fs->fs_fsize, <, sectorsize, %jd); 572 FCHK(fs->fs_fsize * fs->fs_frag, !=, fs->fs_bsize, %jd); 573 FCHK(powerof2(fs->fs_fsize), ==, 0, %jd); 574 FCHK(fs->fs_fpg, <, 3 * fs->fs_frag, %jd); 575 FCHK(fs->fs_ncg, <, 1, %jd); 576 FCHK(fs->fs_ipg, <, fs->fs_inopb, %jd); 577 FCHK((uint64_t)fs->fs_ipg * fs->fs_ncg, >, 578 (((int64_t)(1)) << 32) - INOPB(fs), %jd); 579 FCHK(fs->fs_cstotal.cs_nifree, <, 0, %jd); 580 FCHK(fs->fs_cstotal.cs_nifree, >, (uint64_t)fs->fs_ipg * fs->fs_ncg, 581 %jd); 582 FCHK(fs->fs_cstotal.cs_ndir, <, 0, %jd); 583 FCHK(fs->fs_cstotal.cs_ndir, >, 584 ((uint64_t)fs->fs_ipg * fs->fs_ncg) - fs->fs_cstotal.cs_nifree, 585 %jd); 586 FCHK(fs->fs_sbsize, >, SBLOCKSIZE, %jd); 587 FCHK(fs->fs_sbsize, <, (signed)sizeof(struct fs), %jd); 588 /* fix for misconfigured filesystems */ 589 if (fs->fs_maxbsize == 0) 590 fs->fs_maxbsize = fs->fs_bsize; 591 FCHK(fs->fs_maxbsize, <, fs->fs_bsize, %jd); 592 FCHK(powerof2(fs->fs_maxbsize), ==, 0, %jd); 593 FCHK(fs->fs_maxbsize, >, FS_MAXCONTIG * fs->fs_bsize, %jd); 594 FCHK(fs->fs_bmask, !=, ~(fs->fs_bsize - 1), %#jx); 595 FCHK(fs->fs_fmask, !=, ~(fs->fs_fsize - 1), %#jx); 596 FCHK(fs->fs_qbmask, !=, ~fs->fs_bmask, %#jx); 597 FCHK(fs->fs_qfmask, !=, ~fs->fs_fmask, %#jx); 598 FCHK(fs->fs_bshift, !=, ILOG2(fs->fs_bsize), %jd); 599 FCHK(fs->fs_fshift, !=, ILOG2(fs->fs_fsize), %jd); 600 FCHK(fs->fs_fragshift, !=, ILOG2(fs->fs_frag), %jd); 601 FCHK(fs->fs_fsbtodb, !=, ILOG2(fs->fs_fsize / sectorsize), %jd); 602 FCHK(fs->fs_old_cgoffset, <, 0, %jd); 603 FCHK2(fs->fs_old_cgoffset, >, 0, ~fs->fs_old_cgmask, <, 0, %jd); 604 FCHK(fs->fs_old_cgoffset * (~fs->fs_old_cgmask), >, fs->fs_fpg, %jd); 605 FCHK(CGSIZE(fs), >, fs->fs_bsize, %jd); 606 /* 607 * If anything has failed up to this point, it is usafe to proceed 608 * as checks below may divide by zero or make other fatal calculations. 609 * So if we have any errors at this point, give up. 610 */ 611 if (error) 612 return (error); 613 FCHK(fs->fs_sbsize % sectorsize, !=, 0, %jd); 614 FCHK(fs->fs_ipg % fs->fs_inopb, !=, 0, %jd); 615 FCHK(fs->fs_sblkno, !=, roundup( 616 howmany(fs->fs_sblockloc + SBLOCKSIZE, fs->fs_fsize), 617 fs->fs_frag), %jd); 618 FCHK(fs->fs_cblkno, !=, fs->fs_sblkno + 619 roundup(howmany(SBLOCKSIZE, fs->fs_fsize), fs->fs_frag), %jd); 620 FCHK(fs->fs_iblkno, !=, fs->fs_cblkno + fs->fs_frag, %jd); 621 FCHK(fs->fs_dblkno, !=, fs->fs_iblkno + fs->fs_ipg / INOPF(fs), %jd); 622 FCHK(fs->fs_cgsize, >, fs->fs_bsize, %jd); 623 FCHK(fs->fs_cgsize, <, fs->fs_fsize, %jd); 624 FCHK(fs->fs_cgsize % fs->fs_fsize, !=, 0, %jd); 625 /* 626 * This test is valid, however older versions of growfs failed 627 * to correctly update fs_dsize so will fail this test. Thus we 628 * exclude it from the requirements. 629 */ 630 #ifdef notdef 631 WCHK(fs->fs_dsize, !=, fs->fs_size - fs->fs_sblkno - 632 fs->fs_ncg * (fs->fs_dblkno - fs->fs_sblkno) - 633 howmany(fs->fs_cssize, fs->fs_fsize), %jd); 634 #endif 635 WCHK(fs->fs_metaspace, <, 0, %jd); 636 WCHK(fs->fs_metaspace, >, fs->fs_fpg / 2, %jd); 637 WCHK(fs->fs_minfree, >, 99, %jd%%); 638 maxfilesize = fs->fs_bsize * UFS_NDADDR - 1; 639 for (sizepb = fs->fs_bsize, i = 0; i < UFS_NIADDR; i++) { 640 sizepb *= NINDIR(fs); 641 maxfilesize += sizepb; 642 } 643 WCHK(fs->fs_maxfilesize, >, maxfilesize, %jd); 644 /* 645 * These values have a tight interaction with each other that 646 * makes it hard to tightly bound them. So we can only check 647 * that they are within a broader possible range. 648 * 649 * The size cannot always be accurately determined, but ensure 650 * that it is consistent with the number of cylinder groups (fs_ncg) 651 * and the number of fragments per cylinder group (fs_fpg). Ensure 652 * that the summary information size is correct and that it starts 653 * and ends in the data area of the same cylinder group. 654 */ 655 FCHK(fs->fs_size, <, 8 * fs->fs_frag, %jd); 656 FCHK(fs->fs_size, <=, ((int64_t)fs->fs_ncg - 1) * fs->fs_fpg, %jd); 657 FCHK(fs->fs_size, >, (int64_t)fs->fs_ncg * fs->fs_fpg, %jd); 658 /* 659 * If we are not requested to read in the csum data stop here 660 * as the correctness of the remaining values is only important 661 * to bound the space needed to be allocated to hold the csum data. 662 */ 663 if ((flags & UFS_NOCSUM) != 0) 664 return (error); 665 FCHK(fs->fs_csaddr, <, 0, %jd); 666 FCHK(fs->fs_cssize, !=, 667 fragroundup(fs, fs->fs_ncg * sizeof(struct csum)), %jd); 668 FCHK(fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize), >, 669 fs->fs_size, %jd); 670 FCHK(fs->fs_csaddr, <, cgdmin(fs, dtog(fs, fs->fs_csaddr)), %jd); 671 FCHK(dtog(fs, fs->fs_csaddr + howmany(fs->fs_cssize, fs->fs_fsize)), >, 672 dtog(fs, fs->fs_csaddr), %jd); 673 /* 674 * With file system clustering it is possible to allocate 675 * many contiguous blocks. The kernel variable maxphys defines 676 * the maximum transfer size permitted by the controller and/or 677 * buffering. The fs_maxcontig parameter controls the maximum 678 * number of blocks that the filesystem will read or write 679 * in a single transfer. It is calculated when the filesystem 680 * is created as maxphys / fs_bsize. The loader uses a maxphys 681 * of 128K even when running on a system that supports larger 682 * values. If the filesystem was built on a system that supports 683 * a larger maxphys (1M is typical) it will have configured 684 * fs_maxcontig for that larger system. So we bound the upper 685 * allowable limit for fs_maxconfig to be able to at least 686 * work with a 1M maxphys on the smallest block size filesystem: 687 * 1M / 4096 == 256. There is no harm in allowing the mounting of 688 * filesystems that make larger than maxphys I/O requests because 689 * those (mostly 32-bit machines) can (very slowly) handle I/O 690 * requests that exceed maxphys. 691 */ 692 WCHK(fs->fs_maxcontig, <, 0, %jd); 693 WCHK(fs->fs_maxcontig, >, MAX(256, maxphys / fs->fs_bsize), %jd); 694 FCHK2(fs->fs_maxcontig, ==, 0, fs->fs_contigsumsize, !=, 0, %jd); 695 FCHK2(fs->fs_maxcontig, >, 1, fs->fs_contigsumsize, !=, 696 MIN(fs->fs_maxcontig, FS_MAXCONTIG), %jd); 697 return (error); 698 } 699 700 /* 701 * Make an extensive search to find a superblock. If the superblock 702 * in the standard place cannot be used, try looking for one of the 703 * backup superblocks. 704 * 705 * Flags are made up of the following or'ed together options: 706 * 707 * UFS_NOMSG indicates that superblock inconsistency error messages 708 * should not be printed. 709 * 710 * UFS_NOCSUM causes only the superblock itself to be returned, but does 711 * not read in any auxillary data structures like the cylinder group 712 * summary information. 713 */ 714 int 715 ffs_sbsearch(void *devfd, struct fs **fsp, int reqflags, 716 struct malloc_type *filltype, 717 int (*readfunc)(void *devfd, off_t loc, void **bufp, int size)) 718 { 719 struct fsrecovery *fsr; 720 struct fs *protofs; 721 void *fsrbuf; 722 char *cp; 723 long nocsum, flags, msg, cg; 724 off_t sblk, secsize; 725 int error; 726 727 msg = (reqflags & UFS_NOMSG) == 0; 728 nocsum = reqflags & UFS_NOCSUM; 729 /* 730 * Try normal superblock read and return it if it works. 731 * 732 * Suppress messages if it fails until we find out if 733 * failure can be avoided. 734 */ 735 flags = UFS_NOMSG | nocsum; 736 error = ffs_sbget(devfd, fsp, UFS_STDSB, flags, filltype, readfunc); 737 /* 738 * If successful or endian error, no need to try further. 739 */ 740 if (error == 0 || error == EILSEQ) { 741 if (msg && error == EILSEQ) 742 printf("UFS superblock failed due to endian mismatch " 743 "between machine and filesystem\n"); 744 return (error); 745 } 746 /* 747 * First try: ignoring hash failures. 748 */ 749 flags |= UFS_NOHASHFAIL; 750 if (msg) 751 flags &= ~UFS_NOMSG; 752 if (ffs_sbget(devfd, fsp, UFS_STDSB, flags, filltype, readfunc) == 0) 753 return (0); 754 /* 755 * Next up is to check if fields of the superblock that are 756 * needed to find backup superblocks are usable. 757 */ 758 if (msg) 759 printf("Attempted recovery for standard superblock: failed\n"); 760 flags = UFS_FSRONLY | UFS_NOHASHFAIL | UFS_NOCSUM | UFS_NOMSG; 761 if (ffs_sbget(devfd, &protofs, UFS_STDSB, flags, filltype, 762 readfunc) == 0) { 763 if (msg) 764 printf("Attempt extraction of recovery data from " 765 "standard superblock.\n"); 766 } else { 767 /* 768 * Final desperation is to see if alternate superblock 769 * parameters have been saved in the boot area. 770 */ 771 if (msg) 772 printf("Attempted extraction of recovery data from " 773 "standard superblock: failed\nAttempt to find " 774 "boot zone recovery data.\n"); 775 /* 776 * Look to see if recovery information has been saved. 777 * If so we can generate a prototype superblock based 778 * on that information. 779 * 780 * We need fragments-per-group, number of cylinder groups, 781 * location of the superblock within the cylinder group, and 782 * the conversion from filesystem fragments to disk blocks. 783 * 784 * When building a UFS2 filesystem, newfs(8) stores these 785 * details at the end of the boot block area at the start 786 * of the filesystem partition. If they have been overwritten 787 * by a boot block, we fail. But usually they are there 788 * and we can use them. 789 * 790 * We could ask the underlying device for its sector size, 791 * but some devices lie. So we just try a plausible range. 792 */ 793 error = ENOENT; 794 fsrbuf = NULL; 795 for (secsize = dbtob(1); secsize <= SBLOCKSIZE; secsize *= 2) 796 if ((error = (*readfunc)(devfd, (SBLOCK_UFS2 - secsize), 797 &fsrbuf, secsize)) == 0) 798 break; 799 if (error != 0) 800 goto trynowarn; 801 cp = fsrbuf; /* type change to keep compiler happy */ 802 fsr = (struct fsrecovery *)&cp[secsize - sizeof *fsr]; 803 if (fsr->fsr_magic != FS_UFS2_MAGIC || 804 (protofs = UFS_MALLOC(SBLOCKSIZE, filltype, M_NOWAIT)) 805 == NULL) { 806 UFS_FREE(fsrbuf, filltype); 807 goto trynowarn; 808 } 809 memset(protofs, 0, sizeof(struct fs)); 810 protofs->fs_fpg = fsr->fsr_fpg; 811 protofs->fs_fsbtodb = fsr->fsr_fsbtodb; 812 protofs->fs_sblkno = fsr->fsr_sblkno; 813 protofs->fs_magic = fsr->fsr_magic; 814 protofs->fs_ncg = fsr->fsr_ncg; 815 UFS_FREE(fsrbuf, filltype); 816 } 817 /* 818 * Scan looking for alternative superblocks. 819 */ 820 flags = nocsum; 821 if (!msg) 822 flags |= UFS_NOMSG; 823 for (cg = 0; cg < protofs->fs_ncg; cg++) { 824 sblk = fsbtodb(protofs, cgsblock(protofs, cg)); 825 if (msg) 826 printf("Try cg %ld at sblock loc %jd\n", cg, 827 (intmax_t)sblk); 828 if (ffs_sbget(devfd, fsp, dbtob(sblk), flags, filltype, 829 readfunc) == 0) { 830 if (msg) 831 printf("Succeeded with alternate superblock " 832 "at %jd\n", (intmax_t)sblk); 833 UFS_FREE(protofs, filltype); 834 return (0); 835 } 836 } 837 UFS_FREE(protofs, filltype); 838 /* 839 * Our alternate superblock strategies failed. Our last ditch effort 840 * is to see if the standard superblock has only non-critical errors. 841 */ 842 trynowarn: 843 flags = UFS_NOWARNFAIL | UFS_NOMSG | nocsum; 844 if (msg) { 845 printf("Finding an alternate superblock failed.\nCheck for " 846 "only non-critical errors in standard superblock\n"); 847 flags &= ~UFS_NOMSG; 848 } 849 if (ffs_sbget(devfd, fsp, UFS_STDSB, flags, filltype, readfunc) != 0) { 850 if (msg) 851 printf("Failed, superblock has critical errors\n"); 852 return (ENOENT); 853 } 854 if (msg) 855 printf("Success, using standard superblock with " 856 "non-critical errors.\n"); 857 return (0); 858 } 859 860 /* 861 * Write a superblock to the devfd device from the memory pointed to by fs. 862 * Write out the superblock summary information if it is present. 863 * 864 * If the write is successful, zero is returned. Otherwise one of the 865 * following error values is returned: 866 * EIO: failed to write superblock. 867 * EIO: failed to write superblock summary information. 868 */ 869 int 870 ffs_sbput(void *devfd, struct fs *fs, off_t loc, 871 int (*writefunc)(void *devfd, off_t loc, void *buf, int size)) 872 { 873 int i, error, blks, size; 874 uint8_t *space; 875 876 /* 877 * If there is summary information, write it first, so if there 878 * is an error, the superblock will not be marked as clean. 879 */ 880 if (fs->fs_si != NULL && fs->fs_csp != NULL) { 881 blks = howmany(fs->fs_cssize, fs->fs_fsize); 882 space = (uint8_t *)fs->fs_csp; 883 for (i = 0; i < blks; i += fs->fs_frag) { 884 size = fs->fs_bsize; 885 if (i + fs->fs_frag > blks) 886 size = (blks - i) * fs->fs_fsize; 887 if ((error = (*writefunc)(devfd, 888 dbtob(fsbtodb(fs, fs->fs_csaddr + i)), 889 space, size)) != 0) 890 return (error); 891 space += size; 892 } 893 } 894 fs->fs_fmod = 0; 895 #ifndef _KERNEL 896 { 897 struct fs_summary_info *fs_si; 898 899 fs->fs_time = time(NULL); 900 /* Clear the pointers for the duration of writing. */ 901 fs_si = fs->fs_si; 902 fs->fs_si = NULL; 903 fs->fs_ckhash = ffs_calc_sbhash(fs); 904 error = (*writefunc)(devfd, loc, fs, fs->fs_sbsize); 905 fs->fs_si = fs_si; 906 } 907 #else /* _KERNEL */ 908 fs->fs_time = time_second; 909 fs->fs_ckhash = ffs_calc_sbhash(fs); 910 error = (*writefunc)(devfd, loc, fs, fs->fs_sbsize); 911 #endif /* _KERNEL */ 912 return (error); 913 } 914 915 /* 916 * Calculate the check-hash for a superblock. 917 */ 918 uint32_t 919 ffs_calc_sbhash(struct fs *fs) 920 { 921 uint32_t ckhash, save_ckhash; 922 923 /* 924 * A filesystem that was using a superblock ckhash may be moved 925 * to an older kernel that does not support ckhashes. The 926 * older kernel will clear the FS_METACKHASH flag indicating 927 * that it does not update hashes. When the disk is moved back 928 * to a kernel capable of ckhashes it disables them on mount: 929 * 930 * if ((fs->fs_flags & FS_METACKHASH) == 0) 931 * fs->fs_metackhash = 0; 932 * 933 * This leaves (fs->fs_metackhash & CK_SUPERBLOCK) == 0) with an 934 * old stale value in the fs->fs_ckhash field. Thus the need to 935 * just accept what is there. 936 */ 937 if ((fs->fs_metackhash & CK_SUPERBLOCK) == 0) 938 return (fs->fs_ckhash); 939 940 save_ckhash = fs->fs_ckhash; 941 fs->fs_ckhash = 0; 942 /* 943 * If newly read from disk, the caller is responsible for 944 * verifying that fs->fs_sbsize <= SBLOCKSIZE. 945 */ 946 ckhash = calculate_crc32c(~0L, (void *)fs, fs->fs_sbsize); 947 fs->fs_ckhash = save_ckhash; 948 return (ckhash); 949 } 950 951 /* 952 * Update the frsum fields to reflect addition or deletion 953 * of some frags. 954 */ 955 void 956 ffs_fragacct(struct fs *fs, int fragmap, int32_t fraglist[], int cnt) 957 { 958 int inblk; 959 int field, subfield; 960 int siz, pos; 961 962 inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 963 fragmap <<= 1; 964 for (siz = 1; siz < fs->fs_frag; siz++) { 965 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 966 continue; 967 field = around[siz]; 968 subfield = inside[siz]; 969 for (pos = siz; pos <= fs->fs_frag; pos++) { 970 if ((fragmap & field) == subfield) { 971 fraglist[siz] += cnt; 972 pos += siz; 973 field <<= siz; 974 subfield <<= siz; 975 } 976 field <<= 1; 977 subfield <<= 1; 978 } 979 } 980 } 981 982 /* 983 * block operations 984 * 985 * check if a block is available 986 */ 987 int 988 ffs_isblock(struct fs *fs, unsigned char *cp, ufs1_daddr_t h) 989 { 990 unsigned char mask; 991 992 switch ((int)fs->fs_frag) { 993 case 8: 994 return (cp[h] == 0xff); 995 case 4: 996 mask = 0x0f << ((h & 0x1) << 2); 997 return ((cp[h >> 1] & mask) == mask); 998 case 2: 999 mask = 0x03 << ((h & 0x3) << 1); 1000 return ((cp[h >> 2] & mask) == mask); 1001 case 1: 1002 mask = 0x01 << (h & 0x7); 1003 return ((cp[h >> 3] & mask) == mask); 1004 default: 1005 #ifdef _KERNEL 1006 panic("ffs_isblock"); 1007 #endif 1008 break; 1009 } 1010 return (0); 1011 } 1012 1013 /* 1014 * check if a block is free 1015 */ 1016 int 1017 ffs_isfreeblock(struct fs *fs, uint8_t *cp, ufs1_daddr_t h) 1018 { 1019 1020 switch ((int)fs->fs_frag) { 1021 case 8: 1022 return (cp[h] == 0); 1023 case 4: 1024 return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0); 1025 case 2: 1026 return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0); 1027 case 1: 1028 return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0); 1029 default: 1030 #ifdef _KERNEL 1031 panic("ffs_isfreeblock"); 1032 #endif 1033 break; 1034 } 1035 return (0); 1036 } 1037 1038 /* 1039 * take a block out of the map 1040 */ 1041 void 1042 ffs_clrblock(struct fs *fs, uint8_t *cp, ufs1_daddr_t h) 1043 { 1044 1045 switch ((int)fs->fs_frag) { 1046 case 8: 1047 cp[h] = 0; 1048 return; 1049 case 4: 1050 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1051 return; 1052 case 2: 1053 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1054 return; 1055 case 1: 1056 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1057 return; 1058 default: 1059 #ifdef _KERNEL 1060 panic("ffs_clrblock"); 1061 #endif 1062 break; 1063 } 1064 } 1065 1066 /* 1067 * put a block into the map 1068 */ 1069 void 1070 ffs_setblock(struct fs *fs, unsigned char *cp, ufs1_daddr_t h) 1071 { 1072 1073 switch ((int)fs->fs_frag) { 1074 case 8: 1075 cp[h] = 0xff; 1076 return; 1077 case 4: 1078 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1079 return; 1080 case 2: 1081 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 1082 return; 1083 case 1: 1084 cp[h >> 3] |= (0x01 << (h & 0x7)); 1085 return; 1086 default: 1087 #ifdef _KERNEL 1088 panic("ffs_setblock"); 1089 #endif 1090 break; 1091 } 1092 } 1093 1094 /* 1095 * Update the cluster map because of an allocation or free. 1096 * 1097 * Cnt == 1 means free; cnt == -1 means allocating. 1098 */ 1099 void 1100 ffs_clusteracct(struct fs *fs, struct cg *cgp, ufs1_daddr_t blkno, int cnt) 1101 { 1102 int32_t *sump; 1103 int32_t *lp; 1104 uint8_t *freemapp, *mapp; 1105 int i, start, end, forw, back, map; 1106 uint64_t bit; 1107 1108 if (fs->fs_contigsumsize <= 0) 1109 return; 1110 freemapp = cg_clustersfree(cgp); 1111 sump = cg_clustersum(cgp); 1112 /* 1113 * Allocate or clear the actual block. 1114 */ 1115 if (cnt > 0) 1116 setbit(freemapp, blkno); 1117 else 1118 clrbit(freemapp, blkno); 1119 /* 1120 * Find the size of the cluster going forward. 1121 */ 1122 start = blkno + 1; 1123 end = start + fs->fs_contigsumsize; 1124 if (end >= cgp->cg_nclusterblks) 1125 end = cgp->cg_nclusterblks; 1126 mapp = &freemapp[start / NBBY]; 1127 map = *mapp++; 1128 bit = 1U << (start % NBBY); 1129 for (i = start; i < end; i++) { 1130 if ((map & bit) == 0) 1131 break; 1132 if ((i & (NBBY - 1)) != (NBBY - 1)) { 1133 bit <<= 1; 1134 } else { 1135 map = *mapp++; 1136 bit = 1; 1137 } 1138 } 1139 forw = i - start; 1140 /* 1141 * Find the size of the cluster going backward. 1142 */ 1143 start = blkno - 1; 1144 end = start - fs->fs_contigsumsize; 1145 if (end < 0) 1146 end = -1; 1147 mapp = &freemapp[start / NBBY]; 1148 map = *mapp--; 1149 bit = 1U << (start % NBBY); 1150 for (i = start; i > end; i--) { 1151 if ((map & bit) == 0) 1152 break; 1153 if ((i & (NBBY - 1)) != 0) { 1154 bit >>= 1; 1155 } else { 1156 map = *mapp--; 1157 bit = 1U << (NBBY - 1); 1158 } 1159 } 1160 back = start - i; 1161 /* 1162 * Account for old cluster and the possibly new forward and 1163 * back clusters. 1164 */ 1165 i = back + forw + 1; 1166 if (i > fs->fs_contigsumsize) 1167 i = fs->fs_contigsumsize; 1168 sump[i] += cnt; 1169 if (back > 0) 1170 sump[back] -= cnt; 1171 if (forw > 0) 1172 sump[forw] -= cnt; 1173 /* 1174 * Update cluster summary information. 1175 */ 1176 lp = &sump[fs->fs_contigsumsize]; 1177 for (i = fs->fs_contigsumsize; i > 0; i--) 1178 if (*lp-- > 0) 1179 break; 1180 fs->fs_maxcluster[cgp->cg_cgx] = i; 1181 } 1182