]> git.neil.brown.name Git - lafs-utils.git/commitdiff
Add printing of directory block
authorNeilBrown <neilb@suse.de>
Fri, 25 Mar 2011 23:57:57 +0000 (10:57 +1100)
committerNeilBrown <neilb@suse.de>
Fri, 25 Mar 2011 23:57:57 +0000 (10:57 +1100)
Shows avl tree structure of a block given a virtual
address or a file address.

Signed-off-by: NeilBrown <neilb@suse.de>
include/lafs/lafs.h
tools/lafs.c

index 8525f432137bae8b726f8e41ffaf47db2e42fddd..9ad5a62559639dc56224dd41d55e536b705b7e68 100644 (file)
@@ -95,6 +95,8 @@ void lafs_dir_repack(char *block, int psz, char *new, u32 seed, int merge);
 int lafs_dir_find(char *block, int psz, u32 seed, u32 hash, u8 *pp);
 int lafs_dir_empty(char *block);
 int lafs_dir_blk_size(char *block, int psz);
+void lafs_dir_print(char *buf, int psz);
+
 int lafs_dir_next(struct lafs_ino *dir, u32 *indexp, char *name,
                  u32 *inop, int *typep);
 uint64_t lafs_leaf_lookup(unsigned char *buf, int len, u32 startaddr,
index b1a82b79d0200aea8b07f9142baea9786b9978d2..34d96d2613a28cb8d660ea0db3817fcdb0aa4c51 100644 (file)
@@ -727,6 +727,44 @@ static long parse_num_print(char *arg, char **error, char *func, char *name)
        }
        return rv;
 }
+
+static struct lafs_ino *get_inode(struct lafs *fs, void *args[], char **err)
+{
+       struct lafs_ino *inode;
+       *err = NULL;
+       if (fs->ss.root == 0) {
+               asprintf(err, "filesystem not ready for inode access");
+               return NULL;
+       }
+       inode = lafs_get_itable(fs);
+       if (args[1]) {
+               char *inostr = args[1];
+               char *endp;
+               int ino = strtoul(inostr, &endp, 10);
+               if (endp == inostr || *endp) {
+                       asprintf(err, "%s is not a valid inode number",
+                                inostr);
+                       return NULL;
+               }
+               if (ino)
+                       inode = lafs_get_inode(inode, ino);
+               if (!inode) {
+                       asprintf(err, "cannot find inode %d",ino);
+                       return NULL;
+               }
+       } else {
+               char *path = args[0];
+               inode = lafs_get_inode(inode, 2);
+               inode = lafs_lookup_path(inode, inode, path, NULL);
+
+               if (!inode) {
+                       asprintf(err, "cannot find inode for %s", path);
+                       return NULL;
+               }
+       }
+       return inode;
+}
+
 /****** EXIT ******/
 static char help_exit[] = "Exit lafs";
 static struct args args_exit[] = { TERMINAL_ARG };
@@ -1266,38 +1304,17 @@ static struct args args_show_inode[] = {
 static void c_show_inode(struct state *st, void **args)
 {
        struct lafs_ino *inode;
+       char *err;
        if (!args[2]) {
                printf("show inode: please give file name or inode number\n");
                return;
        }
-       if (st->lafs->ss.root == 0) {
-               printf("show inode: filesytem not ready\n");
+       inode = get_inode(st->lafs, args+2, &err);
+       if (!inode) {
+               printf("show inode: %s\n", err);
+               free(err);
                return;
        }
-       inode = lafs_get_itable(st->lafs);
-       if (args[3]) {
-               char *inostr = args[3];
-               char *endp;
-               int ino = strtoul(inostr, &endp, 10);
-               if (endp == inostr || *endp) {
-                       printf("show inode: %s is not a valid inode number\n",
-                              inostr);
-                       return;
-               }
-               if (ino)
-                       inode = lafs_get_inode(inode, ino);
-               if (!inode)
-                       printf("show inode: cannot find inode %d\n",ino);
-       } else {
-               char *path = args[2];
-               inode = lafs_get_inode(inode, 2);
-               inode = lafs_lookup_path(inode, inode, path, NULL);
-
-               if (!inode) {
-                       printf("show inode: cannot find inode for %s\n", path);
-                       return;
-               }
-       }
        lafs_print_inode(inode);
 }
 
@@ -1566,10 +1583,67 @@ static void c_show_cluster(struct state *st, void **args)
        }
 }
 
+/****** SHOW DIRBLOCK ******/
+static char help_show_dirblock[] = "Show the detailed contents of directory block";
+static struct args args_show_dirblock[] = {
+       { "BLOCK", opaque, -1, {NULL}, "Block number in file or LaFS"},
+       { "PATH", internal, -1, {NULL}, "Path of directory containing block"},
+       { "-inum", opaque, 1, {NULL}, "Inode number containing block"},
+       TERMINAL_ARG
+};
+static void c_show_dirblock(struct state *st, void **args)
+{
+       int bnum;
+       char *buf;
+       char *bstr = args[2];
+
+       if (!bstr) {
+               printf("show dirblock: now block number given\n");
+               return;
+       }
+       if (get_int(bstr, &bnum) < 0) {
+               printf("show dirblock: %s is not a valid address\n", bstr);
+               return;
+       }
+       if (!st->lafs->blocksize) {
+               printf("show dirblock: LaFS not ready to show blocks\n");
+               return;
+       }
+       if (args[3]) {
+               char *err;
+               struct lafs_dblk *db;
+               struct lafs_ino *inode = get_inode(st->lafs, args+3, &err);
+               if (!inode) {
+                       printf("show dirblock: %s\n", err);
+                       free(err);
+                       return;
+               }
+               db = lafs_dblk(inode, bnum);
+               if (lafs_load_dblk(db)) {
+                       printf("show dirblock: cannot load block %d of inode %d\n",
+                              bnum, inode->inum);
+                       return;
+               }
+               buf = db->b.data;
+       } else {
+               buf = malloc(st->lafs->blocksize);
+               if (lafs_read_virtual(st->lafs, buf, bnum)) {
+                       printf("show dirblock: cannot read block at %d\n", bnum);
+                       free(buf);
+                       return;
+               }
+       }
+       lafs_dir_print(buf, st->lafs->blockbits-8);
+       if (!args[3])
+               free(buf);
+}
+
+
 #define SCMD(x) {#x, c_show_##x, args_show_##x, help_show_##x}
 static struct cmd show_cmds[] = {
        SCMD(cluster),
        SCMD(device),
+       SCMD(dirblock),
        SCMD(inode),
        SCMD(state),
        { NULL, NULL, NULL, NULL}
@@ -1655,6 +1729,7 @@ static char ctypes[] = "?pc3d5b7-9lBsDWF";
 static char help_ls[] = "List files in a directory";
 static struct args args_ls[] = {
        {"DIRECTORY", internal, -1, {NULL}, "Directory to list"},
+       {"-inum", opaque, 0, {NULL}, "Inode number of directory to list"},
        {"-long", flag, -1, {NULL}, "Get a long, detailed listing"},
        TERMINAL_ARG
 };
@@ -1666,19 +1741,15 @@ static void c_ls(struct state *st, void **args)
        u32 inum;
        int type;
        int col;
+       char *err;
        char *path = args[1];
 
-       if (st->lafs->ss.root == 0) {
-               printf("ls: filesytem not ready\n");
-               return;
-       }
-       ino = lafs_get_itable(st->lafs);
-       ino = lafs_get_inode(ino, 2);
-       if (path)
-               ino = lafs_lookup_path(ino, ino, path, NULL);
-
+       if (!path)
+               args[1] = path = "";
+       ino = get_inode(st->lafs, args+1, &err);
        if (!ino) {
-               printf("ls: cannot find inode for %s\n", path?:"/");
+               printf("ls: %s\n", err);
+               free(err);
                return;
        }
 
@@ -1688,7 +1759,7 @@ static void c_ls(struct state *st, void **args)
        }
        col = 0;
        while (lafs_dir_next(ino, &index, name, &inum, &type) == 1) {
-               if (args[2]) {
+               if (args[3]) {
                        printf("%5lu %cxxxxxxxxx %s\n",
                               (unsigned long)inum, ctypes[type], name);
                } else {
@@ -1702,7 +1773,7 @@ static void c_ls(struct state *st, void **args)
                if (index+1 == 0)
                        break;
        }
-       if (args[2] == NULL && col)
+       if (args[3] == NULL && col)
                printf("\n");
 }
 
@@ -1716,6 +1787,7 @@ static struct args args_flush[] = {
 static void c_flush(struct state *st, void **args)
 {
        struct lafs_ino *inode;
+       char *err;
        if (!args[1]) {
                lafs_flush(st->lafs);
                lafs_cluster_flush(st->lafs, 0);
@@ -1723,34 +1795,12 @@ static void c_flush(struct state *st, void **args)
                        printf("Filesystem flushed\n");
                return;
        }
-       if (st->lafs->ss.root == 0) {
-               printf("show inode: filesytem not ready\n");
+       inode = get_inode(st->lafs, args+1, &err);
+       if (!inode) {
+               printf("flush: %s\n", err);
+               free(err);
                return;
        }
-       inode = lafs_get_itable(st->lafs);
-       if (args[2]) {
-               char *inostr = args[2];
-               char *endp;
-               int ino = strtoul(inostr, &endp, 10);
-               if (endp == inostr || *endp) {
-                       printf("flush: %s is not a valid inode number\n",
-                              inostr);
-                       return;
-               }
-               if (ino)
-                       inode = lafs_get_inode(inode, ino);
-               if (!inode)
-                       printf("flush: cannot find inode %d\n",ino);
-       } else {
-               char *path = args[1];
-               inode = lafs_get_inode(inode, 2);
-               inode = lafs_lookup_path(inode, inode, path, NULL);
-
-               if (!inode) {
-                       printf("flush: cannot find inode for %s\n", path);
-                       return;
-               }
-       }
        lafs_flush_inode(inode);
        lafs_cluster_flush(st->lafs, 0);
        if (st->verbose)