mirror of
https://github.com/versity/scoutfs.git
synced 2026-06-06 19:52:33 +00:00
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 <zab@versity.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user