diff --git a/utils/src/format.h b/utils/src/format.h index b1bbdbbd..6251c8f8 100644 --- a/utils/src/format.h +++ b/utils/src/format.h @@ -50,12 +50,6 @@ struct scoutfs_block_header { __le64 blkno; } __packed; -/* - * The largest possible btree has 2^64 bytes worth of segments with - * the largest possible keys in a pathologically sparse btree where - * all the nodes are half full. - */ - /* * Assert that we'll be able to represent all possible keys with 8 64bit * primary sort values. @@ -94,9 +88,6 @@ enum { SCOUTFS_BTREE_BIT_HALF2 = (1 << 1), }; -#define SCOUTFS_BTREE_HALF_BITS \ - (SCOUTFS_BTREE_BIT_HALF1 | SCOUTFS_BTREE_BIT_HALF2) - struct scoutfs_btree_ref { __le64 blkno; __le64 seq; @@ -165,9 +156,8 @@ struct scoutfs_manifest { * segment key in the manifest btree key. Both of their keys are in the * value. * - * Level 1 segments are sorted by their key before their seq so the - * btree header has the key and the seq is in the footer. Only their - * last key is in the value. + * Level 1 segments are sorted by their first key so their last key is + * in the value. * * We go to all this trouble so that we can communicate a version of the * manifest with one btree root, have dense btree keys which are used as @@ -246,73 +236,78 @@ struct scoutfs_segment_block { } __packed; /* - * Currently we sort keys by the numeric value of the types, but that - * isn't necessary. We could have an arbitrary sort order. So we don't - * have to stress about cleverly allocating the types. + * Keys are first sorted by major key zones. */ -#define SCOUTFS_INODE_KEY 1 -#define SCOUTFS_XATTR_KEY 3 -#define SCOUTFS_DIRENT_KEY 5 -#define SCOUTFS_READDIR_KEY 6 -#define SCOUTFS_LINK_BACKREF_KEY 7 -#define SCOUTFS_SYMLINK_KEY 8 -#define SCOUTFS_FILE_EXTENT_KEY 9 -#define SCOUTFS_ORPHAN_KEY 10 -#define SCOUTFS_FREE_EXTENT_BLKNO_KEY 11 -#define SCOUTFS_FREE_EXTENT_BLOCKS_KEY 12 -#define SCOUTFS_INODE_INDEX_CTIME_KEY 13 /* don't forget first and last */ -#define SCOUTFS_INODE_INDEX_MTIME_KEY 14 -#define SCOUTFS_INODE_INDEX_SIZE_KEY 15 -#define SCOUTFS_INODE_INDEX_META_SEQ_KEY 16 -#define SCOUTFS_INODE_INDEX_DATA_SEQ_KEY 17 -/* not found in the fs */ -#define SCOUTFS_MAX_UNUSED_KEY 253 -#define SCOUTFS_NET_ADDR_KEY 254 -#define SCOUTFS_NET_LISTEN_KEY 255 +#define SCOUTFS_INODE_INDEX_ZONE 1 +#define SCOUTFS_NODE_ZONE 2 +#define SCOUTFS_FS_ZONE 3 + +/* inode index zone */ +#define SCOUTFS_INODE_INDEX_CTIME_TYPE 1 +#define SCOUTFS_INODE_INDEX_MTIME_TYPE 2 +#define SCOUTFS_INODE_INDEX_SIZE_TYPE 3 +#define SCOUTFS_INODE_INDEX_META_SEQ_TYPE 4 +#define SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE 5 -#define SCOUTFS_INODE_INDEX_FIRST SCOUTFS_INODE_INDEX_CTIME_KEY -#define SCOUTFS_INODE_INDEX_LAST SCOUTFS_INODE_INDEX_DATA_SEQ_KEY #define SCOUTFS_INODE_INDEX_NR \ - (SCOUTFS_INODE_INDEX_LAST - SCOUTFS_INODE_INDEX_FIRST + 1) + (SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE - SCOUTFS_INODE_INDEX_CTIME_TYPE + 1) + +/* node zone */ +#define SCOUTFS_FREE_EXTENT_BLKNO_TYPE 11 +#define SCOUTFS_FREE_EXTENT_BLOCKS_TYPE 12 + +/* fs zone */ +#define SCOUTFS_INODE_TYPE 1 +#define SCOUTFS_XATTR_TYPE 2 +#define SCOUTFS_DIRENT_TYPE 3 +#define SCOUTFS_READDIR_TYPE 4 +#define SCOUTFS_LINK_BACKREF_TYPE 5 +#define SCOUTFS_SYMLINK_TYPE 6 +#define SCOUTFS_FILE_EXTENT_TYPE 7 +#define SCOUTFS_ORPHAN_TYPE 8 + +/* XXX don't need these now that we have dlm lock spaces and resources */ +#define SCOUTFS_NET_ADDR_TYPE 254 +#define SCOUTFS_NET_LISTEN_TYPE 255 /* value is struct scoutfs_inode */ struct scoutfs_inode_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; } __packed; /* value is struct scoutfs_dirent without the name */ struct scoutfs_dirent_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; __u8 name[0]; } __packed; /* value is struct scoutfs_dirent with the name */ struct scoutfs_readdir_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; __be64 pos; } __packed; /* value is empty */ struct scoutfs_link_backref_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; __be64 dir_ino; __u8 name[0]; } __packed; -/* no value */ -struct scoutfs_orphan_key { - __u8 type; - __be64 ino; -} __packed; /* no value */ struct scoutfs_file_extent_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; __be64 last_blk_off; __be64 last_blkno; __be64 blocks; @@ -323,23 +318,34 @@ struct scoutfs_file_extent_key { /* no value */ struct scoutfs_free_extent_blkno_key { - __u8 type; + __u8 zone; __be64 node_id; + __u8 type; __be64 last_blkno; __be64 blocks; } __packed; struct scoutfs_free_extent_blocks_key { - __u8 type; + __u8 zone; __be64 node_id; + __u8 type; __be64 blocks; __be64 last_blkno; } __packed; -/* value is each item's part of the full xattr value for the off/len */ -struct scoutfs_xattr_key { +/* no value */ +struct scoutfs_orphan_key { + __u8 zone; + __be64 node_id; __u8 type; __be64 ino; +} __packed; + +/* value is each item's part of the full xattr value for the off/len */ +struct scoutfs_xattr_key { + __u8 zone; + __be64 ino; + __u8 type; __u8 name[0]; } __packed; @@ -355,8 +361,9 @@ struct scoutfs_xattr_val_header { /* size determines nr needed to store full target path in their values */ struct scoutfs_symlink_key { - __u8 type; + __u8 zone; __be64 ino; + __u8 type; __u8 nr; } __packed; @@ -366,6 +373,7 @@ struct scoutfs_betimespec { } __packed; struct scoutfs_inode_index_key { + __u8 zone; __u8 type; __be64 major; __be32 minor; @@ -498,6 +506,19 @@ enum { #define SCOUTFS_XATTR_MAX_PARTS \ DIV_ROUND_UP(SCOUTFS_XATTR_MAX_SIZE, SCOUTFS_XATTR_PART_SIZE) +/* + * structures used by dlm + */ +struct scoutfs_lock_name { + __u8 zone; + __u8 type; + __le64 first; + __le64 second; +} __packed; + +#define SCOUTFS_LOCK_INODE_GROUP_NR 1024 +#define SCOUTFS_LOCK_INODE_GROUP_MASK (SCOUTFS_LOCK_INODE_GROUP_NR - 1) +#define SCOUTFS_LOCK_INODE_GROUP_OFFSET (~0ULL) /* * messages over the wire. diff --git a/utils/src/key.c b/utils/src/key.c index 1487f9e3..46bc1420 100644 --- a/utils/src/key.c +++ b/utils/src/key.c @@ -10,14 +10,16 @@ /* * This is mechanically derived from scoutfs_key_str() in the kernel: - * - s/key->data/key_data/ - * - s/key->key_len/key_len/ - * - s/return snprintf_null(buf, size, /return printf(/ + * - :.,$s/key->data/key_data/g + * - :.,$s/key->key_len/key_len/g + * - :.,$s/return snprintf_null(buf, size, /return printf(/g */ int print_key(void *key_data, unsigned key_len) { + struct scoutfs_inode_key *ikey; + u8 zone = 0; + u8 type = 0; int len; - u8 type; if (key_data == NULL) return printf("[NULL]"); @@ -25,21 +27,88 @@ int print_key(void *key_data, unsigned key_len) if (key_len == 0) return printf("[0 len]"); - type = *(u8 *)key_data; + zone = *(u8 *)key_data; - switch(type) { + /* handle smaller and unknown zones, fall through to fs types */ + switch(zone) { + case SCOUTFS_INODE_INDEX_ZONE: { + struct scoutfs_inode_index_key *ikey = key_data; + static char *type_strings[] = { + [SCOUTFS_INODE_INDEX_CTIME_TYPE] = "ctm", + [SCOUTFS_INODE_INDEX_MTIME_TYPE] = "mtm", + [SCOUTFS_INODE_INDEX_SIZE_TYPE] = "siz", + [SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = "msq", + [SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = "dsq", + }; - case SCOUTFS_INODE_KEY: { + if (key_len < sizeof(struct scoutfs_inode_index_key)) + break; + + if (type_strings[ikey->type]) + return printf("iin.%s.%llu.%u.%llu", + type_strings[ikey->type], + be64_to_cpu(ikey->major), + be32_to_cpu(ikey->minor), + be64_to_cpu(ikey->ino)); + else + return printf("[iin type %u?]", + ikey->type); + } + + /* node zone keys start with zone, node, type */ + case SCOUTFS_NODE_ZONE: { + struct scoutfs_free_extent_blkno_key *fkey = key_data; + + static char *type_strings[] = { + [SCOUTFS_FREE_EXTENT_BLKNO_TYPE] = "fno", + [SCOUTFS_FREE_EXTENT_BLOCKS_TYPE] = "fks", + }; + + switch(fkey->type) { + case SCOUTFS_ORPHAN_TYPE: { + struct scoutfs_orphan_key *okey = key_data; + + if (key_len < sizeof(struct scoutfs_orphan_key)) + break; + return printf("nod.%llu.orp.%llu", + be64_to_cpu(okey->node_id), + be64_to_cpu(okey->ino)); + } + + case SCOUTFS_FREE_EXTENT_BLKNO_TYPE: + case SCOUTFS_FREE_EXTENT_BLOCKS_TYPE: + return printf("nod.%llu.%s.%llu.%llu", + be64_to_cpu(fkey->node_id), + type_strings[fkey->type], + be64_to_cpu(fkey->last_blkno), + be64_to_cpu(fkey->blocks)); + default: + return printf("[nod type %u?]", + fkey->type); + } + } + + case SCOUTFS_FS_ZONE: + break; + + default: + return printf("[zone %u?]", zone); + } + + /* everything in the fs tree starts with zone, ino, type */ + ikey = key_data; + switch(ikey->type) { + case SCOUTFS_INODE_TYPE: { struct scoutfs_inode_key *ikey = key_data; if (key_len < sizeof(struct scoutfs_inode_key)) break; - return printf("ino.%llu", + return printf("fs.%llu.ino", be64_to_cpu(ikey->ino)); } - case SCOUTFS_XATTR_KEY: { + case SCOUTFS_XATTR_TYPE: { struct scoutfs_xattr_key *xkey = key_data; len = (int)key_len - offsetof(struct scoutfs_xattr_key, @@ -47,53 +116,53 @@ int print_key(void *key_data, unsigned key_len) if (len <= 0) break; - return printf("xat.%llu.%.*s", + return printf("fs.%llu.xat.%.*s", be64_to_cpu(xkey->ino), len, xkey->name); } - case SCOUTFS_DIRENT_KEY: { + case SCOUTFS_DIRENT_TYPE: { struct scoutfs_dirent_key *dkey = key_data; len = (int)key_len - sizeof(struct scoutfs_dirent_key); if (len <= 0) break; - return printf("dnt.%llu.%.*s", + return printf("fs.%llu.dnt.%.*s", be64_to_cpu(dkey->ino), len, dkey->name); } - case SCOUTFS_READDIR_KEY: { + case SCOUTFS_READDIR_TYPE: { struct scoutfs_readdir_key *rkey = key_data; - return printf("rdr.%llu.%llu", + return printf("fs.%llu.rdr.%llu", be64_to_cpu(rkey->ino), be64_to_cpu(rkey->pos)); } - case SCOUTFS_LINK_BACKREF_KEY: { + case SCOUTFS_LINK_BACKREF_TYPE: { struct scoutfs_link_backref_key *lkey = key_data; len = (int)key_len - sizeof(*lkey); if (len <= 0) break; - return printf("lbr.%llu.%llu.%.*s", + return printf("fs.%llu.lbr.%llu.%.*s", be64_to_cpu(lkey->ino), be64_to_cpu(lkey->dir_ino), len, lkey->name); } - case SCOUTFS_SYMLINK_KEY: { + case SCOUTFS_SYMLINK_TYPE: { struct scoutfs_symlink_key *skey = key_data; - return printf("sym.%llu", + return printf("fs.%llu.sym", be64_to_cpu(skey->ino)); } - case SCOUTFS_FILE_EXTENT_KEY: { + case SCOUTFS_FILE_EXTENT_TYPE: { struct scoutfs_file_extent_key *ekey = key_data; - return printf("ext.%llu.%llu.%llu.%llu.%x", + return printf("fs.%llu.ext.%llu.%llu.%llu.%x", be64_to_cpu(ekey->ino), be64_to_cpu(ekey->last_blk_off), be64_to_cpu(ekey->last_blkno), @@ -101,48 +170,11 @@ int print_key(void *key_data, unsigned key_len) ekey->flags); } - case SCOUTFS_ORPHAN_KEY: { - struct scoutfs_orphan_key *okey = key_data; - - return printf("orp.%llu", - be64_to_cpu(okey->ino)); - } - - case SCOUTFS_FREE_EXTENT_BLKNO_KEY: - case SCOUTFS_FREE_EXTENT_BLOCKS_KEY: { - struct scoutfs_free_extent_blkno_key *fkey = key_data; - - return printf("%s.%llu.%llu.%llu", - fkey->type == SCOUTFS_FREE_EXTENT_BLKNO_KEY ? "fel" : - "fes", - be64_to_cpu(fkey->node_id), - be64_to_cpu(fkey->last_blkno), - be64_to_cpu(fkey->blocks)); - } - - case SCOUTFS_INODE_INDEX_CTIME_KEY: - case SCOUTFS_INODE_INDEX_MTIME_KEY: - case SCOUTFS_INODE_INDEX_SIZE_KEY: - case SCOUTFS_INODE_INDEX_META_SEQ_KEY: - case SCOUTFS_INODE_INDEX_DATA_SEQ_KEY: { - struct scoutfs_inode_index_key *ikey = key_data; - - return printf("%s.%llu.%u.%llu", - ikey->type == SCOUTFS_INODE_INDEX_CTIME_KEY ? "ctm" : - ikey->type == SCOUTFS_INODE_INDEX_MTIME_KEY ? "mtm" : - ikey->type == SCOUTFS_INODE_INDEX_SIZE_KEY ? "siz" : - ikey->type == SCOUTFS_INODE_INDEX_META_SEQ_KEY ? "msq" : - ikey->type == SCOUTFS_INODE_INDEX_DATA_SEQ_KEY ? "dsq" : - "uii", be64_to_cpu(ikey->major), - be32_to_cpu(ikey->minor), - be64_to_cpu(ikey->ino)); - } - default: - return printf("[unknown type %u len %u]", - type, key_len); + return printf("[fs type %u?]", type); } - return printf("[truncated type %u len %u]", + return printf("[fs type %u trunc len %u]", type, key_len); + } diff --git a/utils/src/mkfs.c b/utils/src/mkfs.c index 1388009e..6182d199 100644 --- a/utils/src/mkfs.c +++ b/utils/src/mkfs.c @@ -242,32 +242,34 @@ static int write_new_fs(char *path, int fd) bt->nr_items = cpu_to_le16(1); /* btree item allocated from the back of the block */ - idx_key = (void *)bt + SCOUTFS_BLOCK_SIZE - sizeof(*idx_key); - mval = (void *)idx_key - sizeof(*mval); - ikey = (void *)mval - sizeof(*ikey); - mkey = (void *)ikey - sizeof(*mkey); + ikey = (void *)bt + SCOUTFS_BLOCK_SIZE - sizeof(*ikey); + mval = (void *)ikey - sizeof(*mval); + idx_key = (void *)mval - sizeof(*idx_key); + mkey = (void *)idx_key - sizeof(*mkey); btitem = (void *)mkey - sizeof(*btitem); bt->item_hdrs[0].off = cpu_to_le16((long)btitem - (long)bt); bt->free_end = bt->item_hdrs[0].off; btitem->key_len = cpu_to_le16(sizeof(struct scoutfs_manifest_btree_key) + - sizeof(struct scoutfs_inode_key)); - btitem->val_len = cpu_to_le16(sizeof(struct scoutfs_manifest_btree_val) + sizeof(struct scoutfs_inode_index_key)); + btitem->val_len = cpu_to_le16(sizeof(struct scoutfs_manifest_btree_val) + + sizeof(struct scoutfs_inode_key)); mkey->level = 1; - ikey->type = SCOUTFS_INODE_KEY; - ikey->ino = cpu_to_be64(SCOUTFS_ROOT_INO); + idx_key->zone = SCOUTFS_INODE_INDEX_ZONE; + idx_key->type = SCOUTFS_INODE_INDEX_CTIME_TYPE; + idx_key->major = cpu_to_be64(tv.tv_sec); + idx_key->minor = cpu_to_be32(tv.tv_usec * 1000); + idx_key->ino = cpu_to_be64(SCOUTFS_ROOT_INO); mval->segno = cpu_to_le64(first_segno); mval->seq = cpu_to_le64(1); - mval->first_key_len = cpu_to_le16(sizeof(struct scoutfs_inode_key)); - mval->last_key_len = cpu_to_le16(sizeof(struct scoutfs_inode_index_key)); - idx_key->type = SCOUTFS_INODE_INDEX_META_SEQ_KEY; - idx_key->major = cpu_to_be64(0); - idx_key->minor = 0; - idx_key->ino = cpu_to_be64(SCOUTFS_ROOT_INO); + mval->first_key_len = cpu_to_le16(sizeof(struct scoutfs_inode_index_key)); + mval->last_key_len = cpu_to_le16(sizeof(struct scoutfs_inode_key)); + ikey->zone = SCOUTFS_FS_ZONE; + ikey->ino = cpu_to_be64(SCOUTFS_ROOT_INO); + ikey->type = SCOUTFS_INODE_TYPE; bt->crc = cpu_to_le32(crc_btree_block(bt)); @@ -287,6 +289,42 @@ static int write_new_fs(char *path, int fd) prev_link = &sblk->skip_links[0]; item = (void *)(sblk + 1); + *prev_link = cpu_to_le32((long)item -(long)sblk); + prev_link = &item->skip_links[0]; + + /* write the root inode index keys */ + for (i = SCOUTFS_INODE_INDEX_CTIME_TYPE; + i <= SCOUTFS_INODE_INDEX_META_SEQ_TYPE; i++) { + + item->key_len = cpu_to_le16(sizeof(*idx_key)); + item->val_len = 0; + item->nr_links = 1; + + idx_key = (void *)&item->skip_links[1]; + idx_key->zone = SCOUTFS_INODE_INDEX_ZONE; + idx_key->type = i; + idx_key->ino = cpu_to_be64(SCOUTFS_ROOT_INO); + + switch(i) { + case SCOUTFS_INODE_INDEX_CTIME_TYPE: + case SCOUTFS_INODE_INDEX_MTIME_TYPE: + idx_key->major = cpu_to_be64(tv.tv_sec); + idx_key->minor = cpu_to_be32(tv.tv_usec * 1000); + break; + default: + idx_key->major = cpu_to_be64(0); + idx_key->minor = 0; + break; + } + + + item = (void *)(idx_key + 1); + *prev_link = cpu_to_le32((long)item -(long)sblk); + prev_link = &item->skip_links[0]; + } + + sblk->last_item_off = cpu_to_le32((long)item - (long)sblk); + ikey = (void *)&item->skip_links[1]; inode = (void *)ikey + sizeof(struct scoutfs_inode_key); @@ -294,8 +332,9 @@ static int write_new_fs(char *path, int fd) item->val_len = cpu_to_le16(sizeof(struct scoutfs_inode)); item->nr_links = 1; - ikey->type = SCOUTFS_INODE_KEY; + ikey->zone = SCOUTFS_FS_ZONE; ikey->ino = cpu_to_be64(SCOUTFS_ROOT_INO); + ikey->type = SCOUTFS_INODE_TYPE; inode->next_readdir_pos = cpu_to_le64(2); inode->nlink = cpu_to_le32(SCOUTFS_DIRENT_FIRST_POS); @@ -307,44 +346,7 @@ static int write_new_fs(char *path, int fd) inode->mtime.sec = inode->atime.sec; inode->mtime.nsec = inode->atime.nsec; - *prev_link = cpu_to_le32((long)item -(long)sblk); - prev_link = &item->skip_links[0]; - - item = (void *)inode + sizeof(struct scoutfs_inode); - idx_key = (void *)&item->skip_links[1]; - - /* write the root inode index keys */ - for (i = SCOUTFS_INODE_INDEX_CTIME_KEY; - i <= SCOUTFS_INODE_INDEX_META_SEQ_KEY; i++) { - - item->key_len = cpu_to_le16(sizeof(*idx_key)); - item->val_len = 0; - item->nr_links = 1; - - idx_key->type = i; - idx_key->ino = cpu_to_be64(SCOUTFS_ROOT_INO); - - switch(i) { - case SCOUTFS_INODE_INDEX_CTIME_KEY: - case SCOUTFS_INODE_INDEX_MTIME_KEY: - idx_key->major = cpu_to_be64(tv.tv_sec); - idx_key->minor = cpu_to_be32(tv.tv_usec * 1000); - break; - default: - idx_key->major = cpu_to_be64(0); - idx_key->minor = 0; - break; - } - - *prev_link = cpu_to_le32((long)item -(long)sblk); - prev_link = &item->skip_links[0]; - - sblk->last_item_off = cpu_to_le32((long)item - (long)sblk); - - item = (void *)(idx_key + 1); - idx_key = (void *)&item->skip_links[1]; - } - + item = (void *)(inode + 1); sblk->total_bytes = cpu_to_le32((long)item - (long)sblk); ret = pwrite(fd, sblk, SCOUTFS_SEGMENT_SIZE, diff --git a/utils/src/print.c b/utils/src/print.c index 6462e161..3b3b4367 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -216,7 +216,7 @@ static void print_free_extent(void *key, int key_len, void *val, int val_len) u64 blkno; char *str; - if (blk->type == SCOUTFS_FREE_EXTENT_BLKNO_KEY) { + if (blk->type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE) { str = "free (blkno)"; node_id = be64_to_cpu(blk->node_id); last_blkno = be64_to_cpu(blk->last_blkno); @@ -245,23 +245,58 @@ static void print_inode_index(void *key, int key_len, void *val, int val_len) typedef void (*print_func_t)(void *key, int key_len, void *val, int val_len); -static print_func_t printers[] = { - [SCOUTFS_INODE_KEY] = print_inode, - [SCOUTFS_XATTR_KEY] = print_xattr, - [SCOUTFS_ORPHAN_KEY] = print_orphan, - [SCOUTFS_DIRENT_KEY] = print_dirent, - [SCOUTFS_READDIR_KEY] = print_readdir, - [SCOUTFS_SYMLINK_KEY] = print_symlink, - [SCOUTFS_LINK_BACKREF_KEY] = print_link_backref, - [SCOUTFS_FILE_EXTENT_KEY] = print_file_extent, - [SCOUTFS_FREE_EXTENT_BLKNO_KEY] = print_free_extent, - [SCOUTFS_FREE_EXTENT_BLOCKS_KEY] = print_free_extent, - [SCOUTFS_INODE_INDEX_CTIME_KEY] = print_inode_index, - [SCOUTFS_INODE_INDEX_MTIME_KEY] = print_inode_index, - [SCOUTFS_INODE_INDEX_SIZE_KEY] = print_inode_index, - [SCOUTFS_INODE_INDEX_META_SEQ_KEY] = print_inode_index, - [SCOUTFS_INODE_INDEX_DATA_SEQ_KEY] = print_inode_index, -}; +static print_func_t find_printer(u8 zone, u8 type) +{ + if (zone == SCOUTFS_INODE_INDEX_ZONE && + type >= SCOUTFS_INODE_INDEX_CTIME_TYPE && + type <= SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE) + return print_inode_index; + + if (zone == SCOUTFS_NODE_ZONE) { + if (type >= SCOUTFS_FREE_EXTENT_BLKNO_TYPE && + type <= SCOUTFS_FREE_EXTENT_BLOCKS_TYPE) + return print_free_extent; + if (type == SCOUTFS_ORPHAN_TYPE) + return print_orphan; + } + + if (zone == SCOUTFS_FS_ZONE) { + switch(type) { + case SCOUTFS_INODE_TYPE: return print_inode; + case SCOUTFS_XATTR_TYPE: return print_xattr; + case SCOUTFS_DIRENT_TYPE: return print_dirent; + case SCOUTFS_READDIR_TYPE: return print_readdir; + case SCOUTFS_SYMLINK_TYPE: return print_symlink; + case SCOUTFS_LINK_BACKREF_TYPE: return print_link_backref; + case SCOUTFS_FILE_EXTENT_TYPE: return print_file_extent; + } + } + + return NULL; +} + +static void find_zone_type(void *key, u8 *zone, u8 *type) +{ + struct scoutfs_inode_index_key *idx_key = key; + struct scoutfs_inode_key *ikey = key; + struct scoutfs_orphan_key *okey = key; + + *zone = *(u8 *)key; + + switch (*zone) { + case SCOUTFS_INODE_INDEX_ZONE: + *type = idx_key->type; + break; + case SCOUTFS_NODE_ZONE: + *type = okey->type; + break; + case SCOUTFS_FS_ZONE: + *type = ikey->type; + break; + default: + *type = 0; + } +} static void print_item(struct scoutfs_segment_block *sblk, struct scoutfs_segment_item *item, u32 which, u32 off) @@ -269,19 +304,20 @@ static void print_item(struct scoutfs_segment_block *sblk, print_func_t printer; void *key; void *val; - __u8 type; + u8 type; + u8 zone; int i; key = (char *)&item->skip_links[item->nr_links]; val = (char *)key + le16_to_cpu(item->key_len); - type = *(__u8 *)key; - printer = type < array_size(printers) ? printers[type] : NULL; + find_zone_type(key, &zone, &type); + printer = find_printer(zone, type); - printf(" [%u]: type %u off %u key_len %u val_len %u nr_links %u flags %x%s\n", - which, type, off, le16_to_cpu(item->key_len), + printf(" [%u]: off %u key_len %u val_len %u nr_links %u flags %x%s\n", + which, off, le16_to_cpu(item->key_len), le16_to_cpu(item->val_len), item->nr_links, - item->flags, printer ? "" : " (unrecognized type)"); + item->flags, printer ? "" : " (unrecognized zone+type)"); printf(" links:"); for (i = 0; i < item->nr_links; i++) printf(" %u", le32_to_cpu(item->skip_links[i]));