scoutfs: add radix allocator

Add the allocator that uses bits stored in the leaves of a cow radix.
It'll replace two metadata and data allocators that were previously
storing allocation bitmap fragments in btree items.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-02-25 12:03:46 -08:00
committed by Zach Brown
parent 8681f920e0
commit 455a547e8e
5 changed files with 1696 additions and 0 deletions
+1
View File
@@ -28,6 +28,7 @@ scoutfs-y += \
options.o \
per_task.o \
quorum.o \
radix.o \
scoutfs_trace.o \
server.o \
spbm.o \
+38
View File
@@ -8,6 +8,7 @@
#define SCOUTFS_BLOCK_MAGIC_SUPER 0x103c428b
#define SCOUTFS_BLOCK_MAGIC_BTREE 0xe597f96d
#define SCOUTFS_BLOCK_MAGIC_BLOOM 0x31995604
#define SCOUTFS_BLOCK_MAGIC_RADIX 0xebeb5e65
/*
* The super block and btree blocks are fixed 4k.
@@ -132,6 +133,43 @@ struct scoutfs_key {
#define skpe_base _sk_second
#define skpe_part _sk_fourth
struct scoutfs_radix_block {
struct scoutfs_block_header hdr;
__le32 sm_first;
__le32 lg_first;
union {
struct scoutfs_radix_ref {
__le64 blkno;
__le64 seq;
__le64 sm_total;
__le64 lg_total;
} __packed refs[0];
__le64 bits[0];
} __packed;
} __packed;
struct scoutfs_radix_root {
__u8 height;
__le64 next_find_bit;
struct scoutfs_radix_ref ref;
} __packed;
#define SCOUTFS_RADIX_REFS \
((SCOUTFS_BLOCK_SIZE - offsetof(struct scoutfs_radix_block, refs[0])) /\
sizeof(struct scoutfs_radix_ref))
/* 8 meg regions with 4k data blocks */
#define SCOUTFS_RADIX_LG_SHIFT 11
#define SCOUTFS_RADIX_LG_BITS (1 << SCOUTFS_RADIX_LG_SHIFT)
#define SCOUTFS_RADIX_LG_MASK (SCOUTFS_RADIX_LG_BITS - 1)
/* round block bits down to a multiple of large ranges */
#define SCOUTFS_RADIX_BITS \
(((SCOUTFS_BLOCK_SIZE - \
offsetof(struct scoutfs_radix_block, bits[0])) * 8) & \
~(__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.
+1455
View File
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
#ifndef _SCOUTFS_RADIX_H_
#define _SCOUTFS_RADIX_H_
#include "per_task.h"
struct scoutfs_block_writer;
struct scoutfs_radix_allocator {
struct mutex mutex;
struct scoutfs_radix_root avail;
struct scoutfs_radix_root freed;
};
int scoutfs_radix_alloc(struct super_block *sb,
struct scoutfs_radix_allocator *alloc,
struct scoutfs_block_writer *wri, u64 *blkno);
int scoutfs_radix_alloc_data(struct super_block *sb,
struct scoutfs_radix_allocator *alloc,
struct scoutfs_block_writer *wri,
struct scoutfs_radix_root *root,
int count, u64 *blkno_ret, int *count_ret);
int scoutfs_radix_free(struct super_block *sb,
struct scoutfs_radix_allocator *alloc,
struct scoutfs_block_writer *wri, u64 blkno);
int scoutfs_radix_free_data(struct super_block *sb,
struct scoutfs_radix_allocator *alloc,
struct scoutfs_block_writer *wri,
struct scoutfs_radix_root *root,
u64 blkno, int count);
int scoutfs_radix_merge(struct super_block *sb,
struct scoutfs_radix_allocator *alloc,
struct scoutfs_block_writer *wri,
struct scoutfs_radix_root *dst,
struct scoutfs_radix_root *src,
struct scoutfs_radix_root *inp, u64 count);
void scoutfs_radix_init_alloc(struct scoutfs_radix_allocator *alloc,
struct scoutfs_radix_root *avail,
struct scoutfs_radix_root *freed);
void scoutfs_radix_root_init(struct super_block *sb,
struct scoutfs_radix_root *root, bool meta);
u64 scoutfs_radix_bit_leaf_nr(u64 bit);
#endif
+159
View File
@@ -2212,6 +2212,165 @@ DEFINE_EVENT(scoutfs_block_class, scoutfs_block_shrink,
TP_ARGS(sb, bp, blkno, refcount, io_count, bits, lru_moved)
);
TRACE_EVENT(scoutfs_radix_dirty,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
u64 orig_blkno, u64 dirty_blkno, u64 par_blkno),
TP_ARGS(sb, root, orig_blkno, dirty_blkno, par_blkno),
TP_STRUCT__entry(
SCSB_TRACE_FIELDS
__field(__u64, root_blkno)
__field(__u64, orig_blkno)
__field(__u64, dirty_blkno)
__field(__u64, par_blkno)
),
TP_fast_assign(
SCSB_TRACE_ASSIGN(sb);
__entry->root_blkno = le64_to_cpu(root->ref.blkno);
__entry->orig_blkno = orig_blkno;
__entry->dirty_blkno = dirty_blkno;
__entry->par_blkno = par_blkno;
),
TP_printk(SCSBF" root_blkno %llu orig_blkno %llu dirty_blkno %llu par_blkno %llu",
SCSB_TRACE_ARGS, __entry->root_blkno, __entry->orig_blkno,
__entry->dirty_blkno, __entry->par_blkno)
);
TRACE_EVENT(scoutfs_radix_walk,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
int grl, int level, u64 blkno, int ind, u64 bit, u64 next),
TP_ARGS(sb, root, grl, level, blkno, ind, bit, next),
TP_STRUCT__entry(
SCSB_TRACE_FIELDS
__field(__u64, root_blkno)
__field(unsigned int, grl)
__field(__u64, blkno)
__field(int, level)
__field(int, ind)
__field(__u64, bit)
__field(__u64, next)
),
TP_fast_assign(
SCSB_TRACE_ASSIGN(sb);
__entry->root_blkno = le64_to_cpu(root->ref.blkno);
__entry->grl = grl;
__entry->blkno = blkno;
__entry->level = level;
__entry->ind = ind;
__entry->bit = bit;
__entry->next = next;
),
TP_printk(SCSBF" root_blkno %llu grl 0x%x blkno %llu level %d ind %d bit %llu next %llu",
SCSB_TRACE_ARGS, __entry->root_blkno, __entry->grl,
__entry->blkno, __entry->level, __entry->ind, __entry->bit,
__entry->next)
);
TRACE_EVENT(scoutfs_radix_fixup_refs,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
u32 sm_first, u64 sm_total, u16 lg_first, u64 lg_total,
u64 blkno, int level),
TP_ARGS(sb, root, sm_first, sm_total, lg_first, lg_total, blkno, level),
TP_STRUCT__entry(
SCSB_TRACE_FIELDS
__field(__u64, root_blkno)
__field(__u32, sm_first)
__field(__u64, sm_total)
__field(__u16, lg_first)
__field(__u64, lg_total)
__field(__u64, blkno)
__field(int, level)
),
TP_fast_assign(
SCSB_TRACE_ASSIGN(sb);
__entry->root_blkno = le64_to_cpu(root->ref.blkno);
__entry->sm_first = sm_first;
__entry->sm_total = sm_total;
__entry->lg_first = lg_first;
__entry->lg_total = lg_total;
__entry->blkno = blkno;
__entry->level = level;
),
TP_printk(SCSBF" root_blkno %llu sm_first %u sm_total %llu lg_first %u lg_total %llu blkno %llu level %u",
SCSB_TRACE_ARGS, __entry->root_blkno, __entry->sm_first,
__entry->sm_total, __entry->lg_first, __entry->lg_total,
__entry->blkno, __entry->level)
);
DECLARE_EVENT_CLASS(scoutfs_radix_bitop,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
u64 blkno, u64 bit, int ind, int nbits),
TP_ARGS(sb, root, blkno, bit, ind, nbits),
TP_STRUCT__entry(
SCSB_TRACE_FIELDS
__field(__u64, root_blkno)
__field(__u64, blkno)
__field(__u64, bit)
__field(int, ind)
__field(int, nbits)
),
TP_fast_assign(
SCSB_TRACE_ASSIGN(sb);
__entry->root_blkno = le64_to_cpu(root->ref.blkno);
__entry->blkno = blkno;
__entry->bit = bit;
__entry->ind = ind;
__entry->nbits = nbits;
),
TP_printk(SCSBF" root_blkno %llu blkno %llu bit %llu ind %d nbits %d",
SCSB_TRACE_ARGS, __entry->root_blkno, __entry->blkno,
__entry->bit, __entry->ind, __entry->nbits)
);
DEFINE_EVENT(scoutfs_radix_bitop, scoutfs_radix_clear,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
u64 blkno, u64 bit, int ind, int nbits),
TP_ARGS(sb, root, blkno, bit, ind, nbits)
);
DEFINE_EVENT(scoutfs_radix_bitop, scoutfs_radix_set,
TP_PROTO(struct super_block *sb, struct scoutfs_radix_root *root,
u64 blkno, u64 bit, int ind, int nbits),
TP_ARGS(sb, root, blkno, bit, ind, nbits)
);
TRACE_EVENT(scoutfs_radix_merge,
TP_PROTO(struct super_block *sb,
struct scoutfs_radix_root *src, u64 src_blkno,
struct scoutfs_radix_root *dst, u64 dst_blkno,
u64 count, int ind, int sm_delta, int src_lg_delta,
int dst_lg_delta),
TP_ARGS(sb, src, src_blkno, dst, dst_blkno, count, ind,
sm_delta, src_lg_delta, dst_lg_delta),
TP_STRUCT__entry(
SCSB_TRACE_FIELDS
__field(__u64, src_root_blkno)
__field(__u64, src_blkno)
__field(__u64, dst_root_blkno)
__field(__u64, dst_blkno)
__field(__u64, count)
__field(int, ind)
__field(int, sm_delta)
__field(int, src_lg_delta)
__field(int, dst_lg_delta)
),
TP_fast_assign(
SCSB_TRACE_ASSIGN(sb);
__entry->src_root_blkno = le64_to_cpu(src->ref.blkno);
__entry->src_blkno = src_blkno;
__entry->dst_root_blkno = le64_to_cpu(dst->ref.blkno);
__entry->dst_blkno = dst_blkno;
__entry->count = count;
__entry->ind = ind;
__entry->sm_delta = sm_delta;
__entry->src_lg_delta = src_lg_delta;
__entry->dst_lg_delta = dst_lg_delta;
),
TP_printk(SCSBF" src_root_blkno %llu src_blkno %llu dst_root_blkno %llu dst_blkno %llu count %llu ind %u sm_delta %d src_lg_delta %d dst_lg_delta %d",
SCSB_TRACE_ARGS,
__entry->src_root_blkno, __entry->src_blkno,
__entry->dst_root_blkno, __entry->dst_blkno,
__entry->count, __entry->ind, __entry->sm_delta,
__entry->src_lg_delta, __entry->dst_lg_delta)
);
#endif /* _TRACE_SCOUTFS_H */
/* This part must be outside protection */