scoutfs-utils: add packed extents and bitmaps

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2019-12-10 08:54:24 -08:00
committed by Zach Brown
parent c87a9f3a07
commit e0a49c46a7
4 changed files with 168 additions and 178 deletions

View File

@@ -105,11 +105,6 @@ struct scoutfs_key {
#define skxi_ino _sk_second
#define skxi_id _sk_third
/* node free extent */
#define sknf_rid _sk_first
#define sknf_major _sk_second
#define sknf_minor _sk_third
/* node orphan inode */
#define sko_rid _sk_first
#define sko_ino _sk_second
@@ -132,9 +127,10 @@ struct scoutfs_key {
#define sks_ino _sk_first
#define sks_nr _sk_second
/* file extent */
#define skfe_ino _sk_first
#define skfe_last _sk_second
/* packed extents */
#define skpe_ino _sk_first
#define skpe_base _sk_second
#define skpe_part _sk_fourth
/*
* The btree still uses memcmp() to compare keys. We should fix that
@@ -149,9 +145,10 @@ struct scoutfs_key_be {
__u8 _sk_fourth;
}__packed;
/* chose reasonable max key and value lens that have room for some u64s */
/* chose reasonable max key lens that have room for some u64s */
#define SCOUTFS_BTREE_MAX_KEY_LEN 40
#define SCOUTFS_BTREE_MAX_VAL_LEN 256
/* 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
@@ -234,18 +231,32 @@ struct scoutfs_balloc_item_val {
} __packed;
/*
* Free extents are stored in the server in an allocation btree. The
* type differentiates whether start or length is in stored in the major
* value and is the primary sort key. 'start' is set to the final block
* in the extent so that overlaping queries can be done with next
* instead prev.
* Free data blocks are tracked in bitmaps stored in btree items.
*/
struct scoutfs_extent_btree_key {
struct scoutfs_block_bitmap_key {
__u8 type;
__be64 major;
__be64 minor;
__be64 base;
} __packed;
#define SCOUTFS_BLOCK_BITMAP_BIG 0
#define SCOUTFS_BLOCK_BITMAP_LITTLE 1
#define SCOUTFS_PACKED_BITMAP_WORDS 32
#define SCOUTFS_PACKED_BITMAP_BITS (SCOUTFS_PACKED_BITMAP_WORDS * 64)
#define SCOUTFS_PACKED_BITMAP_MAX_BYTES \
offsetof(struct scoutfs_packed_bitmap, \
words[SCOUTFS_PACKED_BITMAP_WORDS])
#define SCOUTFS_BLOCK_BITMAP_BITS SCOUTFS_PACKED_BITMAP_BITS
#define SCOUTFS_BLOCK_BITMAP_BIT_MASK (SCOUTFS_PACKED_BITMAP_BITS - 1)
#define SCOUTFS_BLOCK_BITMAP_BASE_SHIFT (ilog2(SCOUTFS_PACKED_BITMAP_BITS))
struct scoutfs_packed_bitmap {
__le64 present;
__le64 set;
__le64 words[0];
};
/*
* The lock server keeps a persistent record of connected clients so that
* server failover knows who to wait for before resuming operations.
@@ -276,11 +287,18 @@ struct scoutfs_mounted_client_btree_val {
#define SCOUTFS_MOUNTED_CLIENT_VOTER (1 << 0)
/*
* XXX I imagine we should rename these now that they've evolved to track
* all the btrees that clients use during a transaction. It's not just
* about item logs, it's about clients making changes to trees.
*/
struct scoutfs_log_trees {
struct scoutfs_balloc_root alloc_root;
struct scoutfs_balloc_root free_root;
struct scoutfs_btree_root item_root;
struct scoutfs_btree_ref bloom_ref;
struct scoutfs_balloc_root data_alloc;
struct scoutfs_balloc_root data_free;
__le64 rid;
__le64 nr;
} __packed;
@@ -295,6 +313,8 @@ struct scoutfs_log_trees_val {
struct scoutfs_balloc_root free_root;
struct scoutfs_btree_root item_root;
struct scoutfs_btree_ref bloom_ref;
struct scoutfs_balloc_root data_alloc;
struct scoutfs_balloc_root data_free;
} __packed;
struct scoutfs_log_item_value {
@@ -350,9 +370,7 @@ struct scoutfs_bloom_block {
#define SCOUTFS_XATTR_INDEX_NAME_TYPE 1
/* rid zone (also used in server alloc btree) */
#define SCOUTFS_FREE_EXTENT_BLKNO_TYPE 1
#define SCOUTFS_FREE_EXTENT_BLOCKS_TYPE 2
#define SCOUTFS_ORPHAN_TYPE 3
#define SCOUTFS_ORPHAN_TYPE 1
/* fs zone */
#define SCOUTFS_INODE_TYPE 1
@@ -361,23 +379,45 @@ struct scoutfs_bloom_block {
#define SCOUTFS_READDIR_TYPE 4
#define SCOUTFS_LINK_BACKREF_TYPE 5
#define SCOUTFS_SYMLINK_TYPE 6
#define SCOUTFS_FILE_EXTENT_TYPE 7
#define SCOUTFS_PACKED_EXTENT_TYPE 7
/* lock zone, only ever found in lock ranges, never in persistent items */
#define SCOUTFS_RENAME_TYPE 1
#define SCOUTFS_MAX_TYPE 8 /* power of 2 is efficient */
/*
* File extents have more data than easily fits in the key so we move
* the non-indexed fields into the value.
* The extents that map blocks in a fixed-size logical region of a file
* are packed and stored in item values. The packed extents are
* contiguous so the starting logical block is implicit from the length
* of previous extents. Sparse regions are represented by 0 flags and
* blkno. The blkno of a packed extent is encoded as the zigzag (lsb is
* sign bit) difference from the last blkno of the previous extent.
* This guarantees that non-sparse extents must have a blkno delta of at
* least -1/1. High zero byte aren't stored.
*/
struct scoutfs_file_extent {
__le64 blkno;
__le64 len;
__u8 flags;
struct scoutfs_packed_extent {
__le16 count;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 diff_bytes:4,
flags:3,
final:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 final:1,
flags:3,
diff_bytes:4;
#else
#error "no {BIG,LITTLE}_ENDIAN_BITFIELD defined?"
#endif
__u8 le_blkno_diff[0];
} __packed;
#define SCOUTFS_PACKEXT_BLOCKS (8 * 1024 * 1024 / SCOUTFS_BLOCK_SIZE)
#define SCOUTFS_PACKEXT_BASE_SHIFT (ilog2(SCOUTFS_PACKEXT_BLOCKS))
#define SCOUTFS_PACKEXT_BASE_MASK (~((__u64)SCOUTFS_PACKEXT_BLOCKS - 1))
#define SCOUTFS_PACKEXT_MAX_BYTES SCOUTFS_MAX_VAL_SIZE
#define SEF_OFFLINE (1 << 0)
#define SEF_UNWRITTEN (1 << 1)
#define SEF_UNKNOWN (U8_MAX << 2)
@@ -450,8 +490,12 @@ struct scoutfs_super_block {
__le64 next_ino;
__le64 next_trans_seq;
__le64 total_blocks;
__le64 next_uninit_free_block;
__le64 next_uninit_meta_blkno;
__le64 last_uninit_meta_blkno;
__le64 next_uninit_data_blkno;
__le64 last_uninit_data_blkno;
__le64 core_balloc_cursor;
__le64 core_data_alloc_cursor;
__le64 free_blocks;
__le64 first_fs_blkno;
__le64 last_fs_blkno;
@@ -462,7 +506,8 @@ struct scoutfs_super_block {
struct scoutfs_inet_addr server_addr;
struct scoutfs_balloc_root core_balloc_alloc;
struct scoutfs_balloc_root core_balloc_free;
struct scoutfs_btree_root alloc_root;
struct scoutfs_balloc_root core_data_alloc;
struct scoutfs_balloc_root core_data_free;
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
struct scoutfs_btree_root lock_clients;
@@ -652,8 +697,6 @@ struct scoutfs_net_header {
enum {
SCOUTFS_NET_CMD_GREETING = 0,
SCOUTFS_NET_CMD_ALLOC_INODES,
SCOUTFS_NET_CMD_ALLOC_EXTENT,
SCOUTFS_NET_CMD_FREE_EXTENTS,
SCOUTFS_NET_CMD_GET_LOG_TREES,
SCOUTFS_NET_CMD_COMMIT_LOG_TREES,
SCOUTFS_NET_CMD_ADVANCE_SEQ,
@@ -704,25 +747,6 @@ struct scoutfs_net_statfs {
__u8 uuid[SCOUTFS_UUID_BYTES]; /* logical volume uuid */
} __packed;
struct scoutfs_net_extent {
__le64 start;
__le64 len;
} __packed;
struct scoutfs_net_extent_list {
__le64 nr;
struct {
__le64 start;
__le64 len;
} __packed extents[0];
} __packed;
#define SCOUTFS_NET_EXTENT_LIST_BYTES(nr) \
offsetof(struct scoutfs_net_extent_list, extents[nr])
/* arbitrarily makes a nice ~1k extent list payload */
#define SCOUTFS_NET_EXTENT_LIST_MAX_NR 64
struct scoutfs_net_lock {
struct scoutfs_key key;
__le64 write_version;

View File

@@ -30,8 +30,6 @@ char *scoutfs_type_strings[SCOUTFS_MAX_ZONE][SCOUTFS_MAX_TYPE] = {
[SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = "msq",
[SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = "dsq",
[SCOUTFS_XATTR_INDEX_ZONE][SCOUTFS_XATTR_INDEX_NAME_TYPE] = "nam",
[SCOUTFS_RID_ZONE][SCOUTFS_FREE_EXTENT_BLKNO_TYPE] = "fbn",
[SCOUTFS_RID_ZONE][SCOUTFS_FREE_EXTENT_BLOCKS_TYPE] = "fbs",
[SCOUTFS_RID_ZONE][SCOUTFS_ORPHAN_TYPE] = "orp",
[SCOUTFS_FS_ZONE][SCOUTFS_INODE_TYPE] = "ino",
[SCOUTFS_FS_ZONE][SCOUTFS_XATTR_TYPE] = "xat",
@@ -39,7 +37,7 @@ char *scoutfs_type_strings[SCOUTFS_MAX_ZONE][SCOUTFS_MAX_TYPE] = {
[SCOUTFS_FS_ZONE][SCOUTFS_READDIR_TYPE] = "rdr",
[SCOUTFS_FS_ZONE][SCOUTFS_LINK_BACKREF_TYPE] = "lbr",
[SCOUTFS_FS_ZONE][SCOUTFS_SYMLINK_TYPE] = "sym",
[SCOUTFS_FS_ZONE][SCOUTFS_FILE_EXTENT_TYPE] = "fex",
[SCOUTFS_FS_ZONE][SCOUTFS_PACKED_EXTENT_TYPE] = "pex",
};
char scoutfs_unknown_u8_strings[U8_MAX][U8_STR_MAX];

View File

@@ -95,7 +95,6 @@ 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_extent_btree_key *ebk;
struct scoutfs_btree_block *bt;
struct scoutfs_btree_item *btitem;
struct scoutfs_balloc_item_key *bik;
@@ -108,9 +107,10 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
u64 limit;
u64 size;
u64 total_blocks;
u64 free_blkno;
u64 free_start;
u64 free_len;
u64 next_meta;
u64 last_meta;
u64 next_data;
u64 last_data;
int ret;
int i;
@@ -156,63 +156,16 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
super->quorum_count = quorum_count;
/* metadata blocks start after the quorum blocks */
free_blkno = SCOUTFS_QUORUM_BLKNO + SCOUTFS_QUORUM_BLOCKS;
next_meta = SCOUTFS_QUORUM_BLKNO + SCOUTFS_QUORUM_BLOCKS;
/* extents start after btree blocks */
free_start = total_blocks - (total_blocks / 4);
free_len = total_blocks - free_start;
/* fill out some alloc boundaries before using */
super->free_blocks = cpu_to_le64(free_len);
/* extent allocator btree indexes free data extent */
blkno = free_blkno++;
super->alloc_root.ref.blkno = cpu_to_le64(blkno);
super->alloc_root.ref.seq = cpu_to_le64(1);
super->alloc_root.height = 1;
memset(bt, 0, SCOUTFS_BLOCK_SIZE);
bt->hdr.fsid = super->hdr.fsid;
bt->hdr.blkno = cpu_to_le64(blkno);
bt->hdr.seq = cpu_to_le64(1);
bt->nr_items = cpu_to_le32(2);
/* btree item allocated from the back of the block */
ebk = (void *)bt + SCOUTFS_BLOCK_SIZE - sizeof(*ebk);
btitem = (void *)ebk - sizeof(*btitem);
bt->item_hdrs[0].off = cpu_to_le32((long)btitem - (long)bt);
btitem->key_len = cpu_to_le16(sizeof(*ebk));
btitem->val_len = cpu_to_le16(0);
ebk->type = SCOUTFS_FREE_EXTENT_BLKNO_TYPE;
ebk->major = cpu_to_be64(free_start + free_len - 1);
ebk->minor = cpu_to_be64(free_len);
ebk = (void *)btitem - sizeof(*ebk);
btitem = (void *)ebk - sizeof(*btitem);
bt->item_hdrs[1].off = cpu_to_le32((long)btitem - (long)bt);
btitem->key_len = cpu_to_le16(sizeof(*ebk));
btitem->val_len = cpu_to_le16(0);
ebk->type = SCOUTFS_FREE_EXTENT_BLOCKS_TYPE;
ebk->major = cpu_to_be64(free_len);
ebk->minor = cpu_to_be64(free_start + free_len - 1);
bt->free_end = bt->item_hdrs[le32_to_cpu(bt->nr_items) - 1].off;
bt->hdr.magic = cpu_to_le32(SCOUTFS_BLOCK_MAGIC_BTREE);
bt->hdr.crc = cpu_to_le32(crc_block(&bt->hdr));
ret = write_raw_block(fd, blkno, bt);
if (ret)
goto out;
blkno++;
/* data blocks are after metadata, we'll say 1:4 for now */
next_data = round_up(next_meta + ((total_blocks - next_meta) / 5),
SCOUTFS_BLOCK_BITMAP_BITS);
last_meta = next_data - 1;
last_data = total_blocks - 1;
/* fs root starts with root inode and its index items */
blkno = free_blkno++;
blkno = next_meta++;
super->fs_root.ref.blkno = cpu_to_le64(blkno);
super->fs_root.ref.seq = cpu_to_le64(1);
@@ -272,7 +225,7 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
goto out;
/* metadata block allocator has single item, server continues init */
blkno = free_blkno++;
blkno = next_meta++;
super->core_balloc_alloc.root.ref.blkno = cpu_to_le64(blkno);
super->core_balloc_alloc.root.ref.seq = cpu_to_le64(1);
@@ -299,9 +252,10 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
/* set all the bits past our final used blkno */
super->core_balloc_free.total_free =
cpu_to_le64(SCOUTFS_BALLOC_ITEM_BITS - free_blkno);
for (i = free_blkno; i < SCOUTFS_BALLOC_ITEM_BITS; i++)
cpu_to_le64(SCOUTFS_BALLOC_ITEM_BITS - next_meta);
for (i = next_meta; i < SCOUTFS_BALLOC_ITEM_BITS; i++)
set_bit_le(i, &biv->bits);
next_meta = i;
bt->free_end = bt->item_hdrs[le32_to_cpu(bt->nr_items) - 1].off;
@@ -322,7 +276,12 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
}
}
super->next_uninit_free_block = cpu_to_le64(SCOUTFS_BALLOC_ITEM_BITS);
/* fill out allocator fields now that we've written our blocks */
super->next_uninit_meta_blkno = cpu_to_le64(next_meta);
super->last_uninit_meta_blkno = cpu_to_le64(last_meta);
super->next_uninit_data_blkno = cpu_to_le64(next_data);
super->last_uninit_data_blkno = cpu_to_le64(last_data);
super->free_blocks = cpu_to_le64(total_blocks - next_meta);
/* write the super block */
super->hdr.seq = cpu_to_le64(1);
@@ -346,17 +305,16 @@ static int write_new_fs(char *path, int fd, u8 quorum_count)
" uuid: %s\n"
" device blocks: "SIZE_FMT"\n"
" metadata blocks: "SIZE_FMT"\n"
" file extent blocks: "SIZE_FMT"\n"
" data blocks: "SIZE_FMT"\n"
" quorum count: %u\n",
path,
le64_to_cpu(super->hdr.fsid),
le64_to_cpu(super->format_hash),
uuid_str,
SIZE_ARGS(total_blocks, SCOUTFS_BLOCK_SIZE),
SIZE_ARGS(le64_to_cpu(super->total_blocks) -
le64_to_cpu(super->free_blocks),
SIZE_ARGS(last_meta - next_meta + 1,
SCOUTFS_BLOCK_SIZE),
SIZE_ARGS(le64_to_cpu(super->free_blocks),
SIZE_ARGS(last_data - next_data + 1,
SCOUTFS_BLOCK_SIZE),
super->quorum_count);

View File

@@ -144,30 +144,14 @@ static void print_symlink(struct scoutfs_key *key, void *val, int val_len)
le64_to_cpu(key->sks_ino), le64_to_cpu(key->sks_nr), name);
}
static void print_file_extent(struct scoutfs_key *key, void *val, int val_len)
static void print_packed_extent(struct scoutfs_key *key, void *val, int val_len)
{
struct scoutfs_file_extent *fex = val;
u64 iblock = le64_to_cpu(key->skfe_last) - le64_to_cpu(fex->len) + 1;
struct scoutfs_packed_extent *pe = val;
printf(" extent: ino %llu (last %llu) iblock %llu len %llu "
"blkno %llu flags 0x%x\n",
le64_to_cpu(key->skfe_ino), le64_to_cpu(key->skfe_last),
iblock, le64_to_cpu(fex->len), le64_to_cpu(fex->blkno),
fex->flags);
}
static void print_free_extent(struct scoutfs_key *key, void *val, int val_len)
{
u64 start = le64_to_cpu(key->sknf_major);
u64 len = le64_to_cpu(key->sknf_minor);
if (key->sk_type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE)
swap(start, len);
start -= (len - 1);
printf(" free extent: major %llu minor %llu (start %llu "
"len %llu)\n",
le64_to_cpu(key->sknf_major), le64_to_cpu(key->sknf_minor),
start, len);
printf(" packed_extent: ino %llu base %llu part %u count %u diff_bytes %u flags 0x%x final %u\n",
le64_to_cpu(key->skpe_ino), le64_to_cpu(key->skpe_base),
key->skpe_part, le16_to_cpu(pe->count), pe->diff_bytes,
pe->flags, pe->final);
}
static void print_inode_index(struct scoutfs_key *key, void *val, int val_len)
@@ -197,9 +181,6 @@ static print_func_t find_printer(u8 zone, u8 type)
return print_xattr_index;
if (zone == SCOUTFS_RID_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;
}
@@ -212,7 +193,8 @@ static print_func_t find_printer(u8 zone, u8 type)
case SCOUTFS_READDIR_TYPE: return print_dirent;
case SCOUTFS_SYMLINK_TYPE: return print_symlink;
case SCOUTFS_LINK_BACKREF_TYPE: return print_dirent;
case SCOUTFS_FILE_EXTENT_TYPE: return print_file_extent;
case SCOUTFS_PACKED_EXTENT_TYPE:
return print_packed_extent;
}
}
@@ -291,7 +273,9 @@ static int print_log_trees_item(void *key, unsigned key_len, void *val,
printf(" alloc_root: total_free %llu root: height %u blkno %llu seq %llu\n"
" free_root: total_free %llu root: height %u blkno %llu seq %llu\n"
" item_root: height %u blkno %llu seq %llu\n"
" bloom_ref: blkno %llu seq %llu\n",
" bloom_ref: blkno %llu seq %llu\n"
" data_alloc: total_free %llu root: height %u blkno %llu seq %llu\n"
" data_free: total_free %llu root: height %u blkno %llu seq %llu\n",
le64_to_cpu(ltv->alloc_root.total_free),
ltv->alloc_root.root.height,
le64_to_cpu(ltv->alloc_root.root.ref.blkno),
@@ -304,34 +288,20 @@ static int print_log_trees_item(void *key, unsigned key_len, void *val,
le64_to_cpu(ltv->item_root.ref.blkno),
le64_to_cpu(ltv->item_root.ref.seq),
le64_to_cpu(ltv->bloom_ref.blkno),
le64_to_cpu(ltv->bloom_ref.seq));
le64_to_cpu(ltv->bloom_ref.seq),
le64_to_cpu(ltv->data_alloc.total_free),
ltv->data_alloc.root.height,
le64_to_cpu(ltv->data_alloc.root.ref.blkno),
le64_to_cpu(ltv->data_alloc.root.ref.seq),
le64_to_cpu(ltv->data_free.total_free),
ltv->data_free.root.height,
le64_to_cpu(ltv->data_free.root.ref.blkno),
le64_to_cpu(ltv->data_free.root.ref.seq));
}
return 0;
}
static int print_alloc_item(void *key, unsigned key_len, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_extent_btree_key *ebk = key;
u64 start;
u64 len;
/* XXX check sizes */
len = be64_to_cpu(ebk->minor);
start = be64_to_cpu(ebk->major);
if (ebk->type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE)
swap(start, len);
start -= len - 1;
printf(" type %u major %llu minor %llu (start %llu len %llu)\n",
ebk->type, be64_to_cpu(ebk->major),
be64_to_cpu(ebk->minor), start, len);
return 0;
}
static int print_lock_clients_entry(void *key, unsigned key_len, void *val,
unsigned val_len, void *arg)
{
@@ -365,6 +335,19 @@ static int print_balloc_entry(void *key, unsigned key_len, void *val,
return 0;
}
static int print_bitmap_entry(void *key, unsigned key_len, void *val,
unsigned val_len, void *arg)
{
struct scoutfs_block_bitmap_key *bbk = key;
struct scoutfs_packed_bitmap *pb = val;
printf(" type %u base %llu present 0x%016llx set 0x%016llx\n",
bbk->type, be64_to_cpu(bbk->base),
le64_to_cpu(pb->present), le64_to_cpu(pb->set));
return 0;
}
static int print_mounted_client_entry(void *key, unsigned key_len, void *val,
unsigned val_len, void *arg)
{
@@ -502,6 +485,14 @@ static int print_log_trees_roots(void *key, unsigned key_len, void *val,
&ltv->free_root.root,
print_balloc_entry,
},
{ "log_tree_rid:%llu_nr:%llu_data_alloc",
&ltv->data_alloc.root,
print_bitmap_entry,
},
{ "log_tree_rid:%llu_nr:%llu_data_free",
&ltv->data_free.root,
print_bitmap_entry,
},
{ "log_tree_rid:%llu_nr:%llu_item",
&ltv->item_root,
print_logs_item,
@@ -667,22 +658,29 @@ static void print_super_block(struct scoutfs_super_block *super, u64 blkno)
/* XXX these are all in a crazy order */
printf(" next_ino %llu next_trans_seq %llu\n"
" total_blocks %llu free_blocks %llu\n"
" next_uninit_free_block %llu core_balloc_blocks %llu\n"
" next_uninit_meta_blkno %llu last_uninit_meta_blkno %llu\n"
" next_uninit_data_blkno %llu last_uninit_data_blkno %llu\n"
" core_balloc_cursor %llu core_data_alloc_cursor %llu\n"
" quorum_fenced_term %llu quorum_server_term %llu unmount_barrier %llu\n"
" quorum_count %u server_addr %s\n"
" core_balloc_alloc: total_free %llu root: height %u blkno %llu seq %llu\n"
" core_balloc_free: total_free %llu root: height %u blkno %llu seq %llu\n"
" core_data_alloc: total_free %llu root: height %u blkno %llu seq %llu\n"
" core_data_free: total_free %llu root: height %u blkno %llu seq %llu\n"
" lock_clients root: height %u blkno %llu seq %llu\n"
" mounted_clients root: height %u blkno %llu seq %llu\n"
" trans_seqs root: height %u blkno %llu seq %llu\n"
" alloc btree root: height %u blkno %llu seq %llu\n"
" fs_root btree root: height %u blkno %llu seq %llu\n",
le64_to_cpu(super->next_ino),
le64_to_cpu(super->next_trans_seq),
le64_to_cpu(super->total_blocks),
le64_to_cpu(super->free_blocks),
le64_to_cpu(super->next_uninit_free_block),
le64_to_cpu(super->next_uninit_meta_blkno),
le64_to_cpu(super->last_uninit_meta_blkno),
le64_to_cpu(super->next_uninit_data_blkno),
le64_to_cpu(super->last_uninit_data_blkno),
le64_to_cpu(super->core_balloc_cursor),
le64_to_cpu(super->core_data_alloc_cursor),
le64_to_cpu(super->quorum_fenced_term),
le64_to_cpu(super->quorum_server_term),
le64_to_cpu(super->unmount_barrier),
@@ -696,6 +694,14 @@ static void print_super_block(struct scoutfs_super_block *super, u64 blkno)
super->core_balloc_free.root.height,
le64_to_cpu(super->core_balloc_free.root.ref.blkno),
le64_to_cpu(super->core_balloc_free.root.ref.seq),
le64_to_cpu(super->core_data_alloc.total_free),
super->core_data_alloc.root.height,
le64_to_cpu(super->core_data_alloc.root.ref.blkno),
le64_to_cpu(super->core_data_alloc.root.ref.seq),
le64_to_cpu(super->core_data_free.total_free),
super->core_data_free.root.height,
le64_to_cpu(super->core_data_free.root.ref.blkno),
le64_to_cpu(super->core_data_free.root.ref.seq),
super->lock_clients.height,
le64_to_cpu(super->lock_clients.ref.blkno),
le64_to_cpu(super->lock_clients.ref.seq),
@@ -705,9 +711,6 @@ static void print_super_block(struct scoutfs_super_block *super, u64 blkno)
super->trans_seqs.height,
le64_to_cpu(super->trans_seqs.ref.blkno),
le64_to_cpu(super->trans_seqs.ref.seq),
super->alloc_root.height,
le64_to_cpu(super->alloc_root.ref.blkno),
le64_to_cpu(super->alloc_root.ref.seq),
super->fs_root.height,
le64_to_cpu(super->fs_root.ref.blkno),
le64_to_cpu(super->fs_root.ref.seq));
@@ -757,8 +760,15 @@ static int print_volume(int fd)
if (err && !ret)
ret = err;
err = print_btree(fd, super, "alloc", &super->alloc_root,
print_alloc_item, NULL);
err = print_btree(fd, super, "core_data_alloc",
&super->core_data_alloc.root,
print_bitmap_entry, NULL);
if (err && !ret)
ret = err;
err = print_btree(fd, super, "core_data_free",
&super->core_data_free.root,
print_bitmap_entry, NULL);
if (err && !ret)
ret = err;