From c98e75006efc28df0dac016d16e5bbb274512d7e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 28 May 2020 14:04:41 -0700 Subject: [PATCH] scoutfs: remove lock_client entries in commit The lock server maintains some items in btrees in the server. It is usually called by the server core during a commit so it doesn't need to worry about managing commits. But the lock recovery timeout code happens in its own async context. It needs to protect the lock_client item removals with a commit. This was causing failures during xfstests that simulate node crashes by unmounting with dm-flakey. Lock recovery would dirty blocks in the btree writer outside of a commit. The first server commit holder would find dirty blocks and throw an assertion indicating that someone modified blocks without holding a commit. Signed-off-by: Zach Brown --- kmod/src/lock_server.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kmod/src/lock_server.c b/kmod/src/lock_server.c index f4bf64a0..03460ef3 100644 --- a/kmod/src/lock_server.c +++ b/kmod/src/lock_server.c @@ -773,6 +773,10 @@ static void scoutfs_lock_server_recovery_timeout(struct work_struct *work) u64 rid; int ret; + ret = scoutfs_server_hold_commit(sb); + if (ret) + goto out; + /* we enter recovery if there are any client records */ for (rid = 0; ; rid++) { cbk.rid = cpu_to_be64(rid); @@ -802,7 +806,6 @@ static void scoutfs_lock_server_recovery_timeout(struct work_struct *work) scoutfs_err(sb, "client rid %016llx lock recovery timed out", rid); - /* XXX these aren't immediately committed */ cbk.rid = cpu_to_be64(rid); ret = scoutfs_btree_delete(sb, inf->alloc, inf->wri, &super->lock_clients, @@ -811,6 +814,8 @@ static void scoutfs_lock_server_recovery_timeout(struct work_struct *work) break; } + ret = scoutfs_server_apply_commit(sb, ret); +out: /* force processing all pending lock requests */ if (ret == 0) ret = finished_recovery(sb, 0, false);