xref: /freebsd/sys/ufs/ffs/ffs_subr.c (revision 661ca921e8cd56b17fc6615bc7e596e56e0e7c31)
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