Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/fsdb Add a findblk command, which list the inode(s) own...
details: https://anonhg.NetBSD.org/src/rev/02efd1aa537a
branches: trunk
changeset: 546321:02efd1aa537a
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sat Apr 26 08:42:49 2003 +0000
description:
Add a findblk command, which list the inode(s) owning the disk sector(s)
passed as argument.
diffstat:
sbin/fsdb/fsdb.8 | 7 +-
sbin/fsdb/fsdb.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 288 insertions(+), 8 deletions(-)
diffs (truncated from 373 to 300 lines):
diff -r 7af2d9c5fd12 -r 02efd1aa537a sbin/fsdb/fsdb.8
--- a/sbin/fsdb/fsdb.8 Sat Apr 26 08:31:30 2003 +0000
+++ b/sbin/fsdb/fsdb.8 Sat Apr 26 08:42:49 2003 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: fsdb.8,v 1.14 2002/10/01 13:40:33 wiz Exp $
+.\" $NetBSD: fsdb.8,v 1.15 2003/04/26 08:42:49 bouyer Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -129,6 +129,11 @@
.It Cm blks
List the current inode's blocks numbers.
.Pp
+.It Cm findblk Ar disk block number ...
+Find the inode(s) owning the specifed disk block(s) number(s).
+Note that these are not absolute disk blocks numbers, but offsets from the
+start or the partition.
+.Pp
.It Cm rm Ar name
.It Cm del Ar name
Remove the entry
diff -r 7af2d9c5fd12 -r 02efd1aa537a sbin/fsdb/fsdb.c
--- a/sbin/fsdb/fsdb.c Sat Apr 26 08:31:30 2003 +0000
+++ b/sbin/fsdb/fsdb.c Sat Apr 26 08:42:49 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fsdb.c,v 1.24 2003/04/08 14:46:21 fvdl Exp $ */
+/* $NetBSD: fsdb.c,v 1.25 2003/04/26 08:42:49 bouyer Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fsdb.c,v 1.24 2003/04/08 14:46:21 fvdl Exp $");
+__RCSID("$NetBSD: fsdb.c,v 1.25 2003/04/26 08:42:49 bouyer Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -79,8 +79,17 @@
static int dotime __P((char *, int32_t *, int32_t *));
static void print_blks32 __P((int32_t *buf, int size, int *blknum));
static void print_blks64 __P((int64_t *buf, int size, int *blknum));
-static void print_indirblks32 __P((daddr_t blk, int ind_level, int *blknum));
-static void print_indirblks64 __P((daddr_t blk, int ind_level, int *blknum));
+static void print_indirblks32 __P((uint32_t blk, int ind_level, int *blknum));
+static void print_indirblks64 __P((uint64_t blk, int ind_level, int *blknum));
+static int compare_blk32 __P((uint32_t *, uint32_t));
+static int compare_blk64 __P((uint64_t *, uint64_t));
+static int founddatablk __P((uint64_t));
+static int find_blks32 __P((uint32_t *buf, int size, uint32_t *blknum));
+static int find_blks64 __P((uint64_t *buf, int size, uint64_t *blknum));
+static int find_indirblks32 __P((uint32_t blk, int ind_level,
+ uint32_t *blknum));
+static int find_indirblks64 __P((uint64_t blk, int ind_level,
+ uint64_t *blknum));
int returntosingle = 0;
union dinode *curinode;
@@ -156,6 +165,7 @@
CMDFUNC(quit); /* quit */
CMDFUNC(ls); /* list directory */
CMDFUNC(blks); /* list blocks */
+CMDFUNC(findblk); /* find block */
CMDFUNC(rm); /* remove name */
CMDFUNC(ln); /* add name */
CMDFUNC(newtype); /* change type */
@@ -187,6 +197,7 @@
{"linkcount", "Set link count to COUNT", 2, 2, linkcount},
{"ls", "List current inode as directory", 1, 1, ls},
{"blks", "List current inode's data blocks", 1, 1, blks},
+ {"findblk", "Find inode owning disk block(s)", 2, 33, findblk},
{"rm", "Remove NAME from current inode directory", 2, 2, rm},
{"del", "Remove NAME from current inode directory", 2, 2, rm},
{"ln", "Hardlink INO into current inode directory as NAME", 3, 3, ln},
@@ -311,7 +322,7 @@
static ino_t ocurrent;
#define GETINUM(ac,inum) inum = strtoul(argv[ac], &cp, 0); \
- if (inum < ROOTINO || inum > maxino || cp == argv[ac] || *cp != '\0' ) { \
+ if (inum < ROOTINO || inum >= maxino || cp == argv[ac] || *cp != '\0' ) { \
printf("inode %d out of range; range is [%d,%d]\n", \
inum, ROOTINO, maxino); \
return 1; \
@@ -488,6 +499,270 @@
return 0;
}
+static int findblk_numtofind;
+static int wantedblksize;
+CMDFUNCSTART(findblk)
+{
+ ino_t inum, inosused;
+ uint32_t *wantedblk32;
+ uint64_t *wantedblk64;
+ struct cg *cgp = cgrp;
+ int i, c;
+
+ ocurrent = curinum;
+ wantedblksize = (argc - 1);
+ if (is_ufs2) {
+ wantedblk64 = malloc(sizeof(uint64_t) * wantedblksize);
+ if (wantedblk64 == NULL) {
+ perror("malloc");
+ return 1;
+ }
+ memset(wantedblk64, 0, sizeof(uint64_t) * wantedblksize);
+ for (i = 1; i < argc; i++)
+ wantedblk64[i - 1] =
+ dbtofsb(sblock, strtoull(argv[i], NULL, 0));
+ } else {
+ wantedblk32 = malloc(sizeof(uint32_t) * wantedblksize);
+ if (wantedblk32 == NULL) {
+ perror("malloc");
+ return 1;
+ }
+ memset(wantedblk32, 0, sizeof(uint32_t) * wantedblksize);
+ for (i = 1; i < argc; i++)
+ wantedblk32[i - 1] =
+ dbtofsb(sblock, strtoull(argv[i], NULL, 0));
+ }
+ findblk_numtofind = wantedblksize;
+ for (c = 0; c < sblock->fs_ncg; c++) {
+ inum = c * sblock->fs_ipg;
+ getblk(&cgblk, cgtod(sblock, c), sblock->fs_cgsize);
+ memcpy(cgp, cgblk.b_un.b_cg, sblock->fs_cgsize);
+ if (needswap)
+ ffs_cg_swap(cgblk.b_un.b_cg, cgp, sblock);
+ if (is_ufs2)
+ inosused = cgp->cg_initediblk;
+ else
+ inosused = sblock->fs_ipg;
+ for (; inosused > 0; inum++, inosused--) {
+ if (inum < ROOTINO)
+ continue;
+ if (is_ufs2 ? compare_blk64(wantedblk64,
+ ino_to_fsba(sblock, inum)) :
+ compare_blk32(wantedblk32,
+ ino_to_fsba(sblock, inum))) {
+ printf("block %llu: inode block (%d-%d)\n",
+ (unsigned long long)fsbtodb(sblock,
+ ino_to_fsba(sblock, inum)),
+ (inum / INOPB(sblock)) * INOPB(sblock),
+ (inum / INOPB(sblock) + 1) * INOPB(sblock));
+ findblk_numtofind--;
+ if (findblk_numtofind == 0)
+ goto end;
+ }
+ curinum = inum;
+ curinode = ginode(inum);
+ switch (iswap16(DIP(curinode, mode)) & IFMT) {
+ case IFDIR:
+ case IFREG:
+ if (DIP(curinode, blocks) == 0)
+ continue;
+ break;
+ case IFLNK:
+ {
+ uint64_t size = iswap64(DIP(curinode, size));
+ if (size > 0 &&
+ size < sblock->fs_maxsymlinklen &&
+ DIP(curinode, blocks) == 0)
+ continue;
+ else
+ break;
+ }
+ default:
+ continue;
+ }
+ if (is_ufs2 ?
+ find_blks64(curinode->dp2.di_db, NDADDR,
+ wantedblk64) :
+ find_blks32(curinode->dp1.di_db, NDADDR,
+ wantedblk32))
+ goto end;
+ for (i = 0; i < NIADDR; i++) {
+ if (is_ufs2 ?
+ compare_blk64(wantedblk64,
+ iswap64(curinode->dp2.di_ib[i])) :
+ compare_blk32(wantedblk32,
+ iswap32(curinode->dp1.di_ib[i])))
+ if (founddatablk(is_ufs2 ?
+ iswap64(curinode->dp2.di_ib[i]) :
+ iswap32(curinode->dp1.di_ib[i])))
+ goto end;
+ if (is_ufs2 ? (curinode->dp2.di_ib[i] != 0) :
+ (curinode->dp1.di_ib[i] != 0))
+ if (is_ufs2 ?
+ find_indirblks64(
+ iswap64(curinode->dp2.di_ib[i]),
+ i, wantedblk64) :
+ find_indirblks32(
+ iswap32(curinode->dp1.di_ib[i]),
+ i, wantedblk32))
+ goto end;
+ }
+ }
+ }
+end:
+ curinum = ocurrent;
+ curinode = ginode(curinum);
+ return 0;
+}
+
+static int
+compare_blk32(wantedblk, curblk)
+ uint32_t *wantedblk;
+ uint32_t curblk;
+{
+ int i;
+ for (i = 0; i < wantedblksize; i++) {
+ if (wantedblk[i] != 0 && wantedblk[i] == curblk) {
+ wantedblk[i] = 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+compare_blk64(wantedblk, curblk)
+ uint64_t *wantedblk;
+ uint64_t curblk;
+{
+ int i;
+ for (i = 0; i < wantedblksize; i++) {
+ if (wantedblk[i] != 0 && wantedblk[i] == curblk) {
+ wantedblk[i] = 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+founddatablk(blk)
+ uint64_t blk;
+{
+ printf("%llu: data block of inode %d\n",
+ (unsigned long long)fsbtodb(sblock, blk), curinum);
+ findblk_numtofind--;
+ if (findblk_numtofind == 0)
+ return 1;
+ return 0;
+}
+
+static int
+find_blks32(buf, size, wantedblk)
+ uint32_t *buf;
+ int size;
+ uint32_t *wantedblk;
+
+{
+ int blk;
+ for(blk = 0; blk < size; blk++) {
+ if (buf[blk] == 0)
+ continue;
+ if (compare_blk32(wantedblk, iswap32(buf[blk]))) {
+ if (founddatablk(iswap32(buf[blk])))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+find_indirblks32(blk, ind_level, wantedblk)
+ uint32_t blk;
+ int ind_level;
+ uint32_t *wantedblk;
+{
+#define MAXNINDIR (MAXBSIZE / sizeof(uint32_t))
+ uint32_t idblk[MAXNINDIR];
+ int i;
+
+ bread(fsreadfd, (char *)idblk, fsbtodb(sblock, blk),
+ (int)sblock->fs_bsize);
+ if (ind_level <= 0) {
+ if (find_blks32(idblk,
+ sblock->fs_bsize / sizeof(uint32_t), wantedblk))
+ return 1;
+ } else {
+ ind_level--;
+ for (i = 0; i < sblock->fs_bsize / sizeof(uint32_t); i++) {
+ if (compare_blk32(wantedblk, iswap32(idblk[i]))) {
+ if (founddatablk(iswap32(idblk[i])))
+ return 1;
+ }
+ if(idblk[i] != 0)
+ if (find_indirblks32(iswap32(idblk[i]),
+ ind_level, wantedblk))
+ return 1;
+ }
+ }
+#undef MAXNINDIR
+ return 0;
+}
+
+
+static int
Home |
Main Index |
Thread Index |
Old Index