From 0f83dfd51274391e729d6031300c524c5c7db4f9 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 30 Sep 2019 08:15:02 -0700 Subject: [PATCH] scoutfs: update block btree interfaces in server Teach the server to maintain and use its block allocator and writer contexts when operating on its btrees. The manifest tree operations aren't updated because they're about to be removed. Signed-off-by: Zach Brown --- kmod/src/format.h | 2 ++ kmod/src/lock_server.c | 20 ++++++++++++--- kmod/src/lock_server.h | 4 ++- kmod/src/manifest.c | 4 +-- kmod/src/server.c | 57 +++++++++++++++++++++++++++--------------- 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/kmod/src/format.h b/kmod/src/format.h index cb177d18..e667d550 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -502,6 +502,8 @@ struct scoutfs_super_block { __le64 unmount_barrier; __u8 quorum_count; 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_manifest manifest; struct scoutfs_btree_root lock_clients; diff --git a/kmod/src/lock_server.c b/kmod/src/lock_server.c index b330218e..5c393038 100644 --- a/kmod/src/lock_server.c +++ b/kmod/src/lock_server.c @@ -19,6 +19,8 @@ #include "net.h" #include "tseq.h" #include "spbm.h" +#include "block.h" +#include "balloc.h" #include "btree.h" #include "msg.h" #include "scoutfs_trace.h" @@ -84,6 +86,9 @@ struct lock_server_info { struct scoutfs_tseq_tree tseq_tree; struct dentry *tseq_dentry; + + struct scoutfs_balloc_allocator *alloc; + struct scoutfs_block_writer *wri; }; #define DECLARE_LOCK_SERVER_INFO(sb, name) \ @@ -590,7 +595,8 @@ int scoutfs_lock_server_greeting(struct super_block *sb, u64 rid, if (ret == 0) scoutfs_btree_put_iref(&iref); } else { - ret = scoutfs_btree_insert(sb, &super->lock_clients, + ret = scoutfs_btree_insert(sb, inf->alloc, inf->wri, + &super->lock_clients, &cbk, sizeof(cbk), NULL, 0); } mutex_unlock(&inf->mutex); @@ -790,7 +796,8 @@ static void scoutfs_lock_server_recovery_timeout(struct work_struct *work) /* XXX these aren't immediately committed */ cbk.rid = cpu_to_be64(rid); - ret = scoutfs_btree_delete(sb, &super->lock_clients, + ret = scoutfs_btree_delete(sb, inf->alloc, inf->wri, + &super->lock_clients, &cbk, sizeof(cbk)); if (ret) break; @@ -829,7 +836,8 @@ int scoutfs_lock_server_farewell(struct super_block *sb, u64 rid) cli.rid = cpu_to_be64(rid); mutex_lock(&inf->mutex); - ret = scoutfs_btree_delete(sb, &super->lock_clients, &cli, sizeof(cli)); + ret = scoutfs_btree_delete(sb, inf->alloc, inf->wri, + &super->lock_clients, &cli, sizeof(cli)); mutex_unlock(&inf->mutex); if (ret == -ENOENT) { ret = 0; @@ -929,7 +937,9 @@ static void lock_server_tseq_show(struct seq_file *m, * all the existing clients, either they reconnect and replay locks or * we time them out. */ -int scoutfs_lock_server_setup(struct super_block *sb) +int scoutfs_lock_server_setup(struct super_block *sb, + struct scoutfs_balloc_allocator *alloc, + struct scoutfs_block_writer *wri) { struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; @@ -952,6 +962,8 @@ int scoutfs_lock_server_setup(struct super_block *sb) INIT_DELAYED_WORK(&inf->recovery_dwork, scoutfs_lock_server_recovery_timeout); scoutfs_tseq_tree_init(&inf->tseq_tree, lock_server_tseq_show); + inf->alloc = alloc; + inf->wri = wri; inf->tseq_dentry = scoutfs_tseq_create("server_locks", sbi->debug_root, &inf->tseq_tree); diff --git a/kmod/src/lock_server.h b/kmod/src/lock_server.h index 0ac2f772..784b2575 100644 --- a/kmod/src/lock_server.h +++ b/kmod/src/lock_server.h @@ -11,7 +11,9 @@ int scoutfs_lock_server_response(struct super_block *sb, u64 rid, struct scoutfs_net_lock *nl); int scoutfs_lock_server_farewell(struct super_block *sb, u64 rid); -int scoutfs_lock_server_setup(struct super_block *sb); +int scoutfs_lock_server_setup(struct super_block *sb, + struct scoutfs_balloc_allocator *alloc, + struct scoutfs_block_writer *wri); void scoutfs_lock_server_destroy(struct super_block *sb); #endif diff --git a/kmod/src/manifest.c b/kmod/src/manifest.c index 1fa6158a..74a250e8 100644 --- a/kmod/src/manifest.c +++ b/kmod/src/manifest.c @@ -191,7 +191,7 @@ int scoutfs_manifest_add(struct super_block *sb, trace_scoutfs_manifest_add(sb, ment->level, ment->segno, ment->seq, &ment->first, &ment->last); - ret = scoutfs_btree_insert(sb, &super->manifest.root, + ret = scoutfs_btree_insert(sb, NULL, &super->manifest.root, &mkey, sizeof(mkey), &mval, sizeof(mval)); if (ret == 0) { mani->nr_levels = max_t(u8, mani->nr_levels, ment->level + 1); @@ -223,7 +223,7 @@ int scoutfs_manifest_del(struct super_block *sb, init_btree_key(&mkey, ment->level, ment->seq, &ment->first); - ret = scoutfs_btree_delete(sb, &super->manifest.root, + ret = scoutfs_btree_delete(sb, NULL, &super->manifest.root, &mkey, sizeof(mkey)); if (ret == 0) add_level_count(sb, ment->level, -1ULL); diff --git a/kmod/src/server.c b/kmod/src/server.c index 4fabfff6..534aec66 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -25,6 +25,8 @@ #include "format.h" #include "counters.h" #include "inode.h" +#include "block.h" +#include "balloc.h" #include "btree.h" #include "manifest.h" #include "seg.h" @@ -90,6 +92,9 @@ struct server_info { struct mutex farewell_mutex; struct list_head farewell_requests; struct work_struct farewell_work; + + struct scoutfs_balloc_allocator alloc; + struct scoutfs_block_writer wri; }; #define DECLARE_SERVER_INFO(sb, name) \ @@ -155,6 +160,7 @@ static int init_extent_from_btree_key(struct scoutfs_extent *ext, u8 type, static int server_extent_io(struct super_block *sb, int op, struct scoutfs_extent *ext, void *data) { + DECLARE_SERVER_INFO(sb, server); struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; struct scoutfs_extent_btree_key ebk; SCOUTFS_BTREE_ITEM_REF(iref); @@ -197,11 +203,13 @@ static int server_extent_io(struct super_block *sb, int op, } } else if (op == SEI_INSERT) { - ret = scoutfs_btree_insert(sb, &super->alloc_root, + ret = scoutfs_btree_insert(sb, &server->alloc, &server->wri, + &super->alloc_root, &ebk, sizeof(ebk), NULL, 0); } else if (op == SEI_DELETE) { - ret = scoutfs_btree_delete(sb, &super->alloc_root, + ret = scoutfs_btree_delete(sb, &server->alloc, &server->wri, + &super->alloc_root, &ebk, sizeof(ebk)); } else { @@ -599,25 +607,21 @@ static void scoutfs_server_commit_func(struct work_struct *work) goto out; } - if (!scoutfs_btree_has_dirty(sb)) { - ret = 0; - goto out; - } - - ret = scoutfs_btree_write_dirty(sb); + ret = scoutfs_block_writer_write(sb, &server->wri); if (ret) { scoutfs_err(sb, "server error writing btree blocks: %d", ret); goto out; } + super->core_balloc_alloc = server->alloc.alloc_root; + super->core_balloc_free = server->alloc.free_root; + ret = scoutfs_write_super(sb, super); if (ret) { scoutfs_err(sb, "server error writing super block: %d", ret); goto out; } - scoutfs_btree_write_complete(sb); - write_seqcount_begin(&server->stable_seqcount); server->stable_manifest_root = SCOUTFS_SB(sb)->super.manifest.root; write_seqcount_end(&server->stable_seqcount); @@ -910,7 +914,8 @@ static int server_advance_seq(struct super_block *sb, tsk.trans_seq = le64_to_be64(their_seq); tsk.rid = cpu_to_be64(rid); - ret = scoutfs_btree_delete(sb, &super->trans_seqs, + ret = scoutfs_btree_delete(sb, &server->alloc, &server->wri, + &super->trans_seqs, &tsk, sizeof(tsk)); if (ret < 0 && ret != -ENOENT) goto out; @@ -925,7 +930,8 @@ static int server_advance_seq(struct super_block *sb, tsk.trans_seq = le64_to_be64(next_seq); tsk.rid = cpu_to_be64(rid); - ret = scoutfs_btree_insert(sb, &super->trans_seqs, + ret = scoutfs_btree_insert(sb, &server->alloc, &server->wri, + &super->trans_seqs, &tsk, sizeof(tsk), NULL, 0); out: up_write(&server->seq_rwsem); @@ -975,7 +981,9 @@ static int remove_trans_seq(struct super_block *sb, u64 rid) if (be64_to_cpu(tsk.rid) == rid) { trace_scoutfs_trans_seq_farewell(sb, rid, be64_to_cpu(tsk.trans_seq)); - ret = scoutfs_btree_delete(sb, &super->trans_seqs, + ret = scoutfs_btree_delete(sb, &server->alloc, + &server->wri, + &super->trans_seqs, &tsk, sizeof(tsk)); break; } @@ -1185,6 +1193,7 @@ int scoutfs_server_lock_recover_request(struct super_block *sb, u64 rid, static int insert_mounted_client(struct super_block *sb, u64 rid, u64 gr_flags) { + DECLARE_SERVER_INFO(sb, server); struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; struct scoutfs_mounted_client_btree_key mck; struct scoutfs_mounted_client_btree_val mcv; @@ -1194,7 +1203,8 @@ static int insert_mounted_client(struct super_block *sb, u64 rid, if (gr_flags & SCOUTFS_NET_GREETING_FLAG_VOTER) mcv.flags |= SCOUTFS_MOUNTED_CLIENT_VOTER; - return scoutfs_btree_insert(sb, &super->mounted_clients, + return scoutfs_btree_insert(sb, &server->alloc, &server->wri, + &super->mounted_clients, &mck, sizeof(mck), &mcv, sizeof(mcv)); } @@ -1210,13 +1220,15 @@ static int insert_mounted_client(struct super_block *sb, u64 rid, */ static int delete_mounted_client(struct super_block *sb, u64 rid) { + DECLARE_SERVER_INFO(sb, server); struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; struct scoutfs_mounted_client_btree_key mck; int ret; mck.rid = cpu_to_be64(rid); - ret = scoutfs_btree_delete(sb, &super->mounted_clients, + ret = scoutfs_btree_delete(sb, &server->alloc, &server->wri, + &super->mounted_clients, &mck, sizeof(mck)); if (ret == -ENOENT) ret = 0; @@ -2296,10 +2308,16 @@ static void scoutfs_server_worker(struct work_struct *work) goto out; /* start up the server subsystems before accepting */ - ret = scoutfs_read_super(sb, super) ?: - scoutfs_btree_setup(sb) ?: - scoutfs_manifest_setup(sb) ?: - scoutfs_lock_server_setup(sb); + ret = scoutfs_read_super(sb, super); + if (ret < 0) + goto shutdown; + + scoutfs_balloc_init(&server->alloc, &super->core_balloc_alloc, + &super->core_balloc_free); + scoutfs_block_writer_init(sb, &server->wri); + + ret = scoutfs_manifest_setup(sb) ?: + scoutfs_lock_server_setup(sb, &server->alloc, &server->wri); if (ret) goto shutdown; @@ -2340,7 +2358,6 @@ shutdown: destroy_pending_frees(sb); scoutfs_manifest_destroy(sb); - scoutfs_btree_destroy(sb); scoutfs_lock_server_destroy(sb); out: