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:
Zach Brown
2019-10-25 11:34:49 -07:00
committed by Zach Brown
parent 43d416003a
commit fbffad1d51
4 changed files with 13 additions and 2 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)