The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ufs/ffs/ffs_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 534d83a454d820136ce469b138faf5c4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.