void fs_mapinodes(ino_t maxino, u_int64_t *tapesz, int *anydirskipped) { ino_t ino; for (ino = ROOTINO; ino < maxino; ino++) mapfileino(ino, tapesz, anydirskipped); }
void fs_mapinodes(ino_t maxino, int64_t *tapesize, int *anydirskipped) { int i, cg, inosused; struct cg *cgp; ino_t ino; char *cp; if ((cgp = malloc(sblock->fs_cgsize)) == NULL) quit("fs_mapinodes: 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) continue; mapfileino(ino, tapesize, anydirskipped); } } free(cgp); }
/* * Dump pass 1. * * Walk the inode list for a filesystem to find all allocated inodes * that have been modified since the previous dump time. Also, find all * the directories in the filesystem. */ int mapfiles(ino_t maxino, int64_t *tapesize, char *disk, char * const *dirv) { int anydirskipped = 0; if (dirv != NULL) { char curdir[PATH_MAX]; FTS *dirh; FTSENT *entry; int d; if (getcwd(curdir, sizeof(curdir)) == NULL) { msg("Can't determine cwd: %s\n", strerror(errno)); dumpabort(0); } if ((dirh = fts_open(dirv, FTS_PHYSICAL|FTS_SEEDOT|FTS_XDEV, NULL)) == NULL) { msg("fts_open failed: %s\n", strerror(errno)); dumpabort(0); } while ((entry = fts_read(dirh)) != NULL) { switch (entry->fts_info) { case FTS_DNR: /* an error */ case FTS_ERR: case FTS_NS: msg("Can't fts_read %s: %s\n", entry->fts_path, strerror(errno)); /* FALLTHROUGH */ case FTS_DP: /* already seen dir */ continue; } mapfileino(entry->fts_statp->st_ino, tapesize, &anydirskipped); } if (errno) { msg("fts_read failed: %s\n", strerror(errno)); dumpabort(0); } (void)fts_close(dirh); /* * Add any parent directories */ for (d = 0 ; dirv[d] != NULL ; d++) { char path[PATH_MAX]; if (dirv[d][0] != '/') (void)snprintf(path, sizeof(path), "%s/%s", curdir, dirv[d]); else (void)snprintf(path, sizeof(path), "%s", dirv[d]); while (strcmp(path, disk) != 0) { char *p; struct stat sb; if (*path == '\0') break; if ((p = strrchr(path, '/')) == NULL) break; if (p == path) break; *p = '\0'; if (stat(path, &sb) == -1) { msg("Can't stat %s: %s\n", path, strerror(errno)); break; } mapfileino(sb.st_ino, tapesize, &anydirskipped); } } /* * Ensure that the root inode actually appears in the * file list for a subdir */ mapfileino(ROOTINO, tapesize, &anydirskipped); } else { fs_mapinodes(maxino, tapesize, &anydirskipped); } /* * Restore gets very upset if the root is not dumped, * so ensure that it always is dumped. */ SETINO(ROOTINO, dumpinomap); return (anydirskipped); }