[ Charset UTF-8 unsupported, converting... ]
> Author: mckusick
> Date: Fri Feb  9 19:10:46 2018
> New Revision: 329076
> URL: https://svnweb.freebsd.org/changeset/base/329076
> 
> Log:
>   This is a little C-program that can be used to print out the list
>   of blocks used by a requested list of inodes.
>   
>   For example, to list the blocks referenced by your kernel:
>   
>   guest_12 % df /
>   Filesystem      1K-blocks     Used   Avail Capacity  Mounted on
>   /dev/gpt/rootfs  20307196 10707336 7975288    57%    /
>   
>   guest_12 % ls -i /boot/kernel/kernel
>   160603 /boot/kernel/kernel
>   
>   guest_12 % ./prtblknos /dev/gpt/rootfs 160603
>   160603:     lbn 0-7 blkno 3217584-3217647
>       lbn 8-11 blkno 3217864-3217895 distance 216
>   First-level indirect, blkno 3217896-3217903 distance 0
>       lbn 12-19 blkno 3217904-3217967 distance 8
>       lbn 20-75 blkno 3251816-3252263 distance 33848
>       lbn 76-83 blkno 3252368-3252431 distance 104
>       lbn 84-91 blkno 3252464-3252527 distance 32
>       lbn 92-852 blkno 3252896-3258983 distance 368
>   
>   Each contiguous range of blocks is printed on a line.
>   The distance metric is the size of the gap from the end of the
>   previous set of blocks to the beginning of the next set of blocks.
>   Short distances are desirable.

Cant this be done with fsdb blocks command?

> 
> Added:
>   head/tools/diag/prtblknos/
>   head/tools/diag/prtblknos/Makefile   (contents, props changed)
>   head/tools/diag/prtblknos/README   (contents, props changed)
>   head/tools/diag/prtblknos/prtblknos.c   (contents, props changed)
> Modified:
>   head/tools/diag/README
> 
> Modified: head/tools/diag/README
> ==============================================================================
> --- head/tools/diag/README    Fri Feb  9 18:47:00 2018        (r329075)
> +++ head/tools/diag/README    Fri Feb  9 19:10:46 2018        (r329076)
> @@ -11,4 +11,4 @@ Please make a subdir per program, and add a brief desc
>  dumpvfscache program that can be used to examine the contents of the vfs
>               name cache.
>  localeck     check for invalid/incomplete locales 
> -
> +prtblknos    Print out the blocks used by each inode in the list
> 
> Added: head/tools/diag/prtblknos/Makefile
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/diag/prtblknos/Makefile        Fri Feb  9 19:10:46 2018        
> (r329076)
> @@ -0,0 +1,10 @@
> +# $FreeBSD$
> +
> +PROG=        prtblknos
> +
> +MAN=
> +
> +test:        ${PROG}
> +     ./${PROG} > a
> +
> +.include <bsd.prog.mk>
> 
> Added: head/tools/diag/prtblknos/README
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/diag/prtblknos/README  Fri Feb  9 19:10:46 2018        
> (r329076)
> @@ -0,0 +1,31 @@
> +# $FreeBSD$
> +
> +This is a little C-program that can be used to print out the list
> +of blocks used by a requested list of inodes.
> +
> +For example, to list the blocks referenced by your kernel:
> +
> +guest_12 % df /
> +Filesystem      1K-blocks     Used   Avail Capacity  Mounted on
> +/dev/gpt/rootfs  20307196 10707336 7975288    57%    /
> +
> +guest_12 % ls -i /boot/kernel/kernel
> +160603 /boot/kernel/kernel
> +
> +guest_12 % ./prtblknos /dev/gpt/rootfs 160603
> +160603:      lbn 0-7 blkno 3217584-3217647
> +     lbn 8-11 blkno 3217864-3217895 distance 216
> +First-level indirect, blkno 3217896-3217903 distance 0
> +     lbn 12-19 blkno 3217904-3217967 distance 8
> +     lbn 20-75 blkno 3251816-3252263 distance 33848
> +     lbn 76-83 blkno 3252368-3252431 distance 104
> +     lbn 84-91 blkno 3252464-3252527 distance 32
> +     lbn 92-852 blkno 3252896-3258983 distance 368
> +
> +Each contiguous range of blocks is printed on a line.
> +The distance metric is the size of the gap from the end of the
> +previous set of blocks to the beginning of the next set of blocks.
> +Short distances are desirable.
> +
> +     Marshall Kirk McKusick
> +     January 19, 2018
> 
> Added: head/tools/diag/prtblknos/prtblknos.c
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/diag/prtblknos/prtblknos.c     Fri Feb  9 19:10:46 2018        
> (r329076)
> @@ -0,0 +1,314 @@
> +/*
> + * 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 <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>
> +
> +union dinode {
> +     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);
> +
> +/* 
> + * Possible superblock locations ordered from most to least likely.
> + */
> +static int sblock_try[] = SBLOCKSEARCH;
> +
> +int
> +main(argc, argv)
> +     int argc;
> +     char *argv[];
> +{
> +     int i, len, lbn, frags, inonum, numblks, blksperindir;
> +     char sblock[SBLOCKSIZE], ibuf[MAXBSIZE];
> +     ufs2_daddr_t blkno;
> +     off_t size, offset;
> +     union dinode dp;
> +
> +     if (argc < 3) {
> +             (void)fprintf(stderr,"usage: prtblknos filesystem inode ...\n");
> +             exit(1);
> +     }
> +
> +     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;
> +     }
> +     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);
> +     }
> +     (void)close(fd);
> +     exit(0);
> +}
> +
> +void
> +indirprt(level, blksperindir, lbn, blkno, lastlbn)
> +     int level;
> +     int blksperindir;
> +     int lbn;
> +     ufs2_daddr_t blkno;
> +     int lastlbn;
> +{
> +     char indir[MAXBSIZE];
> +     off_t offset;
> +     int i, last;
> +
> +     printblk(lbn, blkno, sbp->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 (blksperindir == 1) {
> +             for (i = 0; i < last; i++) {
> +                     if (sbp->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);
> +             }
> +             return;
> +     }
> +     for (i = 0; i < last; i++) {
> +             if (sbp->fs_magic == FS_UFS1_MAGIC)
> +                     blkno = ((ufs1_daddr_t *)indir)[i];
> +             else
> +                     blkno = ((ufs2_daddr_t *)indir)[i];
> +             indirprt(level - 1, blksperindir / NINDIR(sbp),
> +                 lbn + blksperindir * i, blkno, lastlbn);
> +     }
> +}
> +
> +char *
> +distance(lastblk, firstblk)
> +     daddr_t lastblk;
> +     daddr_t firstblk;
> +{
> +     daddr_t delta;
> +     int firstcg, lastcg;
> +     static char buf[100];
> +
> +     if (lastblk == 0)
> +             return ("");
> +     delta = firstblk - lastblk - 1;
> +     firstcg = dtog(sbp, firstblk);
> +     lastcg = dtog(sbp, 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));
> +     return (&buf[0]);
> +}
> +     
> +
> +char *indirname[UFS_NIADDR] = { "First", "Second", "Third" };
> +
> +void
> +printblk(lbn, blkno, numblks, lastlbn)
> +     int lbn;
> +     ufs2_daddr_t blkno;
> +     int numblks;
> +     int lastlbn;
> +{
> +     static int seq;
> +     static daddr_t lastindirblk, lastblk, firstblk;
> +
> +     if (lastlbn <= 0)
> +             goto flush;
> +     if (seq == 0) {
> +             seq = 1;
> +             firstblk = blkno;
> +             return;
> +     }
> +     if (lbn == 0) {
> +             seq = 1;
> +             lastblk = 0;
> +             firstblk = blkno;
> +             lastindirblk = 0;
> +             return;
> +     }
> +     if (lbn < lastlbn && ((firstblk == 0 && blkno == 0) ||
> +         (firstblk == BLK_NOCOPY && blkno == BLK_NOCOPY) ||
> +         (firstblk == BLK_SNAP && blkno == BLK_SNAP) ||
> +         blkno == firstblk + seq * numblks)) {
> +             seq++;
> +             return;
> +     }
> +flush:
> +     if (seq == 0)
> +             goto prtindir;
> +     if (firstblk <= BLK_SNAP) {
> +             if (seq == 1)
> +                     printf("\tlbn %d %s\n", lbn - seq,
> +                         firstblk == 0 ? "hole" :
> +                         firstblk == BLK_NOCOPY ? "nocopy" :
> +                         "snapblk");
> +             else
> +                     printf("\tlbn %d-%d %s\n",
> +                         lbn - seq, lbn - 1,
> +                         firstblk == 0 ? "hole" :
> +                         firstblk == BLK_NOCOPY ? "nocopy" :
> +                         "snapblk");
> +     } else if (seq == 1) {
> +             if (numblks == 1)
> +                     printf("\tlbn %d blkno %jd%s\n", lbn - seq,
> +                         (intmax_t)firstblk, distance(lastblk, firstblk));
> +             else
> +                     printf("\tlbn %d blkno %jd-%jd%s\n", lbn - seq,
> +                         (intmax_t)firstblk,
> +                         (intmax_t)(firstblk + numblks - 1),
> +                         distance(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;
> +     }
> +     if (lastlbn > 0 || blkno == 0) {
> +             seq = 1;
> +             firstblk = blkno;
> +             return;
> +     }
> +prtindir:
> +     if (seq != 0 && (sbp->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));
> +     lastindirblk = blkno + numblks - 1;
> +     if (sbp->fs_metaspace == 0)
> +             lastblk = lastindirblk;
> +     seq = 0;
> +}
> 
> 

-- 
Rod Grimes                                                 rgri...@freebsd.org
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to