All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: chris.mason@oracle.com
Cc: linux-btrfs@vger.kernel.org,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Subject: [PATCH -V2 6/6] debug-btrfs: Add print_inode command
Date: Thu,  4 Feb 2010 23:14:07 +0530	[thread overview]
Message-ID: <1265305447-30780-6-git-send-email-aneesh.kumar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1265305447-30780-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 debugbtrfs/cmds.c              |  191 ++++++++++++++++++++++++++++++++++++++++
 debugbtrfs/debug_btrfs_cmds.ct |    3 +
 lib/volumes.c                  |   16 ----
 lib/volumes.h                  |   12 +++
 4 files changed, 206 insertions(+), 16 deletions(-)

diff --git a/debugbtrfs/cmds.c b/debugbtrfs/cmds.c
index cd2901b..55a1ed7 100644
--- a/debugbtrfs/cmds.c
+++ b/debugbtrfs/cmds.c
@@ -20,10 +20,15 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <uuid/uuid.h>
+#include <time.h>
 
 #include "ctree.h"
 #include "disk-io.h"
+#include "extent_io.h"
+#include "transaction.h"
 #include "debug_btrfs.h"
+#include "volumes.h"
 
 void do_show_debugfs_params(int argc, char *argv[])
 {
@@ -48,3 +53,189 @@ void do_open_filesys(int argc, char *argv[])
 		return;
 	}
 }
+
+void dump_inode_details(FILE *out, u64 ino, struct extent_buffer *leaf,
+			struct btrfs_inode_item *inode_item)
+{
+	time_t t;
+	fprintf(out, "%-7s%-20llu", "Inode:", (unsigned long long)ino);
+	fprintf(out, "Generation: %llu\n",
+		btrfs_inode_generation(leaf, inode_item));
+
+	fprintf(out, "%-7s%-5o", "Mode:",
+		btrfs_inode_mode(leaf, inode_item) & 0777);
+
+	fprintf(out, "%-7s%-10d", "User:",
+		btrfs_inode_gid(leaf, inode_item));
+	fprintf(out, "%-7s%-10d\n", "Group:",
+		btrfs_inode_uid(leaf, inode_item));
+
+	fprintf(out, "%-7s%-20llu", "Size:", (unsigned long long)
+		btrfs_inode_size(leaf, inode_item));
+	fprintf(out, "%-7s%u\n", "Link:",
+		(unsigned int)btrfs_inode_nlink(leaf, inode_item));
+
+	t = (time_t)btrfs_timespec_sec(leaf,
+				btrfs_inode_atime(inode_item));
+	fprintf(out, "atime: %s", ctime(&t));
+	t = (time_t)btrfs_timespec_sec(leaf,
+				btrfs_inode_ctime(inode_item));
+	fprintf(out, "ctime: %s", ctime(&t));
+	t = (time_t)btrfs_timespec_sec(leaf,
+				btrfs_inode_mtime(inode_item));
+	fprintf(out, "mtime: %s", ctime(&t));
+	t = (time_t)btrfs_timespec_sec(leaf,
+				btrfs_inode_otime(inode_item));
+	fprintf(out, "otime: %s", ctime(&t));
+
+	return;
+}
+
+void dump_map_type(FILE *out, struct map_lookup *map)
+{
+	u64 type = map->type;
+
+	fprintf(out, "Raid type = ");
+
+	if (type & BTRFS_BLOCK_GROUP_RAID0)
+		fprintf(out, "Raid0");
+	else if (type & BTRFS_BLOCK_GROUP_RAID1)
+		fprintf(out, "Raid1");
+	else if (type & BTRFS_BLOCK_GROUP_RAID10)
+		fprintf(out, "Raid10");
+	else if (type & BTRFS_BLOCK_GROUP_DUP)
+		fprintf(out, "Duplicated data");
+	else
+		fprintf(out, "None");
+
+	fprintf(out, "\n");
+}
+
+void dump_chunk_details(FILE *out, u64 logical, u64 length)
+{
+	int ret, i;
+	char fs_uuid[37];
+	struct cache_extent *ce;
+        struct map_lookup *map;
+	struct btrfs_multi_bio *multi = NULL;
+	struct btrfs_mapping_tree *map_tree = &current_fs_root->fs_info->mapping_tree;
+
+	ret = btrfs_map_block(map_tree, WRITE, logical, &length, &multi, 0);
+	if (ret) {
+		fprintf(stderr, "Error in finding the chunk details \n");
+		return;
+	}
+	fprintf(out, "Number of devices = %d\n", multi->num_stripes);
+	ce = find_first_cache_extent(&map_tree->cache_tree, logical);
+	map = container_of(ce, struct map_lookup, ce);
+	dump_map_type(out, map);
+	for (i = 0; i < multi->num_stripes; i++) {
+		uuid_unparse(multi->stripes[i].dev->uuid , fs_uuid);
+		fprintf(out, "Device uuid = %s\n", fs_uuid);
+		fprintf(out, "Device = %s Offset = %llu \n",
+			multi->stripes[i].dev->name,
+			multi->stripes[i].physical);
+
+	}
+}
+
+void dump_file_extent(FILE *out, int count, u64 offset,
+		struct extent_buffer *leaf,
+		struct btrfs_file_extent_item *file_extent_item,
+		int print_chunk_details)
+{
+	fprintf(out, "\nExtent %d\n", count);
+	fprintf(out, "Logical offset = %llu Extent size = %llu\n",
+		(unsigned long long) offset,
+		btrfs_file_extent_num_bytes(leaf, file_extent_item));
+
+	fprintf(out, "Disk bytenr = %llu Actual disk size = %llu",
+		(unsigned long long)
+		btrfs_file_extent_disk_bytenr(leaf, file_extent_item),
+		btrfs_file_extent_disk_num_bytes(leaf, file_extent_item));
+
+	if (!btrfs_file_extent_disk_bytenr(leaf, file_extent_item))
+		fprintf(out, " (Hole)");
+	fprintf(out, "\n");
+	if (print_chunk_details)
+		dump_chunk_details(out, btrfs_file_extent_disk_bytenr(leaf, file_extent_item),
+				btrfs_file_extent_disk_num_bytes(leaf, file_extent_item));
+	return ;
+}
+
+void do_print_inode(int argc, char *argv[])
+{
+	FILE *out;
+	int c;
+	int print_chunk_details = 0;
+	int ret, count = 0;
+	u64 offset, inode_i_size;
+	struct btrfs_path *path;
+	struct btrfs_key inode_key;
+	struct extent_buffer *leaf;
+	struct btrfs_trans_handle *trans;
+	struct btrfs_inode_item *inode_item;
+	struct btrfs_file_extent_item *file_extent_item;
+
+
+	reset_getopt();
+	while ((c = getopt (argc, argv, "ch")) != EOF) {
+                switch (c) {
+                case 'c':
+                        print_chunk_details = 1;
+                        break;
+                default:
+			fprintf(stderr, "Usage %s [-ch] inode number\n",
+				argv[0]);
+			return;
+                }
+        }
+	if (optind == argc) {
+		fprintf(stderr, "Usage %s [-ch] inode number\n",
+			argv[0]);
+		return;
+	}
+	out = open_pager();
+	inode_key.objectid = atoll(argv[optind]);
+	inode_key.type     = BTRFS_INODE_ITEM_KEY;
+	inode_key.offset   = 0;
+
+	path = btrfs_alloc_path();
+	btrfs_init_path(path);
+	trans = btrfs_start_transaction(current_fs_root, 1);
+
+	ret = btrfs_search_slot(trans, current_fs_root, &inode_key, path, 0, 0);
+	if (ret != 0) {
+		fprintf(stderr, "Failed get the inode details for %llu\n",
+			(unsigned long long)inode_key.objectid);
+		goto err_out;
+	}
+	leaf = path->nodes[0];
+	inode_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item);
+	dump_inode_details(out, inode_key.objectid, leaf, inode_item);
+	inode_i_size = btrfs_inode_size(leaf, inode_item);
+	btrfs_release_path(current_fs_root, path);
+
+	/* get the file extent details */
+	offset = 0;
+	while (offset < inode_i_size) {
+		ret = btrfs_lookup_file_extent(trans, current_fs_root, path,
+					inode_key.objectid, offset, 0);
+		if (ret != 0) {
+			fprintf(stderr, "Not able to retrive extent information\n");
+			break;
+		}
+		leaf = path->nodes[0];
+		file_extent_item = btrfs_item_ptr(leaf, path->slots[0],
+						struct btrfs_file_extent_item);
+		dump_file_extent(out, count, offset,
+				leaf, file_extent_item, print_chunk_details);
+		offset += btrfs_file_extent_num_bytes(leaf, file_extent_item);
+		btrfs_release_path(current_fs_root, path);
+		count++;
+	}
+err_out:
+	btrfs_free_path(path);
+	btrfs_commit_transaction(trans, current_fs_root);
+	close_pager(out);
+}
diff --git a/debugbtrfs/debug_btrfs_cmds.ct b/debugbtrfs/debug_btrfs_cmds.ct
index cd40cf4..e6c5801 100644
--- a/debugbtrfs/debug_btrfs_cmds.ct
+++ b/debugbtrfs/debug_btrfs_cmds.ct
@@ -47,5 +47,8 @@ request do_dump_csum_tree, "Show btrfs checksum tree",
 request do_dump_log_tree, "Show btrfs log tree",
 	dump_log_tree;
 
+request do_print_inode, "Print inode details",
+	print_inode;
+
 end;
 
diff --git a/lib/volumes.c b/lib/volumes.c
index 7671855..08b75bb 100644
--- a/lib/volumes.c
+++ b/lib/volumes.c
@@ -30,22 +30,6 @@
 #include "print-tree.h"
 #include "volumes.h"
 
-struct stripe {
-	struct btrfs_device *dev;
-	u64 physical;
-};
-
-struct map_lookup {
-	struct cache_extent ce;
-	u64 type;
-	int io_align;
-	int io_width;
-	int stripe_len;
-	int sector_size;
-	int num_stripes;
-	int sub_stripes;
-	struct btrfs_bio_stripe stripes[];
-};
 
 #define map_lookup_size(n) (sizeof(struct map_lookup) + \
 			    (sizeof(struct btrfs_bio_stripe) * (n)))
diff --git a/lib/volumes.h b/lib/volumes.h
index bb78751..4c35b7a 100644
--- a/lib/volumes.h
+++ b/lib/volumes.h
@@ -88,6 +88,18 @@ struct btrfs_multi_bio {
 	struct btrfs_bio_stripe stripes[];
 };
 
+struct map_lookup {
+	struct cache_extent ce;
+	u64 type;
+	int io_align;
+	int io_width;
+	int stripe_len;
+	int sector_size;
+	int num_stripes;
+	int sub_stripes;
+	struct btrfs_bio_stripe stripes[];
+};
+
 #define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
 			    (sizeof(struct btrfs_bio_stripe) * (n)))
 
-- 
1.7.0.rc0.48.gdace5


  parent reply	other threads:[~2010-02-04 17:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-04 17:44 [PATCH -V2 1/6] btrfs-progs: Move files around Aneesh Kumar K.V
2010-02-04 17:44 ` [PATCH -V2 2/6] btrfs-progs: Add debug-btrfs command Aneesh Kumar K.V
2010-02-04 17:44 ` [PATCH -V2 3/6] debug-btrfs: Add open file system command Aneesh Kumar K.V
2010-02-04 17:44 ` [PATCH -V2 4/6] debug-btrfs: Add command to dump each of the btrfs trees Aneesh Kumar K.V
2010-02-04 17:44 ` [PATCH -V2 5/6] debug-btrfs: Add pager support Aneesh Kumar K.V
2010-02-04 17:44 ` Aneesh Kumar K.V [this message]
2010-02-04 17:48 ` Add debug-btrfs (btrfs file system debugger) Aneesh Kumar K. V

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1265305447-30780-6-git-send-email-aneesh.kumar@linux.vnet.ibm.com \
    --to=aneesh.kumar@linux.vnet.ibm.com \
    --cc=chris.mason@oracle.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.