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