mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-06 20:16:25 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user