From c4f2563cc1f3b2bd44327b8aeed48eb2a12f47b3 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 23 Jan 2017 18:06:48 -0800 Subject: [PATCH] Update tools to new segment item layout The segment item struct used to have fiddly packed offsets and lengths. Now it's just normal fields so we can work with them directly and get rid of the native item indirection. Signed-off-by: Zach Brown --- utils/src/format.h | 18 +++++++-------- utils/src/item.c | 57 ---------------------------------------------- utils/src/item.h | 22 ------------------ utils/src/mkfs.c | 15 ++++++------ utils/src/print.c | 36 +++++++++++++++++++++-------- 5 files changed, 43 insertions(+), 105 deletions(-) delete mode 100644 utils/src/item.c delete mode 100644 utils/src/item.h diff --git a/utils/src/format.h b/utils/src/format.h index 6495d457..a2931169 100644 --- a/utils/src/format.h +++ b/utils/src/format.h @@ -96,6 +96,8 @@ struct scoutfs_treap_root { */ #define SCOUTFS_MANIFEST_MAX_LEVEL 20 +#define SCOUTFS_MANIFEST_FANOUT 10 + struct scoutfs_manifest { struct scoutfs_treap_root root; __le64 level_counts[SCOUTFS_MANIFEST_MAX_LEVEL]; @@ -128,20 +130,18 @@ struct scoutfs_alloc_region { * aligned. This ensures that they won't cross page boundaries and we * can use pointers to them in the page vecs that make up segments without * funny business. - * - * We limit segment sizes to 8 megs (23 bits) and value lengths to 512 bytes - * (9 bits). The item offsets and lengths then take up 64 bits. - * - * We then operate on the items in on-stack nice native structs. */ struct scoutfs_segment_item { __le64 seq; - __le32 key_off_len; - __le32 val_off_len; + __le32 key_off; + __le32 val_off; + __le16 key_len; + __le16 val_len; + __u8 padding[11]; + __u8 flags; } __packed; -#define SCOUTFS_SEGMENT_ITEM_OFF_SHIFT 9 -#define SCOUTFS_SEGMENT_ITEM_LEN_MASK ((1 << SCOUTFS_SEGMENT_ITEM_OFF_SHIFT)-1) +#define SCOUTFS_ITEM_FLAG_DELETION (1 << 0) /* * Each large segment starts with a segment block that describes the diff --git a/utils/src/item.c b/utils/src/item.c deleted file mode 100644 index b6db8b15..00000000 --- a/utils/src/item.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -#include "sparse.h" -#include "util.h" -#include "format.h" -#include "item.h" - -/* utils uses bit contiguous allocations */ -static void *off_ptr(struct scoutfs_segment_block *sblk, u32 off) -{ - return (char *)sblk + off; -} - -static u32 pos_off(struct scoutfs_segment_block *sblk, u32 pos) -{ - return offsetof(struct scoutfs_segment_block, items[pos]); -} - -static void *pos_ptr(struct scoutfs_segment_block *sblk, u32 pos) -{ - return off_ptr(sblk, pos_off(sblk, pos)); -} - -void load_item(struct scoutfs_segment_block *sblk, u32 pos, - struct native_item *item) -{ - struct scoutfs_segment_item *sitem = pos_ptr(sblk, pos); - u32 packed; - - item->seq = le64_to_cpu(sitem->seq); - - packed = le32_to_cpu(sitem->key_off_len); - item->key_off = packed >> SCOUTFS_SEGMENT_ITEM_OFF_SHIFT; - item->key_len = packed & SCOUTFS_SEGMENT_ITEM_LEN_MASK; - - packed = le32_to_cpu(sitem->val_off_len); - item->val_off = packed >> SCOUTFS_SEGMENT_ITEM_OFF_SHIFT; - item->val_len = packed & SCOUTFS_SEGMENT_ITEM_LEN_MASK; -} - -void store_item(struct scoutfs_segment_block *sblk, u32 pos, - struct native_item *item) -{ - struct scoutfs_segment_item *sitem = pos_ptr(sblk, pos); - u32 packed; - - sitem->seq = cpu_to_le64(item->seq); - - packed = (item->key_off << SCOUTFS_SEGMENT_ITEM_OFF_SHIFT) | - (item->key_len & SCOUTFS_SEGMENT_ITEM_LEN_MASK); - sitem->key_off_len = cpu_to_le32(packed); - - packed = (item->val_off << SCOUTFS_SEGMENT_ITEM_OFF_SHIFT) | - (item->val_len & SCOUTFS_SEGMENT_ITEM_LEN_MASK); - sitem->val_off_len = cpu_to_le32(packed); -} diff --git a/utils/src/item.h b/utils/src/item.h deleted file mode 100644 index 7c307eee..00000000 --- a/utils/src/item.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ITEM_H_ -#define _ITEM_H_ - -/* - * The persistent item fields that are stored in the segment are packed - * with funny precision. We translate those to and from a much more - * natural native representation of the fields. - */ -struct native_item { - u64 seq; - u32 key_off; - u32 val_off; - u16 key_len; - u16 val_len; -}; - -void load_item(struct scoutfs_segment_block *sblk, u32 pos, - struct native_item *item); -void store_item(struct scoutfs_segment_block *sblk, u32 pos, - struct native_item *item); - -#endif diff --git a/utils/src/mkfs.c b/utils/src/mkfs.c index e3dd1675..db310b14 100644 --- a/utils/src/mkfs.c +++ b/utils/src/mkfs.c @@ -18,7 +18,6 @@ #include "rand.h" #include "dev.h" #include "buddy.h" -#include "item.h" static int write_raw_block(int fd, u64 blkno, void *blk) { @@ -95,7 +94,7 @@ static int write_new_fs(char *path, int fd) struct scoutfs_segment_block *sblk; struct scoutfs_manifest_entry *ment; struct scoutfs_treap_node *node; - struct native_item item; + struct scoutfs_segment_item *item; struct timeval tv; char uuid_str[37]; void *ring; @@ -169,15 +168,15 @@ static int write_new_fs(char *path, int fd) root_ikey.type = SCOUTFS_INODE_KEY; root_ikey.ino = cpu_to_be64(SCOUTFS_ROOT_INO); + item = &sblk->items[0]; ikey = (void *)&sblk->items[1]; inode = (void *)(ikey + 1); - item.seq = 1; - item.key_off = (long)ikey - (long)sblk; - item.val_off = (long)inode - (long)sblk; - item.key_len = sizeof(struct scoutfs_inode_key); - item.val_len = sizeof(struct scoutfs_inode); - store_item(sblk, 0, &item); + item->seq = cpu_to_le64(1); + item->key_off = cpu_to_le32((long)ikey - (long)sblk); + item->val_off = cpu_to_le32((long)inode - (long)sblk); + item->key_len = cpu_to_le16(sizeof(struct scoutfs_inode_key)); + item->val_len = cpu_to_le16(sizeof(struct scoutfs_inode)); *ikey = root_ikey; diff --git a/utils/src/print.c b/utils/src/print.c index f92c8af3..412cf3a7 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -16,7 +16,6 @@ #include "cmd.h" #include "crc.h" #include "buddy.h" -#include "item.h" /* XXX maybe these go somewhere */ #define SKF "%llu.%u.%llu" @@ -198,29 +197,48 @@ static print_func_t printers[] = { [SCOUTFS_READDIR_KEY] = print_readdir, }; +/* utils uses big contiguous allocations */ +static void *off_ptr(struct scoutfs_segment_block *sblk, u32 off) +{ + return (char *)sblk + off; +} + +static u32 pos_off(struct scoutfs_segment_block *sblk, u32 pos) +{ + return offsetof(struct scoutfs_segment_block, items[pos]); +} + +static void *pos_ptr(struct scoutfs_segment_block *sblk, u32 pos) +{ + return off_ptr(sblk, pos_off(sblk, pos)); +} + static void print_item(struct scoutfs_segment_block *sblk, u32 pos) { print_func_t printer; - struct native_item item; + struct scoutfs_segment_item *item; void *key; void *val; __u8 type; - load_item(sblk, pos, &item); + item = pos_ptr(sblk, pos); - key = (char *)sblk + item.key_off; - val = (char *)sblk + item.val_off; + key = (char *)sblk + le32_to_cpu(item->key_off); + val = (char *)sblk + le32_to_cpu(item->val_off); type = *(__u8 *)key; printer = type < array_size(printers) ? printers[type] : NULL; printf(" [%u]: type %u seq %llu key_off %u val_off %u key_len %u " - "val_len %u%s\n", - pos, type, item.seq, item.key_off, item.val_off, item.key_len, - item.val_len, printer ? "" : " (unrecognized type)"); + "val_len %u flags %x%s\n", + pos, type, le64_to_cpu(item->seq), le32_to_cpu(item->key_off), + le32_to_cpu(item->val_off), le16_to_cpu(item->key_len), + le16_to_cpu(item->val_len), item->flags, + printer ? "" : " (unrecognized type)"); if (printer) - printer(key, item.key_len, val, item.val_len); + printer(key, le16_to_cpu(item->key_len), + val, le16_to_cpu(item->val_len)); } static void print_segment_block(struct scoutfs_segment_block *sblk)