[Ocfs2-tools-devel] debugfs.ocfs2 bmap command
tao.ma
tao.ma at oracle.com
Mon Aug 28 00:45:32 PDT 2006
Hi,
I have seen the code. And write some comments.
Please Mark, Joel & Sunil rectify it if there is something wrong. :)
GONG Jie wrote:
>Hi, all
>
>I have added the ``bmap'' command to debugfs.ocfs2. Enclosed please find the
>patch.
>
>
>
>------------------------------------------------------------------------
>
>Index: debugfs.ocfs2/commands.c
>===================================================================
>--- debugfs.ocfs2/commands.c (revision 1229)
>+++ debugfs.ocfs2/commands.c (working copy)
>@@ -65,10 +65,12 @@ static void do_encode_lockres (char **ar
> static void do_decode_lockres (char **args);
> static void do_locate (char **args);
> static void do_fs_locks (char **args);
>+static void do_bmap (char **args);
>
> dbgfs_gbls gbls;
>
> static Command commands[] = {
>+ { "bmap", do_bmap },
> { "cat", do_cat },
> { "cd", do_cd },
> { "chroot", do_chroot },
>@@ -95,7 +97,7 @@ static Command commands[] = {
> { "stat", do_stat },
> { "stats", do_stats },
> { "encode", do_encode_lockres },
>- { "decode", do_decode_lockres }
>+ { "decode", do_decode_lockres },
> };
>
> /*
>@@ -402,6 +404,48 @@ bail:
> return ret;
> }
>
>+/*
>+ * dump_logical_blkno()
>+ *
>+ */
>+static errcode_t dump_logical_blkno(ocfs2_filesys *fs, struct ocfs2_extent_list *el,
>+ uint64_t loglblkno, FILE *out)
>
>
As far as I know, for a file's extent record, it is stored in numbers of
cluster, not of block. So rec->e_clusters is the size of clusters and
you can't just use loglblkno -= rec->e_clusters. See
ocfs2_clusters_to_blocks or ocfs2_blocks_to_clusters for how to transfer
between them.
So you may first find the start blkno of the cluster which your logical
blkno belongs to and then add the offset of this blkno in that cluster
for the real blkno.
>+{
>+ struct ocfs2_extent_block *eb;
>+ struct ocfs2_extent_rec *rec;
>+ errcode_t ret = 0;
>+ char *buf = NULL;
>+ int i;
>+
>+ for (i = 0; i < el->l_next_free_rec; ++i) {
>+ rec = &(el->l_recs[i]);
>+ if (loglblkno < rec->e_clusters) {
>+ if (el->l_tree_depth) {
>+ ret = ocfs2_malloc_block(gbls.fs->fs_io, &buf);
>+ if (ret)
>+ goto bail;
>+
>+ ret = ocfs2_read_extent_block(fs, rec->e_blkno, buf);
>+ if (ret)
>+ goto bail;
>+
>+ eb = (struct ocfs2_extent_block *)buf;
>+
>+ ret = dump_logical_blkno(fs, &(eb->h_list), loglblkno, out);
>+ } else
>+ fprintf(out, "%"PRIu64"\n", rec->e_blkno + loglblkno);
>+ goto bail;
>+ } else
>+ loglblkno -= rec->e_clusters;
>+ }
>+ fprintf(out, "0\n");
>+
>+bail:
>+ if (buf)
>+ ocfs2_free(&buf);
>+ return ret;
>+}
>+
>
> /*
> * do_open()
>@@ -601,6 +645,7 @@ static void do_ls (char **args)
> */
> static void do_help (char **args)
> {
>+ printf ("bmap <filespec> <logical_blk>\t\tCalculate the logical->physical block mapping for an inode\n");
> printf ("cat <filespec>\t\t\t\tPrints file on stdout\n");
> printf ("cd <filespec>\t\t\t\tChange directory\n");
> printf ("chroot <filespec>\t\t\tChange root\n");
>@@ -1211,3 +1256,75 @@ static void do_fs_locks(char **args)
> dump_fs_locks(gbls.fs->uuid_str, out, dump_lvbs);
> close_pager(out);
> }
>+
>+/*
>+ * do_bmap()
>+ *
>+ */
>+static void do_bmap(char **args)
>+{
>+ struct ocfs2_dinode *inode;
>+ const char *bmap_usage = "usage: bmap <filespec> <logical_blk>";
>+ uint64_t blkno;
>+ uint64_t loglblkno;
>+ char *endptr;
>+ char *buf = NULL;
>+ FILE *out;
>+ errcode_t ret = 1;
>+
>+ if (check_device_open())
>+ return;
>+
>+ if (!args[1]) {
>+ fprintf(stderr, "usage: %s\n", bmap_usage);
>+ return;
>+ }
>+
>+ if (!args[1] || !args[2]) {
>+ fprintf(stderr, "usage: %s\n", bmap_usage);
>+ return;
>+ }
>+
>+ ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
>+ args[1], &blkno);
>+ if (ret) {
>+ com_err(args[0], ret, "'%s'", args[1]);
>+ return;
>+ }
>+
>+ if (blkno >= gbls.max_blocks) {
>+ fprintf(stderr, "%s: Block number is larger than volume size\n",
>+ args[0]);
>+ return;
>+ }
>+
>+ loglblkno = strtoul(args[2], &endptr, 0);
>+ if (*endptr) {
>+ fprintf(stderr, "%s: Invalid logical block number\n", args[0]);
>+ return;
>+ }
>+
>+ buf = gbls.blockbuf;
>+ ret = ocfs2_read_inode(gbls.fs, blkno, buf);
>+ if (ret) {
>+ com_err(args[0], ret, " ");
>+ return ;
>+ }
>+
>+ inode = (struct ocfs2_dinode *)buf;
>+
>+ out = open_pager(gbls.interactive);
>+
>+ if ((inode->i_flags & (OCFS2_LOCAL_ALLOC_FL | OCFS2_CHAIN_FL | OCFS2_DEALLOC_FL))
>+ || S_ISLNK(inode->i_mode) && !inode->i_clusters)
>+ fprintf(out, "0\n");
>+ else
>
>
You may check whether this inode has the logical blkno that user has
input here. So if a user input a large blkno that exceed the file size,
you don't need to go through the whole file's extent list. See
inode->i_clusters.
>+ dump_logical_blkno(gbls.fs, &(inode->id2.i_list), loglblkno, out);
>+
>+ if (ret)
>+ com_err(args[0], ret, " ");
>+
>+ close_pager(out);
>+
>+ return ;
>+}
>
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Ocfs2-tools-devel mailing list
>Ocfs2-tools-devel at oss.oracle.com
>http://oss.oracle.com/mailman/listinfo/ocfs2-tools-devel
>
>
--
* ** Tao Ma
* Member of Techincal Staff *
Oracle Asia Development Center
Emerging Technology & Solution Development
*
Tel: +86 10 8278 6026
Mobile: +86 13701237602
URL: OADC Intranet <http://cdc.oraclecorp.com/>, Oracle.com/cdc
<http://www.oracle.com/cdc/>
More information about the Ocfs2-tools-devel
mailing list