static daddr_t ext2fs_mapsearch(struct m_ext2fs *fs, char *bbp, daddr_t bpref) { int start, len, loc, i, map; /* * find the fragment by searching through the free block * map for an appropriate bit pattern */ if (bpref) start = dtogd(fs, bpref) / NBBY; else start = 0; len = howmany(fs->e2fs.e2fs_fpg, NBBY) - start; loc = skpc(0xff, len, &bbp[start]); if (loc == 0) { len = start + 1; start = 0; loc = skpc(0xff, len, &bbp[start]); if (loc == 0) { printf("start = %d, len = %d, fs = %s\n", start, len, fs->e2fs_fsmnt); panic("ext2fs_alloccg: map corrupted"); /* NOTREACHED */ } } i = start + len - loc; map = bbp[i] ^ 0xff; if (map == 0) { printf("fs = %s\n", fs->e2fs_fsmnt); panic("ext2fs_mapsearch: block not in map"); } return i * NBBY + ffs(map) - 1; }
/* * Determine whether an inode can be allocated. * * Check to see if an inode is available, and if it is, * allocate it using the following policy: * 1) allocate the requested inode. * 2) allocate the next available inode after the requested * inode in the specified cylinder group. */ static daddr_t ext2fs_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) { struct m_ext2fs *fs; char *ibp; struct buf *bp; int error, start, len, loc, map, i; ipref--; /* to avoid a lot of (ipref -1) */ if (ipref == -1) ipref = 0; fs = ip->i_e2fs; if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) return (0); error = bread(ip->i_devvp, fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_i_bitmap), (int)fs->e2fs_bsize, NOCRED, B_MODIFY, &bp); if (error) { brelse(bp, 0); return (0); } ibp = (char *)bp->b_data; if (ipref) { ipref %= fs->e2fs.e2fs_ipg; if (isclr(ibp, ipref)) goto gotit; } start = ipref / NBBY; len = howmany(fs->e2fs.e2fs_ipg - ipref, NBBY); loc = skpc(0xff, len, &ibp[start]); if (loc == 0) { len = start + 1; start = 0; loc = skpc(0xff, len, &ibp[0]); if (loc == 0) { printf("cg = %d, ipref = %lld, fs = %s\n", cg, (long long)ipref, fs->e2fs_fsmnt); panic("ext2fs_nodealloccg: map corrupted"); /* NOTREACHED */ } } i = start + len - loc; map = ibp[i] ^ 0xff; if (map == 0) { printf("fs = %s\n", fs->e2fs_fsmnt); panic("ext2fs_nodealloccg: block not in map"); } ipref = i * NBBY + ffs(map) - 1; gotit: setbit(ibp, ipref); fs->e2fs.e2fs_ficount--; fs->e2fs_gd[cg].ext2bgd_nifree--; fs->e2fs_fmod = 1; if ((mode & IFMT) == IFDIR) { fs->e2fs_gd[cg].ext2bgd_ndirs++; } bdwrite(bp); return (cg * fs->e2fs.e2fs_ipg + ipref +1); }
static int32_t ext2fs_mapsearch(struct m_ext2fs *fs, char *bbp, int32_t bpref) { int32_t bno; int start, len, loc, i, map; /* * find the fragment by searching through the free block * map for an appropriate bit pattern */ if (bpref) start = dtogd(fs, bpref) / NBBY; else start = 0; len = howmany(fs->e2fs.e2fs_fpg, NBBY) - start; loc = skpc(0xff, len, &bbp[start]); if (loc == 0) { len = start + 1; start = 0; loc = skpc(0xff, len, &bbp[start]); if (loc == 0) { printf("start = %d, len = %d, fs = %s\n", start, len, fs->e2fs_fsmnt); panic("ext2fs_alloccg: map corrupted"); /* NOTREACHED */ } } i = start + len - loc; map = bbp[i]; bno = i * NBBY; for (i = 1; i < (1 << NBBY); i <<= 1, bno++) { if ((map & i) == 0) return (bno); } printf("fs = %s\n", fs->e2fs_fsmnt); panic("ext2fs_mapsearch: block not in map"); /* NOTREACHED */ }
/***************************************************************** * TAG( findruns ) * * Find runs not a given color in the row. * Inputs: * row: Row of pixel values * rowlen: Number of pixels in the row. * color: Color to compare against. * nrun: Number of runs already found (in different colors). * brun: Runs found in other color channels already. * Outputs: * brun: Modified to reflect merging of runs in this color. * Returns number of runs in brun. * Assumptions: * * Algorithm: * Search for occurences of pixels not of the given color outside * the runs already found. When some are found, add a new run or * extend an existing one. Adjacent runs with fewer than two * pixels intervening are merged. */ static int findruns(rle_pixel * const row, int const rowlen, int const color, int const nrunAlready, short (* const brun)[2]) { int i = 0, lower, upper; int s, j; int nrun; #ifdef DEBUG fprintf( stderr, "findruns( " ); for ( s = 0; s < rowlen; s++ ) fprintf( stderr, "%2x.%s", row[s], (s % 20 == 19) ? "\n\t" : "" ); if ( s % 20 != 0 ) fprintf( stderr, "\n\t" ); fprintf( stderr, "%d, %d, %d, \n\t", rowlen, color, nrun ); for ( j = 0; j < nrun; j++ ) fprintf( stderr, "(%3d,%3d) %s", brun[j][0], brun[j][1], (j % 6 == 5) ? "\n\t" : "" ); fprintf( stderr, ")\n" ); #endif nrun = nrunAlready; while ( i <= nrun ) { /* Assert: 0 <= i <= rowlen * brun[i] is the run following the "blank" space being * searched. If i == rowlen, search after brun[i-1]. */ /* get lower and upper bounds of search */ if ( i == 0 ) lower = 0; else lower = brun[i-1][1] + 1; if ( i == nrun ) upper = rowlen - 1; else upper = brun[i][0] - 1; #ifdef DEBUG fprintf( stderr, "Searching before run %d from %d to %d\n", i, lower, upper ); #endif /* Search for beginning of run != color */ #if defined(LOCC)&defined(vax) s = upper - skpc( (char *)row + lower, upper - lower + 1, color ) + 1; #else for ( s = lower; s <= upper; s++ ) if ( row[s] != color ) break; #endif if ( s <= upper ) /* found a new run? */ { if ( s > lower + 1 || i == 0 ) /* disjoint from preceding run? */ { #ifdef DEBUG fprintf( stderr, "Found new run starting at %d\n", s ); #endif /* Shift following runs up */ for ( j = nrun; j > i; j-- ) { brun[j][0] = brun[j-1][0]; brun[j][1] = brun[j-1][1]; } brun[i][0] = s; nrun++; } else { i--; /* just add to preceding run */ #ifdef DEBUG fprintf( stderr, "Adding to previous run\n" ); #endif } #if defined(LOCC)&defined(vax) s = upper - locc( (char *)row + s, upper - s + 1, color ) + 1; #else for ( ; s <= upper; s++ ) if ( row[s] == color ) break; #endif brun[i][1] = s - 1; #ifdef DEBUG fprintf( stderr, "Ends at %d", s - 1 ); #endif if ( s >= upper && i < nrun - 1 ) /* merge with following run */ { brun[i][1] = brun[i+1][1]; /* move following runs back down */ for ( j = i + 2; j < nrun; j++ ) { brun[j-1][0] = brun[j][0]; brun[j-1][1] = brun[j][1]; } nrun--; #ifdef DEBUG fprintf( stderr, ", add to next run" ); #endif } #ifdef DEBUG putc( '\n', stderr ); #endif } /* Search in next space */ i++; } return nrun; }