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