scoutfs-utils: use scoutfs_key as btree key

Track the kernel changes to use the scoutfs_key struct as the btree key
instead of a big-endian binary blob.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-04-30 09:45:15 -07:00
committed by Zach Brown
parent ac2d465b66
commit aa84f7c601
4 changed files with 69 additions and 140 deletions

View File

@@ -133,6 +133,20 @@ struct scoutfs_key {
#define skpe_base _sk_second
#define skpe_part _sk_fourth
/* log trees */
#define sklt_rid _sk_first
#define sklt_nr _sk_second
/* lock clients */
#define sklc_rid _sk_first
/* seqs */
#define skts_trans_seq _sk_first
#define skts_rid _sk_second
/* mounted clients */
#define skmc_rid _sk_first
struct scoutfs_radix_block {
struct scoutfs_block_header hdr;
__le32 sm_first;
@@ -170,34 +184,17 @@ struct scoutfs_radix_root {
~(__u64)SCOUTFS_RADIX_LG_MASK)
#define SCOUTFS_RADIX_BITS_BYTES (SCOUTFS_RADIX_BITS / 8)
/*
* The btree still uses memcmp() to compare keys. We should fix that
* before too long.
*/
struct scoutfs_key_be {
__u8 sk_zone;
__be64 _sk_first;
__u8 sk_type;
__be64 _sk_second;
__be64 _sk_third;
__u8 _sk_fourth;
}__packed;
/* chose reasonable max key lens that have room for some u64s */
#define SCOUTFS_BTREE_MAX_KEY_LEN 40
/* when we split we want to have multiple items on each side */
#define SCOUTFS_BTREE_MAX_VAL_LEN (SCOUTFS_BLOCK_SIZE / 8)
/*
* The min number of free bytes we must leave in a parent as we descend
* to modify. This leaves enough free bytes to insert a possibly maximal
* sized key as a seperator for a child block. Fewer bytes then this
* and split/merge might try to insert a max child item in the parent
* that wouldn't fit.
* to modify. This guarantees enough free bytes in a parent to insert a
* new child reference item as a child block splits.
*/
#define SCOUTFS_BTREE_PARENT_MIN_FREE_BYTES \
(sizeof(struct scoutfs_btree_item_header) + \
sizeof(struct scoutfs_btree_item) + SCOUTFS_BTREE_MAX_KEY_LEN +\
sizeof(struct scoutfs_btree_item) + \
sizeof(struct scoutfs_btree_ref))
/*
@@ -233,9 +230,9 @@ struct scoutfs_btree_item_header {
} __packed;
struct scoutfs_btree_item {
__le16 key_len;
struct scoutfs_key key;
__le16 val_len;
__u8 data[0];
__u8 val[0];
} __packed;
struct scoutfs_btree_block {
@@ -246,30 +243,6 @@ struct scoutfs_btree_block {
struct scoutfs_btree_item_header item_hdrs[0];
} __packed;
/*
* The lock server keeps a persistent record of connected clients so that
* server failover knows who to wait for before resuming operations.
*/
struct scoutfs_lock_client_btree_key {
__be64 rid;
} __packed;
/*
* The server tracks transaction sequence numbers that clients have
* open. This limits results that can be returned from the seq indices.
*/
struct scoutfs_trans_seq_btree_key {
__be64 trans_seq;
__be64 rid;
} __packed;
/*
* The server keeps a persistent record of mounted clients.
*/
struct scoutfs_mounted_client_btree_key {
__be64 rid;
} __packed;
struct scoutfs_mounted_client_btree_val {
__u8 flags;
} __packed;
@@ -292,11 +265,6 @@ struct scoutfs_log_trees {
__le64 nr;
} __packed;
struct scoutfs_log_trees_key {
__be64 rid;
__be64 nr;
} __packed;
struct scoutfs_log_trees_val {
struct scoutfs_radix_root meta_avail;
struct scoutfs_radix_root meta_freed;
@@ -348,6 +316,11 @@ struct scoutfs_bloom_block {
#define SCOUTFS_RID_ZONE 3
#define SCOUTFS_FS_ZONE 4
#define SCOUTFS_LOCK_ZONE 5
/* Items only stored in server btrees */
#define SCOUTFS_LOG_TREES_ZONE 6
#define SCOUTFS_LOCK_CLIENTS_ZONE 7
#define SCOUTFS_TRANS_SEQ_ZONE 8
#define SCOUTFS_MOUNTED_CLIENT_ZONE 9
/* inode index zone */
#define SCOUTFS_INODE_INDEX_META_SEQ_TYPE 1

View File

@@ -141,26 +141,4 @@ static inline void scoutfs_key_dec(struct scoutfs_key *key)
key->sk_zone--;
}
static inline void scoutfs_key_to_be(struct scoutfs_key_be *be,
struct scoutfs_key *key)
{
be->sk_zone = key->sk_zone;
be->_sk_first = le64_to_be64(key->_sk_first);
be->sk_type = key->sk_type;
be->_sk_second = le64_to_be64(key->_sk_second);
be->_sk_third = le64_to_be64(key->_sk_third);
be->_sk_fourth = key->_sk_fourth;
}
static inline void scoutfs_key_from_be(struct scoutfs_key *key,
struct scoutfs_key_be *be)
{
key->sk_zone = be->sk_zone;
key->_sk_first = be64_to_le64(be->_sk_first);
key->sk_type = be->sk_type;
key->_sk_second = be64_to_le64(be->_sk_second);
key->_sk_third = be64_to_le64(be->_sk_third);
key->_sk_fourth = be->_sk_fourth;
}
#endif

View File

@@ -287,11 +287,10 @@ out:
static int write_new_fs(char *path, int fd, u8 quorum_count)
{
struct scoutfs_super_block *super;
struct scoutfs_key_be *kbe;
struct scoutfs_inode *inode;
struct scoutfs_btree_block *bt;
struct scoutfs_btree_item *btitem;
struct scoutfs_key key;
struct scoutfs_key *key;
struct timeval tv;
char uuid_str[37];
void *zeros;
@@ -374,32 +373,28 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
bt->nr_items = cpu_to_le32(2);
/* btree item allocated from the back of the block */
kbe = (void *)bt + SCOUTFS_BLOCK_SIZE - sizeof(*kbe);
btitem = (void *)kbe - sizeof(*btitem);
key = (void *)bt + SCOUTFS_BLOCK_SIZE - sizeof(*key);
btitem = (void *)key - sizeof(*btitem);
bt->item_hdrs[0].off = cpu_to_le32((long)btitem - (long)bt);
btitem->key_len = cpu_to_le16(sizeof(*kbe));
btitem->val_len = cpu_to_le16(0);
memset(&key, 0, sizeof(key));
key.sk_zone = SCOUTFS_INODE_INDEX_ZONE;
key.sk_type = SCOUTFS_INODE_INDEX_META_SEQ_TYPE;
key.skii_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
scoutfs_key_to_be(kbe, &key);
memset(key, 0, sizeof(*key));
key->sk_zone = SCOUTFS_INODE_INDEX_ZONE;
key->sk_type = SCOUTFS_INODE_INDEX_META_SEQ_TYPE;
key->skii_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
inode = (void *)btitem - sizeof(*inode);
kbe = (void *)inode - sizeof(*kbe);
btitem = (void *)kbe - sizeof(*btitem);
key = (void *)inode - sizeof(*key);
btitem = (void *)key - sizeof(*btitem);
bt->item_hdrs[1].off = cpu_to_le32((long)btitem - (long)bt);
btitem->key_len = cpu_to_le16(sizeof(*kbe));
btitem->val_len = cpu_to_le16(sizeof(*inode));
memset(&key, 0, sizeof(key));
key.sk_zone = SCOUTFS_FS_ZONE;
key.ski_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
key.sk_type = SCOUTFS_INODE_TYPE;
scoutfs_key_to_be(kbe, &key);
memset(key, 0, sizeof(*key));
key->sk_zone = SCOUTFS_FS_ZONE;
key->ski_ino = cpu_to_le64(SCOUTFS_ROOT_INO);
key->sk_type = SCOUTFS_INODE_TYPE;
inode->next_readdir_pos = cpu_to_le64(2);
inode->nlink = cpu_to_le32(SCOUTFS_DIRENT_FIRST_POS);

View File

@@ -258,40 +258,34 @@ static print_func_t find_printer(u8 zone, u8 type)
return NULL;
}
static int print_fs_item(void *key, unsigned key_len, void *val,
static int print_fs_item(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_key item_key;
print_func_t printer;
scoutfs_key_from_be(&item_key, key);
printf(" "SK_FMT"\n", SK_ARG(&item_key));
printf(" "SK_FMT"\n", SK_ARG(key));
/* only items in leaf blocks have values */
if (val) {
printer = find_printer(item_key.sk_zone, item_key.sk_type);
printer = find_printer(key->sk_zone, key->sk_type);
if (printer)
printer(&item_key, val, val_len);
printer(key, val, val_len);
else
printf(" (unknown zone %u type %u)\n",
item_key.sk_zone, item_key.sk_type);
key->sk_zone, key->sk_type);
}
return 0;
}
/* same as fs item but with a small header in the value */
static int print_logs_item(void *key, unsigned key_len, void *val,
static int print_logs_item(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_key item_key;
struct scoutfs_log_item_value *liv;
print_func_t printer;
scoutfs_key_from_be(&item_key, key);
printf(" "SK_FMT"\n", SK_ARG(&item_key));
printf(" "SK_FMT"\n", SK_ARG(key));
/* only items in leaf blocks have values */
if (val) {
@@ -301,14 +295,14 @@ static int print_logs_item(void *key, unsigned key_len, void *val,
/* deletion items don't have values */
if (!(liv->flags & SCOUTFS_LOG_ITEM_FLAG_DELETION)) {
printer = find_printer(item_key.sk_zone,
item_key.sk_type);
printer = find_printer(key->sk_zone,
key->sk_type);
if (printer)
printer(&item_key, val + sizeof(*liv),
printer(key, val + sizeof(*liv),
val_len - sizeof(*liv));
else
printf(" (unknown zone %u type %u)\n",
item_key.sk_zone, item_key.sk_type);
key->sk_zone, key->sk_type);
}
}
@@ -328,14 +322,13 @@ static int print_logs_item(void *key, unsigned key_len, void *val,
RADREF_A(&(root)->ref)
/* same as fs item but with a small header in the value */
static int print_log_trees_item(void *key, unsigned key_len, void *val,
static int print_log_trees_item(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_log_trees_key *ltk = key;
struct scoutfs_log_trees_val *ltv = val;
printf(" rid %llu nr %llu\n",
be64_to_cpu(ltk->rid), be64_to_cpu(ltk->nr));
le64_to_cpu(key->sklt_rid), le64_to_cpu(key->sklt_nr));
/* only items in leaf blocks have values */
if (val) {
@@ -359,48 +352,43 @@ static int print_log_trees_item(void *key, unsigned key_len, void *val,
return 0;
}
static int print_lock_clients_entry(void *key, unsigned key_len, void *val,
static int print_lock_clients_entry(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_lock_client_btree_key *cbk = key;
printf(" rid %016llx\n", be64_to_cpu(cbk->rid));
printf(" rid %016llx\n", le64_to_cpu(key->sklc_rid));
return 0;
}
static int print_trans_seqs_entry(void *key, unsigned key_len, void *val,
static int print_trans_seqs_entry(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_trans_seq_btree_key *tsk = key;
printf(" trans_seq %llu rid %016llx\n",
be64_to_cpu(tsk->trans_seq), be64_to_cpu(tsk->rid));
le64_to_cpu(key->skts_trans_seq), le64_to_cpu(key->skts_rid));
return 0;
}
static int print_mounted_client_entry(void *key, unsigned key_len, void *val,
static int print_mounted_client_entry(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_mounted_client_btree_key *mck = key;
struct scoutfs_mounted_client_btree_val *mcv = val;
printf(" rid %016llx flags 0x%x\n",
be64_to_cpu(mck->rid), mcv->flags);
le64_to_cpu(key->skmc_rid), mcv->flags);
return 0;
}
typedef int (*print_item_func)(void *key, unsigned key_len, void *val,
typedef int (*print_item_func)(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg);
static int print_btree_ref(void *key, unsigned key_len, void *val,
static int print_btree_ref(struct scoutfs_key *key, void *val,
unsigned val_len, print_item_func func, void *arg)
{
struct scoutfs_btree_ref *ref = val;
func(key, key_len, NULL, 0, arg);
func(key, NULL, 0, arg);
printf(" ref blkno %llu seq %llu\n",
le64_to_cpu(ref->blkno), le64_to_cpu(ref->seq));
@@ -413,9 +401,8 @@ static int print_btree_block(int fd, struct scoutfs_super_block *super,
{
struct scoutfs_btree_item *item;
struct scoutfs_btree_block *bt;
unsigned key_len;
struct scoutfs_key *key;
unsigned val_len;
void *key;
void *val;
int ret;
int i;
@@ -440,10 +427,9 @@ static int print_btree_block(int fd, struct scoutfs_super_block *super,
for (i = 0; i < le32_to_cpu(bt->nr_items); i++) {
item = (void *)bt + le32_to_cpu(bt->item_hdrs[i].off);
key_len = le16_to_cpu(item->key_len);
val_len = le16_to_cpu(item->val_len);
key = (void *)(item + 1);
val = (void *)key + key_len;
key = &item->key;
val = item->val;
if (level < bt->level) {
ref = val;
@@ -457,13 +443,13 @@ static int print_btree_block(int fd, struct scoutfs_super_block *super,
continue;
}
printf(" item [%u] off %u key_len %u val_len %u\n",
i, le32_to_cpu(bt->item_hdrs[i].off), key_len, val_len);
printf(" item [%u] off %u val_len %u\n",
i, le32_to_cpu(bt->item_hdrs[i].off), val_len);
if (level)
print_btree_ref(key, key_len, val, val_len, func, arg);
print_btree_ref(key, val, val_len, func, arg);
else
func(key, key_len, val, val_len, arg);
func(key, val, val_len, arg);
}
free(bt);
@@ -563,10 +549,9 @@ struct print_recursion_args {
};
/* same as fs item but with a small header in the value */
static int print_log_trees_roots(void *key, unsigned key_len, void *val,
static int print_log_trees_roots(struct scoutfs_key *key, void *val,
unsigned val_len, void *arg)
{
// struct scoutfs_log_trees_key *ltk = key;
struct scoutfs_log_trees_val *ltv = val;
struct print_recursion_args *pa = arg;
int ret = 0;
@@ -605,7 +590,6 @@ static int print_btree_leaf_items(int fd, struct scoutfs_super_block *super,
{
struct scoutfs_btree_item *item;
struct scoutfs_btree_block *bt;
unsigned key_len;
unsigned val_len;
void *key;
void *val;
@@ -621,10 +605,9 @@ static int print_btree_leaf_items(int fd, struct scoutfs_super_block *super,
for (i = 0; i < le32_to_cpu(bt->nr_items); i++) {
item = (void *)bt + le32_to_cpu(bt->item_hdrs[i].off);
key_len = le16_to_cpu(item->key_len);
val_len = le16_to_cpu(item->val_len);
key = (void *)(item + 1);
val = (void *)key + key_len;
val = (void *)(key + 1);
if (bt->level > 0) {
ret = print_btree_leaf_items(fd, super, val, func, arg);
@@ -632,7 +615,7 @@ static int print_btree_leaf_items(int fd, struct scoutfs_super_block *super,
break;
continue;
} else {
func(key, key_len, val, val_len, arg);
func(key, val, val_len, arg);
}
}