]> git.neil.brown.name Git - lafs-utils.git/commitdiff
Add lafs_print_inode / show inode command
authorNeilBrown <neilb@suse.de>
Sun, 20 Mar 2011 05:23:05 +0000 (16:23 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 20 Mar 2011 05:23:05 +0000 (16:23 +1100)
Plus a few bug-fixes

Signed-off-by: NeilBrown <neilb@suse.de>
include/lafs/lafs.h
lib/internal.h
lib/lafs_find_dblk.c
lib/lafs_import_inode.c
lib/lafs_import_inode_buf.c
lib/lafs_inode_init.c
lib/lafs_mount.c
lib/lafs_print_inode.c [new file with mode: 0644]
lib/lafs_read_virtual.c
tools/lafs.c

index 4181339acbb157ab925c497db7da1b121d793de5..4e777dd5361c052c8542a0c5de0cabc448b219e9 100644 (file)
@@ -70,6 +70,7 @@ void lafs_print_devblock(struct lafs_dev *dev);
 char *lafs_mount(struct lafs *fs, int force);
 void lafs_print_state(struct lafs_state *state, int size);
 void lafs_print_lafs(struct lafs *fs);
+void lafs_print_inode(struct lafs_ino *ino);
 
 static inline struct lafs_dblk *dblk(struct lafs_blk *b)
 {
index 8d828d71f3a03d05944b7651301dfa1fb41d5272..464804ea75111edd05c90deb73b63dbe91b37fa3 100644 (file)
@@ -31,3 +31,18 @@ unsigned long crc32(
        unsigned long crc,
        const uint32_t *buf,
        unsigned len);
+
+
+/*
+ * extract little-endian values out of memory.
+ * Each function is given a char*, and moves it forwards
+ */
+
+#define decode16(p) ({ unsigned int _a; _a= (unsigned char)*(p++); _a + (((unsigned char)*p++)<<8); })
+#define decode32(p) ({ long _b; _b = decode16(p); _b + ((u32)decode16(p)<<16); })
+#define decode48(p) ({ u64 _c; _c = decode32(p); _c + ((u64)decode16(p)<<32); })
+
+
+#define encode16(p,n) ({ *(p++) = (n)&255; *(p++) = ((n)>>8) & 255; })
+#define encode32(p,n) ({ encode16(p,n); encode16(p, ((n)>>16)); })
+#define encode48(p,n) ({ encode32(p,n); encode16(p, ((n)>>32)); })
index 4208eabdc5795836ad64524ef9b30ad8098a909e..52cfc2f66cb02d5a338399689aac246a5adb41b5 100644 (file)
@@ -14,7 +14,8 @@
 #include <lafs/lafs.h>
 #include <talloc.h>
 
-static u64 leaf_lookup(unsigned char *buf, int len, u32 target, u32 *nextp);
+static u64 leaf_lookup(unsigned char *buf, int len, u32 startaddr,
+                      u32 target, u32 *nextp);
 
 int lafs_find_dblk(struct lafs_dblk *db)
 {
@@ -44,9 +45,10 @@ int lafs_find_dblk(struct lafs_dblk *db)
        }
 
        db->b.physaddr = leaf_lookup((unsigned char*)ino->dblock->b.data + ino->metadata_size,
-                                  fs->blocksize - ino->metadata_size,
-                                  db->b.fileaddr,
-                                  NULL);
+                                    fs->blocksize - ino->metadata_size,
+                                    0,
+                                    db->b.fileaddr,
+                                    NULL);
        return 0;
 }
 
@@ -61,7 +63,8 @@ int lafs_find_dblk(struct lafs_dblk *db)
 #define decode48(p) ({ u64 _c; _c = decode32(p); _c + ((u64)decode16(p)<<32); })
 
 
-uint64_t leaf_lookup(unsigned char *buf, int len, u32 target, u32 *nextp)
+uint64_t leaf_lookup(unsigned char *buf, int len, u32 startaddr,
+                    u32 target, u32 *nextp)
 {
        /* buf starts with a 2byte header
         * if 1, then 4 byte offset followed by  6byte littleending indirect entries.
@@ -72,7 +75,6 @@ uint64_t leaf_lookup(unsigned char *buf, int len, u32 target, u32 *nextp)
        int hi,lo;
        int elen;
        u32 addr, next;
-       u32 startaddr;
        if (nextp) *nextp = NoBlock;
        if (buf[1]) return 0;
        switch (buf[0]) {
@@ -82,7 +84,6 @@ uint64_t leaf_lookup(unsigned char *buf, int len, u32 target, u32 *nextp)
        case 1: /* indirect */
                len -= 2+4;
                buf += 2;
-               startaddr = decode32(buf);
 
                if ( target < startaddr)
                        return 0;
index c4ca4b935d1fa66a68ff01ede61fe234c0ea4498..dc1626a8496dd042b0f9cd31463d1bb564d78aaf 100644 (file)
@@ -3,9 +3,14 @@
 struct lafs_ino *lafs_import_inode(struct lafs_dblk *db)
 {
        struct lafs_ino *parent = db->b.ino;
-       struct lafs_ino *ino =  lafs_import_inode_buf(parent->fs, db->b.data, db->b.fileaddr, parent);
+       struct lafs_ino *ino;
 
-       ino->dblock = db;
+       ino = lafs_import_inode_buf(parent->fs,
+                                   db->b.data, db->b.fileaddr,
+                                   parent);
+
+       if (ino)
+               ino->dblock = db;
        db->my_inode = ino;
        return ino;
 }
index 4c9d2db0498a2c37d35ec13d6a2b047ea1ad643d..da6f167b3e0f4976e1002ab8a36cfc05448287c4 100644 (file)
@@ -27,10 +27,11 @@ struct lafs_ino *lafs_import_inode_buf(struct lafs *fs,
        ino->inum = inum;
        ino->filesys = parent;
 
-       inode_load(ino, (struct la_inode *)buf);
-       /* FIXME callers of this should reparent it to themselves. */
-
-       return ino;
+       if (inode_load(ino, (struct la_inode *)buf))
+               /* FIXME callers of this should reparent it to themselves. */
+               return ino;
+       talloc_free(ino);
+       return NULL;
 }
 
 
index b1eac8f19bbe0794259a78a717cacededac34b89..3c4d2ac3372101fec83a8149147000ca2206eb04 100644 (file)
@@ -14,6 +14,7 @@ void lafs_inode_init(struct lafs *fs, char * buf, int type)
        struct lafs_ino ino;
        unsigned char *ip;
 
+       memset(buf, 0, fs->blocksize);
        memset(&ino, 0, sizeof(ino));
 
        ino.generation = random();
index 5be0527231a2e08be04013efa94e622a2e3b527e..bce49efa312b91e4992a8b3b61007e43f03ba79c 100644 (file)
@@ -103,6 +103,7 @@ char *lafs_mount(struct lafs *fs, int force)
                *ssp = ss;
                ssp = &ss->next;
        }
+       lafs_get_itable(fs);
 
        fs->max_segment = 0;
        for (dv = fs->devs ; dv; dv=dv->next)
diff --git a/lib/lafs_print_inode.c b/lib/lafs_print_inode.c
new file mode 100644 (file)
index 0000000..64ca36d
--- /dev/null
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#include <lafs/lafs.h>
+#include "internal.h"
+
+static char *type_names[] = { "-none-",
+       "InodeFile", "InodeMap", "SegmentMap", "Quota", "Orphanlist",
+       "AccessTime", "7", "8", "9", "10", "11", "12", "13", "14", "15",
+       "File", "Dir", "Symlink", "Device", "Pipe", "Attr"
+};
+
+void lafs_print_inode(struct lafs_ino *ino)
+{
+       struct lafs *fs = ino->fs;
+       struct fs_md *f;
+       struct inodemap_md *im;
+       struct su_md *sum;
+       struct file_md *fm;
+       char *body;
+       int bodybytes;
+       int cnt;
+       struct extent *ip;
+       int ind;
+
+/*     printf("inode at %p, iblock %p, data %p\n", ino, ino->iblock, ino->iblock->data);*/
+
+       printf("Inode %lu at %llu:\n", (unsigned long)ino->inum,
+              (unsigned long long)ino->dblock->b.physaddr);
+       printf(" Data Blocks  : %u\n", (unsigned)ino->cblocks);
+       printf(" Index Blocks : %u\n", (unsigned)ino->ciblocks);
+       printf(" Virt  Blocks : %u\n", (unsigned)(ino->cblocks+ino->ciblocks+ino->ablocks));
+       printf(" Generation   : %u\n", ino->generation);
+       printf(" MetaSize     : %u\n", ino->metadata_size);
+       printf(" Depth        : %u\n", ino->depth);
+       printf(" TruncGen     : %u\n", ino->trunc_gen);
+       printf(" File Type    : %s\n", (ino->type)<22?type_names[ino->type]:"Unknown");
+       if (ino->flags) {
+               printf(" Flags       :");
+               if (ino->flags & File_nonlogged)
+                       printf(" nonlogged");
+               printf("\n");
+       }
+
+       body = ino->dblock->b.data + ino->metadata_size;
+/*     printf(" body at %p\n", body);*/
+       bodybytes = fs->blocksize - (ino->metadata_size);
+       switch(ino->type) {
+       case TypeInodeFile:
+               f = &ino->md.fs;
+               printf("  UpdateTime  : %lld\n", (unsigned long long)(f->update_time));
+               printf("  Blocks      : %lld\n", (unsigned long long)(f->cblocks_used));
+               //printf("  Blocks(p)   : %lld\n", (unsigned long long)(f->pblocks_used));
+               printf("  BlocksAllow : %lld\n", (unsigned long long)(f->blocks_allowed));
+               printf("  Creation    : %lld\n", (unsigned long long)(f->creation_age));
+               printf("  Inodes      : %ld\n", (unsigned long)(f->inodes_used));
+               printf("  QuotaInodes : %ld,%ld,%ld\n",
+                      (unsigned long)f->quota_inums[0],
+                      (unsigned long)f->quota_inums[1],
+                      (unsigned long)f->quota_inums[2]);
+               printf("  SS Index    : %d\n", (f->usagetable));
+               printf("  Name        : %.40s\n", f->name);
+               break;
+       case TypeInodeMap: 
+               im = &ino->md.inodemap;
+               printf("  Map Size    : %lu\n", (unsigned long)im->size);
+               break;
+
+       case TypeSegmentMap:
+               sum = &ino->md.segmentusage;
+               printf("  Table Size  : %lu\n", (unsigned long)sum->table_size);
+               break;
+
+       case TypeQuota:
+       case TypeOrphanList:
+       case TypeAccessTime:
+               break;
+
+       case TypeFile:
+       case TypeDir:
+       case TypeSymlink:
+       case TypeSpecial:
+       case TypeAttr:
+               fm = &ino->md.file;
+               printf("  Flags       : 0x%hx\n", fm->flags);
+               printf("  Mode        : 0%ho\n", fm->mode);
+               printf("  Uid         : %lu\n", (unsigned long)fm->uid);
+               printf("  Gid         : %lu\n", (unsigned long)fm->gid);
+               printf("  Treeid      : %lu\n", (unsigned long)fm->treeid);
+               printf("  Creationtime: %llu\n", (unsigned long long)fm->creationtime);
+               printf("  ModifyTime  : %llu\n", (unsigned long long)fm->modifytime);
+               printf("  CTime       : %llu\n", (unsigned long long)fm->ctime);
+               printf("  AccessTime  : %llu\n", (unsigned long long)fm->accesstime);
+               printf("  Size        : %llu\n", (unsigned long long)fm->size);
+               printf("  Parent      : %lu\n", (unsigned long)fm->parent);
+               printf("  LinkCount   : %lu\n", (unsigned long)fm->linkcount);
+
+               break;
+       default:
+               printf("---------- unknown type ----------------\n");
+       }
+
+       if (ino->depth == 0) {
+               printf("Body starts:");
+               for (cnt=0; cnt< 16 && cnt < bodybytes; cnt++)
+                       printf(" %02x", 255&body[cnt]);
+               printf("\n");
+       } else if (ino->depth > 1) {
+               if (__le16_to_cpu(*(short*)body) != 0)
+                       printf("Eeek - index type %d at depth %d\n",
+                              __le16_to_cpu(*(short*)body), ino->depth);
+               else {
+                       printf(" Index Entries:\n");
+                       body+= 2;
+                       bodybytes -= 2;
+                       ind = 0;
+                       for (; bodybytes >= 10; body+=10, bodybytes -= 10) {
+                               unsigned char *p = (unsigned char *)body;
+                               u64 addr= decode48(p);
+                               u32 faddr=decode32(p);
+                               if (addr == 0)
+                                       break;
+                               printf(" <%lu -> %llu>", (unsigned long)faddr,
+                                      (unsigned long long)addr);
+                               if ((ind%10)==9) printf("\n");
+                               ind++;
+                       }
+                       if (((ind-1)%10)!= 9) printf("\n");
+               }
+       } else
+               switch (__le16_to_cpu(*(u16*)body)) {
+               case 0:
+                       printf("Eeek - internal index block at level 1!!\n");
+                       break;
+               case 1: /* indirect block */
+                       printf(" Indirect entries:\n");
+                       body+= 2;
+                       bodybytes -= 2;
+                       ind = 0;
+                       for (; bodybytes >= 6 ; body+= 6, bodybytes -= 6) {
+                               unsigned char *p = (unsigned char*)body;
+                               u64 addr = decode48(p);
+                               printf(" %llu", (unsigned long long)addr);
+                               if ((ind&15)==15) printf("\n");
+                               ind++;
+                       }
+                       printf("\n");
+                       break;
+               case 2: /* extent block */
+                       printf(" Extent entries:\n");
+                       ip = (struct extent*)(body+2);
+/*                     printf("body at %p\n", ip);*/
+                       for (; __le16_to_cpu(ip->size) != 0
+                                    && ((char*)(ip+1))<(body+bodybytes) ; ip++) 
+                               printf("  %ld..%ld at %ld\n",
+                                      (unsigned long)__le32_to_cpu(ip->logical),
+                                      (unsigned long)__le32_to_cpu(ip->logical)+
+                                      __le16_to_cpu(ip->size)-1,
+                                      (unsigned long)__le32_to_cpu(ip->phys_lo));
+                       break;
+               default: printf("Eek - unknown index block type: %d\n",
+                               __le16_to_cpu(*(u16*)body));
+               }
+       printf("...dblock=%p iblock=%p\n", ino->dblock, ino->iblock);
+//     if (ino->iblock)
+//     printf("...lc[0]=%d lc[1]=%d refcnt=%d p=%p\n", iblk(ino->iblock)->lockcnt[0],
+//            iblk(ino->iblock)->lockcnt[1], ino->iblock->refcnt, ino->iblock->parent);
+}
index 7651a68df3ba9d620e331750af5af9ef92cc31cf..019e2c5aeb7b98147f8681fa8972294813dbf1a8 100644 (file)
@@ -14,7 +14,9 @@ int lafs_read_virtual(struct lafs *fs, char *buf, loff_t addr)
 
        if (!d)
                return -1;
-       lseek64(d->fd, (addr - d->start) * fs->blocksize, SEEK_SET);
+       lseek64(d->fd,
+               (addr - d->start) * fs->blocksize + d->segment_offset,
+               SEEK_SET);
        n = read(d->fd, buf, fs->blocksize);
                  
 
index e3158607004dd823a2b03056c5f1dd2e1d4b6e86..0a6dc2f327a4fc5158acfa745f9c1380c3f6fde2 100644 (file)
@@ -1191,6 +1191,47 @@ static void c_show(struct state *st, void **args)
        c->cmd(st, args);
 }
 
+/****** SHOW INODE ******/
+static char help_show_inode[] = "Show inode given name or number";
+static struct args args_show_inode[] = {
+       { "PATH", internal, -1, {NULL}, "Path to inode to show"},
+       { "-inum", opaque, 0, {NULL}, "Inode number to show"},
+       TERMINAL_ARG
+};
+static void c_show_inode(struct state *st, void **args)
+{
+       int ino;
+       struct lafs_ino *inode;
+       if (!args[2]) {
+               printf("show inode: please give file name or inode number\n");
+               return;
+       }
+       if (args[3]) {
+               char *inostr = args[3];
+               char *endp;
+               ino = strtoul(inostr, &endp, 10);
+               if (endp == inostr || *endp) {
+                       printf("show inode: %s is not a valid inode number\n",
+                              inostr);
+                       return;
+               }
+       } else {
+               /* For now, path lookup always finds '0' */
+               ino = 0;
+       }
+       if (st->lafs->ss.root == 0) {
+               printf("show inode: filesytem not ready\n");
+               return;
+       }
+       inode = lafs_get_itable(st->lafs);
+       if (ino)
+               inode = lafs_get_inode(inode, ino);
+       if (inode)
+               lafs_print_inode(inode);
+       else
+               printf("show inode: cannot find inode %d\n",ino);
+}
+
 /****** SHOW DEVICE ******/
 static char help_show_device[] = "Show the device-block stored on a device";
 static struct args args_show_device[] = {
@@ -1354,6 +1395,7 @@ static void c_show_state(struct state *st, void **args)
 #define SCMD(x) {#x, c_show_##x, args_show_##x, help_show_##x}
 static struct cmd show_cmds[] = {
        SCMD(device),
+       SCMD(inode),
        SCMD(state),
        { NULL, NULL, NULL, NULL}
 };