pass5.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1980, 1986, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 4. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#if 0 33#ifndef lint 34static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; 35#endif /* not lint */ 36#endif 37#include <sys/cdefs.h> 38__FBSDID("$FreeBSD: stable/11/sbin/fsck_ffs/pass5.c 330897 2018-03-14 03:19:51Z eadler $"); 39 40#include <sys/param.h> 41#include <sys/sysctl.h> 42 43#include <ufs/ufs/dinode.h> 44#include <ufs/ffs/fs.h> 45 46#include <err.h> 47#include <inttypes.h> 48#include <limits.h> 49#include <string.h> 50#include <libufs.h> 51 52#include "fsck.h" 53 54static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *, 55 int *, int, int, int); 56static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end); 57 58void 59pass5(void) 60{ 61 int c, i, j, blk, frags, basesize, mapsize; 62 int inomapsize, blkmapsize; 63 struct fs *fs = &sblock; 64 ufs2_daddr_t d, dbase, dmax, start; 65 int rewritecg = 0; 66 struct csum *cs; 67 struct csum_total cstotal; 68 struct inodesc idesc[3]; 69 char buf[MAXBSIZE]; 70 struct cg *cg, *newcg = (struct cg *)buf; 71 struct bufarea *cgbp; 72 73 inoinfo(WINO)->ino_state = USTATE; 74 memset(newcg, 0, (size_t)fs->fs_cgsize); 75 newcg->cg_niblk = fs->fs_ipg; 76 if (cvtlevel >= 3) { 77 if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 78 if (preen) 79 pwarn("DELETING CLUSTERING MAPS\n"); 80 if (preen || reply("DELETE CLUSTERING MAPS")) { 81 fs->fs_contigsumsize = 0; 82 rewritecg = 1; 83 sbdirty(); 84 } 85 } 86 if (fs->fs_maxcontig > 1) { 87 const char *doit = NULL; 88 89 if (fs->fs_contigsumsize < 1) { 90 doit = "CREAT"; 91 } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 92 fs->fs_contigsumsize < FS_MAXCONTIG) { 93 doit = "EXPAND"; 94 } 95 if (doit) { 96 i = fs->fs_contigsumsize; 97 fs->fs_contigsumsize = 98 MIN(fs->fs_maxcontig, FS_MAXCONTIG); 99 if (CGSIZE(fs) > (u_int)fs->fs_bsize) { 100 pwarn("CANNOT %s CLUSTER MAPS\n", doit); 101 fs->fs_contigsumsize = i; 102 } else if (preen || 103 reply("CREATE CLUSTER MAPS")) { 104 if (preen) 105 pwarn("%sING CLUSTER MAPS\n", 106 doit); 107 fs->fs_cgsize = 108 fragroundup(fs, CGSIZE(fs)); 109 rewritecg = 1; 110 sbdirty(); 111 } 112 } 113 } 114 } 115 basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); 116 if (sblock.fs_magic == FS_UFS2_MAGIC) { 117 newcg->cg_iusedoff = basesize; 118 } else { 119 /* 120 * We reserve the space for the old rotation summary 121 * tables for the benefit of old kernels, but do not 122 * maintain them in modern kernels. In time, they can 123 * go away. 124 */ 125 newcg->cg_old_btotoff = basesize; 126 newcg->cg_old_boff = newcg->cg_old_btotoff + 127 fs->fs_old_cpg * sizeof(int32_t); 128 newcg->cg_iusedoff = newcg->cg_old_boff + 129 fs->fs_old_cpg * fs->fs_old_nrpos * sizeof(u_int16_t); 130 memset(&newcg->cg_space[0], 0, newcg->cg_iusedoff - basesize); 131 } 132 inomapsize = howmany(fs->fs_ipg, CHAR_BIT); 133 newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize; 134 blkmapsize = howmany(fs->fs_fpg, CHAR_BIT); 135 newcg->cg_nextfreeoff = newcg->cg_freeoff + blkmapsize; 136 if (fs->fs_contigsumsize > 0) { 137 newcg->cg_clustersumoff = newcg->cg_nextfreeoff - 138 sizeof(u_int32_t); 139 newcg->cg_clustersumoff = 140 roundup(newcg->cg_clustersumoff, sizeof(u_int32_t)); 141 newcg->cg_clusteroff = newcg->cg_clustersumoff + 142 (fs->fs_contigsumsize + 1) * sizeof(u_int32_t); 143 newcg->cg_nextfreeoff = newcg->cg_clusteroff + 144 howmany(fragstoblks(fs, fs->fs_fpg), CHAR_BIT); 145 } 146 newcg->cg_magic = CG_MAGIC; 147 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 148 memset(&idesc[0], 0, sizeof idesc); 149 for (i = 0; i < 3; i++) 150 idesc[i].id_type = ADDR; 151 memset(&cstotal, 0, sizeof(struct csum_total)); 152 dmax = blknum(fs, fs->fs_size + fs->fs_frag - 1); 153 for (d = fs->fs_size; d < dmax; d++) 154 setbmap(d); 155 for (c = 0; c < fs->fs_ncg; c++) { 156 if (got_siginfo) { 157 printf("%s: phase 5: cyl group %d of %d (%d%%)\n", 158 cdevname, c, sblock.fs_ncg, 159 c * 100 / sblock.fs_ncg); 160 got_siginfo = 0; 161 } 162 if (got_sigalarm) { 163 setproctitle("%s p5 %d%%", cdevname, 164 c * 100 / sblock.fs_ncg); 165 got_sigalarm = 0; 166 } 167 cgbp = cgget(c); 168 cg = cgbp->b_un.b_cg; 169 if (!cg_chkmagic(cg)) 170 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 171 newcg->cg_time = cg->cg_time; 172 newcg->cg_old_time = cg->cg_old_time; 173 newcg->cg_unrefs = cg->cg_unrefs; 174 newcg->cg_cgx = c; 175 dbase = cgbase(fs, c); 176 dmax = dbase + fs->fs_fpg; 177 if (dmax > fs->fs_size) 178 dmax = fs->fs_size; 179 newcg->cg_ndblk = dmax - dbase; 180 if (fs->fs_magic == FS_UFS1_MAGIC) { 181 if (c == fs->fs_ncg - 1) 182 newcg->cg_old_ncyl = howmany(newcg->cg_ndblk, 183 fs->fs_fpg / fs->fs_old_cpg); 184 else 185 newcg->cg_old_ncyl = fs->fs_old_cpg; 186 newcg->cg_old_niblk = fs->fs_ipg; 187 newcg->cg_niblk = 0; 188 } 189 if (fs->fs_contigsumsize > 0) 190 newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 191 newcg->cg_cs.cs_ndir = 0; 192 newcg->cg_cs.cs_nffree = 0; 193 newcg->cg_cs.cs_nbfree = 0; 194 newcg->cg_cs.cs_nifree = fs->fs_ipg; 195 if (cg->cg_rotor >= 0 && cg->cg_rotor < newcg->cg_ndblk) 196 newcg->cg_rotor = cg->cg_rotor; 197 else 198 newcg->cg_rotor = 0; 199 if (cg->cg_frotor >= 0 && cg->cg_frotor < newcg->cg_ndblk) 200 newcg->cg_frotor = cg->cg_frotor; 201 else 202 newcg->cg_frotor = 0; 203 if (cg->cg_irotor >= 0 && cg->cg_irotor < fs->fs_ipg) 204 newcg->cg_irotor = cg->cg_irotor; 205 else 206 newcg->cg_irotor = 0; 207 if (fs->fs_magic == FS_UFS1_MAGIC) { 208 newcg->cg_initediblk = 0; 209 } else { 210 if ((unsigned)cg->cg_initediblk > fs->fs_ipg) 211 newcg->cg_initediblk = fs->fs_ipg; 212 else 213 newcg->cg_initediblk = cg->cg_initediblk; 214 } 215 memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum); 216 memset(cg_inosused(newcg), 0, (size_t)(mapsize)); 217 j = fs->fs_ipg * c; 218 for (i = 0; i < inostathead[c].il_numalloced; j++, i++) { 219 switch (inoinfo(j)->ino_state) { 220 221 case USTATE: 222 break; 223 224 case DSTATE: 225 case DCLEAR: 226 case DFOUND: 227 case DZLINK: 228 newcg->cg_cs.cs_ndir++; 229 /* FALLTHROUGH */ 230 231 case FSTATE: 232 case FCLEAR: 233 case FZLINK: 234 newcg->cg_cs.cs_nifree--; 235 setbit(cg_inosused(newcg), i); 236 break; 237 238 default: 239 if (j < (int)ROOTINO) 240 break; 241 errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 242 inoinfo(j)->ino_state, j); 243 } 244 } 245 if (c == 0) 246 for (i = 0; i < (int)ROOTINO; i++) { 247 setbit(cg_inosused(newcg), i); 248 newcg->cg_cs.cs_nifree--; 249 } 250 start = -1; 251 for (i = 0, d = dbase; 252 d < dmax; 253 d += fs->fs_frag, i += fs->fs_frag) { 254 frags = 0; 255 for (j = 0; j < fs->fs_frag; j++) { 256 if (testbmap(d + j)) { 257 if ((Eflag || Zflag) && start != -1) { 258 clear_blocks(start, d + j - 1); 259 start = -1; 260 } 261 continue; 262 } 263 if (start == -1) 264 start = d + j; 265 setbit(cg_blksfree(newcg), i + j); 266 frags++; 267 } 268 if (frags == fs->fs_frag) { 269 newcg->cg_cs.cs_nbfree++; 270 if (fs->fs_contigsumsize > 0) 271 setbit(cg_clustersfree(newcg), 272 i / fs->fs_frag); 273 } else if (frags > 0) { 274 newcg->cg_cs.cs_nffree += frags; 275 blk = blkmap(fs, cg_blksfree(newcg), i); 276 ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 277 } 278 } 279 if ((Eflag || Zflag) && start != -1) 280 clear_blocks(start, d - 1); 281 if (fs->fs_contigsumsize > 0) { 282 int32_t *sump = cg_clustersum(newcg); 283 u_char *mapp = cg_clustersfree(newcg); 284 int map = *mapp++; 285 int bit = 1; 286 int run = 0; 287 288 for (i = 0; i < newcg->cg_nclusterblks; i++) { 289 if ((map & bit) != 0) { 290 run++; 291 } else if (run != 0) { 292 if (run > fs->fs_contigsumsize) 293 run = fs->fs_contigsumsize; 294 sump[run]++; 295 run = 0; 296 } 297 if ((i & (CHAR_BIT - 1)) != (CHAR_BIT - 1)) { 298 bit <<= 1; 299 } else { 300 map = *mapp++; 301 bit = 1; 302 } 303 } 304 if (run != 0) { 305 if (run > fs->fs_contigsumsize) 306 run = fs->fs_contigsumsize; 307 sump[run]++; 308 } 309 } 310 if (bkgrdflag != 0) { 311 cstotal.cs_nffree += cg->cg_cs.cs_nffree; 312 cstotal.cs_nbfree += cg->cg_cs.cs_nbfree; 313 cstotal.cs_nifree += cg->cg_cs.cs_nifree; 314 cstotal.cs_ndir += cg->cg_cs.cs_ndir; 315 } else { 316 cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 317 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 318 cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 319 cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 320 } 321 cs = &fs->fs_cs(fs, c); 322 if (cursnapshot == 0 && 323 memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 && 324 dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 325 memmove(cs, &newcg->cg_cs, sizeof *cs); 326 sbdirty(); 327 } 328 if (rewritecg) { 329 memmove(cg, newcg, (size_t)fs->fs_cgsize); 330 dirty(cgbp); 331 continue; 332 } 333 if (cursnapshot == 0 && 334 memcmp(newcg, cg, basesize) != 0 && 335 dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 336 memmove(cg, newcg, (size_t)basesize); 337 dirty(cgbp); 338 } 339 if (bkgrdflag != 0 || usedsoftdep || debug) 340 update_maps(cg, newcg, bkgrdflag); 341 if (cursnapshot == 0 && 342 memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 && 343 dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 344 memmove(cg_inosused(cg), cg_inosused(newcg), 345 (size_t)mapsize); 346 dirty(cgbp); 347 } 348 } 349 if (cursnapshot == 0 && 350 memcmp(&cstotal, &fs->fs_cstotal, sizeof cstotal) != 0 351 && dofix(&idesc[0], "SUMMARY BLK COUNT(S) WRONG IN SUPERBLK")) { 352 memmove(&fs->fs_cstotal, &cstotal, sizeof cstotal); 353 fs->fs_ronly = 0; 354 fs->fs_fmod = 0; 355 sbdirty(); 356 } 357 358 /* 359 * When doing background fsck on a snapshot, figure out whether 360 * the superblock summary is inaccurate and correct it when 361 * necessary. 362 */ 363 if (cursnapshot != 0) { 364 cmd.size = 1; 365 366 cmd.value = cstotal.cs_ndir - fs->fs_cstotal.cs_ndir; 367 if (cmd.value != 0) { 368 if (debug) 369 printf("adjndir by %+" PRIi64 "\n", cmd.value); 370 if (bkgrdsumadj == 0 || sysctl(adjndir, MIBSIZE, 0, 0, 371 &cmd, sizeof cmd) == -1) 372 rwerror("ADJUST NUMBER OF DIRECTORIES", cmd.value); 373 } 374 375 cmd.value = cstotal.cs_nbfree - fs->fs_cstotal.cs_nbfree; 376 if (cmd.value != 0) { 377 if (debug) 378 printf("adjnbfree by %+" PRIi64 "\n", cmd.value); 379 if (bkgrdsumadj == 0 || sysctl(adjnbfree, MIBSIZE, 0, 0, 380 &cmd, sizeof cmd) == -1) 381 rwerror("ADJUST NUMBER OF FREE BLOCKS", cmd.value); 382 } 383 384 cmd.value = cstotal.cs_nifree - fs->fs_cstotal.cs_nifree; 385 if (cmd.value != 0) { 386 if (debug) 387 printf("adjnifree by %+" PRIi64 "\n", cmd.value); 388 if (bkgrdsumadj == 0 || sysctl(adjnifree, MIBSIZE, 0, 0, 389 &cmd, sizeof cmd) == -1) 390 rwerror("ADJUST NUMBER OF FREE INODES", cmd.value); 391 } 392 393 cmd.value = cstotal.cs_nffree - fs->fs_cstotal.cs_nffree; 394 if (cmd.value != 0) { 395 if (debug) 396 printf("adjnffree by %+" PRIi64 "\n", cmd.value); 397 if (bkgrdsumadj == 0 || sysctl(adjnffree, MIBSIZE, 0, 0, 398 &cmd, sizeof cmd) == -1) 399 rwerror("ADJUST NUMBER OF FREE FRAGS", cmd.value); 400 } 401 402 cmd.value = cstotal.cs_numclusters - fs->fs_cstotal.cs_numclusters; 403 if (cmd.value != 0) { 404 if (debug) 405 printf("adjnumclusters by %+" PRIi64 "\n", cmd.value); 406 if (bkgrdsumadj == 0 || sysctl(adjnumclusters, MIBSIZE, 0, 0, 407 &cmd, sizeof cmd) == -1) 408 rwerror("ADJUST NUMBER OF FREE CLUSTERS", cmd.value); 409 } 410 } 411} 412 413/* 414 * Compare the original cylinder group inode and block bitmaps with the 415 * updated cylinder group inode and block bitmaps. Free inodes and blocks 416 * that have been added. Complain if any previously freed inodes blocks 417 * are now allocated. 418 */ 419void 420update_maps( 421 struct cg *oldcg, /* cylinder group of claimed allocations */ 422 struct cg *newcg, /* cylinder group of determined allocations */ 423 int usesysctl) /* 1 => use sysctl interface to update maps */ 424{ 425 int inomapsize, excessdirs; 426 struct fs *fs = &sblock; 427 428 inomapsize = howmany(fs->fs_ipg, CHAR_BIT); 429 excessdirs = oldcg->cg_cs.cs_ndir - newcg->cg_cs.cs_ndir; 430 if (excessdirs < 0) { 431 pfatal("LOST %d DIRECTORIES\n", -excessdirs); 432 excessdirs = 0; 433 } 434 if (excessdirs > 0) 435 check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize, 436 oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "DIR", freedirs, 437 0, excessdirs, usesysctl); 438 check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize, 439 oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "FILE", freefiles, 440 excessdirs, fs->fs_ipg, usesysctl); 441 check_maps(cg_blksfree(oldcg), cg_blksfree(newcg), 442 howmany(fs->fs_fpg, CHAR_BIT), 443 oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_fpg, "FRAG", 444 freeblks, 0, fs->fs_fpg, usesysctl); 445} 446 447static void 448check_maps( 449 u_char *map1, /* map of claimed allocations */ 450 u_char *map2, /* map of determined allocations */ 451 int mapsize, /* size of above two maps */ 452 ufs2_daddr_t startvalue, /* resource value for first element in map */ 453 const char *name, /* name of resource found in maps */ 454 int *opcode, /* sysctl opcode to free resource */ 455 int skip, /* number of entries to skip before starting to free */ 456 int limit, /* limit on number of entries to free */ 457 int usesysctl) /* 1 => use sysctl interface to update maps */ 458{ 459# define BUFSIZE 16 460 char buf[BUFSIZE]; 461 long i, j, k, l, m, size; 462 ufs2_daddr_t n, astart, aend, ustart, uend; 463 void (*msg)(const char *fmt, ...); 464 465 if (usesysctl) 466 msg = pfatal; 467 else 468 msg = pwarn; 469 astart = ustart = aend = uend = -1; 470 for (i = 0; i < mapsize; i++) { 471 j = *map1++; 472 k = *map2++; 473 if (j == k) 474 continue; 475 for (m = 0, l = 1; m < CHAR_BIT; m++, l <<= 1) { 476 if ((j & l) == (k & l)) 477 continue; 478 n = startvalue + i * CHAR_BIT + m; 479 if ((j & l) != 0) { 480 if (astart == -1) { 481 astart = aend = n; 482 continue; 483 } 484 if (aend + 1 == n) { 485 aend = n; 486 continue; 487 } 488 if (astart == aend) 489 (*msg)("ALLOCATED %s %" PRId64 490 " MARKED FREE\n", 491 name, astart); 492 else 493 (*msg)("%s %sS %" PRId64 "-%" PRId64 494 " MARKED FREE\n", 495 "ALLOCATED", name, astart, aend); 496 astart = aend = n; 497 } else { 498 if (ustart == -1) { 499 ustart = uend = n; 500 continue; 501 } 502 if (uend + 1 == n) { 503 uend = n; 504 continue; 505 } 506 size = uend - ustart + 1; 507 if (size <= skip) { 508 skip -= size; 509 ustart = uend = n; 510 continue; 511 } 512 if (skip > 0) { 513 ustart += skip; 514 size -= skip; 515 skip = 0; 516 } 517 if (size > limit) 518 size = limit; 519 if (debug && size == 1) 520 pwarn("%s %s %" PRId64 521 " MARKED USED\n", 522 "UNALLOCATED", name, ustart); 523 else if (debug) 524 pwarn("%s %sS %" PRId64 "-%" PRId64 525 " MARKED USED\n", 526 "UNALLOCATED", name, ustart, 527 ustart + size - 1); 528 if (usesysctl != 0) { 529 cmd.value = ustart; 530 cmd.size = size; 531 if (sysctl(opcode, MIBSIZE, 0, 0, 532 &cmd, sizeof cmd) == -1) { 533 snprintf(buf, BUFSIZE, 534 "FREE %s", name); 535 rwerror(buf, cmd.value); 536 } 537 } 538 limit -= size; 539 if (limit <= 0) 540 return; 541 ustart = uend = n; 542 } 543 } 544 } 545 if (astart != -1) { 546 if (astart == aend) 547 (*msg)("ALLOCATED %s %" PRId64 548 " MARKED FREE\n", name, astart); 549 else 550 (*msg)("ALLOCATED %sS %" PRId64 "-%" PRId64 551 " MARKED FREE\n", 552 name, astart, aend); 553 } 554 if (ustart != -1) { 555 size = uend - ustart + 1; 556 if (size <= skip) 557 return; 558 if (skip > 0) { 559 ustart += skip; 560 size -= skip; 561 } 562 if (size > limit) 563 size = limit; 564 if (debug) { 565 if (size == 1) 566 pwarn("UNALLOCATED %s %" PRId64 567 " MARKED USED\n", 568 name, ustart); 569 else 570 pwarn("UNALLOCATED %sS %" PRId64 "-%" PRId64 571 " MARKED USED\n", 572 name, ustart, ustart + size - 1); 573 } 574 if (usesysctl != 0) { 575 cmd.value = ustart; 576 cmd.size = size; 577 if (sysctl(opcode, MIBSIZE, 0, 0, &cmd, 578 sizeof cmd) == -1) { 579 snprintf(buf, BUFSIZE, "FREE %s", name); 580 rwerror(buf, cmd.value); 581 } 582 } 583 } 584} 585 586static void 587clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end) 588{ 589 590 if (debug) 591 printf("Zero frags %jd to %jd\n", start, end); 592 if (Zflag) 593 blzero(fswritefd, fsbtodb(&sblock, start), 594 lfragtosize(&sblock, end - start + 1)); 595 if (Eflag) 596 blerase(fswritefd, fsbtodb(&sblock, start), 597 lfragtosize(&sblock, end - start + 1)); 598} 599