/*- * SPDX-License-Identifier: BSD-3-Clause AND BSD-2-Clause-FreeBSD * * Copyright (c) 2006 Pawel Jakub Dawidek * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "fsck.h" void gjournal_check(const char *filesys) { struct fs *fs; struct inode ip; union dinode *dp; struct bufarea *cgbp; struct cg *cgp; struct inodesc idesc; uint8_t *inosused; ino_t cino, ino; int cg; fs = &sblock; /* Are there any unreferenced inodes in this file system? */ if (fs->fs_unrefs == 0) { //printf("No unreferenced inodes.\n"); sbdirty(); ckfini(1); return; } for (cg = 0; cg < fs->fs_ncg; cg++) { /* Show progress if requested. */ if (got_siginfo) { printf("%s: phase j: cyl group %d of %d (%d%%)\n", cdevname, cg, fs->fs_ncg, cg * 100 / fs->fs_ncg); got_siginfo = 0; } if (got_sigalarm) { setproctitle("%s pj %d%%", cdevname, cg * 100 / fs->fs_ncg); got_sigalarm = 0; } cgbp = cglookup(cg); cgp = cgbp->b_un.b_cg; if (!check_cgmagic(cg, cgbp, 0)) { rerun = 1; ckfini(0); return; } /* Are there any unreferenced inodes in this cylinder group? */ if (cgp->cg_unrefs == 0) continue; //printf("Analizing cylinder group %d (count=%d)\n", cg, cgp->cg_unrefs); /* * Now go through the list of all inodes in this cylinder group * to find unreferenced ones. */ inosused = cg_inosused(cgp); for (cino = 0; cino < fs->fs_ipg; cino++) { ino = fs->fs_ipg * cg + cino; /* Unallocated? Skip it. */ if (isclr(inosused, cino)) continue; ginode(ino, &ip); dp = ip.i_dp; /* Not a regular file nor directory? Skip it. */ if (!S_ISREG(dp->dp2.di_mode) && !S_ISDIR(dp->dp2.di_mode)) { irelse(&ip); continue; } /* Has reference(s)? Skip it. */ if (dp->dp2.di_nlink > 0) { irelse(&ip); continue; } /* printf("Clearing inode=%d (size=%jd)\n", ino, (intmax_t)dp->dp2->di_size); */ /* Deallocate it. */ memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = freeblock; idesc.id_number = ino; clri(&idesc, "UNREF", 1); clrbit(inosused, cino); /* Update position of last used inode. */ if (ino < cgp->cg_irotor) cgp->cg_irotor = ino; /* Update statistics. */ cgp->cg_unrefs--; fs->fs_unrefs--; /* Zero-fill the inode. */ dp->dp2 = zino.dp2; /* Write the inode back. */ inodirty(&ip); irelse(&ip); cgdirty(cgbp); if (cgp->cg_unrefs == 0) { //printf("No more unreferenced inodes in cg=%d.\n", cg); break; } } /* * If there are no more unreferenced inodes, there is no need to * check other cylinder groups. */ if (fs->fs_unrefs == 0) { //printf("No more unreferenced inodes (cg=%d/%d).\n", cg, // fs->fs_ncg); break; } } /* Write back updated statistics and super-block. */ sbdirty(); ckfini(1); }