Fix incorrect output for a file consisting of a single full-size
block followed by a discontiguous fragment. Add checks for unallocated inodes and inodes with unknown mode types. Cleanup variable declarations by changing from type `int' to types like ufs_lbn_t, ufs2_daddr_t, etc. Reported by: bde
This commit is contained in:
parent
93bd79f30a
commit
c2d88526f7
@ -9,6 +9,8 @@ SRCS= main.c prtblknos.c
|
|||||||
|
|
||||||
LIBADD+=ufs
|
LIBADD+=ufs
|
||||||
|
|
||||||
|
WARNS?= 3
|
||||||
|
|
||||||
test: ${PROG}
|
test: ${PROG}
|
||||||
./${PROG} > a
|
./${PROG} > a
|
||||||
|
|
||||||
|
@ -53,14 +53,17 @@ main(argc, argv)
|
|||||||
struct statfs sfb;
|
struct statfs sfb;
|
||||||
char *xargv[4];
|
char *xargv[4];
|
||||||
char ibuf[64];
|
char ibuf[64];
|
||||||
char *fsname;
|
char *fsname, *filename;
|
||||||
int inonum, error;
|
ino_t inonum;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
filename = NULL;
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (stat(argv[1], &sb) != 0)
|
filename = argv[1];
|
||||||
err(1, "stat(%s)", argv[1]);
|
if (lstat(filename, &sb) != 0)
|
||||||
if (statfs(argv[1], &sfb) != 0)
|
err(1, "stat(%s)", filename);
|
||||||
err(1, "statfs(%s)", argv[1]);
|
if (statfs(filename, &sfb) != 0)
|
||||||
|
err(1, "statfs(%s)", filename);
|
||||||
xargv[0] = argv[0];
|
xargv[0] = argv[0];
|
||||||
xargv[1] = sfb.f_mntfromname;
|
xargv[1] = sfb.f_mntfromname;
|
||||||
sprintf(ibuf, "%jd", (intmax_t)sb.st_ino);
|
sprintf(ibuf, "%jd", (intmax_t)sb.st_ino);
|
||||||
@ -87,12 +90,17 @@ main(argc, argv)
|
|||||||
while (*++argv) {
|
while (*++argv) {
|
||||||
/* get the inode number. */
|
/* get the inode number. */
|
||||||
if ((inonum = atoi(*argv)) <= 0 ||
|
if ((inonum = atoi(*argv)) <= 0 ||
|
||||||
inonum >= fs->fs_ipg * fs->fs_ncg)
|
inonum >= (ino_t)fs->fs_ipg * fs->fs_ncg)
|
||||||
warnx("%s is not a valid inode number", *argv);
|
warnx("%s is not a valid inode number", *argv);
|
||||||
(void)printf("%d: ", inonum);
|
if (filename == NULL)
|
||||||
|
(void)printf("inode #%jd: ", (intmax_t)inonum);
|
||||||
|
else
|
||||||
|
(void)printf("%s (inode #%jd): ", filename,
|
||||||
|
(intmax_t)inonum);
|
||||||
|
|
||||||
if ((error = getino(&disk, (void **)&dp, inonum, NULL)) < 0)
|
if ((error = getino(&disk, (void **)&dp, inonum, NULL)) < 0)
|
||||||
warn("Read of inode %d on %s failed", inonum, fsname);
|
warn("Read of inode %jd on %s failed",
|
||||||
|
(intmax_t)inonum, fsname);
|
||||||
|
|
||||||
prtblknos(&disk, dp);
|
prtblknos(&disk, dp);
|
||||||
}
|
}
|
||||||
|
@ -40,16 +40,18 @@ union dinode {
|
|||||||
|
|
||||||
void prtblknos(struct uufsd *disk, union dinode *dp);
|
void prtblknos(struct uufsd *disk, union dinode *dp);
|
||||||
|
|
||||||
static void indirprt(struct uufsd *, int, int, int, ufs2_daddr_t, int);
|
static const char *distance(struct fs *, ufs2_daddr_t, ufs2_daddr_t);
|
||||||
static char *distance(struct fs *, daddr_t, daddr_t);
|
static void printblk(struct fs *, ufs_lbn_t, ufs2_daddr_t, int, ufs_lbn_t);
|
||||||
static void printblk(struct fs *, int, ufs2_daddr_t, int, int);
|
static void indirprt(struct uufsd *, int, ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t,
|
||||||
|
ufs_lbn_t);
|
||||||
|
|
||||||
void
|
void
|
||||||
prtblknos(disk, dp)
|
prtblknos(disk, dp)
|
||||||
struct uufsd *disk;
|
struct uufsd *disk;
|
||||||
union dinode *dp;
|
union dinode *dp;
|
||||||
{
|
{
|
||||||
int i, len, lbn, mode, frags, numblks, blksperindir;
|
int i, mode, frags;
|
||||||
|
ufs_lbn_t lbn, lastlbn, len, blksperindir;
|
||||||
ufs2_daddr_t blkno;
|
ufs2_daddr_t blkno;
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
off_t size;
|
off_t size;
|
||||||
@ -63,6 +65,12 @@ prtblknos(disk, dp)
|
|||||||
mode = dp->dp2.di_mode;
|
mode = dp->dp2.di_mode;
|
||||||
}
|
}
|
||||||
switch (mode & IFMT) {
|
switch (mode & IFMT) {
|
||||||
|
default:
|
||||||
|
printf("unknown inode type 0%d\n", (mode & IFMT));
|
||||||
|
return;
|
||||||
|
case 0:
|
||||||
|
printf("unallocated inode\n");
|
||||||
|
return;
|
||||||
case IFIFO:
|
case IFIFO:
|
||||||
printf("fifo\n");
|
printf("fifo\n");
|
||||||
return;
|
return;
|
||||||
@ -97,20 +105,20 @@ prtblknos(disk, dp)
|
|||||||
printf("empty file\n");
|
printf("empty file\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("regular file, size %ld\n", size);
|
printf("regular file, size %jd\n", (intmax_t)size);
|
||||||
break;
|
break;
|
||||||
case IFDIR:
|
case IFDIR:
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
printf("empty directory\n");
|
printf("empty directory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("directory, size %ld\n", size);
|
printf("directory, size %jd\n", (intmax_t)size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
numblks = howmany(size, fs->fs_bsize);
|
lastlbn = howmany(size, fs->fs_bsize);
|
||||||
len = numblks < UFS_NDADDR ? numblks : UFS_NDADDR;
|
len = lastlbn < UFS_NDADDR ? lastlbn : UFS_NDADDR;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (i < numblks - 1)
|
if (i < lastlbn - 1)
|
||||||
frags = fs->fs_frag;
|
frags = fs->fs_frag;
|
||||||
else
|
else
|
||||||
frags = howmany(size % fs->fs_bsize,
|
frags = howmany(size % fs->fs_bsize,
|
||||||
@ -119,39 +127,39 @@ prtblknos(disk, dp)
|
|||||||
blkno = dp->dp1.di_db[i];
|
blkno = dp->dp1.di_db[i];
|
||||||
else
|
else
|
||||||
blkno = dp->dp2.di_db[i];
|
blkno = dp->dp2.di_db[i];
|
||||||
printblk(fs, i, blkno, frags, numblks);
|
printblk(fs, i, blkno, frags, lastlbn);
|
||||||
}
|
}
|
||||||
|
|
||||||
blksperindir = 1;
|
blksperindir = 1;
|
||||||
len = numblks - UFS_NDADDR;
|
len = lastlbn - UFS_NDADDR;
|
||||||
lbn = UFS_NDADDR;
|
lbn = UFS_NDADDR;
|
||||||
for (i = 0; len > 0 && i < UFS_NIADDR; i++) {
|
for (i = 0; len > 0 && i < UFS_NIADDR; i++) {
|
||||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||||
blkno = dp->dp1.di_ib[i];
|
blkno = dp->dp1.di_ib[i];
|
||||||
else
|
else
|
||||||
blkno = dp->dp2.di_ib[i];
|
blkno = dp->dp2.di_ib[i];
|
||||||
indirprt(disk, i, blksperindir, lbn, blkno, numblks);
|
indirprt(disk, i, blksperindir, lbn, blkno, lastlbn);
|
||||||
blksperindir *= NINDIR(fs);
|
blksperindir *= NINDIR(fs);
|
||||||
lbn += blksperindir;
|
lbn += blksperindir;
|
||||||
len -= blksperindir;
|
len -= blksperindir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dummy print to flush out last extent */
|
/* dummy print to flush out last extent */
|
||||||
printblk(fs, numblks, 0, frags, 0);
|
printblk(fs, lastlbn, 0, frags, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
indirprt(disk, level, blksperindir, lbn, blkno, lastlbn)
|
indirprt(disk, level, blksperindir, lbn, blkno, lastlbn)
|
||||||
struct uufsd *disk;
|
struct uufsd *disk;
|
||||||
int level;
|
int level;
|
||||||
int blksperindir;
|
ufs_lbn_t blksperindir;
|
||||||
int lbn;
|
ufs_lbn_t lbn;
|
||||||
ufs2_daddr_t blkno;
|
ufs2_daddr_t blkno;
|
||||||
int lastlbn;
|
ufs_lbn_t lastlbn;
|
||||||
{
|
{
|
||||||
char indir[MAXBSIZE];
|
char indir[MAXBSIZE];
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
int i, last;
|
ufs_lbn_t i, last;
|
||||||
|
|
||||||
fs = (struct fs *)&disk->d_sb;
|
fs = (struct fs *)&disk->d_sb;
|
||||||
if (blkno == 0) {
|
if (blkno == 0) {
|
||||||
@ -190,13 +198,13 @@ indirprt(disk, level, blksperindir, lbn, blkno, lastlbn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static const char *
|
||||||
distance(fs, lastblk, firstblk)
|
distance(fs, lastblk, firstblk)
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
daddr_t lastblk;
|
ufs2_daddr_t lastblk;
|
||||||
daddr_t firstblk;
|
ufs2_daddr_t firstblk;
|
||||||
{
|
{
|
||||||
daddr_t delta;
|
ufs2_daddr_t delta;
|
||||||
int firstcg, lastcg;
|
int firstcg, lastcg;
|
||||||
static char buf[100];
|
static char buf[100];
|
||||||
|
|
||||||
@ -216,28 +224,30 @@ distance(fs, lastblk, firstblk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *indirname[UFS_NIADDR] = { "First", "Second", "Third" };
|
static const char *indirname[UFS_NIADDR] = { "First", "Second", "Third" };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printblk(fs, lbn, blkno, numblks, lastlbn)
|
printblk(fs, lbn, blkno, numfrags, lastlbn)
|
||||||
struct fs *fs;
|
struct fs *fs;
|
||||||
int lbn;
|
ufs_lbn_t lbn;
|
||||||
ufs2_daddr_t blkno;
|
ufs2_daddr_t blkno;
|
||||||
int numblks;
|
int numfrags;
|
||||||
int lastlbn;
|
ufs_lbn_t lastlbn;
|
||||||
{
|
{
|
||||||
static int seq;
|
static int seq;
|
||||||
static daddr_t lastindirblk, lastblk, firstblk;
|
static ufs2_daddr_t totfrags, lastindirblk, lastblk, firstblk;
|
||||||
|
|
||||||
if (lastlbn <= 0)
|
if (lastlbn <= 0)
|
||||||
goto flush;
|
goto flush;
|
||||||
if (seq == 0) {
|
if (seq == 0) {
|
||||||
seq = howmany(numblks, fs->fs_frag);
|
seq = howmany(numfrags, fs->fs_frag);
|
||||||
|
totfrags = numfrags;
|
||||||
firstblk = blkno;
|
firstblk = blkno;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lbn == 0) {
|
if (lbn == 0) {
|
||||||
seq = howmany(numblks, fs->fs_frag);
|
seq = howmany(numfrags, fs->fs_frag);
|
||||||
|
totfrags = numfrags;
|
||||||
lastblk = 0;
|
lastblk = 0;
|
||||||
firstblk = blkno;
|
firstblk = blkno;
|
||||||
lastindirblk = 0;
|
lastindirblk = 0;
|
||||||
@ -247,7 +257,8 @@ printblk(fs, lbn, blkno, numblks, lastlbn)
|
|||||||
(firstblk == BLK_NOCOPY && blkno == BLK_NOCOPY) ||
|
(firstblk == BLK_NOCOPY && blkno == BLK_NOCOPY) ||
|
||||||
(firstblk == BLK_SNAP && blkno == BLK_SNAP) ||
|
(firstblk == BLK_SNAP && blkno == BLK_SNAP) ||
|
||||||
blkno == firstblk + seq * fs->fs_frag)) {
|
blkno == firstblk + seq * fs->fs_frag)) {
|
||||||
seq += howmany(numblks, fs->fs_frag);
|
seq += howmany(numfrags, fs->fs_frag);
|
||||||
|
totfrags += numfrags;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flush:
|
flush:
|
||||||
@ -255,35 +266,36 @@ printblk(fs, lbn, blkno, numblks, lastlbn)
|
|||||||
goto prtindir;
|
goto prtindir;
|
||||||
if (firstblk <= BLK_SNAP) {
|
if (firstblk <= BLK_SNAP) {
|
||||||
if (seq == 1)
|
if (seq == 1)
|
||||||
printf("\tlbn %d %s\n", lbn - seq,
|
printf("\tlbn %jd %s\n", (intmax_t)(lbn - seq),
|
||||||
firstblk == 0 ? "hole" :
|
firstblk == 0 ? "hole" :
|
||||||
firstblk == BLK_NOCOPY ? "nocopy" :
|
firstblk == BLK_NOCOPY ? "nocopy" :
|
||||||
"snapblk");
|
"snapblk");
|
||||||
else
|
else
|
||||||
printf("\tlbn %d-%d %s\n",
|
printf("\tlbn %jd-%jd %s\n",
|
||||||
lbn - seq, lbn - 1,
|
(intmax_t)lbn - seq, (intmax_t)lbn - 1,
|
||||||
firstblk == 0 ? "hole" :
|
firstblk == 0 ? "hole" :
|
||||||
firstblk == BLK_NOCOPY ? "nocopy" :
|
firstblk == BLK_NOCOPY ? "nocopy" :
|
||||||
"snapblk");
|
"snapblk");
|
||||||
} else if (seq == 1) {
|
} else if (seq == 1) {
|
||||||
if (numblks == 1)
|
if (totfrags == 1)
|
||||||
printf("\tlbn %d blkno %jd%s\n", lbn - seq,
|
printf("\tlbn %jd blkno %jd%s\n", (intmax_t)(lbn - seq),
|
||||||
(intmax_t)firstblk, distance(fs, lastblk, firstblk));
|
(intmax_t)firstblk, distance(fs, lastblk, firstblk));
|
||||||
else
|
else
|
||||||
printf("\tlbn %d blkno %jd-%jd%s\n", lbn - seq,
|
printf("\tlbn %jd blkno %jd-%jd%s\n",
|
||||||
(intmax_t)firstblk,
|
(intmax_t)(lbn - seq), (intmax_t)firstblk,
|
||||||
(intmax_t)(firstblk + numblks - 1),
|
(intmax_t)(firstblk + totfrags - 1),
|
||||||
distance(fs, lastblk, firstblk));
|
distance(fs, lastblk, firstblk));
|
||||||
lastblk = firstblk + numblks - 1;
|
lastblk = firstblk + totfrags - 1;
|
||||||
} else {
|
} else {
|
||||||
printf("\tlbn %d-%d blkno %jd-%jd%s\n", lbn - seq, lbn - 1,
|
printf("\tlbn %jd-%jd blkno %jd-%jd%s\n", (intmax_t)(lbn - seq),
|
||||||
(intmax_t)firstblk, (intmax_t)(firstblk +
|
(intmax_t)(lbn - 1), (intmax_t)firstblk,
|
||||||
(seq - 1) * fs->fs_frag + numblks - 1),
|
(intmax_t)(firstblk + totfrags - 1),
|
||||||
distance(fs, lastblk, firstblk));
|
distance(fs, lastblk, firstblk));
|
||||||
lastblk = firstblk + (seq - 1) * fs->fs_frag + numblks - 1;
|
lastblk = firstblk + totfrags - 1;
|
||||||
}
|
}
|
||||||
if (lastlbn > 0 || blkno == 0) {
|
if (lastlbn > 0 || blkno == 0) {
|
||||||
seq = 1;
|
seq = 1;
|
||||||
|
totfrags = numfrags;
|
||||||
firstblk = blkno;
|
firstblk = blkno;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -291,9 +303,9 @@ printblk(fs, lbn, blkno, numblks, lastlbn)
|
|||||||
if (seq != 0 && (fs->fs_metaspace == 0 || lastindirblk == 0))
|
if (seq != 0 && (fs->fs_metaspace == 0 || lastindirblk == 0))
|
||||||
lastindirblk = lastblk;
|
lastindirblk = lastblk;
|
||||||
printf("%s-level indirect, blkno %jd-%jd%s\n", indirname[-lastlbn],
|
printf("%s-level indirect, blkno %jd-%jd%s\n", indirname[-lastlbn],
|
||||||
(intmax_t)blkno, (intmax_t)(blkno + numblks - 1),
|
(intmax_t)blkno, (intmax_t)(blkno + numfrags - 1),
|
||||||
distance(fs, lastindirblk, blkno));
|
distance(fs, lastindirblk, blkno));
|
||||||
lastindirblk = blkno + numblks - 1;
|
lastindirblk = blkno + numfrags - 1;
|
||||||
if (fs->fs_metaspace == 0)
|
if (fs->fs_metaspace == 0)
|
||||||
lastblk = lastindirblk;
|
lastblk = lastindirblk;
|
||||||
seq = 0;
|
seq = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user