scoutfs: rework get_fs_roots to get_roots

The get_fs_roots rpc and server interfaces were built around individual
roots.  Rebuild it around passing around a struct so that we can add
roots without impacting all the current users.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-06-30 10:33:31 -07:00
committed by Zach Brown
parent 8c114ddb87
commit cca83b1758
9 changed files with 57 additions and 74 deletions

View File

@@ -108,22 +108,14 @@ int scoutfs_client_commit_log_trees(struct super_block *sb,
lt, sizeof(*lt), NULL, 0);
}
int scoutfs_client_get_fs_roots(struct super_block *sb,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root)
int scoutfs_client_get_roots(struct super_block *sb,
struct scoutfs_net_roots *roots)
{
struct client_info *client = SCOUTFS_SB(sb)->client_info;
struct scoutfs_net_fs_roots nfr;
int ret;
ret = scoutfs_net_sync_request(sb, client->conn,
SCOUTFS_NET_CMD_GET_FS_ROOTS,
NULL, 0, &nfr, sizeof(nfr));
if (ret == 0) {
*fs_root = nfr.fs_root;
*logs_root = nfr.logs_root;
}
return 0;
return scoutfs_net_sync_request(sb, client->conn,
SCOUTFS_NET_CMD_GET_ROOTS,
NULL, 0, roots, sizeof(*roots));
}
int scoutfs_client_advance_seq(struct super_block *sb, u64 *seq)

View File

@@ -7,9 +7,8 @@ int scoutfs_client_get_log_trees(struct super_block *sb,
struct scoutfs_log_trees *lt);
int scoutfs_client_commit_log_trees(struct super_block *sb,
struct scoutfs_log_trees *lt);
int scoutfs_client_get_fs_roots(struct super_block *sb,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root);
int scoutfs_client_get_roots(struct super_block *sb,
struct scoutfs_net_roots *roots);
u64 *scoutfs_client_bulk_alloc(struct super_block *sb);
int scoutfs_client_advance_seq(struct super_block *sb, u64 *seq);
int scoutfs_client_get_last_seq(struct super_block *sb, u64 *seq);

View File

@@ -305,8 +305,7 @@ static int refresh_bloom_roots(struct super_block *sb,
{
DECLARE_FOREST_INFO(sb, finf);
struct forest_lock_private *lpriv = ACCESS_ONCE(lock->forest_private);
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
struct scoutfs_net_roots roots;
struct scoutfs_log_trees_val ltv;
SCOUTFS_BTREE_ITEM_REF(iref);
struct forest_bloom_nrs bloom;
@@ -327,26 +326,25 @@ static int refresh_bloom_roots(struct super_block *sb,
/* first use the lock's constant roots, then sample newer roots */
if (!lpriv->used_lock_roots) {
lpriv->used_lock_roots = 1;
fs_root = lock->fs_root;
logs_root = lock->logs_root;
roots = lock->roots;
scoutfs_inc_counter(sb, forest_roots_lock);
} else {
ret = scoutfs_client_get_fs_roots(sb, &fs_root, &logs_root);
ret = scoutfs_client_get_roots(sb, &roots);
if (ret)
goto out;
scoutfs_inc_counter(sb, forest_roots_server);
}
trace_scoutfs_forest_using_roots(sb, &fs_root, &logs_root);
refs->fs_ref = fs_root.ref;
refs->logs_ref = logs_root.ref;
trace_scoutfs_forest_using_roots(sb, &roots.fs_root, &roots.logs_root);
refs->fs_ref = roots.fs_root.ref;
refs->logs_ref = roots.logs_root.ref;
calc_bloom_nrs(&bloom, &lock->start);
scoutfs_key_init_log_trees(&key, 0, 0);
for (;; scoutfs_key_inc(&key)) {
ret = scoutfs_btree_next(sb, &logs_root, &key, &iref);
ret = scoutfs_btree_next(sb, &roots.logs_root, &key, &iref);
if (ret == -ENOENT) {
ret = 0;
break;
@@ -423,7 +421,7 @@ static int refresh_bloom_roots(struct super_block *sb,
/* always add the fs root at the tail */
fr = &lpriv->fs_root;
fr->item_root = fs_root;
fr->item_root = roots.fs_root;
fr->rid = 0;
fr->nr = 0;
list_add_tail(&fr->entry, &lpriv->roots);
@@ -1028,8 +1026,7 @@ int scoutfs_forest_next_hint(struct super_block *sb, struct scoutfs_key *key,
struct scoutfs_key *next)
{
DECLARE_STALE_TRACKING_SUPER_REFS(prev_refs, refs);
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
struct scoutfs_net_roots roots;
struct scoutfs_btree_root item_root;
struct scoutfs_log_trees_val *ltv;
SCOUTFS_BTREE_ITEM_REF(iref);
@@ -1041,13 +1038,13 @@ int scoutfs_forest_next_hint(struct super_block *sb, struct scoutfs_key *key,
retry:
scoutfs_inc_counter(sb, forest_roots_next_hint);
ret = scoutfs_client_get_fs_roots(sb, &fs_root, &logs_root);
ret = scoutfs_client_get_roots(sb, &roots);
if (ret)
goto out;
trace_scoutfs_forest_using_roots(sb, &fs_root, &logs_root);
refs.fs_ref = fs_root.ref;
refs.logs_ref = logs_root.ref;
trace_scoutfs_forest_using_roots(sb, &roots.fs_root, &roots.logs_root);
refs.fs_ref = roots.fs_root.ref;
refs.logs_ref = roots.logs_root.ref;
scoutfs_key_init_log_trees(&ltk, 0, 0);
checked_fs = false;
@@ -1056,9 +1053,10 @@ retry:
for (;;) {
if (!checked_fs) {
checked_fs = true;
item_root = fs_root;
item_root = roots.fs_root;
} else {
ret = scoutfs_btree_next(sb, &logs_root, &ltk, &iref);
ret = scoutfs_btree_next(sb, &roots.logs_root, &ltk,
&iref);
if (ret == -ENOENT) {
if (have_next)
ret = 0;

View File

@@ -682,7 +682,7 @@ enum {
SCOUTFS_NET_CMD_ALLOC_INODES,
SCOUTFS_NET_CMD_GET_LOG_TREES,
SCOUTFS_NET_CMD_COMMIT_LOG_TREES,
SCOUTFS_NET_CMD_GET_FS_ROOTS,
SCOUTFS_NET_CMD_GET_ROOTS,
SCOUTFS_NET_CMD_ADVANCE_SEQ,
SCOUTFS_NET_CMD_GET_LAST_SEQ,
SCOUTFS_NET_CMD_STATFS,
@@ -731,7 +731,7 @@ struct scoutfs_net_statfs {
__u8 uuid[SCOUTFS_UUID_BYTES]; /* logical volume uuid */
} __packed;
struct scoutfs_net_fs_roots {
struct scoutfs_net_roots {
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
} __packed;
@@ -745,7 +745,7 @@ struct scoutfs_net_lock {
struct scoutfs_net_lock_grant_response {
struct scoutfs_net_lock nl;
struct scoutfs_net_fs_roots nfr;
struct scoutfs_net_roots roots;
} __packed;
struct scoutfs_net_lock_recover {

View File

@@ -590,8 +590,7 @@ int scoutfs_lock_grant_response(struct super_block *sb,
lock->request_pending = 0;
lock->mode = nl->new_mode;
lock->write_version = le64_to_cpu(nl->write_version);
lock->fs_root = gr->nfr.fs_root;
lock->logs_root = gr->nfr.logs_root;
lock->roots = gr->roots;
if (lock_count_match_exists(nl->new_mode, lock->waiters))
extend_grace(sb, lock);

View File

@@ -22,8 +22,7 @@ struct scoutfs_lock {
struct rb_node range_node;
u64 refresh_gen;
u64 write_version;
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
struct scoutfs_net_roots roots;
struct list_head lru_head;
wait_queue_head_t waitq;
struct work_struct shrink_work;

View File

@@ -554,8 +554,7 @@ static int process_waiting_requests(struct super_block *sb,
}
gres.nl = nl;
scoutfs_server_get_fs_roots(sb, &gres.nfr.fs_root,
&gres.nfr.logs_root);
scoutfs_server_get_roots(sb, &gres.roots);
ret = scoutfs_server_lock_response(sb, req->rid,
req->net_id, &gres);

View File

@@ -86,9 +86,8 @@ struct server_info {
struct mutex logs_mutex;
/* stable versions stored from commits, given in locks and rpcs */
seqcount_t fs_roots_seqcount;
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
seqcount_t roots_seqcount;
struct scoutfs_net_roots roots;
};
#define DECLARE_SERVER_INFO(sb, name) \
@@ -225,29 +224,27 @@ static void update_free_blocks(__le64 *blocks, struct scoutfs_radix_root *prev,
le64_to_cpu(prev->ref.sm_total));
}
void scoutfs_server_get_fs_roots(struct super_block *sb,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root)
void scoutfs_server_get_roots(struct super_block *sb,
struct scoutfs_net_roots *roots)
{
DECLARE_SERVER_INFO(sb, server);
unsigned int seq;
do {
seq = read_seqcount_begin(&server->fs_roots_seqcount);
*fs_root = server->fs_root;
*logs_root = server->logs_root;
} while (read_seqcount_retry(&server->fs_roots_seqcount, seq));
seq = read_seqcount_begin(&server->roots_seqcount);
*roots = server->roots;
} while (read_seqcount_retry(&server->roots_seqcount, seq));
}
static void set_fs_roots(struct server_info *server,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root)
static void set_roots(struct server_info *server,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root)
{
preempt_disable();
write_seqcount_begin(&server->fs_roots_seqcount);
server->fs_root = *fs_root;
server->logs_root = *logs_root;
write_seqcount_end(&server->fs_roots_seqcount);
write_seqcount_begin(&server->roots_seqcount);
server->roots.fs_root = *fs_root;
server->roots.logs_root = *logs_root;
write_seqcount_end(&server->roots_seqcount);
preempt_enable();
}
@@ -307,7 +304,7 @@ static void scoutfs_server_commit_func(struct work_struct *work)
}
server->prepared_commit = false;
set_fs_roots(server, &super->fs_root, &super->logs_root);
set_roots(server, &super->fs_root, &super->logs_root);
ret = 0;
out:
node = llist_del_all(&server->commit_waiters);
@@ -577,22 +574,23 @@ out:
* visible in persistent storage. We don't want to accidentally give
* them our in-memory dirty version. This can be racing with commits.
*/
static int server_get_fs_roots(struct super_block *sb,
struct scoutfs_net_connection *conn,
u8 cmd, u64 id, void *arg, u16 arg_len)
static int server_get_roots(struct super_block *sb,
struct scoutfs_net_connection *conn,
u8 cmd, u64 id, void *arg, u16 arg_len)
{
struct scoutfs_net_fs_roots nfr;
struct scoutfs_net_roots roots;
int ret;
if (arg_len != 0) {
memset(&nfr, 0, sizeof(nfr));
memset(&roots, 0, sizeof(roots));
ret = -EINVAL;
} else {
scoutfs_server_get_fs_roots(sb, &nfr.fs_root, &nfr.logs_root);
scoutfs_server_get_roots(sb, &roots);
ret = 0;
}
return scoutfs_net_response(sb, conn, cmd, id, 0, &nfr, sizeof(nfr));
return scoutfs_net_response(sb, conn, cmd, id, 0,
&roots, sizeof(roots));
}
/*
@@ -1394,7 +1392,7 @@ static scoutfs_net_request_t server_req_funcs[] = {
[SCOUTFS_NET_CMD_ALLOC_INODES] = server_alloc_inodes,
[SCOUTFS_NET_CMD_GET_LOG_TREES] = server_get_log_trees,
[SCOUTFS_NET_CMD_COMMIT_LOG_TREES] = server_commit_log_trees,
[SCOUTFS_NET_CMD_GET_FS_ROOTS] = server_get_fs_roots,
[SCOUTFS_NET_CMD_GET_ROOTS] = server_get_roots,
[SCOUTFS_NET_CMD_ADVANCE_SEQ] = server_advance_seq,
[SCOUTFS_NET_CMD_GET_LAST_SEQ] = server_get_last_seq,
[SCOUTFS_NET_CMD_STATFS] = server_statfs,
@@ -1485,7 +1483,7 @@ static void scoutfs_server_worker(struct work_struct *work)
if (ret < 0)
goto shutdown;
set_fs_roots(server, &super->fs_root, &super->logs_root);
set_roots(server, &super->fs_root, &super->logs_root);
scoutfs_radix_init_alloc(&server->alloc, &super->core_meta_avail,
&super->core_meta_freed);
scoutfs_block_writer_init(sb, &server->wri);
@@ -1625,7 +1623,7 @@ int scoutfs_server_setup(struct super_block *sb)
INIT_LIST_HEAD(&server->farewell_requests);
INIT_WORK(&server->farewell_work, farewell_worker);
mutex_init(&server->logs_mutex);
seqcount_init(&server->fs_roots_seqcount);
seqcount_init(&server->roots_seqcount);
server->wq = alloc_workqueue("scoutfs_server",
WQ_UNBOUND | WQ_NON_REENTRANT, 0);

View File

@@ -62,11 +62,10 @@ int scoutfs_server_lock_response(struct super_block *sb, u64 rid, u64 id,
struct scoutfs_net_lock_grant_response *gr);
int scoutfs_server_lock_recover_request(struct super_block *sb, u64 rid,
struct scoutfs_key *key);
void scoutfs_server_get_roots(struct super_block *sb,
struct scoutfs_net_roots *roots);
int scoutfs_server_hold_commit(struct super_block *sb);
int scoutfs_server_apply_commit(struct super_block *sb, int err);
void scoutfs_server_get_fs_roots(struct super_block *sb,
struct scoutfs_btree_root *fs_root,
struct scoutfs_btree_root *logs_root);
struct sockaddr_in;
struct scoutfs_quorum_elected_info;