diff options
author | Kirk McKusick <mckusick@FreeBSD.org> | 2018-04-08 06:52:58 +0000 |
---|---|---|
committer | Kirk McKusick <mckusick@FreeBSD.org> | 2018-04-08 06:52:58 +0000 |
commit | 0e3f58b6612b3b0c03ca1b1c85cfa4e8ab460ebe (patch) | |
tree | cdca8edfcadf179d9b17332ac5ae64627966e742 /tools/diag | |
parent | 0c94b536568603bb1316072f3faace16e97ecc9a (diff) | |
download | src-0e3f58b6612b3b0c03ca1b1c85cfa4e8ab460ebe.tar.gz src-0e3f58b6612b3b0c03ca1b1c85cfa4e8ab460ebe.zip |
Notes
Diffstat (limited to 'tools/diag')
-rw-r--r-- | tools/diag/prtblknos/Makefile | 7 | ||||
-rw-r--r-- | tools/diag/prtblknos/main.c | 80 | ||||
-rw-r--r-- | tools/diag/prtblknos/prtblknos.c | 235 |
3 files changed, 169 insertions, 153 deletions
diff --git a/tools/diag/prtblknos/Makefile b/tools/diag/prtblknos/Makefile index e081eb770113..3e7008914bac 100644 --- a/tools/diag/prtblknos/Makefile +++ b/tools/diag/prtblknos/Makefile @@ -1,9 +1,14 @@ # $FreeBSD$ -PROG= prtblknos +BINDIR?= /usr/bin +PROG= prtblknos MAN= +SRCS= main.c prtblknos.c + +LIBADD+=ufs + test: ${PROG} ./${PROG} > a diff --git a/tools/diag/prtblknos/main.c b/tools/diag/prtblknos/main.c new file mode 100644 index 000000000000..9cbc79adbe21 --- /dev/null +++ b/tools/diag/prtblknos/main.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1998, 2003, 2013, 2018 Marshall Kirk McKusick. + * 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 MARSHALL KIRK MCKUSICK ``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 MARSHALL KIRK MCKUSICK 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$ + */ + +#include <ufs/ffs/fs.h> + +#include <err.h> +#include <stdlib.h> +#include <stdio.h> +#include <libufs.h> + +union dinode { + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; +}; + +void prtblknos(struct uufsd *disk, union dinode *dp); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct uufsd disk; + union dinode *dp; + struct fs *fs; + char *fsname; + int inonum, error; + + if (argc < 3) { + (void)fprintf(stderr,"usage: prtblknos filesystem inode ...\n"); + exit(1); + } + + fsname = *++argv; + + /* get the superblock. */ + if ((error = ufs_disk_fillout(&disk, fsname)) < 0) + errx(1, "Cannot find file system superblock on %s\n", fsname); + fs = (struct fs *)&disk.d_sb; + + /* remaining arguments are inode numbers. */ + while (*++argv) { + /* get the inode number. */ + if ((inonum = atoi(*argv)) <= 0 || + inonum >= fs->fs_ipg * fs->fs_ncg) + errx(1, "%s is not a valid inode number", *argv); + (void)printf("%d:", inonum); + + if ((error = getino(&disk, (void **)&dp, inonum, NULL)) < 0) + err(1, "Read of inode %d on %s failed", inonum, fsname); + + prtblknos(&disk, dp); + } + exit(0); +} diff --git a/tools/diag/prtblknos/prtblknos.c b/tools/diag/prtblknos/prtblknos.c index 102b0b55e473..5f257a8dea62 100644 --- a/tools/diag/prtblknos/prtblknos.c +++ b/tools/diag/prtblknos/prtblknos.c @@ -27,146 +27,78 @@ */ #include <sys/param.h> -#include <sys/disklabel.h> -#include <sys/time.h> - -#include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> #include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> #include <stdio.h> -#include <stdint.h> -#include <unistd.h> +#include <libufs.h> union dinode { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; + struct ufs1_dinode dp1; + struct ufs2_dinode dp2; }; -struct fs *sbp; -char *fsname; -int fd; -void indirprt(int level, int blksperindir, int lbn, ufs2_daddr_t blkno, - int lastlbn); -void printblk(int lbn, ufs2_daddr_t blkno, int numblks, int lastlbn); +void prtblknos(struct uufsd *disk, union dinode *dp); -/* - * Possible superblock locations ordered from most to least likely. - */ -static int sblock_try[] = SBLOCKSEARCH; +static void indirprt(struct uufsd *, int, int, int, ufs2_daddr_t, int); +static char *distance(struct fs *, daddr_t, daddr_t); +static void printblk(struct fs *, int, ufs2_daddr_t, int, int); -int -main(argc, argv) - int argc; - char *argv[]; +void +prtblknos(disk, dp) + struct uufsd *disk; + union dinode *dp; { - int i, len, lbn, frags, inonum, numblks, blksperindir; - char sblock[SBLOCKSIZE], ibuf[MAXBSIZE]; + int i, len, lbn, frags, numblks, blksperindir; ufs2_daddr_t blkno; - off_t size, offset; - union dinode dp; - - if (argc < 3) { - (void)fprintf(stderr,"usage: prtblknos filesystem inode ...\n"); - exit(1); + struct fs *fs; + off_t size; + + fs = (struct fs *)&disk->d_sb; + if (fs->fs_magic == FS_UFS1_MAGIC) + size = dp->dp1.di_size; + else + size = dp->dp2.di_size; + numblks = howmany(size, fs->fs_bsize); + if (numblks == 0) { + printf(" empty file\n"); + return; } - - fsname = *++argv; - - /* get the superblock. */ - if ((fd = open(fsname, O_RDONLY, 0)) < 0) - err(1, "%s", fsname); - for (i = 0; sblock_try[i] != -1; i++) { - if (lseek(fd, sblock_try[i], SEEK_SET) < 0) - err(1, "lseek: %s", fsname); - if (read(fd, sblock, (long)SBLOCKSIZE) != SBLOCKSIZE) - err(1, "can't read superblock: %s", fsname); - sbp = (struct fs *)sblock; - if ((sbp->fs_magic == FS_UFS1_MAGIC || - (sbp->fs_magic == FS_UFS2_MAGIC && - sbp->fs_sblockloc == sblock_try[i])) && - sbp->fs_bsize <= MAXBSIZE && - sbp->fs_bsize >= sizeof(struct fs)) - break; + len = numblks < UFS_NDADDR ? numblks : UFS_NDADDR; + for (i = 0; i < len; i++) { + if (i < numblks - 1) + frags = fs->fs_frag; + else + frags = howmany(size % fs->fs_bsize, + fs->fs_fsize); + if (fs->fs_magic == FS_UFS1_MAGIC) + blkno = dp->dp1.di_db[i]; + else + blkno = dp->dp2.di_db[i]; + printblk(fs, i, blkno, frags, numblks); } - if (sblock_try[i] == -1) - errx(1, "Cannot find file system superblock\n"); - - /* remaining arguments are inode numbers. */ - while (*++argv) { - /* get the inode number. */ - if ((inonum = atoi(*argv)) <= 0) - errx(1, "%s is not a valid inode number", *argv); - (void)printf("%d:", inonum); - - /* read in the appropriate block. */ - offset = ino_to_fsba(sbp, inonum); /* inode to fs blk */ - offset = fsbtodb(sbp, offset); /* fs blk disk blk */ - offset *= DEV_BSIZE; /* disk blk to bytes */ - - /* seek and read the block */ - if (lseek(fd, offset, SEEK_SET) < 0) - err(1, "%s", fsname); - if (read(fd, ibuf, sbp->fs_bsize) != sbp->fs_bsize) - err(1, "%s", fsname); - - /* get the inode within the block. */ - if (sbp->fs_magic == FS_UFS1_MAGIC) { - dp.dp1 = &((struct ufs1_dinode *)(ibuf)) - [ino_to_fsbo(sbp, inonum)]; - size = dp.dp1->di_size; - } else { - dp.dp2 = &((struct ufs2_dinode *)(ibuf)) - [ino_to_fsbo(sbp, inonum)]; - size = dp.dp2->di_size; - } - numblks = howmany(size, sbp->fs_bsize); - if (numblks == 0) { - printf(" empty file\n"); - continue; - } - len = numblks < UFS_NDADDR ? numblks : UFS_NDADDR; - for (i = 0; i < len; i++) { - if (i < numblks - 1) - frags = sbp->fs_frag; - else - frags = howmany(size % sbp->fs_bsize, - sbp->fs_fsize); - if (sbp->fs_magic == FS_UFS1_MAGIC) - blkno = dp.dp1->di_db[i]; - else - blkno = dp.dp2->di_db[i]; - printblk(i, blkno, frags, numblks); - } - - blksperindir = 1; - len = numblks - UFS_NDADDR; - lbn = UFS_NDADDR; - for (i = 0; len > 0 && i < UFS_NIADDR; i++) { - if (sbp->fs_magic == FS_UFS1_MAGIC) - blkno = dp.dp1->di_ib[i]; - else - blkno = dp.dp2->di_ib[i]; - indirprt(i, blksperindir, lbn, blkno, numblks); - blksperindir *= NINDIR(sbp); - lbn += blksperindir; - len -= blksperindir; - } - - /* dummy print to flush out last extent */ - printblk(numblks, 0, frags, 0); + blksperindir = 1; + len = numblks - UFS_NDADDR; + lbn = UFS_NDADDR; + for (i = 0; len > 0 && i < UFS_NIADDR; i++) { + if (fs->fs_magic == FS_UFS1_MAGIC) + blkno = dp->dp1.di_ib[i]; + else + blkno = dp->dp2.di_ib[i]; + indirprt(disk, i, blksperindir, lbn, blkno, numblks); + blksperindir *= NINDIR(fs); + lbn += blksperindir; + len -= blksperindir; } - (void)close(fd); - exit(0); + + /* dummy print to flush out last extent */ + printblk(fs, numblks, 0, frags, 0); } -void -indirprt(level, blksperindir, lbn, blkno, lastlbn) +static void +indirprt(disk, level, blksperindir, lbn, blkno, lastlbn) + struct uufsd *disk; int level; int blksperindir; int lbn; @@ -174,41 +106,39 @@ indirprt(level, blksperindir, lbn, blkno, lastlbn) int lastlbn; { char indir[MAXBSIZE]; - off_t offset; + struct fs *fs; int i, last; - printblk(lbn, blkno, sbp->fs_frag, -level); + fs = (struct fs *)&disk->d_sb; + printblk(fs, lbn, blkno, fs->fs_frag, -level); /* read in the indirect block. */ - offset = fsbtodb(sbp, blkno); /* fs blk disk blk */ - offset *= DEV_BSIZE; /* disk blk to bytes */ - if (lseek(fd, offset, SEEK_SET) < 0) - err(1, "%s", fsname); - if (read(fd, indir, sbp->fs_bsize) != sbp->fs_bsize) - err(1, "%s", fsname); - last = howmany(lastlbn - lbn, blksperindir) < NINDIR(sbp) ? - howmany(lastlbn - lbn, blksperindir) : NINDIR(sbp); + if (bread(disk, fsbtodb(fs, blkno), indir, fs->fs_bsize) == -1) + err(1, "Read of indirect block %jd failed", (intmax_t)blkno); + last = howmany(lastlbn - lbn, blksperindir) < NINDIR(fs) ? + howmany(lastlbn - lbn, blksperindir) : NINDIR(fs); if (blksperindir == 1) { for (i = 0; i < last; i++) { - if (sbp->fs_magic == FS_UFS1_MAGIC) + if (fs->fs_magic == FS_UFS1_MAGIC) blkno = ((ufs1_daddr_t *)indir)[i]; else blkno = ((ufs2_daddr_t *)indir)[i]; - printblk(lbn + i, blkno, sbp->fs_frag, lastlbn); + printblk(fs, lbn + i, blkno, fs->fs_frag, lastlbn); } return; } for (i = 0; i < last; i++) { - if (sbp->fs_magic == FS_UFS1_MAGIC) + if (fs->fs_magic == FS_UFS1_MAGIC) blkno = ((ufs1_daddr_t *)indir)[i]; else blkno = ((ufs2_daddr_t *)indir)[i]; - indirprt(level - 1, blksperindir / NINDIR(sbp), + indirprt(disk, level - 1, blksperindir / NINDIR(fs), lbn + blksperindir * i, blkno, lastlbn); } } -char * -distance(lastblk, firstblk) +static char * +distance(fs, lastblk, firstblk) + struct fs *fs; daddr_t lastblk; daddr_t firstblk; { @@ -219,22 +149,23 @@ distance(lastblk, firstblk) if (lastblk == 0) return (""); delta = firstblk - lastblk - 1; - firstcg = dtog(sbp, firstblk); - lastcg = dtog(sbp, lastblk); + firstcg = dtog(fs, firstblk); + lastcg = dtog(fs, lastblk); if (firstcg == lastcg) { snprintf(buf, 100, " distance %jd", (intmax_t)delta); return (&buf[0]); } snprintf(buf, 100, " cg %d blk %jd to cg %d blk %jd", - lastcg, dtogd(sbp, lastblk), firstcg, dtogd(sbp, firstblk)); + lastcg, dtogd(fs, lastblk), firstcg, dtogd(fs, firstblk)); return (&buf[0]); } -char *indirname[UFS_NIADDR] = { "First", "Second", "Third" }; +static char *indirname[UFS_NIADDR] = { "First", "Second", "Third" }; -void -printblk(lbn, blkno, numblks, lastlbn) +static void +printblk(fs, lbn, blkno, numblks, lastlbn) + struct fs *fs; int lbn; ufs2_daddr_t blkno; int numblks; @@ -282,19 +213,19 @@ flush: } else if (seq == 1) { if (numblks == 1) printf("\tlbn %d blkno %jd%s\n", lbn - seq, - (intmax_t)firstblk, distance(lastblk, firstblk)); + (intmax_t)firstblk, distance(fs, lastblk, firstblk)); else printf("\tlbn %d blkno %jd-%jd%s\n", lbn - seq, (intmax_t)firstblk, (intmax_t)(firstblk + numblks - 1), - distance(lastblk, firstblk)); + distance(fs, lastblk, firstblk)); lastblk = firstblk + numblks - 1; } else { printf("\tlbn %d-%d blkno %jd-%jd%s\n", lbn - seq, lbn - 1, (intmax_t)firstblk, (intmax_t)(firstblk + - (seq - 1) * sbp->fs_frag + numblks - 1), - distance(lastblk, firstblk)); - lastblk = firstblk + (seq - 1) * sbp->fs_frag + numblks - 1; + (seq - 1) * fs->fs_frag + numblks - 1), + distance(fs, lastblk, firstblk)); + lastblk = firstblk + (seq - 1) * fs->fs_frag + numblks - 1; } if (lastlbn > 0 || blkno == 0) { seq = 1; @@ -302,13 +233,13 @@ flush: return; } prtindir: - if (seq != 0 && (sbp->fs_metaspace == 0 || lastindirblk == 0)) + if (seq != 0 && (fs->fs_metaspace == 0 || lastindirblk == 0)) lastindirblk = lastblk; printf("%s-level indirect, blkno %jd-%jd%s\n", indirname[-lastlbn], (intmax_t)blkno, (intmax_t)(blkno + numblks - 1), - distance(lastindirblk, blkno)); + distance(fs, lastindirblk, blkno)); lastindirblk = blkno + numblks - 1; - if (sbp->fs_metaspace == 0) + if (fs->fs_metaspace == 0) lastblk = lastindirblk; seq = 0; } |