mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-09 05:13:18 +00:00
scoutfs: add initial lock write_version
We need a way to compare two items in different log btrees and learn which is the most recent. Each time we grant a new write lock we give it a larger write version. Items store the version of the lock they're written under. Readers can now easily see which item is newer. This is a trivial initial implementation which is not consistent across unmount or server failover. We'll need to recover the greatest write_version from locks during recovery and from log trees as the server starts up. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -726,6 +726,7 @@ struct scoutfs_net_extent_list {
|
||||
|
||||
struct scoutfs_net_lock {
|
||||
struct scoutfs_key key;
|
||||
__le64 write_version;
|
||||
__u8 old_mode;
|
||||
__u8 new_mode;
|
||||
} __packed;
|
||||
|
||||
@@ -587,6 +587,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);
|
||||
|
||||
if (lock_count_match_exists(nl->new_mode, lock->waiters))
|
||||
extend_grace(sb, lock);
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define SCOUTFS_LOCK_NR_MODES SCOUTFS_LOCK_INVALID
|
||||
|
||||
/*
|
||||
* A few fields (start, end, refresh_gen, granted_mode) are referenced
|
||||
* by code outside lock.c.
|
||||
* A few fields (start, end, refresh_gen, write_version, granted_mode)
|
||||
* are referenced by code outside lock.c.
|
||||
*/
|
||||
struct scoutfs_lock {
|
||||
struct super_block *sb;
|
||||
@@ -21,6 +21,7 @@ struct scoutfs_lock {
|
||||
struct rb_node node;
|
||||
struct rb_node range_node;
|
||||
u64 refresh_gen;
|
||||
u64 write_version;
|
||||
struct list_head lru_head;
|
||||
wait_queue_head_t waitq;
|
||||
struct work_struct shrink_work;
|
||||
|
||||
@@ -494,6 +494,8 @@ static int process_waiting_requests(struct super_block *sb,
|
||||
struct client_lock_entry *req_tmp;
|
||||
struct client_lock_entry *gr;
|
||||
struct client_lock_entry *gr_tmp;
|
||||
static atomic64_t write_version = ATOMIC64_INIT(0);
|
||||
u64 wv;
|
||||
int ret;
|
||||
|
||||
BUG_ON(!mutex_is_locked(&snode->mutex));
|
||||
@@ -544,6 +546,12 @@ static int process_waiting_requests(struct super_block *sb,
|
||||
nl.old_mode = SCOUTFS_LOCK_NULL;
|
||||
}
|
||||
|
||||
if (nl.new_mode == SCOUTFS_LOCK_WRITE ||
|
||||
nl.new_mode == SCOUTFS_LOCK_WRITE_ONLY) {
|
||||
wv = atomic64_inc_return(&write_version);
|
||||
nl.write_version = cpu_to_le64(wv);
|
||||
}
|
||||
|
||||
ret = scoutfs_server_lock_response(sb, req->rid,
|
||||
req->net_id, &nl);
|
||||
if (ret)
|
||||
|
||||
Reference in New Issue
Block a user