}
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 };
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);
}
}
}
+/****** 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}
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
};
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;
}
}
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 {
if (index+1 == 0)
break;
}
- if (args[2] == NULL && col)
+ if (args[3] == NULL && col)
printf("\n");
}
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);
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)