From d672cabda2f767069d36582cab818bb394e9b842 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 26 Mar 2011 10:57:57 +1100 Subject: [PATCH] Add printing of directory block Shows avl tree structure of a block given a virtual address or a file address. Signed-off-by: NeilBrown --- include/lafs/lafs.h | 2 + tools/lafs.c | 178 ++++++++++++++++++++++++++++---------------- 2 files changed, 116 insertions(+), 64 deletions(-) diff --git a/include/lafs/lafs.h b/include/lafs/lafs.h index 8525f43..9ad5a62 100644 --- a/include/lafs/lafs.h +++ b/include/lafs/lafs.h @@ -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, diff --git a/tools/lafs.c b/tools/lafs.c index b1a82b7..34d96d2 100644 --- a/tools/lafs.c +++ b/tools/lafs.c @@ -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) -- 2.39.5