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