1 /* lfs_alloc.c 2.7 82/06/14 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mount.h" 6 #include "../h/fs.h" 7 #include "../h/conf.h" 8 #include "../h/buf.h" 9 #include "../h/inode.h" 10 #include "../h/dir.h" 11 #include "../h/user.h" 12 13 extern u_long hashalloc(); 14 extern ino_t ialloccg(); 15 extern daddr_t alloccg(); 16 extern daddr_t alloccgblk(); 17 extern daddr_t fragextend(); 18 extern daddr_t blkpref(); 19 extern daddr_t mapsearch(); 20 extern int inside[], around[]; 21 extern unsigned char *fragtbl[]; 22 23 /* 24 * Allocate a block in the file system. 25 * 26 * The size of the requested block is given, which must be some 27 * multiple of fs_fsize and <= fs_bsize. 28 * A preference may be optionally specified. If a preference is given 29 * the following hierarchy is used to allocate a block: 30 * 1) allocate the requested block. 31 * 2) allocate a rotationally optimal block in the same cylinder. 32 * 3) allocate a block in the same cylinder group. 33 * 4) quadradically rehash into other cylinder groups, until an 34 * available block is located. 35 * If no block preference is given the following heirarchy is used 36 * to allocate a block: 37 * 1) allocate a block in the cylinder group that contains the 38 * inode for the file. 39 * 2) quadradically rehash into other cylinder groups, until an 40 * available block is located. 41 */ 42 struct buf * 43 alloc(ip, bpref, size) 44 register struct inode *ip; 45 daddr_t bpref; 46 int size; 47 { 48 daddr_t bno; 49 register struct fs *fs; 50 register struct buf *bp; 51 int cg; 52 53 fs = ip->i_fs; 54 if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0) { 55 printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", 56 ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); 57 panic("alloc: bad size"); 58 } 59 if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) 60 goto nospace; 61 if (u.u_uid != 0 && 62 fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree < 63 fs->fs_dsize * fs->fs_minfree / 100) 64 goto nospace; 65 if (bpref >= fs->fs_size) 66 bpref = 0; 67 if (bpref == 0) 68 cg = itog(fs, ip->i_number); 69 else 70 cg = dtog(fs, bpref); 71 bno = (daddr_t)hashalloc(ip, cg, (long)bpref, size, alloccg); 72 if (bno <= 0) 73 goto nospace; 74 bp = getblk(ip->i_dev, fsbtodb(fs, bno), size); 75 clrbuf(bp); 76 return (bp); 77 nospace: 78 fserr(fs, "file system full"); 79 uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); 80 u.u_error = ENOSPC; 81 return (NULL); 82 } 83 84 /* 85 * Reallocate a fragment to a bigger size 86 * 87 * The number and size of the old block is given, and a preference 88 * and new size is also specified. The allocator attempts to extend 89 * the original block. Failing that, the regular block allocator is 90 * invoked to get an appropriate block. 91 */ 92 struct buf * 93 realloccg(ip, bprev, bpref, osize, nsize) 94 register struct inode *ip; 95 daddr_t bprev, bpref; 96 int osize, nsize; 97 { 98 daddr_t bno; 99 register struct fs *fs; 100 register struct buf *bp, *obp; 101 int cg; 102 103 fs = ip->i_fs; 104 if ((unsigned)osize > fs->fs_bsize || fragoff(fs, osize) != 0 || 105 (unsigned)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) { 106 printf("dev = 0x%x, bsize = %d, osize = %d, nsize = %d, fs = %s\n", 107 ip->i_dev, fs->fs_bsize, osize, nsize, fs->fs_fsmnt); 108 panic("realloccg: bad size"); 109 } 110 if (u.u_uid != 0 && 111 fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree < 112 fs->fs_dsize * fs->fs_minfree / 100) 113 goto nospace; 114 if (bprev == 0) { 115 printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n", 116 ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt); 117 panic("realloccg: bad bprev"); 118 } 119 cg = dtog(fs, bprev); 120 bno = fragextend(ip, cg, (long)bprev, osize, nsize); 121 if (bno != 0) { 122 do { 123 bp = bread(ip->i_dev, fsbtodb(fs, bno), osize); 124 if (bp->b_flags & B_ERROR) { 125 brelse(bp); 126 return (NULL); 127 } 128 } while (brealloc(bp, nsize) == 0); 129 bp->b_flags |= B_DONE; 130 blkclr(bp->b_un.b_addr + osize, nsize - osize); 131 return (bp); 132 } 133 if (bpref >= fs->fs_size) 134 bpref = 0; 135 bno = (daddr_t)hashalloc(ip, cg, (long)bpref, nsize, alloccg); 136 if (bno > 0) { 137 obp = bread(ip->i_dev, fsbtodb(fs, bprev), osize); 138 if (obp->b_flags & B_ERROR) { 139 brelse(obp); 140 return (NULL); 141 } 142 bp = getblk(ip->i_dev, fsbtodb(fs, bno), nsize); 143 bcopy(obp->b_un.b_addr, bp->b_un.b_addr, osize); 144 blkclr(bp->b_un.b_addr + osize, nsize - osize); 145 brelse(obp); 146 fre(ip, bprev, (off_t)osize); 147 return (bp); 148 } 149 nospace: 150 /* 151 * no space available 152 */ 153 fserr(fs, "file system full"); 154 uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); 155 u.u_error = ENOSPC; 156 return (NULL); 157 } 158 159 /* 160 * Allocate an inode in the file system. 161 * 162 * A preference may be optionally specified. If a preference is given 163 * the following hierarchy is used to allocate an inode: 164 * 1) allocate the requested inode. 165 * 2) allocate an inode in the same cylinder group. 166 * 3) quadradically rehash into other cylinder groups, until an 167 * available inode is located. 168 * If no inode preference is given the following heirarchy is used 169 * to allocate an inode: 170 * 1) allocate an inode in cylinder group 0. 171 * 2) quadradically rehash into other cylinder groups, until an 172 * available inode is located. 173 */ 174 struct inode * 175 ialloc(pip, ipref, mode) 176 register struct inode *pip; 177 ino_t ipref; 178 int mode; 179 { 180 ino_t ino; 181 register struct fs *fs; 182 register struct inode *ip; 183 int cg; 184 185 fs = pip->i_fs; 186 if (fs->fs_cstotal.cs_nifree == 0) 187 goto noinodes; 188 if (ipref >= fs->fs_ncg * fs->fs_ipg) 189 ipref = 0; 190 cg = itog(fs, ipref); 191 ino = (ino_t)hashalloc(pip, cg, (long)ipref, mode, ialloccg); 192 if (ino == 0) 193 goto noinodes; 194 ip = iget(pip->i_dev, pip->i_fs, ino); 195 if (ip == NULL) { 196 ifree(ip, ino, 0); 197 return (NULL); 198 } 199 if (ip->i_mode) { 200 printf("mode = 0%o, inum = %d, fs = %s\n", 201 ip->i_mode, ip->i_number, fs->fs_fsmnt); 202 panic("ialloc: dup alloc"); 203 } 204 return (ip); 205 noinodes: 206 fserr(fs, "out of inodes"); 207 uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); 208 u.u_error = ENOSPC; 209 return (NULL); 210 } 211 212 /* 213 * Find a cylinder to place a directory. 214 * 215 * The policy implemented by this algorithm is to select from 216 * among those cylinder groups with above the average number of 217 * free inodes, the one with the smallest number of directories. 218 */ 219 dirpref(fs) 220 register struct fs *fs; 221 { 222 int cg, minndir, mincg, avgifree; 223 224 avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg; 225 minndir = fs->fs_ipg; 226 mincg = 0; 227 for (cg = 0; cg < fs->fs_ncg; cg++) 228 if (fs->fs_cs(fs, cg).cs_ndir < minndir && 229 fs->fs_cs(fs, cg).cs_nifree >= avgifree) { 230 mincg = cg; 231 minndir = fs->fs_cs(fs, cg).cs_ndir; 232 } 233 return (fs->fs_ipg * mincg); 234 } 235 236 /* 237 * Select a cylinder to place a large block of data. 238 * 239 * The policy implemented by this algorithm is to maintain a 240 * rotor that sweeps the cylinder groups. When a block is 241 * needed, the rotor is advanced until a cylinder group with 242 * greater than the average number of free blocks is found. 243 */ 244 daddr_t 245 blkpref(fs) 246 register struct fs *fs; 247 { 248 int cg, avgbfree; 249 250 avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; 251 for (cg = fs->fs_cgrotor + 1; cg < fs->fs_ncg; cg++) 252 if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { 253 fs->fs_cgrotor = cg; 254 return (fs->fs_fpg * cg + fs->fs_frag); 255 } 256 for (cg = 0; cg <= fs->fs_cgrotor; cg++) 257 if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { 258 fs->fs_cgrotor = cg; 259 return (fs->fs_fpg * cg + fs->fs_frag); 260 } 261 return (NULL); 262 } 263 264 /* 265 * Implement the cylinder overflow algorithm. 266 * 267 * The policy implemented by this algorithm is: 268 * 1) allocate the block in its requested cylinder group. 269 * 2) quadradically rehash on the cylinder group number. 270 * 3) brute force search for a free block. 271 */ 272 /*VARARGS5*/ 273 u_long 274 hashalloc(ip, cg, pref, size, allocator) 275 struct inode *ip; 276 int cg; 277 long pref; 278 int size; /* size for data blocks, mode for inodes */ 279 u_long (*allocator)(); 280 { 281 register struct fs *fs; 282 long result; 283 int i, icg = cg; 284 285 fs = ip->i_fs; 286 /* 287 * 1: preferred cylinder group 288 */ 289 result = (*allocator)(ip, cg, pref, size); 290 if (result) 291 return (result); 292 /* 293 * 2: quadratic rehash 294 */ 295 for (i = 1; i < fs->fs_ncg; i *= 2) { 296 cg += i; 297 if (cg >= fs->fs_ncg) 298 cg -= fs->fs_ncg; 299 result = (*allocator)(ip, cg, 0, size); 300 if (result) 301 return (result); 302 } 303 /* 304 * 3: brute force search 305 */ 306 cg = icg; 307 for (i = 0; i < fs->fs_ncg; i++) { 308 result = (*allocator)(ip, cg, 0, size); 309 if (result) 310 return (result); 311 cg++; 312 if (cg == fs->fs_ncg) 313 cg = 0; 314 } 315 return (NULL); 316 } 317 318 /* 319 * Determine whether a fragment can be extended. 320 * 321 * Check to see if the necessary fragments are available, and 322 * if they are, allocate them. 323 */ 324 daddr_t 325 fragextend(ip, cg, bprev, osize, nsize) 326 struct inode *ip; 327 int cg; 328 long bprev; 329 int osize, nsize; 330 { 331 register struct fs *fs; 332 register struct buf *bp; 333 register struct cg *cgp; 334 long bno; 335 int frags, bbase; 336 int i; 337 338 fs = ip->i_fs; 339 if (fs->fs_cs(fs, cg).cs_nffree < nsize - osize) 340 return (NULL); 341 frags = numfrags(fs, nsize); 342 bbase = fragoff(fs, bprev); 343 if (bbase > (bprev + frags - 1) % fs->fs_frag) { 344 /* cannot extend across a block boundry */ 345 return (NULL); 346 } 347 bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize); 348 cgp = bp->b_un.b_cg; 349 if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) { 350 brelse(bp); 351 return (NULL); 352 } 353 cgp->cg_time = time; 354 bno = dtogd(fs, bprev); 355 for (i = numfrags(fs, osize); i < frags; i++) 356 if (isclr(cgp->cg_free, bno + i)) { 357 brelse(bp); 358 return (NULL); 359 } 360 /* 361 * the current fragment can be extended 362 * deduct the count on fragment being extended into 363 * increase the count on the remaining fragment (if any) 364 * allocate the extended piece 365 */ 366 for (i = frags; i < fs->fs_frag - bbase; i++) 367 if (isclr(cgp->cg_free, bno + i)) 368 break; 369 cgp->cg_frsum[i - numfrags(fs, osize)]--; 370 if (i != frags) 371 cgp->cg_frsum[i - frags]++; 372 for (i = numfrags(fs, osize); i < frags; i++) { 373 clrbit(cgp->cg_free, bno + i); 374 cgp->cg_cs.cs_nffree--; 375 fs->fs_cstotal.cs_nffree--; 376 fs->fs_cs(fs, cg).cs_nffree--; 377 } 378 fs->fs_fmod++; 379 bdwrite(bp); 380 return (bprev); 381 } 382 383 /* 384 * Determine whether a block can be allocated. 385 * 386 * Check to see if a block of the apprpriate size is available, 387 * and if it is, allocate it. 388 */ 389 daddr_t 390 alloccg(ip, cg, bpref, size) 391 struct inode *ip; 392 int cg; 393 daddr_t bpref; 394 int size; 395 { 396 register struct fs *fs; 397 register struct buf *bp; 398 register struct cg *cgp; 399 int bno, frags; 400 int allocsiz; 401 register int i; 402 403 fs = ip->i_fs; 404 if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) 405 return (NULL); 406 bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize); 407 cgp = bp->b_un.b_cg; 408 if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) { 409 brelse(bp); 410 return (NULL); 411 } 412 cgp->cg_time = time; 413 if (size == fs->fs_bsize) { 414 bno = alloccgblk(fs, cgp, bpref); 415 bdwrite(bp); 416 return (bno); 417 } 418 /* 419 * check to see if any fragments are already available 420 * allocsiz is the size which will be allocated, hacking 421 * it down to a smaller size if necessary 422 */ 423 frags = numfrags(fs, size); 424 for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++) 425 if (cgp->cg_frsum[allocsiz] != 0) 426 break; 427 if (allocsiz == fs->fs_frag) { 428 /* 429 * no fragments were available, so a block will be 430 * allocated, and hacked up 431 */ 432 if (cgp->cg_cs.cs_nbfree == 0) { 433 brelse(bp); 434 return (NULL); 435 } 436 bno = alloccgblk(fs, cgp, bpref); 437 bpref = dtogd(fs, bno); 438 for (i = frags; i < fs->fs_frag; i++) 439 setbit(cgp->cg_free, bpref + i); 440 i = fs->fs_frag - frags; 441 cgp->cg_cs.cs_nffree += i; 442 fs->fs_cstotal.cs_nffree += i; 443 fs->fs_cs(fs, cg).cs_nffree += i; 444 cgp->cg_frsum[i]++; 445 bdwrite(bp); 446 return (bno); 447 } 448 bno = mapsearch(fs, cgp, bpref, allocsiz); 449 if (bno < 0) 450 return (NULL); 451 for (i = 0; i < frags; i++) 452 clrbit(cgp->cg_free, bno + i); 453 cgp->cg_cs.cs_nffree -= frags; 454 fs->fs_cstotal.cs_nffree -= frags; 455 fs->fs_cs(fs, cg).cs_nffree -= frags; 456 cgp->cg_frsum[allocsiz]--; 457 if (frags != allocsiz) 458 cgp->cg_frsum[allocsiz - frags]++; 459 bdwrite(bp); 460 return (cg * fs->fs_fpg + bno); 461 } 462 463 /* 464 * Allocate a block in a cylinder group. 465 * 466 * This algorithm implements the following policy: 467 * 1) allocate the requested block. 468 * 2) allocate a rotationally optimal block in the same cylinder. 469 * 3) allocate the next available block on the block rotor for the 470 * specified cylinder group. 471 * Note that this routine only allocates fs_bsize blocks; these 472 * blocks may be fragmented by the routine that allocates them. 473 */ 474 daddr_t 475 alloccgblk(fs, cgp, bpref) 476 register struct fs *fs; 477 register struct cg *cgp; 478 daddr_t bpref; 479 { 480 daddr_t bno; 481 int cylno, pos, delta; 482 short *cylbp; 483 register int i; 484 485 if (bpref == 0) { 486 bpref = cgp->cg_rotor; 487 goto norot; 488 } 489 bpref &= ~(fs->fs_frag - 1); 490 bpref = dtogd(fs, bpref); 491 /* 492 * if the requested block is available, use it 493 */ 494 /* 495 * disallow sequential layout. 496 * 497 if (isblock(fs, cgp->cg_free, bpref/fs->fs_frag)) { 498 bno = bpref; 499 goto gotit; 500 } 501 */ 502 /* 503 * check for a block available on the same cylinder 504 */ 505 cylno = cbtocylno(fs, bpref); 506 if (cgp->cg_btot[cylno] == 0) 507 goto norot; 508 if (fs->fs_cpc == 0) { 509 /* 510 * block layout info is not available, so just have 511 * to take any block in this cylinder. 512 */ 513 bpref = howmany(fs->fs_spc * cylno, NSPF(fs)); 514 goto norot; 515 } 516 /* 517 * find a block that is rotationally optimal 518 */ 519 cylbp = cgp->cg_b[cylno]; 520 if (fs->fs_rotdelay == 0) { 521 pos = cbtorpos(fs, bpref); 522 } else { 523 /* 524 * here we convert ms of delay to frags as: 525 * (frags) = (ms) * (rev/sec) * (sect/rev) / 526 * ((sect/frag) * (ms/sec)) 527 * then round up to the next rotational position 528 */ 529 bpref += fs->fs_rotdelay * fs->fs_rps * fs->fs_nsect / 530 (NSPF(fs) * 1000); 531 pos = cbtorpos(fs, bpref); 532 pos = (pos + 1) % NRPOS; 533 } 534 /* 535 * check the summary information to see if a block is 536 * available in the requested cylinder starting at the 537 * optimal rotational position and proceeding around. 538 */ 539 for (i = pos; i < NRPOS; i++) 540 if (cylbp[i] > 0) 541 break; 542 if (i == NRPOS) 543 for (i = 0; i < pos; i++) 544 if (cylbp[i] > 0) 545 break; 546 if (cylbp[i] > 0) { 547 /* 548 * found a rotational position, now find the actual 549 * block. A panic if none is actually there. 550 */ 551 pos = cylno % fs->fs_cpc; 552 bno = (cylno - pos) * fs->fs_spc / NSPB(fs); 553 if (fs->fs_postbl[pos][i] == -1) { 554 printf("pos = %d, i = %d, fs = %s\n", 555 pos, i, fs->fs_fsmnt); 556 panic("alloccgblk: cyl groups corrupted"); 557 } 558 for (i = fs->fs_postbl[pos][i];; ) { 559 if (isblock(fs, cgp->cg_free, bno + i)) { 560 bno = (bno + i) * fs->fs_frag; 561 goto gotit; 562 } 563 delta = fs->fs_rotbl[i]; 564 if (delta <= 0 || delta > MAXBPC - i) 565 break; 566 i += delta; 567 } 568 printf("pos = %d, i = %d, fs = %s\n", pos, i, fs->fs_fsmnt); 569 panic("alloccgblk: can't find blk in cyl"); 570 } 571 norot: 572 /* 573 * no blocks in the requested cylinder, so take next 574 * available one in this cylinder group. 575 */ 576 bno = mapsearch(fs, cgp, bpref, fs->fs_frag); 577 if (bno < 0) 578 return (NULL); 579 cgp->cg_rotor = bno; 580 gotit: 581 clrblock(fs, cgp->cg_free, bno/fs->fs_frag); 582 cgp->cg_cs.cs_nbfree--; 583 fs->fs_cstotal.cs_nbfree--; 584 fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--; 585 cylno = cbtocylno(fs, bno); 586 cgp->cg_b[cylno][cbtorpos(fs, bno)]--; 587 cgp->cg_btot[cylno]--; 588 fs->fs_fmod++; 589 return (cgp->cg_cgx * fs->fs_fpg + bno); 590 } 591 592 /* 593 * Determine whether an inode can be allocated. 594 * 595 * Check to see if an inode is available, and if it is, 596 * allocate it using the following policy: 597 * 1) allocate the requested inode. 598 * 2) allocate the next available inode after the requested 599 * inode in the specified cylinder group. 600 */ 601 ino_t 602 ialloccg(ip, cg, ipref, mode) 603 struct inode *ip; 604 int cg; 605 daddr_t ipref; 606 int mode; 607 { 608 register struct fs *fs; 609 register struct buf *bp; 610 register struct cg *cgp; 611 int i; 612 613 fs = ip->i_fs; 614 if (fs->fs_cs(fs, cg).cs_nifree == 0) 615 return (NULL); 616 bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize); 617 cgp = bp->b_un.b_cg; 618 if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) { 619 brelse(bp); 620 return (NULL); 621 } 622 cgp->cg_time = time; 623 if (ipref) { 624 ipref %= fs->fs_ipg; 625 if (isclr(cgp->cg_iused, ipref)) 626 goto gotit; 627 } else 628 ipref = cgp->cg_irotor; 629 for (i = 0; i < fs->fs_ipg; i++) { 630 ipref++; 631 if (ipref >= fs->fs_ipg) 632 ipref = 0; 633 if (isclr(cgp->cg_iused, ipref)) { 634 cgp->cg_irotor = ipref; 635 goto gotit; 636 } 637 } 638 brelse(bp); 639 return (NULL); 640 gotit: 641 setbit(cgp->cg_iused, ipref); 642 cgp->cg_cs.cs_nifree--; 643 fs->fs_cstotal.cs_nifree--; 644 fs->fs_cs(fs, cg).cs_nifree--; 645 fs->fs_fmod++; 646 if ((mode & IFMT) == IFDIR) { 647 cgp->cg_cs.cs_ndir++; 648 fs->fs_cstotal.cs_ndir++; 649 fs->fs_cs(fs, cg).cs_ndir++; 650 } 651 bdwrite(bp); 652 return (cg * fs->fs_ipg + ipref); 653 } 654 655 /* 656 * Free a block or fragment. 657 * 658 * The specified block or fragment is placed back in the 659 * free map. If a fragment is deallocated, a possible 660 * block reassembly is checked. 661 */ 662 fre(ip, bno, size) 663 register struct inode *ip; 664 daddr_t bno; 665 off_t size; 666 { 667 register struct fs *fs; 668 register struct cg *cgp; 669 register struct buf *bp; 670 int cg, blk, frags, bbase; 671 register int i; 672 673 fs = ip->i_fs; 674 if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0) { 675 printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", 676 ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); 677 panic("free: bad size"); 678 } 679 cg = dtog(fs, bno); 680 if (badblock(fs, bno)) { 681 printf("bad block %d, ino %d\n", bno, ip->i_number); 682 return; 683 } 684 bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize); 685 cgp = bp->b_un.b_cg; 686 if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) { 687 brelse(bp); 688 return; 689 } 690 cgp->cg_time = time; 691 bno = dtogd(fs, bno); 692 if (size == fs->fs_bsize) { 693 if (isblock(fs, cgp->cg_free, bno/fs->fs_frag)) { 694 printf("dev = 0x%x, block = %d, fs = %s\n", 695 ip->i_dev, bno, fs->fs_fsmnt); 696 panic("free: freeing free block"); 697 } 698 setblock(fs, cgp->cg_free, bno/fs->fs_frag); 699 cgp->cg_cs.cs_nbfree++; 700 fs->fs_cstotal.cs_nbfree++; 701 fs->fs_cs(fs, cg).cs_nbfree++; 702 i = cbtocylno(fs, bno); 703 cgp->cg_b[i][cbtorpos(fs, bno)]++; 704 cgp->cg_btot[i]++; 705 } else { 706 bbase = bno - (bno % fs->fs_frag); 707 /* 708 * decrement the counts associated with the old frags 709 */ 710 blk = blkmap(fs, cgp->cg_free, bbase); 711 fragacct(fs, blk, cgp->cg_frsum, -1); 712 /* 713 * deallocate the fragment 714 */ 715 frags = numfrags(fs, size); 716 for (i = 0; i < frags; i++) { 717 if (isset(cgp->cg_free, bno + i)) { 718 printf("dev = 0x%x, block = %d, fs = %s\n", 719 ip->i_dev, bno + i, fs->fs_fsmnt); 720 panic("free: freeing free frag"); 721 } 722 setbit(cgp->cg_free, bno + i); 723 } 724 cgp->cg_cs.cs_nffree += i; 725 fs->fs_cstotal.cs_nffree += i; 726 fs->fs_cs(fs, cg).cs_nffree += i; 727 /* 728 * add back in counts associated with the new frags 729 */ 730 blk = blkmap(fs, cgp->cg_free, bbase); 731 fragacct(fs, blk, cgp->cg_frsum, 1); 732 /* 733 * if a complete block has been reassembled, account for it 734 */ 735 if (isblock(fs, cgp->cg_free, bbase / fs->fs_frag)) { 736 cgp->cg_cs.cs_nffree -= fs->fs_frag; 737 fs->fs_cstotal.cs_nffree -= fs->fs_frag; 738 fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag; 739 cgp->cg_cs.cs_nbfree++; 740 fs->fs_cstotal.cs_nbfree++; 741 fs->fs_cs(fs, cg).cs_nbfree++; 742 i = cbtocylno(fs, bbase); 743 cgp->cg_b[i][cbtorpos(fs, bbase)]++; 744 cgp->cg_btot[i]++; 745 } 746 } 747 fs->fs_fmod++; 748 bdwrite(bp); 749 } 750 751 /* 752 * Free an inode. 753 * 754 * The specified inode is placed back in the free map. 755 */ 756 ifree(ip, ino, mode) 757 struct inode *ip; 758 ino_t ino; 759 int mode; 760 { 761 register struct fs *fs; 762 register struct cg *cgp; 763 register struct buf *bp; 764 int cg; 765 766 fs = ip->i_fs; 767 if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg) { 768 printf("dev = 0x%x, ino = %d, fs = %s\n", 769 ip->i_dev, ino, fs->fs_fsmnt); 770 panic("ifree: range"); 771 } 772 cg = itog(fs, ino); 773 bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize); 774 cgp = bp->b_un.b_cg; 775 if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) { 776 brelse(bp); 777 return; 778 } 779 cgp->cg_time = time; 780 ino %= fs->fs_ipg; 781 if (isclr(cgp->cg_iused, ino)) { 782 printf("dev = 0x%x, ino = %d, fs = %s\n", 783 ip->i_dev, ino, fs->fs_fsmnt); 784 panic("ifree: freeing free inode"); 785 } 786 clrbit(cgp->cg_iused, ino); 787 cgp->cg_cs.cs_nifree++; 788 fs->fs_cstotal.cs_nifree++; 789 fs->fs_cs(fs, cg).cs_nifree++; 790 if ((mode & IFMT) == IFDIR) { 791 cgp->cg_cs.cs_ndir--; 792 fs->fs_cstotal.cs_ndir--; 793 fs->fs_cs(fs, cg).cs_ndir--; 794 } 795 fs->fs_fmod++; 796 bdwrite(bp); 797 } 798 799 /* 800 * Find a block of the specified size in the specified cylinder group. 801 * 802 * It is a panic if a request is made to find a block if none are 803 * available. 804 */ 805 daddr_t 806 mapsearch(fs, cgp, bpref, allocsiz) 807 register struct fs *fs; 808 register struct cg *cgp; 809 daddr_t bpref; 810 int allocsiz; 811 { 812 daddr_t bno; 813 int start, len, loc, i; 814 int blk, field, subfield, pos; 815 816 /* 817 * find the fragment by searching through the free block 818 * map for an appropriate bit pattern 819 */ 820 if (bpref) 821 start = dtogd(fs, bpref) / NBBY; 822 else 823 start = cgp->cg_frotor / NBBY; 824 len = howmany(fs->fs_fpg, NBBY) - start; 825 loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag], 826 1 << (allocsiz - 1 + (fs->fs_frag % NBBY))); 827 if (loc == 0) { 828 len = start + 1; 829 start = 0; 830 loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag], 831 1 << (allocsiz - 1 + (fs->fs_frag % NBBY))); 832 if (loc == 0) { 833 printf("start = %d, len = %d, fs = %s\n", 834 start, len, fs->fs_fsmnt); 835 panic("alloccg: map corrupted"); 836 return (-1); 837 } 838 } 839 bno = (start + len - loc) * NBBY; 840 cgp->cg_frotor = bno; 841 /* 842 * found the byte in the map 843 * sift through the bits to find the selected frag 844 */ 845 for (i = bno + NBBY; bno < i; bno += fs->fs_frag) { 846 blk = blkmap(fs, cgp->cg_free, bno); 847 blk <<= 1; 848 field = around[allocsiz]; 849 subfield = inside[allocsiz]; 850 for (pos = 0; pos <= fs->fs_frag - allocsiz; pos++) { 851 if ((blk & field) == subfield) 852 return (bno + pos); 853 field <<= 1; 854 subfield <<= 1; 855 } 856 } 857 printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt); 858 panic("alloccg: block not in map"); 859 return (-1); 860 } 861 862 /* 863 * Update the frsum fields to reflect addition or deletion 864 * of some frags. 865 */ 866 fragacct(fs, fragmap, fraglist, cnt) 867 struct fs *fs; 868 int fragmap; 869 long fraglist[]; 870 int cnt; 871 { 872 int inblk; 873 register int field, subfield; 874 register int siz, pos; 875 876 inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 877 fragmap <<= 1; 878 for (siz = 1; siz < fs->fs_frag; siz++) { 879 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 880 continue; 881 field = around[siz]; 882 subfield = inside[siz]; 883 for (pos = siz; pos <= fs->fs_frag; pos++) { 884 if ((fragmap & field) == subfield) { 885 fraglist[siz] += cnt; 886 pos += siz; 887 field <<= siz; 888 subfield <<= siz; 889 } 890 field <<= 1; 891 subfield <<= 1; 892 } 893 } 894 } 895 896 /* 897 * Check that a specified block number is in range. 898 */ 899 badblock(fs, bn) 900 register struct fs *fs; 901 daddr_t bn; 902 { 903 904 if ((unsigned)bn >= fs->fs_size) { 905 printf("bad block %d, ", bn); 906 fserr(fs, "bad block"); 907 return (1); 908 } 909 return (0); 910 } 911 912 /* 913 * Getfs maps a device number into a pointer to the incore super block. 914 * 915 * The algorithm is a linear search through the mount table. A 916 * consistency check of the super block magic number is performed. 917 * 918 * panic: no fs -- the device is not mounted. 919 * this "cannot happen" 920 */ 921 struct fs * 922 getfs(dev) 923 dev_t dev; 924 { 925 register struct mount *mp; 926 register struct fs *fs; 927 928 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { 929 if (mp->m_bufp == NULL || mp->m_dev != dev) 930 continue; 931 fs = mp->m_bufp->b_un.b_fs; 932 if (fs->fs_magic != FS_MAGIC) { 933 printf("dev = 0x%x, fs = %s\n", dev, fs->fs_fsmnt); 934 panic("getfs: bad magic"); 935 } 936 return (fs); 937 } 938 printf("dev = 0x%x\n", dev); 939 panic("getfs: no fs"); 940 return (NULL); 941 } 942 943 /* 944 * Fserr prints the name of a file system with an error diagnostic. 945 * 946 * The form of the error message is: 947 * fs: error message 948 */ 949 fserr(fs, cp) 950 struct fs *fs; 951 char *cp; 952 { 953 954 printf("%s: %s\n", fs->fs_fsmnt, cp); 955 } 956 957 /* 958 * Getfsx returns the index in the file system 959 * table of the specified device. The swap device 960 * is also assigned a pseudo-index. The index may 961 * be used as a compressed indication of the location 962 * of a block, recording 963 * <getfsx(dev),blkno> 964 * rather than 965 * <dev, blkno> 966 * provided the information need remain valid only 967 * as long as the file system is mounted. 968 */ 969 getfsx(dev) 970 dev_t dev; 971 { 972 register struct mount *mp; 973 974 if (dev == swapdev) 975 return (MSWAPX); 976 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 977 if (mp->m_dev == dev) 978 return (mp - &mount[0]); 979 return (-1); 980 } 981 982 /* 983 * Update is the internal name of 'sync'. It goes through the disk 984 * queues to initiate sandbagged IO; goes through the inodes to write 985 * modified nodes; and it goes through the mount table to initiate 986 * the writing of the modified super blocks. 987 */ 988 update(flag) 989 int flag; 990 { 991 register struct inode *ip; 992 register struct mount *mp; 993 register struct buf *bp; 994 struct fs *fs; 995 int i, blks; 996 997 if (updlock) 998 return; 999 updlock++; 1000 /* 1001 * Write back modified superblocks. 1002 * Consistency check that the superblock 1003 * of each file system is still in the buffer cache. 1004 */ 1005 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { 1006 if (mp->m_bufp == NULL) 1007 continue; 1008 fs = mp->m_bufp->b_un.b_fs; 1009 if (fs->fs_fmod == 0) 1010 continue; 1011 if (fs->fs_ronly != 0) { /* ### */ 1012 printf("fs = %s\n", fs->fs_fsmnt); 1013 panic("update: rofs mod"); 1014 } 1015 fs->fs_fmod = 0; 1016 fs->fs_time = time; 1017 sbupdate(mp); 1018 } 1019 /* 1020 * Write back each (modified) inode. 1021 */ 1022 for (ip = inode; ip < inodeNINODE; ip++) { 1023 if ((ip->i_flag & ILOCK) != 0 || ip->i_count == 0) 1024 continue; 1025 ip->i_flag |= ILOCK; 1026 ip->i_count++; 1027 iupdat(ip, &time, &time, 0); 1028 iput(ip); 1029 } 1030 updlock = 0; 1031 /* 1032 * Force stale buffer cache information to be flushed, 1033 * for all devices. 1034 */ 1035 bflush(NODEV); 1036 } 1037 1038 /* 1039 * block operations 1040 * 1041 * check if a block is available 1042 */ 1043 isblock(fs, cp, h) 1044 struct fs *fs; 1045 unsigned char *cp; 1046 int h; 1047 { 1048 unsigned char mask; 1049 1050 switch (fs->fs_frag) { 1051 case 8: 1052 return (cp[h] == 0xff); 1053 case 4: 1054 mask = 0x0f << ((h & 0x1) << 2); 1055 return ((cp[h >> 1] & mask) == mask); 1056 case 2: 1057 mask = 0x03 << ((h & 0x3) << 1); 1058 return ((cp[h >> 2] & mask) == mask); 1059 case 1: 1060 mask = 0x01 << (h & 0x7); 1061 return ((cp[h >> 3] & mask) == mask); 1062 default: 1063 panic("isblock"); 1064 return (NULL); 1065 } 1066 } 1067 1068 /* 1069 * take a block out of the map 1070 */ 1071 clrblock(fs, cp, h) 1072 struct fs *fs; 1073 unsigned char *cp; 1074 int h; 1075 { 1076 switch ((fs)->fs_frag) { 1077 case 8: 1078 cp[h] = 0; 1079 return; 1080 case 4: 1081 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1082 return; 1083 case 2: 1084 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1085 return; 1086 case 1: 1087 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1088 return; 1089 default: 1090 panic("clrblock"); 1091 return; 1092 } 1093 } 1094 1095 /* 1096 * put a block into the map 1097 */ 1098 setblock(fs, cp, h) 1099 struct fs *fs; 1100 unsigned char *cp; 1101 int h; 1102 { 1103 switch (fs->fs_frag) { 1104 case 8: 1105 cp[h] = 0xff; 1106 return; 1107 case 4: 1108 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1109 return; 1110 case 2: 1111 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 1112 return; 1113 case 1: 1114 cp[h >> 3] |= (0x01 << (h & 0x7)); 1115 return; 1116 default: 1117 panic("setblock"); 1118 return; 1119 } 1120 } 1121