+/*
+ * find a block of the specified size in the specified cylinder group
+ * It is a panic if a request is made to find a block if none are
+ * available.
+ */
+daddr_t
+mapsearch(fs, cgp, bpref, allocsiz)
+ register struct fs *fs;
+ register struct cg *cgp;
+ daddr_t bpref;
+ int allocsiz;
+{
+ daddr_t bno;
+ int start, len, loc, i;
+ int blk, field, subfield, pos;
+
+ /*
+ * find the fragment by searching through the free block
+ * map for an appropriate bit pattern
+ */
+ if (bpref)
+ start = bpref % fs->fs_fpg / NBBY;
+ else
+ start = cgp->cg_frotor / NBBY;
+ len = roundup(fs->fs_fpg - 1, NBBY) / NBBY - start;
+ loc = scanc(len, &cgp->cg_free[start], fragtbl, 1 << (allocsiz - 1));
+ if (loc == 0) {
+ len = start - 1;
+ start = (cgdmin(cgp->cg_cgx, fs) -
+ cgbase(cgp->cg_cgx, fs)) / NBBY;
+ loc = scanc(len, &cgp->cg_free[start], fragtbl,
+ 1 << (allocsiz - 1));
+ if (loc == 0) {
+ panic("alloccg: map corrupted");
+ return (0);
+ }
+ }
+ bno = (start + len - loc) * NBBY;
+ cgp->cg_frotor = bno;
+ /*
+ * found the byte in the map
+ * sift through the bits to find the selected frag
+ */
+ for (i = 0; i < NBBY; i += FRAG) {
+ blk = (cgp->cg_free[bno / NBBY] >> i) & (0xff >> NBBY - FRAG);
+ blk <<= 1;
+ field = around[allocsiz];
+ subfield = inside[allocsiz];
+ for (pos = 0; pos <= FRAG - allocsiz; pos++) {
+ if ((blk & field) == subfield) {
+ return (bno + i + pos);
+ }
+ field <<= 1;
+ subfield <<= 1;
+ }
+ }
+ panic("alloccg: block not in map");
+ return (0);
+}
+