mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-11 06:00:19 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(<k, 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, <k, &iref);
|
||||
ret = scoutfs_btree_next(sb, &roots.logs_root, <k,
|
||||
&iref);
|
||||
if (ret == -ENOENT) {
|
||||
if (have_next)
|
||||
ret = 0;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user