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