FAILED: patch "[PATCH] fs: dlm: fix mismatch of plock results from userspace" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 57e2c2f2d94cfd551af91cedfa1af6d972487197
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023072125-convent-backshift-8f6a@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
57e2c2f2d94c ("fs: dlm: fix mismatch of plock results from userspace") c847f4e20304 ("fs: dlm: fix cleanup pending ops when interrupted") b92a4e3f86b1 ("fs: dlm: change posix lock sigint handling") 4d413ae9ced4 ("fs: dlm: use dlm_plock_info for do_unlock_close") ea06d4cabf52 ("fs: dlm: change plock interrupted message to debug again") 19d7ca051d30 ("fs: dlm: add pid to debug log")dc1acd5c9469 ("dlm: replace usage of found with dedicated list iterator variable") bcfad4265ced ("dlm: improve plock logging if interrupted") a800ba77fd28 ("dlm: rearrange async condition return")bcbb4ba6c9ba ("dlm: cleanup plock_op vs plock_xop")a559790caa1c ("dlm: replace sanity checks with WARN_ON")42252d0d2aa9 ("dlm: fix plock invalid read")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 57e2c2f2d94cfd551af91cedfa1af6d972487197 Mon Sep 17 00:00:00 2001
From: Alexander Aring <[email protected]>
Date: Wed, 24 May 2023 12:02:04 -0400
Subject: [PATCH] fs: dlm: fix mismatch of plock results from userspace
When a waiting plock request (F_SETLKW) is sent to userspace for processing (dlm_controld), the result is returned at a later time. That result could be incorrectly matched to a different waiting request in cases where the owner field is the same (e.g. different threads in a process.) This is fixed by comparing all the properties in the request and reply.
The results for non-waiting plock requests are now matched based on list order because the results are returned in the same order they were sent.
fs/dlm/plock.c +45 -13
@@ -395,7 +395,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,if (op->info.flags &DLM_PLOCK_FL_CLOSE )list_del (&op->list);else -list_move (&op->list, &recv_list); +list_move_tail (&op->list, &recv_list);memcpy (&info, &op->info,sizeof (info)); }spin_unlock (&ops_lock);
@@ -433,20 +433,52 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,if (check_version (&info))return -EINVAL ; +/* +* The results for waiting ops (SETLKW) can be returned in any +* order, so match all fields to find the op. The results for +* non-waiting ops are returned in the order that they were sent +* to userspace, so match the result with the first non-waiting op. +*/ spin_lock (&ops_lock); -list_for_each_entry (iter, &recv_list, list) { -if (iter->info.fsid == info.fsid && - iter->info.number == info.number && - iter->info.owner == info.owner) { -list_del_init (&iter->list); -memcpy (&iter->info, &info,sizeof (info)); -if (iter->data) - do_callback =1 ; -else - iter->done =1 ; - op = iter; -break ; +if (info.wait) { +list_for_each_entry (iter, &recv_list, list) { +if (iter->info.fsid == info.fsid && + iter->info.number == info.number && + iter->info.owner == info.owner && + iter->info.pid == info.pid && + iter->info.start == info.start && + iter->info.end == info.end && + iter->info.ex == info.ex && + iter->info.wait) { + op = iter; +break ; + } } + }else { +list_for_each_entry (iter, &recv_list, list) { +if (!iter->info.wait) { + op = iter; +break ; + } + } + } + +if (op) { +/* Sanity check that op and info match. */ +if (info.wait) +WARN_ON (op->info.optype !=DLM_PLOCK_OP_LOCK ); +else +WARN_ON (op->info.fsid != info.fsid || + op->info.number != info.number || + op->info.owner != info.owner || + op->info.optype != info.optype); + +list_del_init (&op->list); +memcpy (&op->info, &info,sizeof (info)); +if (op->data) + do_callback =1 ; +else + op->done =1 ; }spin_unlock (&ops_lock);