+ goto norot;
+ }
+ bpref &= ~(fs->fs_frag - 1);
+ bpref = dtogd(fs, bpref);
+ /*
+ * if the requested block is available, use it
+ */
+ if (isblock(fs, cgp->cg_free, bpref/fs->fs_frag)) {
+ bno = bpref;
+ goto gotit;
+ }
+ /*
+ * check for a block available on the same cylinder
+ */
+ cylno = cbtocylno(fs, bpref);
+ if (cgp->cg_btot[cylno] == 0)
+ goto norot;
+ if (fs->fs_cpc == 0) {
+ /*
+ * block layout info is not available, so just have
+ * to take any block in this cylinder.
+ */
+ bpref = howmany(fs->fs_spc * cylno, NSPF(fs));
+ goto norot;
+ }
+ /*
+ * find a block that is rotationally optimal
+ */
+ cylbp = cgp->cg_b[cylno];
+ if (fs->fs_rotdelay == 0) {
+ pos = cbtorpos(fs, bpref);
+ } else {
+ /*
+ * here we convert ms of delay to frags as:
+ * (frags) = (ms) * (rev/sec) * (sect/rev) /
+ * ((sect/frag) * (ms/sec))
+ * then round up to the next rotational position
+ */
+ bpref += fs->fs_rotdelay * fs->fs_rps * fs->fs_nsect /
+ (NSPF(fs) * 1000);
+ pos = cbtorpos(fs, bpref);
+ pos = (pos + 1) % NRPOS;
+ }
+ /*
+ * check the summary information to see if a block is
+ * available in the requested cylinder starting at the
+ * optimal rotational position and proceeding around.
+ */
+ for (i = pos; i < NRPOS; i++)
+ if (cylbp[i] > 0)
+ break;
+ if (i == NRPOS)
+ for (i = 0; i < pos; i++)
+ if (cylbp[i] > 0)
+ break;
+ if (cylbp[i] > 0) {
+ /*
+ * found a rotational position, now find the actual
+ * block. A panic if none is actually there.
+ */
+ pos = cylno % fs->fs_cpc;
+ bno = (cylno - pos) * fs->fs_spc / NSPB(fs);
+ if (fs->fs_postbl[pos][i] == -1) {
+ printf("pos = %d, i = %d, fs = %s\n",
+ pos, i, fs->fs_fsmnt);
+ panic("alloccgblk: cyl groups corrupted");
+ }
+ for (i = fs->fs_postbl[pos][i];; ) {
+ if (isblock(fs, cgp->cg_free, bno + i)) {
+ bno = (bno + i) * fs->fs_frag;
+ goto gotit;
+ }
+ delta = fs->fs_rotbl[i];
+ if (delta <= 0 || delta > MAXBPC - i)
+ break;
+ i += delta;