diff --git a/sbin/Makefile b/sbin/Makefile index a0cfa58e7ffb..d65d5375fad6 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -21,7 +21,6 @@ SUBDIR= adjkerntz \ ffsinfo \ fsck \ fsck_ffs \ - fsck_ifs \ fsck_msdosfs \ fsdb \ fsirand \ @@ -42,7 +41,6 @@ SUBDIR= adjkerntz \ mount \ mount_cd9660 \ mount_ext2fs \ - mount_ifs \ mount_msdosfs \ mount_nfs \ mount_ntfs \ diff --git a/sbin/fsck_ifs/Makefile b/sbin/fsck_ifs/Makefile deleted file mode 100644 index c16ac80b3089..000000000000 --- a/sbin/fsck_ifs/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ -# @(#)Makefile 8.2 (Berkeley) 4/27/95 - -PROG= fsck_ifs -NOMAN= true -SRCS= dir.c fsutil.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ - pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c -WARNS= 0 - -.PATH: ${.CURDIR}/../../sys/ufs/ffs - -.include diff --git a/sbin/fsck_ifs/dir.c b/sbin/fsck_ifs/dir.c deleted file mode 100644 index 8d24768286ea..000000000000 --- a/sbin/fsck_ifs/dir.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include - -#include -#include -#include - -#include -#include - -#include "fsck.h" - -char *lfname = "lost+found"; -int lfmode = 01777; -struct dirtemplate emptydir = { 0, DIRBLKSIZ }; -struct dirtemplate dirhead = { - 0, 12, DT_DIR, 1, ".", - 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." -}; -struct odirtemplate odirhead = { - 0, 12, 1, ".", - 0, DIRBLKSIZ - 12, 2, ".." -}; - -static int chgino(struct inodesc *); -static int dircheck(struct inodesc *, struct direct *); -static int expanddir(struct dinode *dp, char *name); -static void freedir(ino_t ino, ino_t parent); -static struct direct *fsck_readdir(struct inodesc *); -static struct bufarea *getdirblk(ufs_daddr_t blkno, long size); -static int lftempname(char *bufp, ino_t ino); -static int mkentry(struct inodesc *); - -/* - * Propagate connected state through the tree. - */ -void -propagate(void) -{ - struct inoinfo **inpp, *inp; - struct inoinfo **inpend; - long change; - - inpend = &inpsort[inplast]; - do { - change = 0; - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_parent == 0) - continue; - if (inoinfo(inp->i_parent)->ino_state == DFOUND && - inoinfo(inp->i_number)->ino_state == DSTATE) { - inoinfo(inp->i_number)->ino_state = DFOUND; - change++; - } - } - } while (change > 0); -} - -/* - * Scan each entry in a directory block. - */ -int -dirscan(struct inodesc *idesc) -{ - struct direct *dp; - struct bufarea *bp; - int dsize, n; - long blksiz; - char dbuf[DIRBLKSIZ]; - - if (idesc->id_type != DATA) - errx(EEXIT, "wrong type to dirscan %d", idesc->id_type); - if (idesc->id_entryno == 0 && - (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0) - idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ); - blksiz = idesc->id_numfrags * sblock.fs_fsize; - if (chkrange(idesc->id_blkno, idesc->id_numfrags)) { - idesc->id_filesize -= blksiz; - return (SKIP); - } - idesc->id_loc = 0; - for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { - dsize = dp->d_reclen; - if (dsize > sizeof(dbuf)) - dsize = sizeof(dbuf); - memmove(dbuf, dp, (size_t)dsize); -# if (BYTE_ORDER == LITTLE_ENDIAN) - if (!newinofmt) { - struct direct *tdp = (struct direct *)dbuf; - u_char tmp; - - tmp = tdp->d_namlen; - tdp->d_namlen = tdp->d_type; - tdp->d_type = tmp; - } -# endif - idesc->id_dirp = (struct direct *)dbuf; - if ((n = (*idesc->id_func)(idesc)) & ALTERED) { -# if (BYTE_ORDER == LITTLE_ENDIAN) - if (!newinofmt && !doinglevel2) { - struct direct *tdp; - u_char tmp; - - tdp = (struct direct *)dbuf; - tmp = tdp->d_namlen; - tdp->d_namlen = tdp->d_type; - tdp->d_type = tmp; - } -# endif - bp = getdirblk(idesc->id_blkno, blksiz); - memmove(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf, - (size_t)dsize); - dirty(bp); - sbdirty(); - } - if (n & STOP) - return (n); - } - return (idesc->id_filesize > 0 ? KEEPON : STOP); -} - -/* - * get next entry in a directory. - */ -static struct direct * -fsck_readdir(struct inodesc *idesc) -{ - struct direct *dp, *ndp; - struct bufarea *bp; - long size, blksiz, fix, dploc; - - blksiz = idesc->id_numfrags * sblock.fs_fsize; - bp = getdirblk(idesc->id_blkno, blksiz); - if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 && - idesc->id_loc < blksiz) { - dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); - if (dircheck(idesc, dp)) - goto dpok; - if (idesc->id_fix == IGNORE) - return (0); - fix = dofix(idesc, "DIRECTORY CORRUPTED"); - bp = getdirblk(idesc->id_blkno, blksiz); - dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); - dp->d_reclen = DIRBLKSIZ; - dp->d_ino = 0; - dp->d_type = 0; - dp->d_namlen = 0; - dp->d_name[0] = '\0'; - if (fix) - dirty(bp); - idesc->id_loc += DIRBLKSIZ; - idesc->id_filesize -= DIRBLKSIZ; - return (dp); - } -dpok: - if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz) - return NULL; - dploc = idesc->id_loc; - dp = (struct direct *)(bp->b_un.b_buf + dploc); - idesc->id_loc += dp->d_reclen; - idesc->id_filesize -= dp->d_reclen; - if ((idesc->id_loc % DIRBLKSIZ) == 0) - return (dp); - ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); - if (idesc->id_loc < blksiz && idesc->id_filesize > 0 && - dircheck(idesc, ndp) == 0) { - size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); - idesc->id_loc += size; - idesc->id_filesize -= size; - if (idesc->id_fix == IGNORE) - return (0); - fix = dofix(idesc, "DIRECTORY CORRUPTED"); - bp = getdirblk(idesc->id_blkno, blksiz); - dp = (struct direct *)(bp->b_un.b_buf + dploc); - dp->d_reclen += size; - if (fix) - dirty(bp); - } - return (dp); -} - -/* - * Verify that a directory entry is valid. - * This is a superset of the checks made in the kernel. - */ -static int -dircheck(struct inodesc *idesc, struct direct *dp) -{ - int size; - char *cp; - u_char namlen, type; - int spaceleft; - - spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); - if (dp->d_reclen == 0 || - dp->d_reclen > spaceleft || - (dp->d_reclen & 0x3) != 0) - goto bad; - if (dp->d_ino == 0) - return (1); - size = DIRSIZ(!newinofmt, dp); -# if (BYTE_ORDER == LITTLE_ENDIAN) - if (!newinofmt) { - type = dp->d_namlen; - namlen = dp->d_type; - } else { - namlen = dp->d_namlen; - type = dp->d_type; - } -# else - namlen = dp->d_namlen; - type = dp->d_type; -# endif - if (dp->d_reclen < size || - idesc->id_filesize < size || - namlen > MAXNAMLEN || - type > 15) - goto bad; - for (cp = dp->d_name, size = 0; size < namlen; size++) - if (*cp == '\0' || (*cp++ == '/')) - goto bad; - if (*cp != '\0') - goto bad; - return (1); -bad: - if (debug) - printf("Bad dir: ino %d reclen %d namlen %d type %d name %s\n", - dp->d_ino, dp->d_reclen, dp->d_namlen, dp->d_type, - dp->d_name); - return (0); -} - -void -direrror(ino_t ino, char *errmesg) -{ - - fileerror(ino, ino, errmesg); -} - -void -fileerror(ino_t cwd, ino_t ino, char *errmesg) -{ - struct dinode *dp; - char pathbuf[MAXPATHLEN + 1]; - - pwarn("%s ", errmesg); - pinode(ino); - printf("\n"); - getpathname(pathbuf, cwd, ino); - if (ino < ROOTINO || ino > maxino) { - pfatal("NAME=%s\n", pathbuf); - return; - } - dp = ginode(ino); - if (ftypeok(dp)) - pfatal("%s=%s\n", - (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); - else - pfatal("NAME=%s\n", pathbuf); -} - -void -adjust(struct inodesc *idesc, int lcnt) -{ - struct dinode *dp; - int saveresolved; - - dp = ginode(idesc->id_number); - if (dp->di_nlink == lcnt) { - /* - * If we have not hit any unresolved problems, are running - * in preen mode, and are on a filesystem using soft updates, - * then just toss any partially allocated files. - */ - if (resolved && preen && usedsoftdep) { - clri(idesc, "UNREF", 1); - return; - } else { - /* - * The filesystem can be marked clean even if - * a file is not linked up, but is cleared. - * Hence, resolved should not be cleared when - * linkup is answered no, but clri is answered yes. - */ - saveresolved = resolved; - if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) { - resolved = saveresolved; - clri(idesc, "UNREF", 0); - return; - } - /* - * Account for the new reference created by linkup(). - */ - dp = ginode(idesc->id_number); - lcnt--; - } - } - if (lcnt != 0) { - pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : - ((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE")); - pinode(idesc->id_number); - printf(" COUNT %d SHOULD BE %d", - dp->di_nlink, dp->di_nlink - lcnt); - if (preen || usedsoftdep) { - if (lcnt < 0) { - printf("\n"); - pfatal("LINK COUNT INCREASING"); - } - if (preen) - printf(" (ADJUSTED)\n"); - } - if (preen || reply("ADJUST") == 1) { - dp->di_nlink -= lcnt; - inodirty(); - } - } -} - -static int -mkentry(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - struct direct newent; - int newlen, oldlen; - - newent.d_namlen = strlen(idesc->id_name); - newlen = DIRSIZ(0, &newent); - if (dirp->d_ino != 0) - oldlen = DIRSIZ(0, dirp); - else - oldlen = 0; - if (dirp->d_reclen - oldlen < newlen) - return (KEEPON); - newent.d_reclen = dirp->d_reclen - oldlen; - dirp->d_reclen = oldlen; - dirp = (struct direct *)(((char *)dirp) + oldlen); - dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ - dirp->d_reclen = newent.d_reclen; - if (newinofmt) - dirp->d_type = inoinfo(idesc->id_parent)->ino_type; - else - dirp->d_type = 0; - dirp->d_namlen = newent.d_namlen; - memmove(dirp->d_name, idesc->id_name, (size_t)newent.d_namlen + 1); -# if (BYTE_ORDER == LITTLE_ENDIAN) - /* - * If the entry was split, dirscan() will only reverse the byte - * order of the original entry, and not the new one, before - * writing it back out. So, we reverse the byte order here if - * necessary. - */ - if (oldlen != 0 && !newinofmt && !doinglevel2) { - u_char tmp; - - tmp = dirp->d_namlen; - dirp->d_namlen = dirp->d_type; - dirp->d_type = tmp; - } -# endif - return (ALTERED|STOP); -} - -static int -chgino(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - - if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1)) - return (KEEPON); - dirp->d_ino = idesc->id_parent; - if (newinofmt) - dirp->d_type = inoinfo(idesc->id_parent)->ino_type; - else - dirp->d_type = 0; - return (ALTERED|STOP); -} - -int -linkup(ino_t orphan, ino_t parentdir, char *name) -{ - struct dinode *dp; - int lostdir; - ino_t oldlfdir; - struct inodesc idesc; - char tempname[BUFSIZ]; - - memset(&idesc, 0, sizeof(struct inodesc)); - dp = ginode(orphan); - lostdir = (dp->di_mode & IFMT) == IFDIR; - pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); - pinode(orphan); - if (preen && dp->di_size == 0) - return (0); - if (preen) - printf(" (RECONNECTED)\n"); - else - if (reply("RECONNECT") == 0) - return (0); - if (lfdir == 0) { - dp = ginode(ROOTINO); - idesc.id_name = lfname; - idesc.id_type = DATA; - idesc.id_func = findino; - idesc.id_number = ROOTINO; - if ((ckinode(dp, &idesc) & FOUND) != 0) { - lfdir = idesc.id_parent; - } else { - pwarn("NO lost+found DIRECTORY"); - if (preen || reply("CREATE")) { - lfdir = allocdir(ROOTINO, (ino_t)0, lfmode); - if (lfdir != 0) { - if (makeentry(ROOTINO, lfdir, lfname) != 0) { - numdirs++; - if (preen) - printf(" (CREATED)\n"); - } else { - freedir(lfdir, ROOTINO); - lfdir = 0; - if (preen) - printf("\n"); - } - } - } - } - if (lfdir == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY"); - printf("\n\n"); - return (0); - } - } - dp = ginode(lfdir); - if ((dp->di_mode & IFMT) != IFDIR) { - pfatal("lost+found IS NOT A DIRECTORY"); - if (reply("REALLOCATE") == 0) - return (0); - oldlfdir = lfdir; - if ((lfdir = allocdir(ROOTINO, (ino_t)0, lfmode)) == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n"); - return (0); - } - if ((changeino(ROOTINO, lfname, lfdir) & ALTERED) == 0) { - pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n"); - return (0); - } - inodirty(); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - idesc.id_number = oldlfdir; - adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1); - inoinfo(oldlfdir)->ino_linkcnt = 0; - dp = ginode(lfdir); - } - if (inoinfo(lfdir)->ino_state != DFOUND) { - pfatal("SORRY. NO lost+found DIRECTORY\n\n"); - return (0); - } - (void)lftempname(tempname, orphan); - if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) { - pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); - printf("\n\n"); - return (0); - } - inoinfo(orphan)->ino_linkcnt--; - if (lostdir) { - if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 && - parentdir != (ino_t)-1) - (void)makeentry(orphan, lfdir, ".."); - dp = ginode(lfdir); - dp->di_nlink++; - inodirty(); - inoinfo(lfdir)->ino_linkcnt++; - pwarn("DIR I=%lu CONNECTED. ", orphan); - if (parentdir != (ino_t)-1) { - printf("PARENT WAS I=%lu\n", (u_long)parentdir); - /* - * The parent directory, because of the ordering - * guarantees, has had the link count incremented - * for the child, but no entry was made. This - * fixes the parent link count so that fsck does - * not need to be rerun. - */ - inoinfo(parentdir)->ino_linkcnt++; - } - if (preen == 0) - printf("\n"); - } - return (1); -} - -/* - * fix an entry in a directory. - */ -int -changeino(ino_t dir, char *name, ino_t newnum) -{ - struct inodesc idesc; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_func = chgino; - idesc.id_number = dir; - idesc.id_fix = DONTKNOW; - idesc.id_name = name; - idesc.id_parent = newnum; /* new value for name */ - return (ckinode(ginode(dir), &idesc)); -} - -/* - * make an entry in a directory - */ -int -makeentry(ino_t parent, ino_t ino, char *name) -{ - struct dinode *dp; - struct inodesc idesc; - char pathbuf[MAXPATHLEN + 1]; - - if (parent < ROOTINO || parent >= maxino || - ino < ROOTINO || ino >= maxino) - return (0); - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_func = mkentry; - idesc.id_number = parent; - idesc.id_parent = ino; /* this is the inode to enter */ - idesc.id_fix = DONTKNOW; - idesc.id_name = name; - dp = ginode(parent); - if (dp->di_size % DIRBLKSIZ) { - dp->di_size = roundup(dp->di_size, DIRBLKSIZ); - inodirty(); - } - if ((ckinode(dp, &idesc) & ALTERED) != 0) - return (1); - getpathname(pathbuf, parent, parent); - dp = ginode(parent); - if (expanddir(dp, pathbuf) == 0) - return (0); - return (ckinode(dp, &idesc) & ALTERED); -} - -/* - * Attempt to expand the size of a directory - */ -static int -expanddir(struct dinode *dp, char *name) -{ - ufs_daddr_t lastbn, newblk; - struct bufarea *bp; - char *cp, firstblk[DIRBLKSIZ]; - - lastbn = lblkno(&sblock, dp->di_size); - if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) - return (0); - if ((newblk = allocblk(sblock.fs_frag)) == 0) - return (0); - dp->di_db[lastbn + 1] = dp->di_db[lastbn]; - dp->di_db[lastbn] = newblk; - dp->di_size += sblock.fs_bsize; - dp->di_blocks += btodb(sblock.fs_bsize); - bp = getdirblk(dp->di_db[lastbn + 1], - (long)dblksize(&sblock, dp, lastbn + 1)); - if (bp->b_errs) - goto bad; - memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ); - bp = getdirblk(newblk, sblock.fs_bsize); - if (bp->b_errs) - goto bad; - memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ); - for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; - cp < &bp->b_un.b_buf[sblock.fs_bsize]; - cp += DIRBLKSIZ) - memmove(cp, &emptydir, sizeof emptydir); - dirty(bp); - bp = getdirblk(dp->di_db[lastbn + 1], - (long)dblksize(&sblock, dp, lastbn + 1)); - if (bp->b_errs) - goto bad; - memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir); - pwarn("NO SPACE LEFT IN %s", name); - if (preen) - printf(" (EXPANDED)\n"); - else if (reply("EXPAND") == 0) - goto bad; - dirty(bp); - inodirty(); - return (1); -bad: - dp->di_db[lastbn] = dp->di_db[lastbn + 1]; - dp->di_db[lastbn + 1] = 0; - dp->di_size -= sblock.fs_bsize; - dp->di_blocks -= btodb(sblock.fs_bsize); - freeblk(newblk, sblock.fs_frag); - return (0); -} - -/* - * allocate a new directory - */ -ino_t -allocdir(ino_t parent, ino_t request, int mode) -{ - ino_t ino; - char *cp; - struct dinode *dp; - struct bufarea *bp; - struct inoinfo *inp; - struct dirtemplate *dirp; - - ino = allocino(request, IFDIR|mode); - if (newinofmt) - dirp = &dirhead; - else - dirp = (struct dirtemplate *)&odirhead; - dirp->dot_ino = ino; - dirp->dotdot_ino = parent; - dp = ginode(ino); - bp = getdirblk(dp->di_db[0], sblock.fs_fsize); - if (bp->b_errs) { - freeino(ino); - return (0); - } - memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate)); - for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; - cp < &bp->b_un.b_buf[sblock.fs_fsize]; - cp += DIRBLKSIZ) - memmove(cp, &emptydir, sizeof emptydir); - dirty(bp); - dp->di_nlink = 2; - inodirty(); - if (ino == ROOTINO) { - inoinfo(ino)->ino_linkcnt = dp->di_nlink; - cacheino(dp, ino); - return(ino); - } - if (inoinfo(parent)->ino_state != DSTATE && - inoinfo(parent)->ino_state != DFOUND) { - freeino(ino); - return (0); - } - cacheino(dp, ino); - inp = getinoinfo(ino); - inp->i_parent = parent; - inp->i_dotdot = parent; - inoinfo(ino)->ino_state = inoinfo(parent)->ino_state; - if (inoinfo(ino)->ino_state == DSTATE) { - inoinfo(ino)->ino_linkcnt = dp->di_nlink; - inoinfo(parent)->ino_linkcnt++; - } - dp = ginode(parent); - dp->di_nlink++; - inodirty(); - return (ino); -} - -/* - * free a directory inode - */ -static void -freedir(ino_t ino, ino_t parent) -{ - struct dinode *dp; - - if (ino != parent) { - dp = ginode(parent); - dp->di_nlink--; - inodirty(); - } - freeino(ino); -} - -/* - * generate a temporary name for the lost+found directory. - */ -static int -lftempname(char *bufp, ino_t ino) -{ - ino_t in; - char *cp; - int namlen; - - cp = bufp + 2; - for (in = maxino; in > 0; in /= 10) - cp++; - *--cp = 0; - namlen = cp - bufp; - in = ino; - while (cp > bufp) { - *--cp = (in % 10) + '0'; - in /= 10; - } - *cp = '#'; - return (namlen); -} - -/* - * Get a directory block. - * Insure that it is held until another is requested. - */ -static struct bufarea * -getdirblk(ufs_daddr_t blkno, long size) -{ - - if (pdirbp != 0) - pdirbp->b_flags &= ~B_INUSE; - pdirbp = getdatablk(blkno, size); - return (pdirbp); -} diff --git a/sbin/fsck_ifs/fsck.h b/sbin/fsck_ifs/fsck.h deleted file mode 100644 index 2173cd4da682..000000000000 --- a/sbin/fsck_ifs/fsck.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - * - * @(#)fsck.h 8.4 (Berkeley) 5/9/95 - * $FreeBSD$ - */ - -#include -#include -#include - -#define MAXDUP 10 /* limit on dup blks (per inode) */ -#define MAXBAD 10 /* limit on bad blks (per inode) */ -#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ -#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */ - -/* - * Each inode on the filesystem is described by the following structure. - * The linkcnt is initially set to the value in the inode. Each time it - * is found during the descent in passes 2, 3, and 4 the count is - * decremented. Any inodes whose count is non-zero after pass 4 needs to - * have its link count adjusted by the value remaining in ino_linkcnt. - */ -struct inostat { - char ino_state; /* state of inode, see below */ - char ino_type; /* type of inode */ - short ino_linkcnt; /* number of links not found */ -}; -/* - * Inode states. - */ -#define USTATE 01 /* inode not allocated */ -#define FSTATE 02 /* inode is file */ -#define DSTATE 03 /* inode is directory */ -#define DFOUND 04 /* directory found during descent */ -#define DCLEAR 05 /* directory is to be cleared */ -#define FCLEAR 06 /* file is to be cleared */ -/* - * Inode state information is contained on per cylinder group lists - * which are described by the following structure. - */ -struct inostatlist { - long il_numalloced; /* number of inodes allocated in this cg */ - struct inostat *il_stat;/* inostat info for this cylinder group */ -} *inostathead; - -/* - * buffer cache structure. - */ -struct bufarea { - struct bufarea *b_next; /* free list queue */ - struct bufarea *b_prev; /* free list queue */ - ufs_daddr_t b_bno; - int b_size; - int b_errs; - int b_flags; - union { - char *b_buf; /* buffer space */ - ufs_daddr_t *b_indir; /* indirect block */ - struct fs *b_fs; /* super block */ - struct cg *b_cg; /* cylinder group */ - struct dinode *b_dinode; /* inode block */ - } b_un; - char b_dirty; -}; - -#define B_INUSE 1 - -#define MINBUFS 5 /* minimum number of buffers required */ -struct bufarea bufhead; /* head of list of other blks in filesys */ -struct bufarea sblk; /* filesystem superblock */ -struct bufarea cgblk; /* cylinder group blocks */ -struct bufarea *pdirbp; /* current directory contents */ -struct bufarea *pbp; /* current inode block */ - -#define dirty(bp) (bp)->b_dirty = 1 -#define initbarea(bp) \ - (bp)->b_dirty = 0; \ - (bp)->b_bno = (ufs_daddr_t)-1; \ - (bp)->b_flags = 0; - -#define sbdirty() sblk.b_dirty = 1 -#define cgdirty() cgblk.b_dirty = 1 -#define sblock (*sblk.b_un.b_fs) -#define cgrp (*cgblk.b_un.b_cg) - -enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; -ino_t cursnapshot; - -struct inodesc { - enum fixstate id_fix; /* policy on fixing errors */ - int (*id_func)(); /* function to be applied to blocks of inode */ - ino_t id_number; /* inode number described */ - ino_t id_parent; /* for DATA nodes, their parent */ - int id_lbn; /* logical block number of current block */ - ufs_daddr_t id_blkno; /* current block number being examined */ - int id_numfrags; /* number of frags contained in block */ - quad_t id_filesize; /* for DATA nodes, the size of the directory */ - int id_loc; /* for DATA nodes, current location in dir */ - int id_entryno; /* for DATA nodes, current entry number */ - struct direct *id_dirp; /* for DATA nodes, ptr to current entry */ - char *id_name; /* for DATA nodes, name to find or enter */ - char id_type; /* type of descriptor, DATA or ADDR */ -}; -/* file types */ -#define DATA 1 /* a directory */ -#define SNAP 2 /* a snapshot */ -#define ADDR 3 /* anything but a directory or a snapshot */ - -/* - * Linked list of duplicate blocks. - * - * The list is composed of two parts. The first part of the - * list (from duplist through the node pointed to by muldup) - * contains a single copy of each duplicate block that has been - * found. The second part of the list (from muldup to the end) - * contains duplicate blocks that have been found more than once. - * To check if a block has been found as a duplicate it is only - * necessary to search from duplist through muldup. To find the - * total number of times that a block has been found as a duplicate - * the entire list must be searched for occurences of the block - * in question. The following diagram shows a sample list where - * w (found twice), x (found once), y (found three times), and z - * (found once) are duplicate block numbers: - * - * w -> y -> x -> z -> y -> w -> y - * ^ ^ - * | | - * duplist muldup - */ -struct dups { - struct dups *next; - ufs_daddr_t dup; -}; -struct dups *duplist; /* head of dup list */ -struct dups *muldup; /* end of unique duplicate dup block numbers */ - -/* - * Linked list of inodes with zero link counts. - */ -struct zlncnt { - struct zlncnt *next; - ino_t zlncnt; -}; -struct zlncnt *zlnhead; /* head of zero link count list */ - -/* - * Inode cache data structures. - */ -struct inoinfo { - struct inoinfo *i_nexthash; /* next entry in hash chain */ - ino_t i_number; /* inode number of this entry */ - ino_t i_parent; /* inode number of parent */ - ino_t i_dotdot; /* inode number of `..' */ - size_t i_isize; /* size of inode */ - u_int i_numblks; /* size of block array in bytes */ - ufs_daddr_t i_blks[1]; /* actually longer */ -} **inphead, **inpsort; -long numdirs, dirhash, listmax, inplast; -long countdirs; /* number of directories we actually found */ - -char *cdevname; /* name of device being checked */ -long dev_bsize; /* computed value of DEV_BSIZE */ -long secsize; /* actual disk sector size */ -char fflag; /* force check, ignore clean flag */ -char nflag; /* assume a no response */ -char yflag; /* assume a yes response */ -int bflag; /* location of alternate super block */ -int debug; /* output debugging info */ -int cvtlevel; /* convert to newer filesystem format */ -int doinglevel1; /* converting to new cylinder group format */ -int doinglevel2; /* converting to new inode format */ -int newinofmt; /* filesystem has new inode format */ -char usedsoftdep; /* just fix soft dependency inconsistencies */ -char preen; /* just fix normal inconsistencies */ -char rerun; /* rerun fsck. Only used in non-preen mode */ -int returntosingle; /* 1 => return to single user mode on exit */ -char resolved; /* cleared if unresolved changes => not clean */ -int markclean; /* mark filesystem clean when done */ -char havesb; /* superblock has been read */ -char skipclean; /* skip clean filesystems if preening */ -int fsmodified; /* 1 => write done to filesystem */ -int fsreadfd; /* file descriptor for reading filesystem */ -int fswritefd; /* file descriptor for writing filesystem */ - -ufs_daddr_t maxfsblock; /* number of blocks in the filesystem */ -char *blockmap; /* ptr to primary blk allocation map */ -ino_t maxino; /* number of inodes in filesystem */ - -ino_t lfdir; /* lost & found directory inode number */ -char *lfname; /* lost & found directory name */ -int lfmode; /* lost & found directory creation mode */ - -ufs_daddr_t n_blks; /* number of blocks in use */ -ufs_daddr_t n_files; /* number of files in use */ - -#define clearinode(dp) (*(dp) = zino) -struct dinode zino; - -#define setbmap(blkno) setbit(blockmap, blkno) -#define testbmap(blkno) isset(blockmap, blkno) -#define clrbmap(blkno) clrbit(blockmap, blkno) - -#define STOP 0x01 -#define SKIP 0x02 -#define KEEPON 0x04 -#define ALTERED 0x08 -#define FOUND 0x10 - -#define EEXIT 8 /* Standard error exit. */ - -struct fstab; - - -void adjust(struct inodesc *, int lcnt); -ufs_daddr_t allocblk(long frags); -ino_t allocdir(ino_t parent, ino_t request, int mode); -ino_t allocino(ino_t request, int type); -void blkerror(ino_t ino, char *type, ufs_daddr_t blk); -char *blockcheck(char *name); -int bread(int fd, char *buf, ufs_daddr_t blk, long size); -void bufinit(void); -void bwrite(int fd, char *buf, ufs_daddr_t blk, long size); -void cacheino(struct dinode *dp, ino_t inumber); -void catch(int); -void catchquit(int); -int changeino(ino_t dir, char *name, ino_t newnum); -int chkrange(ufs_daddr_t blk, int cnt); -void ckfini(int markclean); -int ckinode(struct dinode *dp, struct inodesc *); -void clri(struct inodesc *, char *type, int flag); -int clearentry(struct inodesc *); -void direrror(ino_t ino, char *errmesg); -int dirscan(struct inodesc *); -int dofix(struct inodesc *, char *msg); -void ffs_clrblock(struct fs *, u_char *, ufs_daddr_t); -void ffs_fragacct(struct fs *, int, int32_t [], int); -int ffs_isblock(struct fs *, u_char *, ufs_daddr_t); -void ffs_setblock(struct fs *, u_char *, ufs_daddr_t); -void fileerror(ino_t cwd, ino_t ino, char *errmesg); -int findino(struct inodesc *); -int findname(struct inodesc *); -void flush(int fd, struct bufarea *bp); -void freeblk(ufs_daddr_t blkno, long frags); -void freeino(ino_t ino); -void freeinodebuf(void); -int ftypeok(struct dinode *dp); -void getblk(struct bufarea *bp, ufs_daddr_t blk, long size); -struct bufarea *getdatablk(ufs_daddr_t blkno, long size); -struct inoinfo *getinoinfo(ino_t inumber); -struct dinode *getnextinode(ino_t inumber); -void getpathname(char *namebuf, ino_t curdir, ino_t ino); -struct dinode *ginode(ino_t inumber); -void inocleanup(void); -void inodirty(void); -struct inostat *inoinfo(ino_t inum); -int linkup(ino_t orphan, ino_t parentdir, char *name); -int makeentry(ino_t parent, ino_t ino, char *name); -void panic(const char *fmt, ...) __printflike(1, 2); -void pass1(void); -void pass1b(void); -int pass1check(struct inodesc *); -void pass2(void); -void pass3(void); -void pass4(void); -int pass4check(struct inodesc *); -void pass5(void); -void pfatal(const char *fmt, ...) __printflike(1, 2); -void pinode(ino_t ino); -void propagate(void); -void pwarn(const char *fmt, ...) __printflike(1, 2); -int reply(char *question); -void setinodebuf(ino_t); -int setup(char *dev); -void voidquit(int); diff --git a/sbin/fsck_ifs/fsck_ifs.8 b/sbin/fsck_ifs/fsck_ifs.8 deleted file mode 100644 index 23f7f0945cce..000000000000 --- a/sbin/fsck_ifs/fsck_ifs.8 +++ /dev/null @@ -1,322 +0,0 @@ -.\" -.\" Copyright (c) 1980, 1989, 1991, 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. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgment: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. 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. -.\" -.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 -.\" $FreeBSD$ -.\" -.Dd November 15, 1996 -.Dt FSCK 8 -.Os -.Sh NAME -.Nm fsck -.Nd filesystem consistency check and interactive repair -.Sh SYNOPSIS -.Nm -.Fl p -.Op Fl f -.Op Fl m Ar mode -.Op Ar filesystem -.Ar ... -.Nm -.Op Fl ny -.Op Fl b Ar block# -.Op Fl c Ar level -.Op Fl l Ar maxparallel -.Op Fl m Ar mode -.Op Ar filesystem -.Ar ... -.Sh DESCRIPTION -The first form of -.Nm -preens a standard set of filesystems or the specified filesystems. -It is normally used in the script -.Pa /etc/rc -during automatic reboot. -Here -.Nm -reads the table -.Pa /etc/fstab -to determine which filesystems to check. -Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro'' -and that have non-zero pass number are checked. -Filesystems with pass number 1 (normally just the root filesystem) -are checked one at a time. -When pass 1 completes, all remaining filesystems are checked, -running one process per disk drive. -The disk drive containing each filesystem is inferred from the longest prefix -of the device name that ends in a digit; the remaining characters are assumed -to be the partition designator. -.Pp -In "preen" mode the clean flag of each filesystem's superblock is examined -and only those filesystems that -are not marked clean are checked. -Filesystems are marked clean when they are unmounted, -when they have been mounted read-only, or when -.Nm -runs on them successfully. -If the -.Fl f -option is specified, the filesystems -will be checked regardless of the state of their clean flag. -.Pp -The kernel takes care that only a restricted class of innocuous filesystem -inconsistencies can happen unless hardware or software failures intervene. -These are limited to the following: -.Pp -.Bl -item -compact -offset indent -.It -Unreferenced inodes -.It -Link counts in inodes too large -.It -Missing blocks in the free map -.It -Blocks in the free map also in files -.It -Counts in the super-block wrong -.El -.Pp -These are the only inconsistencies that -.Nm -with the -.Fl p -option will correct; if it encounters other inconsistencies, it exits -with an abnormal return status and an automatic reboot will then fail. -For each corrected inconsistency one or more lines will be printed -identifying the filesystem on which the correction will take place, -and the nature of the correction. After successfully correcting a filesystem, -.Nm -will print the number of files on that filesystem, -the number of used and free blocks, -and the percentage of fragmentation. -.Pp -If sent a -.Dv QUIT -signal, -.Nm -will finish the filesystem checks, then exit with an abnormal -return status that causes an automatic reboot to fail. -This is useful when you want to finish the filesystem checks during an -automatic reboot, -but do not want the machine to come up multiuser after the checks complete. -.Pp -Without the -.Fl p -option, -.Nm -audits and interactively repairs inconsistent conditions for filesystems. -If the filesystem is inconsistent the operator is prompted for concurrence -before each correction is attempted. -It should be noted that some of the corrective actions which are not -correctable under the -.Fl p -option will result in some loss of data. -The amount and severity of data lost may be determined from the diagnostic -output. -The default action for each consistency correction -is to wait for the operator to respond -.Li yes -or -.Li no . -If the operator does not have write permission on the filesystem -.Nm -will default to a -.Fl n -action. -.Pp -.Nm Fsck -has more consistency checks than -its predecessors -.Em check , dcheck , fcheck , -and -.Em icheck -combined. -.Pp -The following flags are interpreted by -.Nm . -.Bl -tag -width indent -.It Fl b -Use the block specified immediately after the flag as -the super block for the filesystem. Block 32 is usually -an alternate super block. -.It Fl c -Convert the filesystem to the specified level. -Note that the level of a filesystem can only be raised. -There are currently four levels defined: -.Bl -tag -width indent -.It 0 -The filesystem is in the old (static table) format. -.It 1 -The filesystem is in the new (dynamic table) format. -.It 2 -The filesystem supports 32-bit uid's and gid's, -short symbolic links are stored in the inode, -and directories have an added field showing the file type. -.It 3 -If maxcontig is greater than one, -build the free segment maps to aid in finding contiguous sets of blocks. -If maxcontig is equal to one, delete any existing segment maps. -.El -.Pp -In interactive mode, -.Nm -will list the conversion to be made -and ask whether the conversion should be done. -If a negative answer is given, -no further operations are done on the filesystem. -In preen mode, -the conversion is listed and done if -possible without user interaction. -Conversion in preen mode is best used when all the filesystems -are being converted at once. -The format of a filesystem can be determined from the -first line of output from -.Xr dumpfs 8 . -.It Fl f -Force -.Nm -to check -.Sq clean -filesystems when preening. -.It Fl l -Limit the number of parallel checks to the number specified in the following -argument. -By default, the limit is the number of disks, running one process per disk. -If a smaller limit is given, the disks are checked round-robin, one filesystem -at a time. -.It Fl m -Use the mode specified in octal immediately after the flag as the -permission bits to use when creating the -.Pa lost+found -directory rather than the default 1777. -In particular, systems that do not wish to have lost files accessible -by all users on the system should use a more restrictive -set of permissions such as 700. -.It Fl n -Assume a no response to all questions asked by -.Nm -except for -.Ql CONTINUE? , -which is assumed to be affirmative; -do not open the filesystem for writing. -.It Fl p -Preen filesystems (see above). -.It Fl y -Assume a yes response to all questions asked by -.Nm ; -this should be used with great caution as this is a free license -to continue after essentially unlimited trouble has been encountered. -.El -.Pp -If no filesystems are given to -.Nm -then a default list of filesystems is read from -the file -.Pa /etc/fstab . -.Pp -Inconsistencies checked are as follows: -.Pp -.Bl -enum -compact -.It -Blocks claimed by more than one inode or the free map. -.It -Blocks claimed by an inode outside the range of the filesystem. -.It -Incorrect link counts. -.It -Size checks: -.Bl -item -offset indent -compact -.It -Directory size not a multiple of DIRBLKSIZ. -.It -Partially truncated file. -.El -.It -Bad inode format. -.It -Blocks not accounted for anywhere. -.It -Directory checks: -.Bl -item -offset indent -compact -.It -File pointing to unallocated inode. -.It -Inode number out of range. -.It -Directories with unallocated blocks (holes). -.It -Dot or dot-dot not the first two entries of a directory -or having the wrong inode number. -.El -.It -Super Block checks: -.Bl -item -offset indent -compact -.It -More blocks for inodes than there are in the filesystem. -.It -Bad free block map format. -.It -Total free block and/or free inode count incorrect. -.El -.El -.Pp -Orphaned files and directories (allocated but unreferenced) are, -with the operator's concurrence, reconnected by -placing them in the -.Pa lost+found -directory. -The name assigned is the inode number. -If the -.Pa lost+found -directory does not exist, it is created. -If there is insufficient space its size is increased. -.Pp -Because of inconsistencies between the block device and the buffer cache, -the raw device should always be used. -.Sh FILES -.Bl -tag -width /etc/fstab -compact -.It Pa /etc/fstab -contains default list of filesystems to check. -.El -.Sh DIAGNOSTICS -The diagnostics produced by -.Nm -are fully enumerated and explained in Appendix A of -.Rs -.%T "Fsck \- The UNIX File System Check Program" -.Re -.Sh SEE ALSO -.Xr fs 5 , -.Xr fstab 5 , -.Xr fsdb 8 , -.Xr newfs 8 , -.Xr reboot 8 diff --git a/sbin/fsck_ifs/fsutil.c b/sbin/fsck_ifs/fsutil.c deleted file mode 100644 index 5b6faba9eb3d..000000000000 --- a/sbin/fsck_ifs/fsutil.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsck.h" - -long diskreads, totalreads; /* Disk cache statistics */ - -static void rwerror(char *mesg, ufs_daddr_t blk); - -int -ftypeok(struct dinode *dp) -{ - switch (dp->di_mode & IFMT) { - - case IFDIR: - case IFREG: - case IFBLK: - case IFCHR: - case IFLNK: - case IFSOCK: - case IFIFO: - return (1); - - default: - if (debug) - printf("bad file type 0%o\n", dp->di_mode); - return (0); - } -} - -int -reply(char *question) -{ - int persevere; - char c; - - if (preen) - pfatal("INTERNAL ERROR: GOT TO reply()"); - persevere = !strcmp(question, "CONTINUE"); - printf("\n"); - if (!persevere && (nflag || fswritefd < 0)) { - printf("%s? no\n\n", question); - resolved = 0; - return (0); - } - if (yflag || (persevere && nflag)) { - printf("%s? yes\n\n", question); - return (1); - } - do { - printf("%s? [yn] ", question); - (void) fflush(stdout); - c = getc(stdin); - while (c != '\n' && getc(stdin) != '\n') { - if (feof(stdin)) { - resolved = 0; - return (0); - } - } - } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); - printf("\n"); - if (c == 'y' || c == 'Y') - return (1); - resolved = 0; - return (0); -} - -/* - * Look up state information for an inode. - */ -struct inostat * -inoinfo(ino_t inum) -{ - static struct inostat unallocated = { USTATE, 0, 0 }; - struct inostatlist *ilp; - int iloff; - - if (inum > maxino) - errx(EEXIT, "inoinfo: inumber %d out of range", inum); - ilp = &inostathead[inum / sblock.fs_ipg]; - iloff = inum % sblock.fs_ipg; - if (iloff >= ilp->il_numalloced) - return (&unallocated); - return (&ilp->il_stat[iloff]); -} - -/* - * Malloc buffers and set up cache. - */ -void -bufinit(void) -{ - struct bufarea *bp; - long bufcnt, i; - char *bufp; - - pbp = pdirbp = (struct bufarea *)0; - bufp = malloc((unsigned int)sblock.fs_bsize); - if (bufp == 0) - errx(EEXIT, "cannot allocate buffer pool"); - cgblk.b_un.b_buf = bufp; - initbarea(&cgblk); - bufhead.b_next = bufhead.b_prev = &bufhead; - bufcnt = MAXBUFSPACE / sblock.fs_bsize; - if (bufcnt < MINBUFS) - bufcnt = MINBUFS; - for (i = 0; i < bufcnt; i++) { - bp = (struct bufarea *)malloc(sizeof(struct bufarea)); - bufp = malloc((unsigned int)sblock.fs_bsize); - if (bp == NULL || bufp == NULL) { - if (i >= MINBUFS) - break; - errx(EEXIT, "cannot allocate buffer pool"); - } - bp->b_un.b_buf = bufp; - bp->b_prev = &bufhead; - bp->b_next = bufhead.b_next; - bufhead.b_next->b_prev = bp; - bufhead.b_next = bp; - initbarea(bp); - } - bufhead.b_size = i; /* save number of buffers */ -} - -/* - * Manage a cache of directory blocks. - */ -struct bufarea * -getdatablk(ufs_daddr_t blkno, long size) -{ - struct bufarea *bp; - - for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next) - if (bp->b_bno == fsbtodb(&sblock, blkno)) - goto foundit; - for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev) - if ((bp->b_flags & B_INUSE) == 0) - break; - if (bp == &bufhead) - errx(EEXIT, "deadlocked buffer pool"); - getblk(bp, blkno, size); - /* fall through */ -foundit: - totalreads++; - bp->b_prev->b_next = bp->b_next; - bp->b_next->b_prev = bp->b_prev; - bp->b_prev = &bufhead; - bp->b_next = bufhead.b_next; - bufhead.b_next->b_prev = bp; - bufhead.b_next = bp; - bp->b_flags |= B_INUSE; - return (bp); -} - -void -getblk(struct bufarea *bp, ufs_daddr_t blk, long size) -{ - ufs_daddr_t dblk; - - dblk = fsbtodb(&sblock, blk); - if (bp->b_bno != dblk) { - flush(fswritefd, bp); - diskreads++; - bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size); - bp->b_bno = dblk; - bp->b_size = size; - } -} - -void -flush(int fd, struct bufarea *bp) -{ - int i, j; - - if (!bp->b_dirty) - return; - if (bp->b_errs != 0) - pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n", - (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ", - bp->b_bno); - bp->b_dirty = 0; - bp->b_errs = 0; - bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); - if (bp != &sblk) - return; - for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { - bwrite(fswritefd, (char *)sblock.fs_csp + i, - fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), - sblock.fs_cssize - i < sblock.fs_bsize ? - sblock.fs_cssize - i : sblock.fs_bsize); - } -} - -static void -rwerror(char *mesg, ufs_daddr_t blk) -{ - - if (preen == 0) - printf("\n"); - pfatal("CANNOT %s: BLK %ld", mesg, blk); - if (reply("CONTINUE") == 0) - exit(EEXIT); -} - -void -ckfini(int markclean) -{ - struct bufarea *bp, *nbp; - int ofsmodified, cnt = 0; - - if (fswritefd < 0) { - (void)close(fsreadfd); - return; - } - flush(fswritefd, &sblk); - if (havesb && sblk.b_bno != SBOFF / dev_bsize && - !preen && reply("UPDATE STANDARD SUPERBLOCK")) { - sblk.b_bno = SBOFF / dev_bsize; - sbdirty(); - flush(fswritefd, &sblk); - } - flush(fswritefd, &cgblk); - free(cgblk.b_un.b_buf); - for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { - cnt++; - flush(fswritefd, bp); - nbp = bp->b_prev; - free(bp->b_un.b_buf); - free((char *)bp); - } - if (bufhead.b_size != cnt) - errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt); - pbp = pdirbp = (struct bufarea *)0; - if (sblock.fs_clean != markclean) { - sblock.fs_clean = markclean; - sbdirty(); - ofsmodified = fsmodified; - flush(fswritefd, &sblk); - fsmodified = ofsmodified; - if (!preen) { - printf("\n***** FILE SYSTEM MARKED %s *****\n", - markclean ? "CLEAN" : "DIRTY"); - if (!markclean) - rerun = 1; - } - } else if (!preen && !markclean) { - printf("\n***** FILE SYSTEM STILL DIRTY *****\n"); - rerun = 1; - } - if (debug) - printf("cache missed %ld of %ld (%d%%)\n", diskreads, - totalreads, (int)(diskreads * 100 / totalreads)); - (void)close(fsreadfd); - (void)close(fswritefd); -} - -int -bread(int fd, char *buf, ufs_daddr_t blk, long size) -{ - char *cp; - int i, errs; - off_t offset; - - offset = blk; - offset *= dev_bsize; - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - else if (read(fd, buf, (int)size) == size) - return (0); - rwerror("READ", blk); - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - errs = 0; - memset(buf, 0, (size_t)size); - printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); - for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { - if (read(fd, cp, (int)secsize) != secsize) { - (void)lseek(fd, offset + i + secsize, 0); - if (secsize != dev_bsize && dev_bsize != 1) - printf(" %ld (%ld),", - (blk * dev_bsize + i) / secsize, - blk + i / dev_bsize); - else - printf(" %ld,", blk + i / dev_bsize); - errs++; - } - } - printf("\n"); - if (errs) - resolved = 0; - return (errs); -} - -void -bwrite(int fd, char *buf, ufs_daddr_t blk, long size) -{ - int i; - char *cp; - off_t offset; - - if (fd < 0) - return; - offset = blk; - offset *= dev_bsize; - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - else if (write(fd, buf, (int)size) == size) { - fsmodified = 1; - return; - } - resolved = 0; - rwerror("WRITE", blk); - if (lseek(fd, offset, 0) < 0) - rwerror("SEEK", blk); - printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:"); - for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize) - if (write(fd, cp, (int)dev_bsize) != dev_bsize) { - (void)lseek(fd, offset + i + dev_bsize, 0); - printf(" %ld,", blk + i / dev_bsize); - } - printf("\n"); - return; -} - -/* - * allocate a data block with the specified number of fragments - */ -ufs_daddr_t -allocblk(long frags) -{ - int i, j, k, cg, baseblk; - struct cg *cgp = &cgrp; - - if (frags <= 0 || frags > sblock.fs_frag) - return (0); - for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) { - for (j = 0; j <= sblock.fs_frag - frags; j++) { - if (testbmap(i + j)) - continue; - for (k = 1; k < frags; k++) - if (testbmap(i + j + k)) - break; - if (k < frags) { - j += k; - continue; - } - cg = dtog(&sblock, i + j); - getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); - if (!cg_chkmagic(cgp)) - pfatal("CG %d: BAD MAGIC NUMBER\n", cg); - baseblk = dtogd(&sblock, i + j); - for (k = 0; k < frags; k++) { - setbmap(i + j + k); - clrbit(cg_blksfree(cgp), baseblk + k); - } - n_blks += frags; - if (frags == sblock.fs_frag) - cgp->cg_cs.cs_nbfree--; - else - cgp->cg_cs.cs_nffree -= frags; - cgdirty(); - return (i + j); - } - } - return (0); -} - -/* - * Free a previously allocated block - */ -void -freeblk(ufs_daddr_t blkno, long frags) -{ - struct inodesc idesc; - - idesc.id_blkno = blkno; - idesc.id_numfrags = frags; - (void)pass4check(&idesc); -} - -/* - * Find a pathname - */ -void -getpathname(char *namebuf, ino_t curdir, ino_t ino) -{ - int len; - char *cp; - struct inodesc idesc; - static int busy = 0; - - if (curdir == ino && ino == ROOTINO) { - (void)strcpy(namebuf, "/"); - return; - } - if (busy || - (inoinfo(curdir)->ino_state != DSTATE && - inoinfo(curdir)->ino_state != DFOUND)) { - (void)strcpy(namebuf, "?"); - return; - } - busy = 1; - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_fix = IGNORE; - cp = &namebuf[MAXPATHLEN - 1]; - *cp = '\0'; - if (curdir != ino) { - idesc.id_parent = curdir; - goto namelookup; - } - while (ino != ROOTINO) { - idesc.id_number = ino; - idesc.id_func = findino; - idesc.id_name = ".."; - if ((ckinode(ginode(ino), &idesc) & FOUND) == 0) - break; - namelookup: - idesc.id_number = idesc.id_parent; - idesc.id_parent = ino; - idesc.id_func = findname; - idesc.id_name = namebuf; - if ((ckinode(ginode(idesc.id_number), &idesc)&FOUND) == 0) - break; - len = strlen(namebuf); - cp -= len; - memmove(cp, namebuf, (size_t)len); - *--cp = '/'; - if (cp < &namebuf[MAXNAMLEN]) - break; - ino = idesc.id_number; - } - busy = 0; - if (ino != ROOTINO) - *--cp = '?'; - memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp)); -} - -void -catch(int sig) -{ - if (!doinglevel2) - ckfini(0); - exit(12); -} - -/* - * When preening, allow a single quit to signal - * a special exit after filesystem checks complete - * so that reboot sequence may be interrupted. - */ -void -catchquit(int sig) -{ - printf("returning to single-user after filesystem check\n"); - returntosingle = 1; - (void)signal(SIGQUIT, SIG_DFL); -} - -/* - * Ignore a single quit signal; wait and flush just in case. - * Used by child processes in preen. - */ -void -voidquit(int sig) -{ - - sleep(1); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGQUIT, SIG_DFL); -} - -/* - * determine whether an inode should be fixed. - */ -int -dofix(struct inodesc *idesc, char *msg) -{ - - switch (idesc->id_fix) { - - case DONTKNOW: - if (idesc->id_type == DATA) - direrror(idesc->id_number, msg); - else - pwarn("%s", msg); - if (preen) { - printf(" (SALVAGED)\n"); - idesc->id_fix = FIX; - return (ALTERED); - } - if (reply("SALVAGE") == 0) { - idesc->id_fix = NOFIX; - return (0); - } - idesc->id_fix = FIX; - return (ALTERED); - - case FIX: - return (ALTERED); - - case NOFIX: - case IGNORE: - return (0); - - default: - errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix); - } - /* NOTREACHED */ - return (0); -} - -#include - -/* - * An unexpected inconsistency occured. - * Die if preening or filesystem is running with soft dependency protocol, - * otherwise just print message and continue. - */ -void -pfatal(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (!preen) { - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (usedsoftdep) - (void)fprintf(stderr, - "\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n"); - return; - } - if (cdevname == NULL) - cdevname = "fsck"; - (void)fprintf(stderr, "%s: ", cdevname); - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, - "\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n", - cdevname, usedsoftdep ? " SOFT UPDATE " : " "); - ckfini(0); - exit(EEXIT); -} - -/* - * Pwarn just prints a message when not preening or running soft dependency - * protocol, or a warning (preceded by filename) when preening. - */ -void -pwarn(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (preen) - (void)fprintf(stderr, "%s: ", cdevname); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); -} - -/* - * Stub for routines from kernel. - */ -void -panic(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - pfatal("INTERNAL INCONSISTENCY:"); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - exit(EEXIT); -} diff --git a/sbin/fsck_ifs/inode.c b/sbin/fsck_ifs/inode.c deleted file mode 100644 index 20ff339fcc6d..000000000000 --- a/sbin/fsck_ifs/inode.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "fsck.h" - -static ino_t startinum; - -static int iblock(struct inodesc *, long ilevel, quad_t isize); - -int -ckinode(struct dinode *dp, struct inodesc *idesc) -{ - ufs_daddr_t *ap; - int ret; - long n, ndb, offset; - struct dinode dino; - quad_t remsize, sizepb; - mode_t mode; - char pathbuf[MAXPATHLEN + 1]; - - if (idesc->id_fix != IGNORE) - idesc->id_fix = DONTKNOW; - idesc->id_lbn = -1; - idesc->id_entryno = 0; - idesc->id_filesize = dp->di_size; - mode = dp->di_mode & IFMT; - if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && - dp->di_size < (unsigned)sblock.fs_maxsymlinklen)) - return (KEEPON); - dino = *dp; - ndb = howmany(dino.di_size, sblock.fs_bsize); - for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { - idesc->id_lbn++; - if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) - idesc->id_numfrags = - numfrags(&sblock, fragroundup(&sblock, offset)); - else - idesc->id_numfrags = sblock.fs_frag; - if (*ap == 0) { - if (idesc->id_type == DATA && ndb >= 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, idesc->id_number, - idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - dp->di_size = (ap - &dino.di_db[0]) * - sblock.fs_bsize; - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - - } - } - continue; - } - idesc->id_blkno = *ap; - if (idesc->id_type != DATA) - ret = (*idesc->id_func)(idesc); - else - ret = dirscan(idesc); - if (ret & STOP) - return (ret); - } - idesc->id_numfrags = sblock.fs_frag; - remsize = dino.di_size - sblock.fs_bsize * NDADDR; - sizepb = sblock.fs_bsize; - for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { - sizepb *= NINDIR(&sblock); - if (*ap) { - idesc->id_blkno = *ap; - ret = iblock(idesc, n, remsize); - if (ret & STOP) - return (ret); - } else { - idesc->id_lbn += sizepb / sblock.fs_bsize; - if (idesc->id_type == DATA && remsize > 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, idesc->id_number, - idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - dp->di_size -= remsize; - remsize = 0; - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - break; - } - } - } - remsize -= sizepb; - } - return (KEEPON); -} - -static int -iblock(struct inodesc *idesc, long ilevel, quad_t isize) -{ - ufs_daddr_t *ap; - ufs_daddr_t *aplim; - struct bufarea *bp; - int i, n, (*func)(), nif; - quad_t sizepb; - char buf[BUFSIZ]; - char pathbuf[MAXPATHLEN + 1]; - struct dinode *dp; - - if (idesc->id_type != DATA) { - func = idesc->id_func; - if (((n = (*func)(idesc)) & KEEPON) == 0) - return (n); - } else - func = dirscan; - if (chkrange(idesc->id_blkno, idesc->id_numfrags)) - return (SKIP); - bp = getdatablk(idesc->id_blkno, sblock.fs_bsize); - ilevel--; - for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) - sizepb *= NINDIR(&sblock); - nif = howmany(isize , sizepb); - if (nif > NINDIR(&sblock)) - nif = NINDIR(&sblock); - if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) { - aplim = &bp->b_un.b_indir[NINDIR(&sblock)]; - for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) { - if (*ap == 0) - continue; - (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu", - (u_long)idesc->id_number); - if (dofix(idesc, buf)) { - *ap = 0; - dirty(bp); - } - } - flush(fswritefd, bp); - } - aplim = &bp->b_un.b_indir[nif]; - for (ap = bp->b_un.b_indir; ap < aplim; ap++) { - if (ilevel == 0) - idesc->id_lbn++; - if (*ap) { - idesc->id_blkno = *ap; - if (ilevel == 0) - n = (*func)(idesc); - else - n = iblock(idesc, ilevel, isize); - if (n & STOP) { - bp->b_flags &= ~B_INUSE; - return (n); - } - } else { - if (idesc->id_type == DATA && isize > 0) { - /* An empty block in a directory XXX */ - getpathname(pathbuf, idesc->id_number, - idesc->id_number); - pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", - pathbuf); - if (reply("ADJUST LENGTH") == 1) { - dp = ginode(idesc->id_number); - dp->di_size -= isize; - isize = 0; - printf( - "YOU MUST RERUN FSCK AFTERWARDS\n"); - rerun = 1; - inodirty(); - bp->b_flags &= ~B_INUSE; - return(STOP); - } - } - } - isize -= sizepb; - } - bp->b_flags &= ~B_INUSE; - return (KEEPON); -} - -/* - * Check that a block in a legal block number. - * Return 0 if in range, 1 if out of range. - */ -int -chkrange(ufs_daddr_t blk, int cnt) -{ - int c; - - if (cnt <= 0 || blk <= 0 || blk > maxfsblock || - cnt - 1 > maxfsblock - blk) - return (1); - if (cnt > sblock.fs_frag || - fragnum(&sblock, blk) + cnt > sblock.fs_frag) { - if (debug) - printf("bad size: blk %ld, offset %ld, size %ld\n", - blk, fragnum(&sblock, blk), cnt); - return (1); - } - c = dtog(&sblock, blk); - if (blk < cgdmin(&sblock, c)) { - if ((blk + cnt) > cgsblock(&sblock, c)) { - if (debug) { - printf("blk %ld < cgdmin %ld;", - (long)blk, (long)cgdmin(&sblock, c)); - printf(" blk + cnt %ld > cgsbase %ld\n", - (long)(blk + cnt), - (long)cgsblock(&sblock, c)); - } - return (1); - } - } else { - if ((blk + cnt) > cgbase(&sblock, c+1)) { - if (debug) { - printf("blk %ld >= cgdmin %ld;", - (long)blk, (long)cgdmin(&sblock, c)); - printf(" blk + cnt %ld > sblock.fs_fpg %ld\n", - (long)(blk + cnt), (long)sblock.fs_fpg); - } - return (1); - } - } - return (0); -} - -/* - * General purpose interface for reading inodes. - */ -struct dinode * -ginode(ino_t inumber) -{ - ufs_daddr_t iblk; - - if (inumber < ROOTINO || inumber > maxino) - errx(EEXIT, "bad inode number %d to ginode", inumber); - if (startinum == 0 || - inumber < startinum || inumber >= startinum + INOPB(&sblock)) { - iblk = ino_to_fsba(&sblock, inumber); - if (pbp != 0) - pbp->b_flags &= ~B_INUSE; - pbp = getdatablk(iblk, sblock.fs_bsize); - startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); - } - return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]); -} - -/* - * Special purpose version of ginode used to optimize first pass - * over all the inodes in numerical order. - */ -ino_t nextino, lastinum, lastvalidinum; -long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; -struct dinode *inodebuf; - -struct dinode * -getnextinode(ino_t inumber) -{ - long size; - ufs_daddr_t dblk; - static struct dinode *dp; - - if (inumber != nextino++ || inumber > lastvalidinum) - errx(EEXIT, "bad inode number %d to nextinode", inumber); - if (inumber >= lastinum) { - readcnt++; - dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); - if (readcnt % readpercg == 0) { - size = partialsize; - lastinum += partialcnt; - } else { - size = inobufsize; - lastinum += fullcnt; - } - /* - * If bread returns an error, it will already have zeroed - * out the buffer, so we do not need to do so here. - */ - (void)bread(fsreadfd, (char *)inodebuf, dblk, size); - dp = inodebuf; - } - return (dp++); -} - -void -setinodebuf(ino_t inum) -{ - - if (inum % sblock.fs_ipg != 0) - errx(EEXIT, "bad inode number %d to setinodebuf", inum); - lastvalidinum = inum + sblock.fs_ipg - 1; - startinum = 0; - nextino = inum; - lastinum = inum; - readcnt = 0; - if (inodebuf != NULL) - return; - inobufsize = blkroundup(&sblock, INOBUFSIZE); - fullcnt = inobufsize / sizeof(struct dinode); - readpercg = sblock.fs_ipg / fullcnt; - partialcnt = sblock.fs_ipg % fullcnt; - partialsize = partialcnt * sizeof(struct dinode); - if (partialcnt != 0) { - readpercg++; - } else { - partialcnt = fullcnt; - partialsize = inobufsize; - } - if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL) - errx(EEXIT, "cannot allocate space for inode buffer"); -} - -void -freeinodebuf(void) -{ - - if (inodebuf != NULL) - free((char *)inodebuf); - inodebuf = NULL; -} - -/* - * Routines to maintain information about directory inodes. - * This is built during the first pass and used during the - * second and third passes. - * - * Enter inodes into the cache. - */ -void -cacheino(struct dinode *dp, ino_t inumber) -{ - struct inoinfo *inp; - struct inoinfo **inpp; - int blks; - - blks = howmany(dp->di_size, sblock.fs_bsize); - if (blks > NDADDR) - blks = NDADDR + NIADDR; - inp = (struct inoinfo *) - malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t)); - if (inp == NULL) - errx(EEXIT, "cannot increase directory list"); - inpp = &inphead[inumber % dirhash]; - inp->i_nexthash = *inpp; - *inpp = inp; - inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0; - inp->i_dotdot = (ino_t)0; - inp->i_number = inumber; - inp->i_isize = dp->di_size; - inp->i_numblks = blks * sizeof(ufs_daddr_t); - memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks); - if (inplast == listmax) { - listmax += 100; - inpsort = (struct inoinfo **)realloc((char *)inpsort, - (unsigned)listmax * sizeof(struct inoinfo *)); - if (inpsort == NULL) - errx(EEXIT, "cannot increase directory list"); - } - inpsort[inplast++] = inp; -} - -/* - * Look up an inode cache structure. - */ -struct inoinfo * -getinoinfo(ino_t inumber) -{ - struct inoinfo *inp; - - for (inp = inphead[inumber % dirhash]; inp; inp = inp->i_nexthash) { - if (inp->i_number != inumber) - continue; - return (inp); - } - errx(EEXIT, "cannot find inode %d", inumber); - return ((struct inoinfo *)0); -} - -/* - * Clean up all the inode cache structure. - */ -void -inocleanup(void) -{ - struct inoinfo **inpp; - - if (inphead == NULL) - return; - for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) - free((char *)(*inpp)); - free((char *)inphead); - free((char *)inpsort); - inphead = inpsort = NULL; -} - -void -inodirty(void) -{ - - dirty(pbp); -} - -void -clri(struct inodesc *idesc, char *type, int flag) -{ - struct dinode *dp; - - dp = ginode(idesc->id_number); - if (flag == 1) { - pwarn("%s %s", type, - (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"); - pinode(idesc->id_number); - } - if (preen || reply("CLEAR") == 1) { - if (preen) - printf(" (CLEARED)\n"); - n_files--; - (void)ckinode(dp, idesc); - clearinode(dp); - inoinfo(idesc->id_number)->ino_state = USTATE; - inodirty(); - } -} - -int -findname(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - - if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) { - idesc->id_entryno++; - return (KEEPON); - } - memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1); - return (STOP|FOUND); -} - -int -findino(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - - if (dirp->d_ino == 0) - return (KEEPON); - if (strcmp(dirp->d_name, idesc->id_name) == 0 && - dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) { - idesc->id_parent = dirp->d_ino; - return (STOP|FOUND); - } - return (KEEPON); -} - -int -clearentry(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - - if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) { - idesc->id_entryno++; - return (KEEPON); - } - dirp->d_ino = 0; - return (STOP|FOUND|ALTERED); -} - -void -pinode(ino_t ino) -{ - struct dinode *dp; - char *p; - struct passwd *pw; - time_t t; - - printf(" I=%lu ", (u_long)ino); - if (ino < ROOTINO || ino > maxino) - return; - dp = ginode(ino); - printf(" OWNER="); - if ((pw = getpwuid((int)dp->di_uid)) != 0) - printf("%s ", pw->pw_name); - else - printf("%u ", (unsigned)dp->di_uid); - printf("MODE=%o\n", dp->di_mode); - if (preen) - printf("%s: ", cdevname); - printf("SIZE=%qu ", dp->di_size); - t = dp->di_mtime; - p = ctime(&t); - printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); -} - -void -blkerror(ino_t ino, char *type, ufs_daddr_t blk) -{ - - pfatal("%ld %s I=%lu", blk, type, ino); - printf("\n"); - switch (inoinfo(ino)->ino_state) { - - case FSTATE: - inoinfo(ino)->ino_state = FCLEAR; - return; - - case DSTATE: - inoinfo(ino)->ino_state = DCLEAR; - return; - - case FCLEAR: - case DCLEAR: - return; - - default: - errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state); - /* NOTREACHED */ - } -} - -/* - * allocate an unused inode - */ -ino_t -allocino(ino_t request, int type) -{ - ino_t ino; - struct dinode *dp; - struct cg *cgp = &cgrp; - int cg; - - if (request == 0) - request = ROOTINO; - else if (inoinfo(request)->ino_state != USTATE) - return (0); - for (ino = request; ino < maxino; ino++) - if (inoinfo(ino)->ino_state == USTATE) - break; - if (ino == maxino) - return (0); - cg = ino_to_cg(&sblock, ino); - getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); - if (!cg_chkmagic(cgp)) - pfatal("CG %d: BAD MAGIC NUMBER\n", cg); - setbit(cg_inosused(cgp), ino % sblock.fs_ipg); - cgp->cg_cs.cs_nifree--; - switch (type & IFMT) { - case IFDIR: - inoinfo(ino)->ino_state = DSTATE; - cgp->cg_cs.cs_ndir++; - break; - case IFREG: - case IFLNK: - inoinfo(ino)->ino_state = FSTATE; - break; - default: - return (0); - } - cgdirty(); - dp = ginode(ino); - dp->di_db[0] = allocblk((long)1); - if (dp->di_db[0] == 0) { - inoinfo(ino)->ino_state = USTATE; - return (0); - } - dp->di_mode = type; - dp->di_flags = 0; - dp->di_atime = time(NULL); - dp->di_mtime = dp->di_ctime = dp->di_atime; - dp->di_mtimensec = dp->di_ctimensec = dp->di_atimensec = 0; - dp->di_size = sblock.fs_fsize; - dp->di_blocks = btodb(sblock.fs_fsize); - n_files++; - inodirty(); - if (newinofmt) - inoinfo(ino)->ino_type = IFTODT(type); - return (ino); -} - -/* - * deallocate an inode - */ -void -freeino(ino_t ino) -{ - struct inodesc idesc; - struct dinode *dp; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - idesc.id_number = ino; - dp = ginode(ino); - (void)ckinode(dp, &idesc); - clearinode(dp); - inodirty(); - inoinfo(ino)->ino_state = USTATE; - n_files--; -} diff --git a/sbin/fsck_ifs/main.c b/sbin/fsck_ifs/main.c deleted file mode 100644 index 046ee4477690..000000000000 --- a/sbin/fsck_ifs/main.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1980, 1986, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; -#endif -#endif /* not lint */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "fsck.h" - -int returntosingle; - -static void usage(void) __dead2; -static int argtoi(int flag, char *req, char *str, int base); -static int docheck(struct fstab *fsp); -static int checkfilesys(char *filesys, char *mntpt, long auxdata, int child); -static struct statfs *getmntpt(const char *); - -int -main(int argc, char *argv[]) -{ - int ch; - struct rlimit rlimit; - int ret = 0; - - sync(); - skipclean = 1; - markclean = 1; - while ((ch = getopt(argc, argv, "b:c:dfFm:npy")) != -1) { - switch (ch) { - case 'b': - skipclean = 0; - bflag = argtoi('b', "number", optarg, 10); - printf("Alternate super block location: %d\n", bflag); - break; - - case 'c': - skipclean = 0; - cvtlevel = argtoi('c', "conversion level", optarg, 10); - break; - - case 'd': - debug++; - break; - - case 'f': - skipclean = 0; - break; - - case 'F': - /* We can never run in background */ - exit(EEXIT); - break; - - case 'm': - lfmode = argtoi('m', "mode", optarg, 8); - if (lfmode &~ 07777) - errx(EEXIT, "bad mode to -m: %o", lfmode); - printf("** lost+found creation mode %o\n", lfmode); - break; - - case 'n': - nflag++; - yflag = 0; - break; - - case 'p': - preen++; - break; - - case 'y': - yflag++; - nflag = 0; - break; - - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (!argc) - usage(); - - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - (void)signal(SIGINT, catch); - if (preen) - (void)signal(SIGQUIT, catchquit); - /* - * Push up our allowed memory limit so we can cope - * with huge filesystems. - */ - if (getrlimit(RLIMIT_DATA, &rlimit) == 0) { - rlimit.rlim_cur = rlimit.rlim_max; - (void)setrlimit(RLIMIT_DATA, &rlimit); - } - while (argc-- > 0) - (void)checkfilesys(blockcheck(*argv++), 0, 0L, 0); - - if (returntosingle) - ret = 2; - exit(ret); -} - -static int -argtoi(int flag, char *req, char *str, int base) -{ - char *cp; - int ret; - - ret = (int)strtol(str, &cp, base); - if (cp == str || *cp) - errx(EEXIT, "-%c flag requires a %s", flag, req); - return (ret); -} - -/* - * Check the specified filesystem. - */ -/* ARGSUSED */ -static int -checkfilesys(char *filesys, char *mntpt, long auxdata, int child) -{ - ufs_daddr_t n_ffree, n_bfree; - struct dups *dp; - struct statfs *mntbuf; - struct zlncnt *zlnp; - int cylno; - - if (preen && child) - (void)signal(SIGQUIT, voidquit); - cdevname = filesys; - if (debug && preen) - pwarn("starting\n"); - switch (setup(filesys)) { - case 0: - if (preen) - pfatal("CAN'T CHECK FILE SYSTEM."); - return (0); - case -1: - pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree + - sblock.fs_frag * sblock.fs_cstotal.cs_nbfree); - printf("(%d frags, %d blocks, %.1f%% fragmentation)\n", - sblock.fs_cstotal.cs_nffree, sblock.fs_cstotal.cs_nbfree, - sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize); - return (0); - } - - /* - * Get the mount point information of the filesystem, if - * it is available. - */ - mntbuf = getmntpt(filesys); - - /* - * Cleared if any questions answered no. Used to decide if - * the superblock should be marked clean. - */ - resolved = 1; - /* - * 1: scan inodes tallying blocks used - */ - if (preen == 0) { - printf("** Last Mounted on %s\n", sblock.fs_fsmnt); - if (mntbuf != NULL && mntbuf->f_flags & MNT_ROOTFS) - printf("** Root filesystem\n"); - printf("** Phase 1 - Check Blocks and Sizes\n"); - } - pass1(); - - /* - * 1b: locate first references to duplicates, if any - */ - if (duplist) { - if (preen || usedsoftdep) - pfatal("INTERNAL ERROR: dups with -p"); - printf("** Phase 1b - Rescan For More DUPS\n"); - pass1b(); - } - - /* - * 2: traverse directories from root to mark all connected directories - */ -#ifdef NOTFORIFS - if (preen == 0) - printf("** Phase 2 - Check Pathnames\n"); - pass2(); -#endif - printf("** Skipping phase 2 for IFS\n"); - - /* - * 3: scan inodes looking for disconnected directories - */ - if (preen == 0) - printf("** Phase 3 - Check Connectivity\n"); - pass3(); - - /* - * 4: scan inodes looking for disconnected files; check reference counts - */ - if (preen == 0) - printf("** Phase 4 - Check Reference Counts\n"); - pass4(); - - /* - * 5: check and repair resource counts in cylinder groups - */ - if (preen == 0) - printf("** Phase 5 - Check Cyl groups\n"); - pass5(); - - /* - * print out summary statistics - */ - n_ffree = sblock.fs_cstotal.cs_nffree; - n_bfree = sblock.fs_cstotal.cs_nbfree; - pwarn("%ld files, %ld used, %ld free ", - n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree); - printf("(%d frags, %d blocks, %.1f%% fragmentation)\n", - n_ffree, n_bfree, n_ffree * 100.0 / sblock.fs_dsize); - if (debug && - (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree)) - printf("%d files missing\n", n_files); - if (debug) { - n_blks += sblock.fs_ncg * - (cgdmin(&sblock, 0) - cgsblock(&sblock, 0)); - n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0); - n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); - if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree)) - printf("%d blocks missing\n", n_blks); - if (duplist != NULL) { - printf("The following duplicate blocks remain:"); - for (dp = duplist; dp; dp = dp->next) - printf(" %d,", dp->dup); - printf("\n"); - } - if (zlnhead != NULL) { - printf("The following zero link count inodes remain:"); - for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) - printf(" %u,", zlnp->zlncnt); - printf("\n"); - } - } - zlnhead = (struct zlncnt *)0; - duplist = (struct dups *)0; - muldup = (struct dups *)0; - inocleanup(); - if (fsmodified) { - sblock.fs_time = time(NULL); - sbdirty(); - } - if (cvtlevel && sblk.b_dirty) { - /* - * Write out the duplicate super blocks - */ - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) - bwrite(fswritefd, (char *)&sblock, - fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); - } - if (rerun) - resolved = 0; - - /* - * Check to see if the filesystem is mounted read-write. - */ - if (mntbuf != NULL && (mntbuf->f_flags & MNT_RDONLY) == 0) - resolved = 0; - ckfini(resolved); - - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) - if (inostathead[cylno].il_stat != NULL) - free((char *)inostathead[cylno].il_stat); - free((char *)inostathead); - inostathead = NULL; - if (fsmodified && !preen) - printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); - if (rerun) - printf("\n***** PLEASE RERUN FSCK *****\n"); - if (mntbuf != NULL) { - struct ufs_args args; - int ret; - /* - * We modified a mounted filesystem. Do a mount update on - * it unless it is read-write, so we can continue using it - * as safely as possible. - */ - if (mntbuf->f_flags & MNT_RDONLY) { - args.fspec = 0; - args.export.ex_flags = 0; - args.export.ex_root = 0; - ret = mount("ifs", mntbuf->f_mntonname, - mntbuf->f_flags | MNT_UPDATE | MNT_RELOAD, &args); - if (ret == 0) - return (0); - pwarn("mount reload of '%s' failed: %s\n\n", - mntbuf->f_mntonname, strerror(errno)); - } - if (!fsmodified) - return (0); - if (!preen) - printf("\n***** REBOOT NOW *****\n"); - sync(); - return (4); - } - return (0); -} - -/* - * Get the directory that the device is mounted on. - */ -static struct statfs * -getmntpt(const char *name) -{ - struct stat devstat, mntdevstat; - char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; - char *devname; - struct statfs *mntbuf; - int i, mntsize; - - if (stat(name, &devstat) != 0 || - !(S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))) - return (NULL); - mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); - for (i = 0; i < mntsize; i++) { - if (strcmp(mntbuf[i].f_fstypename, "ifs") != 0) - continue; - devname = mntbuf[i].f_mntfromname; - if (*devname != '/') { - strcpy(device, _PATH_DEV); - strcat(device, devname); - devname = device; - } - if (stat(devname, &mntdevstat) == 0 && - mntdevstat.st_rdev == devstat.st_rdev) - return (&mntbuf[i]); - } - return (NULL); -} - -static void -usage(void) -{ - (void) fprintf(stderr, - "usage: %s [-dfnpy] [-B be|le] [-b block] [-c level] [-m mode] " - "filesystem ...\n", - getprogname()); - exit(1); -} diff --git a/sbin/fsck_ifs/pass1.c b/sbin/fsck_ifs/pass1.c deleted file mode 100644 index 4a949b94021e..000000000000 --- a/sbin/fsck_ifs/pass1.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include - -#include -#include -#include - -#include -#include - -#include "fsck.h" - -static ufs_daddr_t badblk; -static ufs_daddr_t dupblk; -static ino_t lastino; /* last inode in use */ - -static void checkinode(ino_t inumber, struct inodesc *); - -void -pass1(void) -{ - u_int8_t *cp; - ino_t inumber; - int c, i, cgd, inosused; - struct inostat *info; - struct inodesc idesc; - - /* - * Set filesystem reserved blocks in used block map. - */ - for (c = 0; c < sblock.fs_ncg; c++) { - cgd = cgdmin(&sblock, c); - if (c == 0) { - i = cgbase(&sblock, c); - cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); - } else - i = cgsblock(&sblock, c); - for (; i < cgd; i++) - setbmap(i); - } - /* - * Find all allocated blocks. - */ - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_func = pass1check; - n_files = n_blks = 0; - for (c = 0; c < sblock.fs_ncg; c++) { - inumber = c * sblock.fs_ipg; - setinodebuf(inumber); - inosused = sblock.fs_ipg; - /* - * If we are using soft updates, then we can trust the - * cylinder group inode allocation maps to tell us which - * inodes are allocated. We will scan the used inode map - * to find the inodes that are really in use, and then - * read only those inodes in from disk. - */ - if (preen && usedsoftdep) { - getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); - if (!cg_chkmagic(&cgrp)) - pfatal("CG %d: BAD MAGIC NUMBER\n", c); - cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY]; - for ( ; inosused > 0; inosused -= NBBY, cp--) { - if (*cp == 0) - continue; - for (i = 1 << (NBBY - 1); i > 0; i >>= 1) { - if (*cp & i) - break; - inosused--; - } - break; - } - if (inosused < 0) - inosused = 0; - } - /* - * Allocate inoinfo structures for the allocated inodes. - */ - inostathead[c].il_numalloced = inosused; - if (inosused == 0) { - inostathead[c].il_stat = 0; - continue; - } - info = calloc((unsigned)inosused, sizeof(struct inostat)); - if (info == NULL) - pfatal("cannot alloc %u bytes for inoinfo\n", - (unsigned)(sizeof(struct inostat) * inosused)); - inostathead[c].il_stat = info; - /* - * Scan the allocated inodes. - */ - for (i = 0; i < inosused; i++, inumber++) { - if (inumber < ROOTINO) { - (void)getnextinode(inumber); - continue; - } - checkinode(inumber, &idesc); - } - lastino += 1; - if (inosused < sblock.fs_ipg || inumber == lastino) - continue; - /* - * If we were not able to determine in advance which inodes - * were in use, then reduce the size of the inoinfo structure - * to the size necessary to describe the inodes that we - * really found. - */ - inosused = lastino - (c * sblock.fs_ipg); - if (inosused < 0) - inosused = 0; - inostathead[c].il_numalloced = inosused; - if (inosused == 0) { - free(inostathead[c].il_stat); - inostathead[c].il_stat = 0; - continue; - } - info = calloc((unsigned)inosused, sizeof(struct inostat)); - if (info == NULL) - pfatal("cannot alloc %u bytes for inoinfo\n", - (unsigned)(sizeof(struct inostat) * inosused)); - memmove(info, inostathead[c].il_stat, inosused * sizeof(*info)); - free(inostathead[c].il_stat); - inostathead[c].il_stat = info; - } - freeinodebuf(); -} - -static void -checkinode(ino_t inumber, struct inodesc *idesc) -{ - struct dinode *dp; - struct zlncnt *zlnp; - int ndb, j; - mode_t mode; - char *symbuf; - - dp = getnextinode(inumber); - mode = dp->di_mode & IFMT; - if (mode == 0) { - if (memcmp(dp->di_db, zino.di_db, - NDADDR * sizeof(ufs_daddr_t)) || - memcmp(dp->di_ib, zino.di_ib, - NIADDR * sizeof(ufs_daddr_t)) || - dp->di_mode || dp->di_size) { - pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); - if (reply("CLEAR") == 1) { - dp = ginode(inumber); - clearinode(dp); - inodirty(); - } - } - inoinfo(inumber)->ino_state = USTATE; - return; - } - lastino = inumber; - if (/* dp->di_size < 0 || */ - dp->di_size + sblock.fs_bsize - 1 < dp->di_size || - (mode == IFDIR && dp->di_size > MAXDIRSIZE)) { - if (debug) - printf("bad size %qu:", dp->di_size); - goto unknown; - } - if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { - dp = ginode(inumber); - dp->di_size = sblock.fs_fsize; - dp->di_mode = IFREG|0600; - inodirty(); - } - if ((mode == IFBLK || mode == IFCHR || mode == IFIFO || - mode == IFSOCK) && dp->di_size != 0) { - if (debug) - printf("bad special-file size %qu:", dp->di_size); - goto unknown; - } - ndb = howmany(dp->di_size, sblock.fs_bsize); - if (ndb < 0) { - if (debug) - printf("bad size %qu ndb %d:", - dp->di_size, ndb); - goto unknown; - } - if (mode == IFBLK || mode == IFCHR) - ndb++; - if (mode == IFLNK) { - if (doinglevel2 && - dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && - dp->di_blocks != 0) { - symbuf = alloca(secsize); - if (bread(fsreadfd, symbuf, - fsbtodb(&sblock, dp->di_db[0]), - (long)secsize) != 0) - errx(EEXIT, "cannot read symlink"); - if (debug) { - symbuf[dp->di_size] = 0; - printf("convert symlink %lu(%s) of size %ld\n", - (u_long)inumber, symbuf, (long)dp->di_size); - } - dp = ginode(inumber); - memmove(dp->di_shortlink, symbuf, (long)dp->di_size); - dp->di_blocks = 0; - inodirty(); - } - /* - * Fake ndb value so direct/indirect block checks below - * will detect any garbage after symlink string. - */ - if (dp->di_size < sblock.fs_maxsymlinklen) { - ndb = howmany(dp->di_size, sizeof(ufs_daddr_t)); - if (ndb > NDADDR) { - j = ndb - NDADDR; - for (ndb = 1; j > 1; j--) - ndb *= NINDIR(&sblock); - ndb += NDADDR; - } - } - } - for (j = ndb; j < NDADDR; j++) - if (dp->di_db[j] != 0) { - if (debug) - printf("bad direct addr: %ld\n", - (long)dp->di_db[j]); - goto unknown; - } - for (j = 0, ndb -= NDADDR; ndb > 0; j++) - ndb /= NINDIR(&sblock); - for (; j < NIADDR; j++) - if (dp->di_ib[j] != 0) { - if (debug) - printf("bad indirect addr: %ld\n", - (long)dp->di_ib[j]); - goto unknown; - } - if (ftypeok(dp) == 0) - goto unknown; - n_files++; - inoinfo(inumber)->ino_linkcnt = dp->di_nlink; - if (dp->di_nlink <= 0) { - zlnp = (struct zlncnt *)malloc(sizeof *zlnp); - if (zlnp == NULL) { - pfatal("LINK COUNT TABLE OVERFLOW"); - if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - } else { - zlnp->zlncnt = inumber; - zlnp->next = zlnhead; - zlnhead = zlnp; - } - } - if (mode == IFDIR) { - if (dp->di_size == 0) - inoinfo(inumber)->ino_state = DCLEAR; - else - inoinfo(inumber)->ino_state = DSTATE; - cacheino(dp, inumber); - countdirs++; - } else - inoinfo(inumber)->ino_state = FSTATE; - inoinfo(inumber)->ino_type = IFTODT(mode); - if (doinglevel2 && - (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) { - dp = ginode(inumber); - dp->di_uid = dp->di_ouid; - dp->di_ouid = -1; - dp->di_gid = dp->di_ogid; - dp->di_ogid = -1; - inodirty(); - } - badblk = dupblk = 0; - idesc->id_number = inumber; - if (dp->di_flags & SF_SNAPSHOT) - idesc->id_type = SNAP; - else - idesc->id_type = ADDR; - (void)ckinode(dp, idesc); - idesc->id_entryno *= btodb(sblock.fs_fsize); - if (dp->di_blocks != idesc->id_entryno) { - pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)", - inumber, dp->di_blocks, idesc->id_entryno); - if (preen) - printf(" (CORRECTED)\n"); - else if (reply("CORRECT") == 0) - return; - dp = ginode(inumber); - dp->di_blocks = idesc->id_entryno; - inodirty(); - } - return; -unknown: - pfatal("UNKNOWN FILE TYPE I=%lu", inumber); - inoinfo(inumber)->ino_state = FCLEAR; - if (reply("CLEAR") == 1) { - inoinfo(inumber)->ino_state = USTATE; - dp = ginode(inumber); - clearinode(dp); - inodirty(); - } -} - -int -pass1check(struct inodesc *idesc) -{ - int res = KEEPON; - int anyout, nfrags; - ufs_daddr_t blkno = idesc->id_blkno; - struct dups *dlp; - struct dups *new; - - if (idesc->id_type == SNAP) { - if (blkno == BLK_NOCOPY) - return (KEEPON); - if (idesc->id_number == cursnapshot) { - if (blkno == blkstofrags(&sblock, idesc->id_lbn)) - return (KEEPON); - if (blkno == BLK_SNAP) { - blkno = blkstofrags(&sblock, idesc->id_lbn); - idesc->id_entryno -= idesc->id_numfrags; - } - } else { - if (blkno == BLK_SNAP) - return (KEEPON); - } - } - if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { - blkerror(idesc->id_number, "BAD", blkno); - if (badblk++ >= MAXBAD) { - pwarn("EXCESSIVE BAD BLKS I=%lu", - idesc->id_number); - if (preen) - printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - return (STOP); - } - } - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (anyout && chkrange(blkno, 1)) { - res = SKIP; - } else if (!testbmap(blkno)) { - n_blks++; - setbmap(blkno); - } else { - blkerror(idesc->id_number, "DUP", blkno); - if (dupblk++ >= MAXDUP) { - pwarn("EXCESSIVE DUP BLKS I=%lu", - idesc->id_number); - if (preen) - printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - return (STOP); - } - new = (struct dups *)malloc(sizeof(struct dups)); - if (new == NULL) { - pfatal("DUP TABLE OVERFLOW."); - if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - return (STOP); - } - new->dup = blkno; - if (muldup == 0) { - duplist = muldup = new; - new->next = 0; - } else { - new->next = muldup->next; - muldup->next = new; - } - for (dlp = duplist; dlp != muldup; dlp = dlp->next) - if (dlp->dup == blkno) - break; - if (dlp == muldup && dlp->dup != blkno) - muldup = new; - } - /* - * count the number of blocks found in id_entryno - */ - idesc->id_entryno++; - } - return (res); -} diff --git a/sbin/fsck_ifs/pass1b.c b/sbin/fsck_ifs/pass1b.c deleted file mode 100644 index 80dd1aff2a7a..000000000000 --- a/sbin/fsck_ifs/pass1b.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include - -#include - -#include "fsck.h" - -static struct dups *duphead; -static int pass1bcheck(struct inodesc *); - -void -pass1b(void) -{ - int c, i; - struct dinode *dp; - struct inodesc idesc; - ino_t inumber; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass1bcheck; - duphead = duplist; - inumber = 0; - for (c = 0; c < sblock.fs_ncg; c++) { - for (i = 0; i < sblock.fs_ipg; i++, inumber++) { - if (inumber < ROOTINO) - continue; - dp = ginode(inumber); - if (dp == NULL) - continue; - idesc.id_number = inumber; - if (inoinfo(inumber)->ino_state != USTATE && - (ckinode(dp, &idesc) & STOP)) - return; - } - } -} - -static int -pass1bcheck(struct inodesc *idesc) -{ - struct dups *dlp; - int nfrags, res = KEEPON; - ufs_daddr_t blkno = idesc->id_blkno; - - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (chkrange(blkno, 1)) - res = SKIP; - for (dlp = duphead; dlp; dlp = dlp->next) { - if (dlp->dup == blkno) { - blkerror(idesc->id_number, "DUP", blkno); - dlp->dup = duphead->dup; - duphead->dup = blkno; - duphead = duphead->next; - } - if (dlp == muldup) - break; - } - if (muldup == 0 || duphead == muldup->next) - return (STOP); - } - return (res); -} diff --git a/sbin/fsck_ifs/pass2.c b/sbin/fsck_ifs/pass2.c deleted file mode 100644 index 1df28efdd7ff..000000000000 --- a/sbin/fsck_ifs/pass2.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include - -#include -#include - -#include "fsck.h" - -#define MINDIRSIZE (sizeof (struct dirtemplate)) - -static int blksort(const void *, const void *); -static int pass2check(struct inodesc *); - -void -pass2(void) -{ - struct dinode *dp; - struct inoinfo **inpp, *inp; - struct inoinfo **inpend; - struct inodesc curino; - struct dinode dino; - char pathbuf[MAXPATHLEN + 1]; - - switch (inoinfo(ROOTINO)->ino_state) { - - case USTATE: - pfatal("ROOT INODE UNALLOCATED"); - if (reply("ALLOCATE") == 0) { - ckfini(0); - exit(EEXIT); - } - if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); - break; - - case DCLEAR: - pfatal("DUPS/BAD IN ROOT INODE"); - if (reply("REALLOCATE")) { - freeino(ROOTINO); - if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); - break; - } - if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - break; - - case FSTATE: - case FCLEAR: - pfatal("ROOT INODE NOT DIRECTORY"); - if (reply("REALLOCATE")) { - freeino(ROOTINO); - if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); - break; - } - if (reply("FIX") == 0) { - ckfini(0); - exit(EEXIT); - } - dp = ginode(ROOTINO); - dp->di_mode &= ~IFMT; - dp->di_mode |= IFDIR; - inodirty(); - break; - - case DSTATE: - break; - - default: - errx(EEXIT, "BAD STATE %d FOR ROOT INODE", - inoinfo(ROOTINO)->ino_state); - } - inoinfo(ROOTINO)->ino_state = DFOUND; - if (newinofmt) { - inoinfo(WINO)->ino_state = FSTATE; - inoinfo(WINO)->ino_type = DT_WHT; - } - /* - * Sort the directory list into disk block order. - */ - qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort); - /* - * Check the integrity of each directory. - */ - memset(&curino, 0, sizeof(struct inodesc)); - curino.id_type = DATA; - curino.id_func = pass2check; - dp = &dino; - inpend = &inpsort[inplast]; - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_isize == 0) - continue; - if (inp->i_isize < MINDIRSIZE) { - direrror(inp->i_number, "DIRECTORY TOO SHORT"); - inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ); - if (reply("FIX") == 1) { - dp = ginode(inp->i_number); - dp->di_size = inp->i_isize; - inodirty(); - dp = &dino; - } - } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) { - getpathname(pathbuf, inp->i_number, inp->i_number); - if (usedsoftdep) - pfatal("%s %s: LENGTH %d NOT MULTIPLE OF %d", - "DIRECTORY", pathbuf, inp->i_isize, - DIRBLKSIZ); - else - pwarn("%s %s: LENGTH %d NOT MULTIPLE OF %d", - "DIRECTORY", pathbuf, inp->i_isize, - DIRBLKSIZ); - if (preen) - printf(" (ADJUSTED)\n"); - inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ); - if (preen || reply("ADJUST") == 1) { - dp = ginode(inp->i_number); - dp->di_size = roundup(inp->i_isize, DIRBLKSIZ); - inodirty(); - dp = &dino; - } - } - memset(&dino, 0, sizeof(struct dinode)); - dino.di_mode = IFDIR; - dp->di_size = inp->i_isize; - memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks); - curino.id_number = inp->i_number; - curino.id_parent = inp->i_parent; - (void)ckinode(dp, &curino); - } - /* - * Now that the parents of all directories have been found, - * make another pass to verify the value of `..' - */ - for (inpp = inpsort; inpp < inpend; inpp++) { - inp = *inpp; - if (inp->i_parent == 0 || inp->i_isize == 0) - continue; - if (inoinfo(inp->i_parent)->ino_state == DFOUND && - inoinfo(inp->i_number)->ino_state == DSTATE) - inoinfo(inp->i_number)->ino_state = DFOUND; - if (inp->i_dotdot == inp->i_parent || - inp->i_dotdot == (ino_t)-1) - continue; - if (inp->i_dotdot == 0) { - inp->i_dotdot = inp->i_parent; - fileerror(inp->i_parent, inp->i_number, "MISSING '..'"); - if (reply("FIX") == 0) - continue; - (void)makeentry(inp->i_number, inp->i_parent, ".."); - inoinfo(inp->i_parent)->ino_linkcnt--; - continue; - } - fileerror(inp->i_parent, inp->i_number, - "BAD INODE NUMBER FOR '..'"); - if (reply("FIX") == 0) - continue; - inoinfo(inp->i_dotdot)->ino_linkcnt++; - inoinfo(inp->i_parent)->ino_linkcnt--; - inp->i_dotdot = inp->i_parent; - (void)changeino(inp->i_number, "..", inp->i_parent); - } - /* - * Mark all the directories that can be found from the root. - */ - propagate(); -} - -static int -pass2check(struct inodesc *idesc) -{ - struct direct *dirp = idesc->id_dirp; - struct inoinfo *inp; - int n, entrysize, ret = 0; - struct dinode *dp; - char *errmsg; - struct direct proto; - char namebuf[MAXPATHLEN + 1]; - char pathbuf[MAXPATHLEN + 1]; - - /* - * If converting, set directory entry type. - */ - if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) { - dirp->d_type = inoinfo(dirp->d_ino)->ino_type; - ret |= ALTERED; - } - /* - * check for "." - */ - if (idesc->id_entryno != 0) - goto chk1; - if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) { - if (dirp->d_ino != idesc->id_number) { - direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'"); - dirp->d_ino = idesc->id_number; - if (reply("FIX") == 1) - ret |= ALTERED; - } - if (newinofmt && dirp->d_type != DT_DIR) { - direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'"); - dirp->d_type = DT_DIR; - if (reply("FIX") == 1) - ret |= ALTERED; - } - goto chk1; - } - direrror(idesc->id_number, "MISSING '.'"); - proto.d_ino = idesc->id_number; - if (newinofmt) - proto.d_type = DT_DIR; - else - proto.d_type = 0; - proto.d_namlen = 1; - (void)strcpy(proto.d_name, "."); -# if BYTE_ORDER == LITTLE_ENDIAN - if (!newinofmt) { - u_char tmp; - - tmp = proto.d_type; - proto.d_type = proto.d_namlen; - proto.d_namlen = tmp; - } -# endif - entrysize = DIRSIZ(0, &proto); - if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { - pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", - dirp->d_name); - } else if (dirp->d_reclen < entrysize) { - pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); - } else if (dirp->d_reclen < 2 * entrysize) { - proto.d_reclen = dirp->d_reclen; - memmove(dirp, &proto, (size_t)entrysize); - if (reply("FIX") == 1) - ret |= ALTERED; - } else { - n = dirp->d_reclen - entrysize; - proto.d_reclen = entrysize; - memmove(dirp, &proto, (size_t)entrysize); - idesc->id_entryno++; - inoinfo(dirp->d_ino)->ino_linkcnt--; - dirp = (struct direct *)((char *)(dirp) + entrysize); - memset(dirp, 0, (size_t)n); - dirp->d_reclen = n; - if (reply("FIX") == 1) - ret |= ALTERED; - } -chk1: - if (idesc->id_entryno > 1) - goto chk2; - inp = getinoinfo(idesc->id_number); - proto.d_ino = inp->i_parent; - if (newinofmt) - proto.d_type = DT_DIR; - else - proto.d_type = 0; - proto.d_namlen = 2; - (void)strcpy(proto.d_name, ".."); -# if BYTE_ORDER == LITTLE_ENDIAN - if (!newinofmt) { - u_char tmp; - - tmp = proto.d_type; - proto.d_type = proto.d_namlen; - proto.d_namlen = tmp; - } -# endif - entrysize = DIRSIZ(0, &proto); - if (idesc->id_entryno == 0) { - n = DIRSIZ(0, dirp); - if (dirp->d_reclen < n + entrysize) - goto chk2; - proto.d_reclen = dirp->d_reclen - n; - dirp->d_reclen = n; - idesc->id_entryno++; - inoinfo(dirp->d_ino)->ino_linkcnt--; - dirp = (struct direct *)((char *)(dirp) + n); - memset(dirp, 0, (size_t)proto.d_reclen); - dirp->d_reclen = proto.d_reclen; - } - if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { - inp->i_dotdot = dirp->d_ino; - if (newinofmt && dirp->d_type != DT_DIR) { - direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'"); - dirp->d_type = DT_DIR; - if (reply("FIX") == 1) - ret |= ALTERED; - } - goto chk2; - } - if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) { - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", - dirp->d_name); - inp->i_dotdot = (ino_t)-1; - } else if (dirp->d_reclen < entrysize) { - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n"); - inp->i_dotdot = (ino_t)-1; - } else if (inp->i_parent != 0) { - /* - * We know the parent, so fix now. - */ - inp->i_dotdot = inp->i_parent; - fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); - proto.d_reclen = dirp->d_reclen; - memmove(dirp, &proto, (size_t)entrysize); - if (reply("FIX") == 1) - ret |= ALTERED; - } - idesc->id_entryno++; - if (dirp->d_ino != 0) - inoinfo(dirp->d_ino)->ino_linkcnt--; - return (ret|KEEPON); -chk2: - if (dirp->d_ino == 0) - return (ret|KEEPON); - if (dirp->d_namlen <= 2 && - dirp->d_name[0] == '.' && - idesc->id_entryno >= 2) { - if (dirp->d_namlen == 1) { - direrror(idesc->id_number, "EXTRA '.' ENTRY"); - dirp->d_ino = 0; - if (reply("FIX") == 1) - ret |= ALTERED; - return (KEEPON | ret); - } - if (dirp->d_name[1] == '.') { - direrror(idesc->id_number, "EXTRA '..' ENTRY"); - dirp->d_ino = 0; - if (reply("FIX") == 1) - ret |= ALTERED; - return (KEEPON | ret); - } - } - idesc->id_entryno++; - n = 0; - if (dirp->d_ino > maxino) { - fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); - n = reply("REMOVE"); - } else if (newinofmt && - ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) || - (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) { - fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY"); - dirp->d_ino = WINO; - dirp->d_type = DT_WHT; - if (reply("FIX") == 1) - ret |= ALTERED; - } else { -again: - switch (inoinfo(dirp->d_ino)->ino_state) { - case USTATE: - if (idesc->id_entryno <= 2) - break; - fileerror(idesc->id_number, dirp->d_ino, "UNALLOCATED"); - n = reply("REMOVE"); - break; - - case DCLEAR: - case FCLEAR: - if (idesc->id_entryno <= 2) - break; - if (inoinfo(dirp->d_ino)->ino_state == FCLEAR) - errmsg = "DUP/BAD"; - else if (!preen && !usedsoftdep) - errmsg = "ZERO LENGTH DIRECTORY"; - else { - n = 1; - break; - } - fileerror(idesc->id_number, dirp->d_ino, errmsg); - if ((n = reply("REMOVE")) == 1) - break; - dp = ginode(dirp->d_ino); - inoinfo(dirp->d_ino)->ino_state = - (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE; - inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink; - goto again; - - case DSTATE: - if (inoinfo(idesc->id_number)->ino_state == DFOUND) - inoinfo(dirp->d_ino)->ino_state = DFOUND; - /* fall through */ - - case DFOUND: - inp = getinoinfo(dirp->d_ino); - if (inp->i_parent != 0 && idesc->id_entryno > 2) { - getpathname(pathbuf, idesc->id_number, - idesc->id_number); - getpathname(namebuf, dirp->d_ino, dirp->d_ino); - pwarn("%s %s %s\n", pathbuf, - "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", - namebuf); - if (preen) { - printf(" (REMOVED)\n"); - n = 1; - break; - } - if ((n = reply("REMOVE")) == 1) - break; - } - if (idesc->id_entryno > 2) - inp->i_parent = idesc->id_number; - /* fall through */ - - case FSTATE: - if (newinofmt && - dirp->d_type != inoinfo(dirp->d_ino)->ino_type) { - fileerror(idesc->id_number, dirp->d_ino, - "BAD TYPE VALUE"); - dirp->d_type = inoinfo(dirp->d_ino)->ino_type; - if (reply("FIX") == 1) - ret |= ALTERED; - } - inoinfo(dirp->d_ino)->ino_linkcnt--; - break; - - default: - errx(EEXIT, "BAD STATE %d FOR INODE I=%d", - inoinfo(dirp->d_ino)->ino_state, dirp->d_ino); - } - } - if (n == 0) - return (ret|KEEPON); - dirp->d_ino = 0; - return (ret|KEEPON|ALTERED); -} - -/* - * Routine to sort disk blocks. - */ -static int -blksort(const void *arg1, const void *arg2) -{ - - return ((*(struct inoinfo **)arg1)->i_blks[0] - - (*(struct inoinfo **)arg2)->i_blks[0]); -} diff --git a/sbin/fsck_ifs/pass3.c b/sbin/fsck_ifs/pass3.c deleted file mode 100644 index 2700c374432b..000000000000 --- a/sbin/fsck_ifs/pass3.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include -#include - -#include - -#include "fsck.h" - -void -pass3(void) -{ - struct inoinfo *inp; - int loopcnt, inpindex, state; - ino_t orphan; - struct inodesc idesc; - char namebuf[MAXNAMLEN+1]; - - for (inpindex = inplast - 1; inpindex >= 0; inpindex--) { - inp = inpsort[inpindex]; - state = inoinfo(inp->i_number)->ino_state; - if (inp->i_number == ROOTINO || - (inp->i_parent != 0 && state != DSTATE)) - continue; - if (state == DCLEAR) - continue; - /* - * If we are running with soft updates and we come - * across unreferenced directories, we just leave - * them in DSTATE which will cause them to be pitched - * in pass 4. - */ - if (preen && resolved && usedsoftdep && state == DSTATE) { - if (inp->i_dotdot >= ROOTINO) - inoinfo(inp->i_dotdot)->ino_linkcnt++; - continue; - } - for (loopcnt = 0; ; loopcnt++) { - orphan = inp->i_number; - if (inp->i_parent == 0 || - inoinfo(inp->i_parent)->ino_state != DSTATE || - loopcnt > countdirs) - break; - inp = getinoinfo(inp->i_parent); - } - if (loopcnt <= countdirs) { - if (linkup(orphan, inp->i_dotdot, NULL)) { - inp->i_parent = inp->i_dotdot = lfdir; - inoinfo(lfdir)->ino_linkcnt--; - } - inoinfo(orphan)->ino_state = DFOUND; - propagate(); - continue; - } - pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", orphan); - if (reply("RECONNECT") == 0) - continue; - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = DATA; - idesc.id_number = inp->i_parent; - idesc.id_parent = orphan; - idesc.id_func = findname; - idesc.id_name = namebuf; - if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0) - pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY"); - if (linkup(orphan, inp->i_parent, namebuf)) { - idesc.id_func = clearentry; - if (ckinode(ginode(inp->i_parent), &idesc) & FOUND) - inoinfo(orphan)->ino_linkcnt++; - inp->i_parent = inp->i_dotdot = lfdir; - inoinfo(lfdir)->ino_linkcnt--; - } - inoinfo(orphan)->ino_state = DFOUND; - propagate(); - } -} diff --git a/sbin/fsck_ifs/pass4.c b/sbin/fsck_ifs/pass4.c deleted file mode 100644 index b189dc3c468f..000000000000 --- a/sbin/fsck_ifs/pass4.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include - -#include -#include - -#include "fsck.h" - -void -pass4(void) -{ - ino_t inumber; - struct zlncnt *zlnp; - struct dinode *dp; - struct inodesc idesc; - int i, n, cg; - - memset(&idesc, 0, sizeof(struct inodesc)); - idesc.id_type = ADDR; - idesc.id_func = pass4check; - for (cg = 0; cg < sblock.fs_ncg; cg++) { - inumber = cg * sblock.fs_ipg; - for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) { - if (inumber < ROOTINO) - continue; - idesc.id_number = inumber; - switch (inoinfo(inumber)->ino_state) { - - case FSTATE: - case DFOUND: - n = inoinfo(inumber)->ino_linkcnt; - if (n) { -#if NOTFORIFS - adjust(&idesc, (short)n); -#endif - break; - } -#if NOTFORIFS - for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) { - if (zlnp->zlncnt == inumber) { - zlnp->zlncnt = zlnhead->zlncnt; - zlnp = zlnhead; - zlnhead = zlnhead->next; - free((char *)zlnp); - clri(&idesc, "UNREF", 1); - break; - } - } -#endif - break; - - case DSTATE: - break; - - case DCLEAR: - dp = ginode(inumber); - if (dp->di_size == 0) { - clri(&idesc, "ZERO LENGTH", 1); - break; - } - /* fall through */ - case FCLEAR: - clri(&idesc, "BAD/DUP", 1); - break; - - case USTATE: - break; - - default: - errx(EEXIT, "BAD STATE %d FOR INODE I=%d", - inoinfo(inumber)->ino_state, inumber); - } - } - } -} - -int -pass4check(struct inodesc *idesc) -{ - struct dups *dlp; - int nfrags, res = KEEPON; - ufs_daddr_t blkno = idesc->id_blkno; - - for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { - if (chkrange(blkno, 1)) { - res = SKIP; - } else if (testbmap(blkno)) { - for (dlp = duplist; dlp; dlp = dlp->next) { - if (dlp->dup != blkno) - continue; - dlp->dup = duplist->dup; - dlp = duplist; - duplist = duplist->next; - free((char *)dlp); - break; - } - if (dlp == 0) { - clrbmap(blkno); - n_blks--; - } - } - } - return (res); -} diff --git a/sbin/fsck_ifs/pass5.c b/sbin/fsck_ifs/pass5.c deleted file mode 100644 index 07d7259ef118..000000000000 --- a/sbin/fsck_ifs/pass5.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include - -#include -#include - -#include "fsck.h" - -void -pass5(void) -{ - int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; - int inomapsize, blkmapsize, astart, aend, ustart, uend; - struct fs *fs = &sblock; - struct cg *cg = &cgrp; - ufs_daddr_t dbase, dmax; - ufs_daddr_t d; - long i, j, k, l, m, n; - struct csum *cs; - struct csum cstotal; - struct inodesc idesc[3]; - char buf[MAXBSIZE]; - struct cg *newcg = (struct cg *)buf; - struct ocg *ocg = (struct ocg *)buf; - - inoinfo(WINO)->ino_state = USTATE; - memset(newcg, 0, (size_t)fs->fs_cgsize); - /* - * Note: cg_niblk is 16 bits and may overflow, so it must never - * be used except for comparing with the old value. - */ - newcg->cg_niblk = fs->fs_ipg; - if (cvtlevel >= 3) { - if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { - if (preen) - pwarn("DELETING CLUSTERING MAPS\n"); - if (preen || reply("DELETE CLUSTERING MAPS")) { - fs->fs_contigsumsize = 0; - doinglevel1 = 1; - sbdirty(); - } - } - if (fs->fs_maxcontig > 1) { - char *doit = 0; - - if (fs->fs_contigsumsize < 1) { - doit = "CREAT"; - } else if (fs->fs_contigsumsize < fs->fs_maxcontig && - fs->fs_contigsumsize < FS_MAXCONTIG) { - doit = "EXPAND"; - } - if (doit) { - i = fs->fs_contigsumsize; - fs->fs_contigsumsize = - MIN(fs->fs_maxcontig, FS_MAXCONTIG); - if (CGSIZE(fs) > fs->fs_bsize) { - pwarn("CANNOT %s CLUSTER MAPS\n", doit); - fs->fs_contigsumsize = i; - } else if (preen || - reply("CREATE CLUSTER MAPS")) { - if (preen) - pwarn("%sING CLUSTER MAPS\n", - doit); - fs->fs_cgsize = - fragroundup(fs, CGSIZE(fs)); - doinglevel1 = 1; - sbdirty(); - } - } - } - } - switch ((int)fs->fs_postblformat) { - - case FS_42POSTBLFMT: - basesize = (char *)(&ocg->cg_btot[0]) - - (char *)(&ocg->cg_firstfield); - sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]); - mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - - (u_char *)&ocg->cg_iused[0]; - blkmapsize = howmany(fs->fs_fpg, NBBY); - inomapsize = &ocg->cg_free[0] - (u_char *)&ocg->cg_iused[0]; - ocg->cg_magic = CG_MAGIC; - savednrpos = fs->fs_nrpos; - fs->fs_nrpos = 8; - break; - - case FS_DYNAMICPOSTBLFMT: - newcg->cg_btotoff = - &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); - newcg->cg_boff = - newcg->cg_btotoff + fs->fs_cpg * sizeof(int32_t); - newcg->cg_iusedoff = newcg->cg_boff + - fs->fs_cpg * fs->fs_nrpos * sizeof(u_int16_t); - newcg->cg_freeoff = - newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); - inomapsize = newcg->cg_freeoff - newcg->cg_iusedoff; - newcg->cg_nextfreeoff = newcg->cg_freeoff + - howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); - blkmapsize = newcg->cg_nextfreeoff - newcg->cg_freeoff; - if (fs->fs_contigsumsize > 0) { - newcg->cg_clustersumoff = newcg->cg_nextfreeoff - - sizeof(u_int32_t); - newcg->cg_clustersumoff = - roundup(newcg->cg_clustersumoff, sizeof(u_int32_t)); - newcg->cg_clusteroff = newcg->cg_clustersumoff + - (fs->fs_contigsumsize + 1) * sizeof(u_int32_t); - newcg->cg_nextfreeoff = newcg->cg_clusteroff + - howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); - } - newcg->cg_magic = CG_MAGIC; - basesize = &newcg->cg_space[0] - - (u_char *)(&newcg->cg_firstfield); - sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; - mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; - break; - - default: - inomapsize = blkmapsize = sumsize = 0; /* keep lint happy */ - errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d", - fs->fs_postblformat); - } - memset(&idesc[0], 0, sizeof idesc); - for (i = 0; i < 3; i++) { - idesc[i].id_type = ADDR; - if (doinglevel2) - idesc[i].id_fix = FIX; - } - memset(&cstotal, 0, sizeof(struct csum)); - j = blknum(fs, fs->fs_size + fs->fs_frag - 1); - for (i = fs->fs_size; i < j; i++) - setbmap(i); - for (c = 0; c < fs->fs_ncg; c++) { - getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); - if (!cg_chkmagic(cg)) - pfatal("CG %d: BAD MAGIC NUMBER\n", c); - dbase = cgbase(fs, c); - dmax = dbase + fs->fs_fpg; - if (dmax > fs->fs_size) - dmax = fs->fs_size; - newcg->cg_time = cg->cg_time; - newcg->cg_cgx = c; - if (c == fs->fs_ncg - 1) - newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; - else - newcg->cg_ncyl = fs->fs_cpg; - newcg->cg_ndblk = dmax - dbase; - if (fs->fs_contigsumsize > 0) - newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; - newcg->cg_cs.cs_ndir = 0; - newcg->cg_cs.cs_nffree = 0; - newcg->cg_cs.cs_nbfree = 0; - newcg->cg_cs.cs_nifree = fs->fs_ipg; - if (cg->cg_rotor < newcg->cg_ndblk) - newcg->cg_rotor = cg->cg_rotor; - else - newcg->cg_rotor = 0; - if (cg->cg_frotor < newcg->cg_ndblk) - newcg->cg_frotor = cg->cg_frotor; - else - newcg->cg_frotor = 0; - if (cg->cg_irotor < fs->fs_ipg) - newcg->cg_irotor = cg->cg_irotor; - else - newcg->cg_irotor = 0; - memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum); - memset(&cg_blktot(newcg)[0], 0, - (size_t)(sumsize + mapsize)); - if (fs->fs_postblformat == FS_42POSTBLFMT) - ocg->cg_magic = CG_MAGIC; - j = fs->fs_ipg * c; - for (i = 0; i < inostathead[c].il_numalloced; j++, i++) { - switch (inoinfo(j)->ino_state) { - - case USTATE: - break; - - case DSTATE: - case DCLEAR: - case DFOUND: - newcg->cg_cs.cs_ndir++; - /* fall through */ - - case FSTATE: - case FCLEAR: - newcg->cg_cs.cs_nifree--; - setbit(cg_inosused(newcg), i); - break; - - default: - if (j < ROOTINO) - break; - errx(EEXIT, "BAD STATE %d FOR INODE I=%ld", - inoinfo(j)->ino_state, j); - } - } - if (c == 0) - for (i = 0; i < ROOTINO; i++) { - setbit(cg_inosused(newcg), i); - newcg->cg_cs.cs_nifree--; - } - for (i = 0, d = dbase; - d < dmax; - d += fs->fs_frag, i += fs->fs_frag) { - frags = 0; - for (j = 0; j < fs->fs_frag; j++) { - if (testbmap(d + j)) - continue; - setbit(cg_blksfree(newcg), i + j); - frags++; - } - if (frags == fs->fs_frag) { - newcg->cg_cs.cs_nbfree++; - j = cbtocylno(fs, i); - cg_blktot(newcg)[j]++; - cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; - if (fs->fs_contigsumsize > 0) - setbit(cg_clustersfree(newcg), - i / fs->fs_frag); - } else if (frags > 0) { - newcg->cg_cs.cs_nffree += frags; - blk = blkmap(fs, cg_blksfree(newcg), i); - ffs_fragacct(fs, blk, newcg->cg_frsum, 1); - } - } - if (fs->fs_contigsumsize > 0) { - int32_t *sump = cg_clustersum(newcg); - u_char *mapp = cg_clustersfree(newcg); - int map = *mapp++; - int bit = 1; - int run = 0; - - for (i = 0; i < newcg->cg_nclusterblks; i++) { - if ((map & bit) != 0) { - run++; - } else if (run != 0) { - if (run > fs->fs_contigsumsize) - run = fs->fs_contigsumsize; - sump[run]++; - run = 0; - } - if ((i & (NBBY - 1)) != (NBBY - 1)) { - bit <<= 1; - } else { - map = *mapp++; - bit = 1; - } - } - if (run != 0) { - if (run > fs->fs_contigsumsize) - run = fs->fs_contigsumsize; - sump[run]++; - } - } - cstotal.cs_nffree += newcg->cg_cs.cs_nffree; - cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; - cstotal.cs_nifree += newcg->cg_cs.cs_nifree; - cstotal.cs_ndir += newcg->cg_cs.cs_ndir; - cs = &fs->fs_cs(fs, c); - if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 && - dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { - memmove(cs, &newcg->cg_cs, sizeof *cs); - sbdirty(); - } - if (doinglevel1) { - memmove(cg, newcg, (size_t)fs->fs_cgsize); - cgdirty(); - continue; - } - if ((memcmp(newcg, cg, basesize) != 0 || - memcmp(&cg_blktot(newcg)[0], - &cg_blktot(cg)[0], sumsize) != 0) && - dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { - memmove(cg, newcg, (size_t)basesize); - memmove(&cg_blktot(cg)[0], - &cg_blktot(newcg)[0], (size_t)sumsize); - cgdirty(); - } - if (debug) { - for (i = 0; i < inomapsize; i++) { - j = cg_inosused(newcg)[i]; - k = cg_inosused(cg)[i]; - if (j == k) - continue; - for (m = 0, l = 1; m < NBBY; m++, l <<= 1) { - if ((j & l) == (k & l)) - continue; - n = c * fs->fs_ipg + i * NBBY + m; - if ((j & l) != 0) - pwarn("%s INODE %d MARKED %s\n", - "ALLOCATED", n, "FREE"); - else - pwarn("%s INODE %d MARKED %s\n", - "UNALLOCATED", n, "USED"); - } - } - astart = ustart = -1; - for (i = 0; i < blkmapsize; i++) { - j = cg_blksfree(cg)[i]; - k = cg_blksfree(newcg)[i]; - if (j == k) - continue; - for (m = 0, l = 1; m < NBBY; m++, l <<= 1) { - if ((j & l) == (k & l)) - continue; - n = c * fs->fs_fpg + i * NBBY + m; - if ((j & l) != 0) { - if (astart == -1) { - astart = aend = n; - continue; - } - if (aend + 1 == n) { - aend = n; - continue; - } - pwarn("%s FRAGS %d-%d %s\n", - "ALLOCATED", astart, aend, - "MARKED FREE"); - astart = aend = n; - } else { - if (ustart == -1) { - ustart = uend = n; - continue; - } - if (uend + 1 == n) { - uend = n; - continue; - } - pwarn("%s FRAGS %d-%d %s\n", - "UNALLOCATED", ustart, uend, - "MARKED USED"); - ustart = uend = n; - } - } - } - if (astart != -1) - pwarn("%s FRAGS %d-%d %s\n", - "ALLOCATED", astart, aend, - "MARKED FREE"); - if (ustart != -1) - pwarn("%s FRAGS %d-%d %s\n", - "UNALLOCATED", ustart, uend, - "MARKED USED"); - } - if (usedsoftdep) { - for (i = 0; i < inomapsize; i++) { - j = cg_inosused(newcg)[i]; - if ((cg_inosused(cg)[i] & j) == j) - continue; - for (k = 0; k < NBBY; k++) { - if ((j & (1 << k)) == 0) - continue; - if (cg_inosused(cg)[i] & (1 << k)) - continue; - pwarn("ALLOCATED INODE %d MARKED FREE\n", - c * fs->fs_ipg + i * NBBY + k); - } - } - for (i = 0; i < blkmapsize; i++) { - j = cg_blksfree(cg)[i]; - if ((cg_blksfree(newcg)[i] & j) == j) - continue; - for (k = 0; k < NBBY; k++) { - if ((j & (1 << k)) == 0) - continue; - if (cg_blksfree(newcg)[i] & (1 << k)) - continue; - pwarn("ALLOCATED FRAG %d MARKED FREE\n", - c * fs->fs_fpg + i * NBBY + k); - } - } - } - if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 && - dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { - memmove(cg_inosused(cg), cg_inosused(newcg), - (size_t)mapsize); - cgdirty(); - } - } - if (fs->fs_postblformat == FS_42POSTBLFMT) - fs->fs_nrpos = savednrpos; - if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0 - && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { - memmove(&fs->fs_cstotal, &cstotal, sizeof *cs); - fs->fs_ronly = 0; - fs->fs_fmod = 0; - sbdirty(); - } -} diff --git a/sbin/fsck_ifs/preen.c b/sbin/fsck_ifs/preen.c deleted file mode 100644 index 6a518de2f901..000000000000 --- a/sbin/fsck_ifs/preen.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 1990, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "fsck.h" - -struct part { - struct part *next; /* forward link of partitions on disk */ - char *name; /* device name */ - char *fsname; /* mounted filesystem name */ - long auxdata; /* auxiliary data for application */ -} *badlist, **badnext = &badlist; - -struct disk { - char *name; /* disk base name */ - struct disk *next; /* forward link for list of disks */ - struct part *part; /* head of list of partitions on disk */ - int pid; /* If != 0, pid of proc working on */ -} *disks; - -int nrun, ndisks; - -static void addpart(char *name, char *fsname, long auxdata); -static struct disk *finddisk(char *name); -static int startdisk(struct disk *dk, int (*checkit)(char *, char *, long, int)); - -int -checkfstab(int preen, int maxrun, int (*docheck)(struct fstab *), - int (*chkit)(char *, char *, long, int)) -{ - struct fstab *fsp; - struct disk *dk, *nextdisk; - struct part *pt; - int ret, pid, retcode, passno, sumstatus, status; - long auxdata; - char *name; - - sumstatus = 0; - for (passno = 1; passno <= 2; passno++) { - if (setfsent() == 0) { - fprintf(stderr, "Can't open checklist file: %s\n", - _PATH_FSTAB); - return (8); - } - while ((fsp = getfsent()) != 0) { - if ((auxdata = (*docheck)(fsp)) == 0) - continue; - if (preen == 0 || - (passno == 1 && fsp->fs_passno == 1)) { - if ((name = blockcheck(fsp->fs_spec)) != 0) { - if ((sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0)) != 0) - return (sumstatus); - } else if (preen) - return (8); - } else if (passno == 2 && fsp->fs_passno > 1) { - if ((name = blockcheck(fsp->fs_spec)) == NULL) { - fprintf(stderr, "BAD DISK NAME %s\n", - fsp->fs_spec); - sumstatus |= 8; - continue; - } - addpart(name, fsp->fs_file, auxdata); - } - } - if (preen == 0) - return (0); - } - if (preen) { - if (maxrun == 0) - maxrun = ndisks; - if (maxrun > ndisks) - maxrun = ndisks; - nextdisk = disks; - for (passno = 0; passno < maxrun; ++passno) { - while ((ret = startdisk(nextdisk, chkit)) && nrun > 0) - sleep(10); - if (ret) - return (ret); - nextdisk = nextdisk->next; - } - while ((pid = wait(&status)) != -1) { - for (dk = disks; dk; dk = dk->next) - if (dk->pid == pid) - break; - if (dk == 0) { - printf("Unknown pid %d\n", pid); - continue; - } - if (WIFEXITED(status)) - retcode = WEXITSTATUS(status); - else - retcode = 0; - if (WIFSIGNALED(status)) { - printf("%s (%s): EXITED WITH SIGNAL %d\n", - dk->part->name, dk->part->fsname, - WTERMSIG(status)); - retcode = 8; - } - if (retcode != 0) { - sumstatus |= retcode; - *badnext = dk->part; - badnext = &dk->part->next; - dk->part = dk->part->next; - *badnext = NULL; - } else - dk->part = dk->part->next; - dk->pid = 0; - nrun--; - if (dk->part == NULL) - ndisks--; - - if (nextdisk == NULL) { - if (dk->part) { - while ((ret = startdisk(dk, chkit)) && - nrun > 0) - sleep(10); - if (ret) - return (ret); - } - } else if (nrun < maxrun && nrun < ndisks) { - for ( ;; ) { - if ((nextdisk = nextdisk->next) == NULL) - nextdisk = disks; - if (nextdisk->part != NULL && - nextdisk->pid == 0) - break; - } - while ((ret = startdisk(nextdisk, chkit)) && - nrun > 0) - sleep(10); - if (ret) - return (ret); - } - } - } - if (sumstatus) { - if (badlist == 0) - return (sumstatus); - fprintf(stderr, "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t", - badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:"); - for (pt = badlist; pt; pt = pt->next) - fprintf(stderr, "%s (%s)%s", pt->name, pt->fsname, - pt->next ? ", " : "\n"); - return (sumstatus); - } - (void)endfsent(); - return (0); -} - -static struct disk * -finddisk(char *name) -{ - struct disk *dk, **dkp; - char *p; - size_t len; - - p = strrchr(name, '/'); - p = p == NULL ? name : p + 1; - while (*p != '\0' && !isdigit((u_char)*p)) - p++; - while (isdigit((u_char)*p)) - p++; - len = (size_t)(p - name); - for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { - if (strncmp(dk->name, name, len) == 0 && - dk->name[len] == 0) - return (dk); - } - if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) { - fprintf(stderr, "out of memory"); - exit (8); - } - dk = *dkp; - if ((dk->name = malloc(len + 1)) == NULL) { - fprintf(stderr, "out of memory"); - exit (8); - } - (void)strncpy(dk->name, name, len); - dk->name[len] = '\0'; - dk->part = NULL; - dk->next = NULL; - dk->pid = 0; - ndisks++; - return (dk); -} - -static void -addpart(char *name, char *fsname, long auxdata) -{ - struct disk *dk = finddisk(name); - struct part *pt, **ppt = &dk->part; - - for (pt = dk->part; pt; ppt = &pt->next, pt = pt->next) - if (strcmp(pt->name, name) == 0) { - printf("%s in fstab more than once!\n", name); - return; - } - if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) { - fprintf(stderr, "out of memory"); - exit (8); - } - pt = *ppt; - if ((pt->name = malloc(strlen(name) + 1)) == NULL) { - fprintf(stderr, "out of memory"); - exit (8); - } - (void)strcpy(pt->name, name); - if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) { - fprintf(stderr, "out of memory"); - exit (8); - } - (void)strcpy(pt->fsname, fsname); - pt->next = NULL; - pt->auxdata = auxdata; -} - -static int -startdisk(struct disk *dk, int (*checkit)(char *, char *, long, int)) -{ - struct part *pt = dk->part; - - dk->pid = fork(); - if (dk->pid < 0) { - perror("fork"); - return (8); - } - if (dk->pid == 0) - exit((*checkit)(pt->name, pt->fsname, pt->auxdata, 1)); - nrun++; - return (0); -} - diff --git a/sbin/fsck_ifs/setup.c b/sbin/fsck_ifs/setup.c deleted file mode 100644 index f60f9ce11c71..000000000000 --- a/sbin/fsck_ifs/setup.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#define DKTYPENAMES -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "fsck.h" - -struct bufarea asblk; -#define altsblock (*asblk.b_un.b_fs) -#define POWEROF2(num) (((num) & ((num) - 1)) == 0) - -static void badsb(int listerr, char *s); -static int calcsb(char *dev, int devfd, struct fs *fs); -static struct disklabel *getdisklabel(char *s, int fd); -static int readsb(int listerr); - -/* - * Read in a superblock finding an alternate if necessary. - * Return 1 if successful, 0 if unsuccessful, -1 if filesystem - * is already clean (preen mode only). - */ -int -setup(char *dev) -{ - long cg, size, asked, i, j; - long skipclean, bmapsize; - struct disklabel *lp; - off_t sizepb; - struct stat statb; - struct fs proto; - - havesb = 0; - fswritefd = -1; - cursnapshot = 0; - skipclean = fflag ? 0 : preen; - if (stat(dev, &statb) < 0) { - printf("Can't stat %s: %s\n", dev, strerror(errno)); - return (0); - } - if ((statb.st_mode & S_IFMT) != S_IFCHR && - (statb.st_mode & S_IFMT) != S_IFBLK) { - if ((statb.st_flags & SF_SNAPSHOT) != 0) { - cursnapshot = statb.st_ino; - } else { - pfatal("%s is not a disk device", dev); - if (reply("CONTINUE") == 0) - return (0); - } - } - if ((fsreadfd = open(dev, O_RDONLY)) < 0) { - printf("Can't open %s: %s\n", dev, strerror(errno)); - return (0); - } - if (preen == 0) - printf("** %s", dev); - if (nflag || (fswritefd = open(dev, O_WRONLY)) < 0) { - fswritefd = -1; - if (preen) - pfatal("NO WRITE ACCESS"); - printf(" (NO WRITE)"); - } - if (preen == 0) - printf("\n"); - fsmodified = 0; - lfdir = 0; - initbarea(&sblk); - initbarea(&asblk); - sblk.b_un.b_buf = malloc(SBSIZE); - asblk.b_un.b_buf = malloc(SBSIZE); - if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) - errx(EEXIT, "cannot allocate space for superblock"); - if ((lp = getdisklabel(NULL, fsreadfd))) - dev_bsize = secsize = lp->d_secsize; - else - dev_bsize = secsize = DEV_BSIZE; - /* - * Read in the superblock, looking for alternates if necessary - */ - if (readsb(1) == 0) { - skipclean = 0; - if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) - return(0); - if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) - return (0); - for (cg = 0; cg < proto.fs_ncg; cg++) { - bflag = fsbtodb(&proto, cgsblock(&proto, cg)); - if (readsb(0) != 0) - break; - } - if (cg >= proto.fs_ncg) { - printf("%s %s\n%s %s\n%s %s\n", - "SEARCH FOR ALTERNATE SUPER-BLOCK", - "FAILED. YOU MUST USE THE", - "-b OPTION TO FSCK TO SPECIFY THE", - "LOCATION OF AN ALTERNATE", - "SUPER-BLOCK TO SUPPLY NEEDED", - "INFORMATION; SEE fsck(8)."); - bflag = 0; - return(0); - } - pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); - bflag = 0; - } - if (skipclean && sblock.fs_clean) { - pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); - return (-1); - } - maxfsblock = sblock.fs_size; - maxino = sblock.fs_ncg * sblock.fs_ipg; - /* - * Check and potentially fix certain fields in the super block. - */ - if (sblock.fs_optim != FS_OPTTIME && sblock.fs_optim != FS_OPTSPACE) { - pfatal("UNDEFINED OPTIMIZATION IN SUPERBLOCK"); - if (reply("SET TO DEFAULT") == 1) { - sblock.fs_optim = FS_OPTTIME; - sbdirty(); - } - } - if ((sblock.fs_minfree < 0 || sblock.fs_minfree > 99)) { - pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK", - sblock.fs_minfree); - if (reply("SET TO DEFAULT") == 1) { - sblock.fs_minfree = 10; - sbdirty(); - } - } - if (sblock.fs_interleave < 1 || - sblock.fs_interleave > sblock.fs_nsect) { - pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK", - sblock.fs_interleave); - sblock.fs_interleave = 1; - if (preen) - printf(" (FIXED)\n"); - if (preen || reply("SET TO DEFAULT") == 1) { - sbdirty(); - dirty(&asblk); - } - } - if (sblock.fs_npsect < sblock.fs_nsect || - sblock.fs_npsect > sblock.fs_nsect*2) { - pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK", - sblock.fs_npsect); - sblock.fs_npsect = sblock.fs_nsect; - if (preen) - printf(" (FIXED)\n"); - if (preen || reply("SET TO DEFAULT") == 1) { - sbdirty(); - dirty(&asblk); - } - } - if (sblock.fs_inodefmt >= FS_44INODEFMT) { - newinofmt = 1; - } else { - sblock.fs_qbmask = ~sblock.fs_bmask; - sblock.fs_qfmask = ~sblock.fs_fmask; - newinofmt = 0; - } - /* - * Convert to new inode format. - */ - if (cvtlevel >= 2 && sblock.fs_inodefmt < FS_44INODEFMT) { - if (preen) - pwarn("CONVERTING TO NEW INODE FORMAT\n"); - else if (!reply("CONVERT TO NEW INODE FORMAT")) - return(0); - doinglevel2++; - sblock.fs_inodefmt = FS_44INODEFMT; - sizepb = sblock.fs_bsize; - sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1; - for (i = 0; i < NIADDR; i++) { - sizepb *= NINDIR(&sblock); - sblock.fs_maxfilesize += sizepb; - } - sblock.fs_maxsymlinklen = MAXSYMLINKLEN; - sblock.fs_qbmask = ~sblock.fs_bmask; - sblock.fs_qfmask = ~sblock.fs_fmask; - sbdirty(); - dirty(&asblk); - } - /* - * Convert to new cylinder group format. - */ - if (cvtlevel >= 1 && sblock.fs_postblformat == FS_42POSTBLFMT) { - if (preen) - pwarn("CONVERTING TO NEW CYLINDER GROUP FORMAT\n"); - else if (!reply("CONVERT TO NEW CYLINDER GROUP FORMAT")) - return(0); - doinglevel1++; - sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT; - sblock.fs_nrpos = 8; - sblock.fs_postbloff = - (char *)(&sblock.fs_opostbl[0][0]) - - (char *)(&sblock.fs_firstfield); - sblock.fs_rotbloff = &sblock.fs_space[0] - - (u_char *)(&sblock.fs_firstfield); - sblock.fs_cgsize = - fragroundup(&sblock, CGSIZE(&sblock)); - sbdirty(); - dirty(&asblk); - } - if (asblk.b_dirty && !bflag) { - memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize); - flush(fswritefd, &asblk); - } - /* - * read in the summary info. - */ - asked = 0; - sblock.fs_csp = calloc(1, sblock.fs_cssize); - for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { - size = sblock.fs_cssize - i < sblock.fs_bsize ? - sblock.fs_cssize - i : sblock.fs_bsize; - if (bread(fsreadfd, (char *)sblock.fs_csp + i, - fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), - size) != 0 && !asked) { - pfatal("BAD SUMMARY INFORMATION"); - if (reply("CONTINUE") == 0) { - ckfini(0); - exit(EEXIT); - } - asked++; - } - } - /* - * allocate and initialize the necessary maps - */ - bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(short)); - blockmap = calloc((unsigned)bmapsize, sizeof (char)); - if (blockmap == NULL) { - printf("cannot alloc %u bytes for blockmap\n", - (unsigned)bmapsize); - goto badsb; - } - inostathead = calloc((unsigned)(sblock.fs_ncg), - sizeof(struct inostatlist)); - if (inostathead == NULL) { - printf("cannot alloc %u bytes for inostathead\n", - (unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg))); - goto badsb; - } - numdirs = sblock.fs_cstotal.cs_ndir; - dirhash = numdirs; -#if NOTFORIFS - if (numdirs == 0) { - printf("numdirs is zero, try using an alternate superblock\n"); - goto badsb; - } -#endif - inplast = 0; - listmax = numdirs + 10; - inpsort = (struct inoinfo **)calloc((unsigned)listmax, - sizeof(struct inoinfo *)); - inphead = (struct inoinfo **)calloc((unsigned)numdirs, - sizeof(struct inoinfo *)); - if (inpsort == NULL || inphead == NULL) { - printf("cannot alloc %u bytes for inphead\n", - (unsigned)numdirs * sizeof(struct inoinfo *)); - goto badsb; - } - bufinit(); - if (sblock.fs_flags & FS_DOSOFTDEP) - usedsoftdep = 1; - else - usedsoftdep = 0; - return (1); - -badsb: - ckfini(0); - return (0); -} - -/* - * Read in the super block and its summary info. - */ -static int -readsb(int listerr) -{ - ufs_daddr_t super = bflag ? bflag : SBOFF / dev_bsize; - - if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0) - return (0); - sblk.b_bno = super; - sblk.b_size = SBSIZE; - /* - * run a few consistency checks of the super block - */ - if (sblock.fs_magic != FS_MAGIC) - { badsb(listerr, "MAGIC NUMBER WRONG"); return (0); } - if (sblock.fs_ncg < 1) - { badsb(listerr, "NCG OUT OF RANGE"); return (0); } - if (sblock.fs_cpg < 1) - { badsb(listerr, "CPG OUT OF RANGE"); return (0); } - if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || - (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) - { badsb(listerr, "NCYL LESS THAN NCG*CPG"); return (0); } - if (sblock.fs_sbsize > SBSIZE) - { badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); } - /* - * Compute block size that the filesystem is based on, - * according to fsbtodb, and adjust superblock block number - * so we can tell if this is an alternate later. - */ - super *= dev_bsize; - dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); - sblk.b_bno = super / dev_bsize; - if (bflag) { - havesb = 1; - return (1); - } - /* - * Set all possible fields that could differ, then do check - * of whole super block against an alternate super block. - * When an alternate super-block is specified this check is skipped. - */ - getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); - if (asblk.b_errs) - return (0); - altsblock.fs_firstfield = sblock.fs_firstfield; - altsblock.fs_unused_1 = sblock.fs_unused_1; - altsblock.fs_time = sblock.fs_time; - altsblock.fs_cstotal = sblock.fs_cstotal; - altsblock.fs_cgrotor = sblock.fs_cgrotor; - altsblock.fs_fmod = sblock.fs_fmod; - altsblock.fs_clean = sblock.fs_clean; - altsblock.fs_ronly = sblock.fs_ronly; - altsblock.fs_flags = sblock.fs_flags; - altsblock.fs_maxcontig = sblock.fs_maxcontig; - altsblock.fs_minfree = sblock.fs_minfree; - altsblock.fs_optim = sblock.fs_optim; - altsblock.fs_rotdelay = sblock.fs_rotdelay; - altsblock.fs_maxbpg = sblock.fs_maxbpg; - memmove(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp); - altsblock.fs_csp = sblock.fs_csp; - altsblock.fs_maxcluster = sblock.fs_maxcluster; - memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt); - memmove(altsblock.fs_snapinum, sblock.fs_snapinum, - sizeof sblock.fs_snapinum); - memmove(altsblock.fs_sparecon, - sblock.fs_sparecon, sizeof sblock.fs_sparecon); - /* - * The following should not have to be copied. - */ - altsblock.fs_fsbtodb = sblock.fs_fsbtodb; - altsblock.fs_interleave = sblock.fs_interleave; - altsblock.fs_npsect = sblock.fs_npsect; - altsblock.fs_nrpos = sblock.fs_nrpos; - altsblock.fs_state = sblock.fs_state; - altsblock.fs_qbmask = sblock.fs_qbmask; - altsblock.fs_qfmask = sblock.fs_qfmask; - altsblock.fs_state = sblock.fs_state; - altsblock.fs_maxfilesize = sblock.fs_maxfilesize; - if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) { - if (debug) { - long *nlp, *olp, *endlp; - - printf("superblock mismatches\n"); - nlp = (long *)&altsblock; - olp = (long *)&sblock; - endlp = olp + (sblock.fs_sbsize / sizeof *olp); - for ( ; olp < endlp; olp++, nlp++) { - if (*olp == *nlp) - continue; - printf( - "offset %d, original %ld, alternate %ld\n", - olp - (long *)&sblock, *olp, *nlp); - } - } - badsb(listerr, - "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); - return (0); - } - havesb = 1; - return (1); -} - -static void -badsb(int listerr, char *s) -{ - - if (!listerr) - return; - if (preen) - printf("%s: ", cdevname); - pfatal("BAD SUPER BLOCK: %s\n", s); -} - -/* - * Calculate a prototype superblock based on information in the disk label. - * When done the cgsblock macro can be calculated and the fs_ncg field - * can be used. Do NOT attempt to use other macros without verifying that - * their needed information is available! - */ -static int -calcsb(char *dev, int devfd, struct fs *fs) -{ - struct disklabel *lp; - struct partition *pp; - char *cp; - int i; - - cp = strchr(dev, '\0') - 1; - if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) { - pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); - return (0); - } - lp = getdisklabel(dev, devfd); - if (isdigit(*cp)) - pp = &lp->d_partitions[0]; - else - pp = &lp->d_partitions[*cp - 'a']; - if (pp->p_fstype != FS_BSDFFS) { - pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n", - dev, pp->p_fstype < FSMAXTYPES ? - fstypenames[pp->p_fstype] : "unknown"); - return (0); - } - if (pp->p_fsize == 0 || pp->p_frag == 0 || - pp->p_cpg == 0 || pp->p_size == 0) { - pfatal("%s: %s: type %s fsize %d, frag %d, cpg %d, size %d\n", - dev, "INCOMPLETE LABEL", fstypenames[pp->p_fstype], - pp->p_fsize, pp->p_frag, pp->p_cpg, pp->p_size); - return (0); - } - memset(fs, 0, sizeof(struct fs)); - fs->fs_fsize = pp->p_fsize; - fs->fs_frag = pp->p_frag; - fs->fs_cpg = pp->p_cpg; - fs->fs_size = pp->p_size; - fs->fs_ntrak = lp->d_ntracks; - fs->fs_nsect = lp->d_nsectors; - fs->fs_spc = lp->d_secpercyl; - fs->fs_nspf = fs->fs_fsize / lp->d_secsize; - fs->fs_cgmask = 0xffffffff; - for (i = fs->fs_ntrak; i > 1; i >>= 1) - fs->fs_cgmask <<= 1; - if (!POWEROF2(fs->fs_ntrak)) - fs->fs_cgmask <<= 1; - fs->fs_cgoffset = roundup( - howmany(fs->fs_nsect, NSPF(fs)), fs->fs_frag); - fs->fs_fpg = (fs->fs_cpg * fs->fs_spc) / NSPF(fs); - fs->fs_ncg = howmany(fs->fs_size / fs->fs_spc, fs->fs_cpg); - for (fs->fs_fsbtodb = 0, i = NSPF(fs); i > 1; i >>= 1) - fs->fs_fsbtodb++; - dev_bsize = lp->d_secsize; - return (1); -} - -static struct disklabel * -getdisklabel(char *s, int fd) -{ - static struct disklabel lab; - - if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { - if (s == NULL) - return ((struct disklabel *)NULL); - pwarn("ioctl (GCINFO): %s\n", strerror(errno)); - errx(EEXIT, "%s: can't read disk label", s); - } - return (&lab); -} diff --git a/sbin/fsck_ifs/utilities.c b/sbin/fsck_ifs/utilities.c deleted file mode 100644 index 7fd535d0da4b..000000000000 --- a/sbin/fsck_ifs/utilities.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsck.h" - - -char * -blockcheck(char *origname) -{ - struct stat stslash, stblock, stchar; - char *newname, *raw; - struct fstab *fsinfo; - int retried = 0, len; - - newname = origname; -retry: - if (stat(newname, &stblock) < 0) { - printf("Can't stat %s: %s\n", newname, strerror(errno)); - return (origname); - } - switch(stblock.st_mode & S_IFMT) { - case S_IFCHR: - case S_IFBLK: - return(newname); - case S_IFDIR: - if (retried) - break; - - len = strlen(origname) - 1; - if (len > 0 && origname[len] == '/') - /* remove trailing slash */ - origname[len] = '\0'; - if ((fsinfo = getfsfile(origname)) == NULL) { - printf("Can't resolve %s to character special device", - origname); - return (0); - } - newname = fsinfo->fs_spec; - retried++; - goto retry; - } - /* - * Not a block or character device, just return name and - * let the user decide whether to use it. - */ - return (origname); -} diff --git a/sbin/mount_ifs/Makefile b/sbin/mount_ifs/Makefile deleted file mode 100644 index d0f566d5358b..000000000000 --- a/sbin/mount_ifs/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# @(#)Makefile 8.6 (Berkeley) 5/8/95 -# $FreeBSD$ - -PROG= mount_ifs -SRCS= mount.c mount_ufs.c getmntopts.c -NOMAN= noman - -MOUNT= ${.CURDIR}/../mount -CFLAGS+= -I${MOUNT} -WARNS= 0 - -.PATH: ${MOUNT} - -.include diff --git a/sbin/mount_ifs/extern.h b/sbin/mount_ifs/extern.h deleted file mode 100644 index 40f822b08435..000000000000 --- a/sbin/mount_ifs/extern.h +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * Copyright (c) 1997 FreeBSD Inc. - * 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 AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -/* mount_ufs.c */ -int mount_ifs(int, char *const *); diff --git a/sbin/mount_ifs/mount.c b/sbin/mount_ifs/mount.c deleted file mode 100644 index ecfaca9fede1..000000000000 --- a/sbin/mount_ifs/mount.c +++ /dev/null @@ -1,567 +0,0 @@ -/*- - * Copyright (c) 1980, 1989, 1993, 1994 - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1980, 1989, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" -#include "mntopts.h" -#include "pathnames.h" - -/* `meta' options */ -#define MOUNT_META_OPTION_FSTAB "fstab" -#define MOUNT_META_OPTION_CURRENT "current" - -int debug, fstab_style, verbose; - -char *catopt(char *, const char *); -struct statfs - *getmntpt(const char *); -int hasopt(const char *, const char *); -int ismounted(struct fstab *, struct statfs *, int); -int isremountable(const char *); -void mangle(char *, int *, const char **); -char *update_options(char *, char *, int); -int mountfs(const char *, const char *, const char *, - int, const char *, const char *); -void remopt(char *, const char *); -void prmount(struct statfs *); -void putfsent(const struct statfs *); -void usage(void); -char *flags2opts(int); - -/* Map from mount options to printable formats. */ -static struct opt { - int o_opt; - const char *o_name; -} optnames[] = { - { MNT_ASYNC, "asynchronous" }, - { MNT_EXPORTED, "NFS exported" }, - { MNT_LOCAL, "local" }, - { MNT_NOATIME, "noatime" }, - { MNT_NODEV, "nodev" }, - { MNT_NOEXEC, "noexec" }, - { MNT_NOSUID, "nosuid" }, - { MNT_NOSYMFOLLOW, "nosymfollow" }, - { MNT_QUOTA, "with quotas" }, - { MNT_RDONLY, "read-only" }, - { MNT_SYNCHRONOUS, "synchronous" }, - { MNT_UNION, "union" }, - { MNT_NOCLUSTERR, "noclusterr" }, - { MNT_NOCLUSTERW, "noclusterw" }, - { MNT_SUIDDIR, "suiddir" }, - { MNT_SOFTDEP, "soft-updates" }, - { 0, NULL } -}; - -/* - * List of VFS types that can be remounted without becoming mounted on top - * of each other. - * XXX Is this list correct? - */ -static const char * -remountable_fs_names[] = { - "ufs", "ffs", "lfs", "ext2fs", - 0 -}; - -int -main(argc, argv) - int argc; - char * const argv[]; -{ - - mount_ifs(argc, argv); - /* NOTREACHED */ -} - -int -ismounted(fs, mntbuf, mntsize) - struct fstab *fs; - struct statfs *mntbuf; - int mntsize; -{ - int i; - - if (fs->fs_file[0] == '/' && fs->fs_file[1] == '\0') - /* the root filesystem can always be remounted */ - return (0); - - for (i = mntsize - 1; i >= 0; --i) - if (strcmp(fs->fs_file, mntbuf[i].f_mntonname) == 0 && - (!isremountable(fs->fs_vfstype) || - strcmp(fs->fs_spec, mntbuf[i].f_mntfromname) == 0)) - return (1); - return (0); -} - -int -isremountable(vfsname) - const char *vfsname; -{ - const char **cp; - - for (cp = remountable_fs_names; *cp; cp++) - if (strcmp(*cp, vfsname) == 0) - return (1); - return (0); -} - -int -hasopt(mntopts, option) - const char *mntopts, *option; -{ - int negative, found; - char *opt, *optbuf; - - if (option[0] == 'n' && option[1] == 'o') { - negative = 1; - option += 2; - } else - negative = 0; - optbuf = strdup(mntopts); - found = 0; - for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) { - if (opt[0] == 'n' && opt[1] == 'o') { - if (!strcasecmp(opt + 2, option)) - found = negative; - } else if (!strcasecmp(opt, option)) - found = !negative; - } - free(optbuf); - return (found); -} - -int -mountfs(vfstype, spec, name, flags, options, mntopts) - const char *vfstype, *spec, *name, *options, *mntopts; - int flags; -{ - /* List of directories containing mount_xxx subcommands. */ - static const char *edirs[] = { - _PATH_SBIN, - _PATH_USRSBIN, - NULL - }; - const char *argv[100], **edir; - struct statfs sf; - pid_t pid; - int argc, i, status; - char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN]; - -#if __GNUC__ - (void)&optbuf; - (void)&name; -#endif - - /* resolve the mountpoint with realpath(3) */ - (void)checkpath(name, mntpath); - name = mntpath; - - if (mntopts == NULL) - mntopts = ""; - if (options == NULL) { - if (*mntopts == '\0') { - options = "rw"; - } else { - options = mntopts; - mntopts = ""; - } - } - optbuf = catopt(strdup(mntopts), options); - - if (strcmp(name, "/") == 0) - flags |= MNT_UPDATE; - if (flags & MNT_FORCE) - optbuf = catopt(optbuf, "force"); - if (flags & MNT_RDONLY) - optbuf = catopt(optbuf, "ro"); - /* - * XXX - * The mount_mfs (newfs) command uses -o to select the - * optimization mode. We don't pass the default "-o rw" - * for that reason. - */ - if (flags & MNT_UPDATE) - optbuf = catopt(optbuf, "update"); - - argc = 0; - argv[argc++] = vfstype; - mangle(optbuf, &argc, argv); - argv[argc++] = spec; - argv[argc++] = name; - argv[argc] = NULL; - - if (debug) { - (void)printf("exec: mount_%s", vfstype); - for (i = 1; i < argc; i++) - (void)printf(" %s", argv[i]); - (void)printf("\n"); - return (0); - } - - switch (pid = fork()) { - case -1: /* Error. */ - warn("fork"); - free(optbuf); - return (1); - case 0: /* Child. */ - if (strcmp(vfstype, "ifs") == 0) - exit(mount_ifs(argc, (char * const *) argv)); - - /* Go find an executable. */ - for (edir = edirs; *edir; edir++) { - (void)snprintf(execname, - sizeof(execname), "%s/mount_%s", *edir, vfstype); - execv(execname, (char * const *)argv); - } - if (errno == ENOENT) { - int len = 0; - char *cp; - for (edir = edirs; *edir; edir++) - len += strlen(*edir) + 2; /* ", " */ - if ((cp = malloc(len)) == NULL) - errx(1, "malloc failed"); - cp[0] = '\0'; - for (edir = edirs; *edir; edir++) { - strcat(cp, *edir); - if (edir[1] != NULL) - strcat(cp, ", "); - } - warn("exec mount_%s not found in %s", vfstype, cp); - } - exit(1); - /* NOTREACHED */ - default: /* Parent. */ - free(optbuf); - - if (waitpid(pid, &status, 0) < 0) { - warn("waitpid"); - return (1); - } - - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) - return (WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]); - return (1); - } - - if (verbose) { - if (statfs(name, &sf) < 0) { - warn("statfs %s", name); - return (1); - } - if (fstab_style) - putfsent(&sf); - else - prmount(&sf); - } - break; - } - - return (0); -} - -void -prmount(sfp) - struct statfs *sfp; -{ - int flags; - struct opt *o; - struct passwd *pw; - - (void)printf("%s on %s (%s", sfp->f_mntfromname, sfp->f_mntonname, - sfp->f_fstypename); - - flags = sfp->f_flags & MNT_VISFLAGMASK; - for (o = optnames; flags && o->o_opt; o++) - if (flags & o->o_opt) { - (void)printf(", %s", o->o_name); - flags &= ~o->o_opt; - } - if (sfp->f_owner) { - (void)printf(", mounted by "); - if ((pw = getpwuid(sfp->f_owner)) != NULL) - (void)printf("%s", pw->pw_name); - else - (void)printf("%d", sfp->f_owner); - } - if (verbose) { - if (sfp->f_syncwrites != 0 || sfp->f_asyncwrites != 0) - (void)printf(", writes: sync %ld async %ld", - sfp->f_syncwrites, sfp->f_asyncwrites); - if (sfp->f_syncreads != 0 || sfp->f_asyncreads != 0) - (void)printf(", reads: sync %ld async %ld", - sfp->f_syncreads, sfp->f_asyncreads); - } - (void)printf(")\n"); -} - -struct statfs * -getmntpt(name) - const char *name; -{ - struct statfs *mntbuf; - int i, mntsize; - - mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); - for (i = mntsize - 1; i >= 0; i--) { - if (strcmp(mntbuf[i].f_mntfromname, name) == 0 || - strcmp(mntbuf[i].f_mntonname, name) == 0) - return (&mntbuf[i]); - } - return (NULL); -} - -char * -catopt(s0, s1) - char *s0; - const char *s1; -{ - size_t i; - char *cp; - - if (s1 == NULL || *s1 == '\0') - return s0; - - if (s0 && *s0) { - i = strlen(s0) + strlen(s1) + 1 + 1; - if ((cp = malloc(i)) == NULL) - errx(1, "malloc failed"); - (void)snprintf(cp, i, "%s,%s", s0, s1); - } else - cp = strdup(s1); - - if (s0) - free(s0); - return (cp); -} - -void -mangle(options, argcp, argv) - char *options; - int *argcp; - const char **argv; -{ - char *p, *s; - int argc; - - argc = *argcp; - for (s = options; (p = strsep(&s, ",")) != NULL;) - if (*p != '\0') { - if (*p == '-') { - argv[argc++] = p; - p = strchr(p, '='); - if (p) { - *p = '\0'; - argv[argc++] = p+1; - } - } else if (strcmp(p, "rw") != 0) { - argv[argc++] = "-o"; - argv[argc++] = p; - } - } - - *argcp = argc; -} - - -char * -update_options(opts, fstab, curflags) - char *opts; - char *fstab; - int curflags; -{ - char *o, *p; - char *cur; - char *expopt, *newopt, *tmpopt; - - if (opts == NULL) - return strdup(""); - - /* remove meta options from list */ - remopt(fstab, MOUNT_META_OPTION_FSTAB); - remopt(fstab, MOUNT_META_OPTION_CURRENT); - cur = flags2opts(curflags); - - /* - * Expand all meta-options passed to us first. - */ - expopt = NULL; - for (p = opts; (o = strsep(&p, ",")) != NULL;) { - if (strcmp(MOUNT_META_OPTION_FSTAB, o) == 0) - expopt = catopt(expopt, fstab); - else if (strcmp(MOUNT_META_OPTION_CURRENT, o) == 0) - expopt = catopt(expopt, cur); - else - expopt = catopt(expopt, o); - } - free(cur); - free(opts); - - /* - * Remove previous contradictory arguments. Given option "foo" we - * remove all the "nofoo" options. Given "nofoo" we remove "nonofoo" - * and "foo" - so we can deal with possible options like "notice". - */ - newopt = NULL; - for (p = expopt; (o = strsep(&p, ",")) != NULL;) { - if ((tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL) - errx(1, "malloc failed"); - - strcpy(tmpopt, "no"); - strcat(tmpopt, o); - remopt(newopt, tmpopt); - free(tmpopt); - - if (strncmp("no", o, 2) == 0) - remopt(newopt, o+2); - - newopt = catopt(newopt, o); - } - free(expopt); - - return newopt; -} - -void -remopt(string, opt) - char *string; - const char *opt; -{ - char *o, *p, *r; - - if (string == NULL || *string == '\0' || opt == NULL || *opt == '\0') - return; - - r = string; - - for (p = string; (o = strsep(&p, ",")) != NULL;) { - if (strcmp(opt, o) != 0) { - if (*r == ',' && *o != '\0') - r++; - while ((*r++ = *o++) != '\0') - ; - *--r = ','; - } - } - *r = '\0'; -} - -void -usage() -{ - - (void)fprintf(stderr, "%s\n", -"usage: mount [-dfpruvw] [-o options] special node"); - exit(1); -} - -void -putfsent(ent) - const struct statfs *ent; -{ - struct fstab *fst; - char *opts; - - opts = flags2opts(ent->f_flags); - printf("%s\t%s\t%s %s", ent->f_mntfromname, ent->f_mntonname, - ent->f_fstypename, opts); - free(opts); - - if ((fst = getfsspec(ent->f_mntfromname))) - printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); - else if ((fst = getfsfile(ent->f_mntonname))) - printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); - else if (strcmp(ent->f_fstypename, "ufs") == 0) { - if (strcmp(ent->f_mntonname, "/") == 0) - printf("\t1 1\n"); - else - printf("\t2 2\n"); - } else - printf("\t0 0\n"); -} - - -char * -flags2opts(flags) - int flags; -{ - char *res; - - res = NULL; - - res = catopt(res, (flags & MNT_RDONLY) ? "ro" : "rw"); - - if (flags & MNT_SYNCHRONOUS) res = catopt(res, "sync"); - if (flags & MNT_NOEXEC) res = catopt(res, "noexec"); - if (flags & MNT_NOSUID) res = catopt(res, "nosuid"); - if (flags & MNT_NODEV) res = catopt(res, "nodev"); - if (flags & MNT_UNION) res = catopt(res, "union"); - if (flags & MNT_ASYNC) res = catopt(res, "async"); - if (flags & MNT_NOATIME) res = catopt(res, "noatime"); - if (flags & MNT_NOCLUSTERR) res = catopt(res, "noclusterr"); - if (flags & MNT_NOCLUSTERW) res = catopt(res, "noclusterw"); - if (flags & MNT_NOSYMFOLLOW) res = catopt(res, "nosymfollow"); - if (flags & MNT_SUIDDIR) res = catopt(res, "suiddir"); - - return res; -} diff --git a/sbin/mount_ifs/mount_ufs.c b/sbin/mount_ifs/mount_ufs.c deleted file mode 100644 index 254aaecc3817..000000000000 --- a/sbin/mount_ifs/mount_ufs.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 1993, 1994 - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mount_ufs.c 8.4 (Berkeley) 4/26/95"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "extern.h" -#include "mntopts.h" - -static void ifs_usage(void); - -static struct mntopt mopts[] = { - MOPT_STDOPTS, - MOPT_ASYNC, - MOPT_FORCE, - MOPT_SYNC, - MOPT_UPDATE, - MOPT_SNAPSHOT, - { NULL } -}; - -int -mount_ifs(argc, argv) - int argc; - char * const argv[]; -{ - struct ufs_args args; - int ch, mntflags; - char *fs_name; - struct vfsconf vfc; - int error = 0; - - mntflags = 0; - optind = optreset = 1; /* Reset for parse of new argv. */ - while ((ch = getopt(argc, argv, "o:")) != -1) - switch (ch) { - case 'o': - getmntopts(optarg, mopts, &mntflags, 0); - break; - case '?': - default: - ifs_usage(); - } - argc -= optind; - argv += optind; - - if (argc != 2) - ifs_usage(); - - args.fspec = argv[0]; /* The name of the device file. */ - fs_name = argv[1]; /* The mount point. */ - -#define DEFAULT_ROOTUID -2 - args.export.ex_root = DEFAULT_ROOTUID; - if (mntflags & MNT_RDONLY) - args.export.ex_flags = MNT_EXRDONLY; - else - args.export.ex_flags = 0; - - error = getvfsbyname("ifs", &vfc); - if (error && vfsisloadable("ifs")) { - if (vfsload("ifs")) { - warn("vfsload(ifs)"); - return (1); - } - endvfsent(); /* flush old table */ - error = getvfsbyname("ifs", &vfc); - } - if (error) { - warnx("ifs filesystem is not available"); - return (1); - } - - if (mount(vfc.vfc_name, fs_name, mntflags, &args) < 0) { - switch (errno) { - case EMFILE: - warnx("%s on %s: mount table full", - args.fspec, fs_name); - break; - case EINVAL: - if (mntflags & MNT_UPDATE) - warnx( - "%s on %s: specified device does not match mounted device", - args.fspec, fs_name); - else - warnx("%s on %s: incorrect super block", - args.fspec, fs_name); - break; - default: - warn(NULL); - break; - } - return (1); - } - return (0); -} - -static void -ifs_usage() -{ - (void)fprintf(stderr, "usage: mount_ifs [-o options] special node\n"); - exit(1); -}