/* * Check the directory entry in SFD. INDEX is its offset, and PATH is * its name; these are used for printing messages. */ static int pass1_direntry(const char *path, uint32_t index, struct sfs_dir *sfd) { int dchanged = 0; uint32_t nblocks; nblocks = sb_totalblocks(); if (sfd->sfd_ino == SFS_NOINO) { if (sfd->sfd_name[0] != 0) { setbadness(EXIT_RECOV); warnx("Directory %s entry %lu has name but no file", path, (unsigned long) index); sfd->sfd_name[0] = 0; dchanged = 1; } } else if (sfd->sfd_ino >= nblocks) { setbadness(EXIT_RECOV); warnx("Directory %s entry %lu has out of range " "inode (cleared)", path, (unsigned long) index); sfd->sfd_ino = SFS_NOINO; sfd->sfd_name[0] = 0; dchanged = 1; } else { if (sfd->sfd_name[0] == 0) { /* XXX: what happens if FSCK.n.m already exists? */ snprintf(sfd->sfd_name, sizeof(sfd->sfd_name), "FSCK.%lu.%lu", (unsigned long) sfd->sfd_ino, (unsigned long) uniqueid()); setbadness(EXIT_RECOV); warnx("Directory %s entry %lu has file but " "no name (fixed: %s)", path, (unsigned long) index, sfd->sfd_name); dchanged = 1; } if (checknullstring(sfd->sfd_name, sizeof(sfd->sfd_name))) { setbadness(EXIT_RECOV); warnx("Directory %s entry %lu not " "null-terminated (fixed)", path, (unsigned long) index); dchanged = 1; } if (checkbadstring(sfd->sfd_name)) { setbadness(EXIT_RECOV); warnx("Directory %s entry %lu contains invalid " "characters (fixed)", path, (unsigned long) index); dchanged = 1; } } return dchanged; }
static void check_sb(void) { struct sfs_super sp; uint32_t i; int schanged=0; diskread(&sp, SFS_SB_LOCATION); swapsb(&sp); if (sp.sp_magic != SFS_MAGIC) { errx(EXIT_UNRECOV, "Not an sfs filesystem"); } assert(nblocks==0); assert(bitblocks==0); nblocks = sp.sp_nblocks; bitblocks = SFS_BITBLOCKS(nblocks); assert(nblocks>0); assert(bitblocks>0); bitmap_init(bitblocks); for (i=nblocks; i<bitblocks*SFS_BLOCKBITS; i++) { bitmap_mark(i, B_PASTEND, 0); } if (checknullstring(sp.sp_volname, sizeof(sp.sp_volname))) { warnx("Volume name not null-terminated (fixed)"); setbadness(EXIT_RECOV); schanged = 1; } if (checkbadstring(sp.sp_volname)) { warnx("Volume name contains illegal characters (fixed)"); setbadness(EXIT_RECOV); schanged = 1; } if (schanged) { swapsb(&sp); diskwrite(&sp, SFS_SB_LOCATION); } bitmap_mark(SFS_SB_LOCATION, B_SUPERBLOCK, 0); for (i=0; i<bitblocks; i++) { bitmap_mark(SFS_MAP_LOCATION+i, B_BITBLOCK, i); } }
static int check_dir_entry(const char *pathsofar, uint32_t index, struct sfs_dir *sfd) { int dchanged = 0; if (sfd->sfd_ino == SFS_NOINO) { if (sfd->sfd_name[0] != 0) { setbadness(EXIT_RECOV); warnx("Directory /%s entry %lu has name but no file", pathsofar, (unsigned long) index); sfd->sfd_name[0] = 0; dchanged = 1; } } else { if (sfd->sfd_name[0] == 0) { snprintf(sfd->sfd_name, sizeof(sfd->sfd_name), "FSCK.%lu.%lu", (unsigned long) sfd->sfd_ino, (unsigned long) uniquecounter++); setbadness(EXIT_RECOV); warnx("Directory /%s entry %lu has file but " "no name (fixed: %s)", pathsofar, (unsigned long) index, sfd->sfd_name); dchanged = 1; } if (checknullstring(sfd->sfd_name, sizeof(sfd->sfd_name))) { setbadness(EXIT_RECOV); warnx("Directory /%s entry %lu not " "null-terminated (fixed)", pathsofar, (unsigned long) index); dchanged = 1; } if (checkbadstring(sfd->sfd_name)) { setbadness(EXIT_RECOV); warnx("Directory /%s entry %lu contains invalid " "characters (fixed)", pathsofar, (unsigned long) index); dchanged = 1; } } return dchanged; }