From: Alexander Aring <aahringo@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH dlm/next 2/2] fs: dlm: cleanup plock op lookup functionality
Date: Wed, 24 May 2023 13:19:32 -0400 [thread overview]
Message-ID: <20230524171932.1132564-2-aahringo@redhat.com> (raw)
In-Reply-To: <20230524171932.1132564-1-aahringo@redhat.com>
This patch will introduce plock_op_lookup() to lookup a plock op when a
result needs to lookup the plock op to find the original request.
Besides that we add additional sanity check to confirm the lookup is
still working in case of non F_SETLKW request as it requires a specific
order in recv_list.
Signed-off-by: Alexander Aring <aahringo@redhat.com>
---
fs/dlm/plock.c | 117 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 78 insertions(+), 39 deletions(-)
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
index d6ec70547b77..b2b6635fcb28 100644
--- a/fs/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -423,66 +423,105 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
return sizeof(info);
}
-/* a write copies in one plock result that should match a plock_op
- on the recv list */
-static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
- loff_t *ppos)
+static struct plock_op *plock_op_lookup(const struct dlm_plock_info *info)
{
struct plock_op *op = NULL, *iter;
- struct dlm_plock_info info;
- int do_callback = 0;
-
- if (count != sizeof(info))
- return -EINVAL;
-
- if (copy_from_user(&info, u, sizeof(info)))
- return -EFAULT;
-
- if (check_version(&info))
- return -EINVAL;
- spin_lock(&ops_lock);
- if (info.wait) {
+ /* F_SETLKW does not have an order in recv_list */
+ 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 &&
+ 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;
+
+ /* sanity check should be DLM_PLOCK_OP_LOCK */
+ WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
break;
}
}
} else {
+ /* others than F_SETLKW have an order in recv_list we
+ * need to jump over all F_SETLKW ops (info->wait) and match
+ * the first one.
+ */
list_for_each_entry(iter, &recv_list, list) {
if (!iter->info.wait) {
op = iter;
+
+ /* sanity check to check we got the right one */
+ WARN_ON(op->info.fsid != info->fsid ||
+ op->info.number != info->number ||
+ op->info.owner != info->owner ||
+ op->info.optype != info->optype);
+
+ switch (op->info.optype) {
+ case DLM_PLOCK_OP_GET:
+ break;
+ default:
+ WARN_ON(op->info.pid != info->pid ||
+ op->info.start != info->start ||
+ op->info.end != info->end ||
+ op->info.ex != info->ex);
+ break;
+ }
break;
}
}
}
- if (op) {
- 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);
+ return op;
+}
- if (op) {
- if (do_callback)
- dlm_plock_callback(op);
- else
- wake_up(&recv_wq);
- } else
+/* a write copies in one plock result that should match a plock_op
+ * on the recv list
+ */
+static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
+ loff_t *ppos)
+{
+ struct dlm_plock_info info;
+ struct plock_op *op;
+
+ if (count != sizeof(info))
+ return -EINVAL;
+
+ if (copy_from_user(&info, u, sizeof(info)))
+ return -EFAULT;
+
+ if (check_version(&info))
+ return -EINVAL;
+
+ spin_lock(&ops_lock);
+ op = plock_op_lookup(&info);
+ if (!op) {
+ spin_unlock(&ops_lock);
pr_debug("%s: no op %x %llx", __func__,
info.fsid, (unsigned long long)info.number);
+ return count;
+ }
+
+ list_del_init(&op->list);
+ /* update set new fields by user space e.g. F_GETLK */
+ memcpy(&op->info, &info, sizeof(info));
+
+ /* check for async handling */
+ if (op->data) {
+ spin_unlock(&ops_lock);
+ dlm_plock_callback(op);
+ } else {
+ /* must be set under ops_lock, because retry in setlkw_wait()
+ * if -ERESTARTSYS.
+ */
+ op->done = 1;
+ spin_unlock(&ops_lock);
+ wake_up(&recv_wq);
+ }
+
return count;
}
--
2.31.1
next prev parent reply other threads:[~2023-05-24 17:19 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-24 17:19 [Cluster-devel] [PATCH dlm/next 1/2] fs: dlm: plock debugfs to check for pending operations Alexander Aring
2023-05-24 17:19 ` Alexander Aring [this message]
-- strict thread matches above, loose matches on Subject: below --
2023-05-19 15:23 Alexander Aring
2023-05-19 15:23 ` [Cluster-devel] [PATCH dlm/next 2/2] fs: dlm: cleanup plock op lookup functionality Alexander Aring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230524171932.1132564-2-aahringo@redhat.com \
--to=aahringo@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).