This patch will revert commit a6b1533e9a57 ("dlm: make posix locks interruptible"). It was probably introduced to reach the fcntl() F_SETLKW requirement to make fcntl() calls interruptible, see:
"F_SETLKW (struct flock *):
As for F_SETLK, but if a conflicting lock is held on the file, then wait for that lock to be released. If a signal is caught while waiting, then the call is interrupted and (after the signal handler has returned) returns immediately (with return value -1 and errno set to EINTR; see signal(7))."
This requires to interrupt the current plock operation in question sitting in the wait_event_interruptible() waiting for op->done becomes true. This isn't currently the case as do_unlock_close() will act like the process was killed as it unlocks all previously acquired locks which can occur into data corruption because the process still thinks it has the previously acquired locks still acquired.
To test this behaviour a ltp testcase was created [0]. After this patch the process can't be interrupted anymore which is against the API but considered currently as a limitation of DLM. However it will stop to unlock all previously acquired locks and the user process isn't aware of it.
It requires more work in DLM to support such feature as intended. It requires some lock request cancellation request which does not yet exists for dlm plock user space communication. As this feature never worked as intended and have side effects as mentioned aboe this patch moves the wait to killable again.
[0] https://gitlab.com/netcoder/ltp/-/blob/dlm_fcntl_owner_testcase/testcases/ke...
Cc: stable@vger.kernel.org Fixes: a6b1533e9a57 ("dlm: make posix locks interruptible") Signed-off-by: Alexander Aring aahringo@redhat.com --- fs/dlm/plock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index fea2157fac5b..31bc601ee3d8 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -155,7 +155,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
send_op(op);
- rv = wait_event_interruptible(recv_wq, (op->done != 0)); + rv = wait_event_killable(recv_wq, (op->done != 0)); if (rv == -ERESTARTSYS) { spin_lock(&ops_lock); /* recheck under ops_lock if we got a done != 0,