From 9051ceb6fc6e02e54d8f6e616aec98b85257f7be Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 8 Dec 2020 14:10:41 -0800 Subject: [PATCH] Add core seq to the super block Add a new seq field to the super block which will be the source of all incremented seqs throughout the system. We give out incremented seqs to callers with an atomic64_t in memory which is synced back to the super block as we commit transactions in the server. Signed-off-by: Zach Brown --- kmod/src/format.h | 1 + kmod/src/server.c | 34 ++++++++++++++++++++++++++++++++++ kmod/src/server.h | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/kmod/src/format.h b/kmod/src/format.h index 924a1842..ee45a422 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -688,6 +688,7 @@ struct scoutfs_super_block { __le64 version; __le64 flags; __u8 uuid[SCOUTFS_UUID_BYTES]; + __le64 seq; __le64 next_ino; __le64 next_trans_seq; __le64 total_meta_blocks; /* both static and dynamic */ diff --git a/kmod/src/server.c b/kmod/src/server.c index 872af0a7..dfeeac15 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -65,6 +65,9 @@ struct server_info { u64 term; struct scoutfs_net_connection *conn; + /* synced with superblock seq on commits */ + atomic64_t seq_atomic; + /* request processing coordinates shared commits */ struct rw_semaphore commit_rwsem; struct llist_head commit_waiters; @@ -248,6 +251,35 @@ static void get_roots(struct super_block *sb, } while (read_seqcount_retry(&server->roots_seqcount, seq)); } +u64 scoutfs_server_seq(struct super_block *sb) +{ + DECLARE_SERVER_INFO(sb, server); + + return atomic64_read(&server->seq_atomic); +} + +u64 scoutfs_server_next_seq(struct super_block *sb) +{ + DECLARE_SERVER_INFO(sb, server); + + return atomic64_inc_return(&server->seq_atomic); +} + +void scoutfs_server_set_seq_if_greater(struct super_block *sb, u64 seq) +{ + DECLARE_SERVER_INFO(sb, server); + u64 expect; + u64 was; + + expect = atomic64_read(&server->seq_atomic); + while (seq > expect) { + was = atomic64_cmpxchg(&server->seq_atomic, expect, seq); + if (was == expect) + break; + expect = was; + } +} + static void set_roots(struct server_info *server, struct scoutfs_btree_root *fs_root, struct scoutfs_btree_root *logs_root, @@ -333,6 +365,7 @@ static void scoutfs_server_commit_func(struct work_struct *work) goto out; } + super->seq = cpu_to_le64(atomic64_read(&server->seq_atomic)); super->server_meta_avail[server->other_ind ^ 1] = server->alloc.avail; super->server_meta_freed[server->other_ind ^ 1] = server->alloc.freed; @@ -2258,6 +2291,7 @@ static void scoutfs_server_worker(struct work_struct *work) server->volopt = super->volopt; write_seqcount_end(&server->volopt_seqcount); + atomic64_set(&server->seq_atomic, le64_to_cpu(super->seq)); set_roots(server, &super->fs_root, &super->logs_root, &super->srch_root); scoutfs_block_writer_init(sb, &server->wri); diff --git a/kmod/src/server.h b/kmod/src/server.h index 40450aa9..79fcb443 100644 --- a/kmod/src/server.h +++ b/kmod/src/server.h @@ -71,6 +71,10 @@ int scoutfs_server_send_omap_request(struct super_block *sb, u64 rid, int scoutfs_server_send_omap_response(struct super_block *sb, u64 rid, u64 id, struct scoutfs_open_ino_map *map, int err); +u64 scoutfs_server_seq(struct super_block *sb); +u64 scoutfs_server_next_seq(struct super_block *sb); +void scoutfs_server_set_seq_if_greater(struct super_block *sb, u64 seq); + struct sockaddr_in; struct scoutfs_quorum_elected_info; int scoutfs_server_start(struct super_block *sb, u64 term);