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 <zab@versity.com>
This commit is contained in:
Zach Brown
2020-05-28 14:04:41 -07:00
committed by Zach Brown
parent ff9386faba
commit c98e75006e

View File

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