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