From: NeilBrown Date: Sun, 20 Mar 2011 05:23:05 +0000 (+1100) Subject: Add lafs_print_inode / show inode command X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=2c0cf421c7a5a4e564af9adddd3b2069e6772243;p=lafs-utils.git Add lafs_print_inode / show inode command Plus a few bug-fixes Signed-off-by: NeilBrown --- diff --git a/include/lafs/lafs.h b/include/lafs/lafs.h index 4181339..4e777dd 100644 --- a/include/lafs/lafs.h +++ b/include/lafs/lafs.h @@ -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) { diff --git a/lib/internal.h b/lib/internal.h index 8d828d7..464804e 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -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)); }) diff --git a/lib/lafs_find_dblk.c b/lib/lafs_find_dblk.c index 4208eab..52cfc2f 100644 --- a/lib/lafs_find_dblk.c +++ b/lib/lafs_find_dblk.c @@ -14,7 +14,8 @@ #include #include -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; diff --git a/lib/lafs_import_inode.c b/lib/lafs_import_inode.c index c4ca4b9..dc1626a 100644 --- a/lib/lafs_import_inode.c +++ b/lib/lafs_import_inode.c @@ -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; } diff --git a/lib/lafs_import_inode_buf.c b/lib/lafs_import_inode_buf.c index 4c9d2db..da6f167 100644 --- a/lib/lafs_import_inode_buf.c +++ b/lib/lafs_import_inode_buf.c @@ -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; } diff --git a/lib/lafs_inode_init.c b/lib/lafs_inode_init.c index b1eac8f..3c4d2ac 100644 --- a/lib/lafs_inode_init.c +++ b/lib/lafs_inode_init.c @@ -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(); diff --git a/lib/lafs_mount.c b/lib/lafs_mount.c index 5be0527..bce49ef 100644 --- a/lib/lafs_mount.c +++ b/lib/lafs_mount.c @@ -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 index 0000000..64ca36d --- /dev/null +++ b/lib/lafs_print_inode.c @@ -0,0 +1,166 @@ +#include +#include +#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); +} diff --git a/lib/lafs_read_virtual.c b/lib/lafs_read_virtual.c index 7651a68..019e2c5 100644 --- a/lib/lafs_read_virtual.c +++ b/lib/lafs_read_virtual.c @@ -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); diff --git a/tools/lafs.c b/tools/lafs.c index e315860..0a6dc2f 100644 --- a/tools/lafs.c +++ b/tools/lafs.c @@ -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} };