Properly handle UFS2 sparsely allocated inodes. The UFS2 filesystem

only preallocates a small number of inodes. The dump program tries
to scan through all the allocated inodes on a filesystem which
causes bad behavior if they have never been allocated. Thus dump
must calculate the set of inodes that have actually been allocated
and scan only those inodes.

Sponsored by:   DARPA & NAI Labs.
This commit is contained in:
Kirk McKusick 2002-12-03 05:10:07 +00:00
parent 7ec589a9b7
commit 69becf4a5e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=107541

View File

@ -139,14 +139,51 @@ blockest(union dinode *dp)
int
mapfiles(ino_t maxino, long *tapesize)
{
int mode;
ino_t ino;
union dinode *dp;
int i, cg, mode, inosused;
int anydirskipped = 0;
union dinode *dp;
struct cg *cgp;
ino_t ino;
char *cp;
for (ino = ROOTINO; ino < maxino; ino++) {
dp = getino(ino, &mode);
if (mode == 0)
if ((cgp = malloc(sblock->fs_cgsize)) == NULL)
quit("mapfiles: cannot allocate memory.\n");
for (cg = 0; cg < sblock->fs_ncg; cg++) {
ino = cg * sblock->fs_ipg;
bread(fsbtodb(sblock, cgtod(sblock, cg)), (char *)cgp,
sblock->fs_cgsize);
if (sblock->fs_magic == FS_UFS2_MAGIC)
inosused = cgp->cg_initediblk;
else
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 (sblock->fs_flags & FS_DOSOFTDEP) {
if (!cg_chkmagic(cgp))
quit("mapfiles: cg %d: bad magic number\n", cg);
cp = &cg_inosused(cgp)[(inosused - 1) / CHAR_BIT];
for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
if (*cp == 0)
continue;
for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
if (*cp & i)
break;
inosused--;
}
break;
}
if (inosused <= 0)
continue;
}
for (i = 0; i < inosused; i++, ino++) {
if (ino < ROOTINO ||
(dp = getino(ino, &mode)) == NULL ||
(mode & IFMT) == 0)
continue;
/*
* Everything must go in usedinomap so that a check
@ -159,18 +196,22 @@ mapfiles(ino_t maxino, long *tapesize)
SETINO(ino, dumpdirmap);
if (WANTTODUMP(dp)) {
SETINO(ino, dumpinomap);
if (mode != IFREG && mode != IFDIR && mode != IFLNK)
if (mode != IFREG &&
mode != IFDIR &&
mode != IFLNK)
*tapesize += 1;
else
*tapesize += blockest(dp);
continue;
}
if (mode == IFDIR) {
if (!nonodump && (DIP(dp, di_flags) & UF_NODUMP))
if (!nonodump &&
(DIP(dp, di_flags) & UF_NODUMP))
CLRINO(ino, usedinomap);
anydirskipped = 1;
}
}
}
/*
* Restore gets very upset if the root is not dumped,
* so ensure that it always is dumped.