From 0b54d71b986c6381350bcb89fdd2a6bbfacbf0ee Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 13 Mar 2018 12:31:40 -0700 Subject: [PATCH] scoutfs: avoid double unlock We weren't sufficiently careful in reacting to basts. If a bast arrived whlie an unlock is in flight we'd turn around and try to unlock again, returning an error, and exploding. More carefully only act on basts if we have an active mode that needs to be unlocked. Now if the racey bast arrives we'll ignore it and end up freeing the lock in processing after the unlock succeeds. Signed-off-by: Zach Brown --- kmod/src/lock.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kmod/src/lock.c b/kmod/src/lock.c index 72eeb88f..0f0c4f13 100644 --- a/kmod/src/lock.c +++ b/kmod/src/lock.c @@ -355,6 +355,7 @@ static void lock_process(struct lock_info *linfo, struct scoutfs_lock *lock) * to expire after an unlock. */ if (lock->work_mode < 0 && + lock->granted_mode >= 0 && lock->bast_mode >= 0 && lock_counts_match(lock->bast_mode, lock->users) && !lock->grace_pending) { @@ -613,11 +614,14 @@ static void scoutfs_lock_ast(void *arg) } /* - * A lock on this node has blocked a lock request on another node. + * A lock on this node has blocked a lock request on another node. We + * translate the dlm's communication of the blocking mode to the mode + * that we should convert our lock to. We can only either downconvert + * to a matching PR or unlock. * - * We can down convert to a PR if we had an EX and they're trying to get - * a PR but all other conflicts cause us to drop our lock and invalidate - * our cache. + * These are truly asynchronous and can arrive multiple times, at any time. + * We're careful to only set the bast mode here and let lock processing + * sort out the state machine. */ static void scoutfs_lock_bast(void *arg, int blocked_mode) {