mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-19 14:34:16 +00:00
scoutfs: add forest subsystem
The forest code presents a consistent item interface that's implemented on top of a forest of persistent btrees. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -21,6 +21,7 @@ scoutfs-y += \
|
||||
export.o \
|
||||
extents.o \
|
||||
file.o \
|
||||
forest.o \
|
||||
inode.o \
|
||||
ioctl.o \
|
||||
item.o \
|
||||
|
||||
+1389
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
#ifndef _SCOUTFS_FOREST_H_
|
||||
#define _SCOUTFS_FOREST_H_
|
||||
|
||||
int scoutfs_forest_lookup(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct kvec *val, struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_lookup_exact(struct super_block *sb,
|
||||
struct scoutfs_key *key, struct kvec *val,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_next(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct scoutfs_key *last, struct kvec *val,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_next_hint(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct scoutfs_key *next);
|
||||
int scoutfs_forest_prev(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct scoutfs_key *first, struct kvec *val,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_create(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct kvec *val, struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_create_force(struct super_block *sb,
|
||||
struct scoutfs_key *key, struct kvec *val,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_update(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct kvec *val, struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_delete_dirty(struct super_block *sb,
|
||||
struct scoutfs_key *key);
|
||||
int scoutfs_forest_delete(struct super_block *sb, struct scoutfs_key *key,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_delete_force(struct super_block *sb,
|
||||
struct scoutfs_key *key,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_delete_save(struct super_block *sb,
|
||||
struct scoutfs_key *key,
|
||||
struct list_head *list,
|
||||
struct scoutfs_lock *lock);
|
||||
int scoutfs_forest_restore(struct super_block *sb, struct list_head *list,
|
||||
struct scoutfs_lock *lock);
|
||||
void scoutfs_forest_free_batch(struct super_block *sb, struct list_head *list);
|
||||
|
||||
int scoutfs_forest_get_log_trees(struct super_block *sb);
|
||||
bool scoutfs_forest_has_dirty(struct super_block *sb);
|
||||
unsigned long scoutfs_forest_dirty_bytes(struct super_block *sb);
|
||||
int scoutfs_forest_write(struct super_block *sb);
|
||||
int scoutfs_forest_commit(struct super_block *sb);
|
||||
|
||||
void scoutfs_forest_clear_lock(struct super_block *sb,
|
||||
struct scoutfs_lock *lock);
|
||||
|
||||
int scoutfs_forest_setup(struct super_block *sb);
|
||||
void scoutfs_forest_destroy(struct super_block *sb);
|
||||
|
||||
#endif
|
||||
+59
-3
@@ -7,6 +7,7 @@
|
||||
/* block header magic values, chosen at random */
|
||||
#define SCOUTFS_BLOCK_MAGIC_SUPER 0x103c428b
|
||||
#define SCOUTFS_BLOCK_MAGIC_BTREE 0xe597f96d
|
||||
#define SCOUTFS_BLOCK_MAGIC_BLOOM 0x31995604
|
||||
|
||||
/*
|
||||
* The super block and btree blocks are fixed 4k.
|
||||
@@ -329,6 +330,61 @@ struct scoutfs_mounted_client_btree_val {
|
||||
|
||||
#define SCOUTFS_MOUNTED_CLIENT_VOTER (1 << 0)
|
||||
|
||||
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;
|
||||
__le64 rid;
|
||||
__le64 nr;
|
||||
} __packed;
|
||||
|
||||
struct scoutfs_log_trees_key {
|
||||
__be64 rid;
|
||||
__be64 nr;
|
||||
} __packed;
|
||||
|
||||
struct scoutfs_log_trees_val {
|
||||
struct scoutfs_balloc_root alloc_root;
|
||||
struct scoutfs_balloc_root free_root;
|
||||
struct scoutfs_btree_root item_root;
|
||||
struct scoutfs_btree_ref bloom_ref;
|
||||
} __packed;
|
||||
|
||||
struct scoutfs_log_item_value {
|
||||
__le64 vers;
|
||||
__u8 flags;
|
||||
__u8 data[0];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* FS items are limited by the max btree value length with the log item
|
||||
* value header.
|
||||
*/
|
||||
#define SCOUTFS_MAX_VAL_SIZE \
|
||||
(SCOUTFS_BTREE_MAX_VAL_LEN - sizeof(struct scoutfs_log_item_value))
|
||||
|
||||
#define SCOUTFS_LOG_ITEM_FLAG_DELETION (1 << 0)
|
||||
|
||||
struct scoutfs_bloom_block {
|
||||
struct scoutfs_block_header hdr;
|
||||
__le64 total_set;
|
||||
__le64 bits[0];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Log trees include a tree of items that make up a fixed size bloom
|
||||
* filter. Just a few megs worth of items lets us test for the presence
|
||||
* of locks that cover billions of files with a .1% chance of false
|
||||
* positives. The log trees should be finalized and merged long before
|
||||
* the bloom filters fill up and start returning excessive false positives.
|
||||
*/
|
||||
#define SCOUTFS_FOREST_BLOOM_NRS 7
|
||||
#define SCOUTFS_FOREST_BLOOM_BITS \
|
||||
(((SCOUTFS_BLOCK_SIZE - sizeof(struct scoutfs_bloom_block)) / \
|
||||
member_sizeof(struct scoutfs_bloom_block, bits[0])) * \
|
||||
member_sizeof(struct scoutfs_bloom_block, bits[0]) * 8) \
|
||||
|
||||
/*
|
||||
* The max number of links defines the max number of entries that we can
|
||||
* index in o(log n) and the static list head storage size in the
|
||||
@@ -496,6 +552,8 @@ struct scoutfs_super_block {
|
||||
__le64 core_balloc_cursor;
|
||||
__le64 free_blocks;
|
||||
__le64 alloc_cursor;
|
||||
__le64 first_fs_blkno;
|
||||
__le64 last_fs_blkno;
|
||||
struct scoutfs_btree_ring bring;
|
||||
__le64 next_seg_seq;
|
||||
__le64 next_compact_id;
|
||||
@@ -507,8 +565,8 @@ struct scoutfs_super_block {
|
||||
struct scoutfs_balloc_root core_balloc_alloc;
|
||||
struct scoutfs_balloc_root core_balloc_free;
|
||||
struct scoutfs_btree_root alloc_root;
|
||||
struct scoutfs_manifest manifest;
|
||||
struct scoutfs_btree_root fs_root;
|
||||
struct scoutfs_manifest manifest;
|
||||
struct scoutfs_btree_root logs_root;
|
||||
struct scoutfs_btree_root lock_clients;
|
||||
struct scoutfs_btree_root trans_seqs;
|
||||
@@ -617,8 +675,6 @@ enum {
|
||||
DIV_ROUND_UP(sizeof(struct scoutfs_xattr) + name_len + val_len, \
|
||||
SCOUTFS_XATTR_MAX_PART_SIZE);
|
||||
|
||||
#define SCOUTFS_MAX_VAL_SIZE SCOUTFS_XATTR_MAX_PART_SIZE
|
||||
|
||||
#define SCOUTFS_LOCK_INODE_GROUP_NR 1024
|
||||
#define SCOUTFS_LOCK_INODE_GROUP_MASK (SCOUTFS_LOCK_INODE_GROUP_NR - 1)
|
||||
#define SCOUTFS_LOCK_SEQ_GROUP_MASK ((1ULL << 10) - 1)
|
||||
|
||||
@@ -36,6 +36,9 @@ struct scoutfs_lock {
|
||||
unsigned int users[SCOUTFS_LOCK_NR_MODES];
|
||||
|
||||
struct scoutfs_tseq_entry tseq_entry;
|
||||
|
||||
/* the forest btree code stores data per lock */
|
||||
struct forest_lock_private *forest_private;
|
||||
};
|
||||
|
||||
struct scoutfs_lock_coverage {
|
||||
|
||||
@@ -27,6 +27,7 @@ struct sysfs_info;
|
||||
struct options_sb_info;
|
||||
struct net_info;
|
||||
struct block_info;
|
||||
struct forest_info;
|
||||
|
||||
struct scoutfs_sb_info {
|
||||
struct super_block *sb;
|
||||
@@ -50,6 +51,7 @@ struct scoutfs_sb_info {
|
||||
struct net_info *net_info;
|
||||
struct quorum_info *quorum_info;
|
||||
struct block_info *block_info;
|
||||
struct forest_info *forest_info;
|
||||
|
||||
wait_queue_head_t trans_hold_wq;
|
||||
struct task_struct *trans_task;
|
||||
|
||||
Reference in New Issue
Block a user