From: Ian Pilcher <arequipeno@gmail.com>
To: linux-block@vger.kernel.org, linux-leds@vger.kernel.org
Cc: axboe@kernel.dk, Ian Pilcher <arequipeno@gmail.com>,
linux-kernel@vger.kernel.org, pavel@ucw.cz,
kernelnewbies@kernelnewbies.org
Subject: [RFC PATCH 3/8] block: Add kernel APIs to create & delete block device LED triggers
Date: Wed, 28 Jul 2021 20:53:39 -0500 [thread overview]
Message-ID: <20210729015344.3366750-4-arequipeno@gmail.com> (raw)
In-Reply-To: <20210729015344.3366750-1-arequipeno@gmail.com>
* New file - include/linux/blk-ledtrig.h
Signed-off-by: Ian Pilcher <arequipeno@gmail.com>
---
block/blk-ledtrig.c | 152 ++++++++++++++++++++++++++++++++++++
include/linux/blk-ledtrig.h | 19 +++++
2 files changed, 171 insertions(+)
create mode 100644 include/linux/blk-ledtrig.h
diff --git a/block/blk-ledtrig.c b/block/blk-ledtrig.c
index 345a3b6bdbc6..c69ea1539336 100644
--- a/block/blk-ledtrig.c
+++ b/block/blk-ledtrig.c
@@ -6,9 +6,11 @@
* Copyright 2021 Ian Pilcher <arequipeno@gmail.com>
*/
+#include <linux/blk-ledtrig.h>
#include <linux/leds.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
/*
@@ -49,3 +51,153 @@ static struct blk_ledtrig *blk_ledtrig_find(const char *const name,
return NULL;
}
+
+
+/*
+ *
+ * Create a new trigger
+ *
+ */
+
+static int __blk_ledtrig_create(const char *const name, const size_t len)
+{
+ struct blk_ledtrig *t;
+ int ret;
+
+ if (len == 0) {
+ pr_warn("empty name specified for blockdev LED trigger\n");
+ ret = -EINVAL;
+ goto create_exit_return;
+ }
+
+ ret = mutex_lock_interruptible(&blk_ledtrig_list_mutex);
+ if (unlikely(ret != 0))
+ goto create_exit_return;
+
+ if (blk_ledtrig_find(name, len) != NULL) {
+ pr_warn("blockdev LED trigger named %.*s already exists\n",
+ (int)len, name);
+ ret = -EEXIST;
+ goto create_exit_unlock_list;
+ }
+
+ t = kzalloc(sizeof(*t) + len + 1, GFP_KERNEL);
+ if (unlikely(t == NULL)) {
+ ret = -ENOMEM;
+ goto create_exit_unlock_list;
+ }
+
+ memcpy(t->name, name, len);
+ t->trigger.name = t->name;
+ mutex_init(&t->refcount_mutex);
+
+ ret = led_trigger_register(&t->trigger);
+ if (ret != 0) {
+ if (likely(ret == -EEXIST)) {
+ pr_warn("LED trigger named %.*s already exists\n",
+ (int)len, name);
+ }
+ goto create_exit_free;
+ }
+
+ list_add(&t->list_node, &blk_ledtrig_list);
+ ret = 0;
+
+create_exit_free:
+ if (ret != 0)
+ kfree(t);
+create_exit_unlock_list:
+ mutex_unlock(&blk_ledtrig_list_mutex);
+create_exit_return:
+ return ret;
+}
+
+/**
+ * blk_ledtrig_create() - creates a new block device LED trigger
+ * @name: the name of the new trigger
+ *
+ * Context: Process context (can sleep). Takes and releases
+ * @blk_ledtrig_list_mutex.
+ *
+ * Return: 0 on success; -@errno on error
+ */
+int blk_ledtrig_create(const char *const name)
+{
+ return __blk_ledtrig_create(name, strlen(name));
+}
+EXPORT_SYMBOL_GPL(blk_ledtrig_create);
+
+
+/*
+ *
+ * Delete a trigger
+ *
+ */
+
+static int __blk_ledtrig_delete(const char *const name, const size_t len)
+{
+ struct blk_ledtrig *t;
+ int ret;
+
+ if (len == 0) {
+ pr_warn("empty name specified for blockdev LED trigger\n");
+ ret = -EINVAL;
+ goto delete_exit_return;
+ }
+
+ ret = mutex_lock_interruptible(&blk_ledtrig_list_mutex);
+ if (unlikely(ret != 0))
+ goto delete_exit_return;
+
+ t = blk_ledtrig_find(name, len);
+ if (t == NULL) {
+ pr_warn("blockdev LED trigger named %.*s doesn't exist\n",
+ (int)len, name);
+ ret = -ENODEV;
+ goto delete_exit_unlock_list;
+ }
+
+ ret = mutex_lock_interruptible(&t->refcount_mutex);
+ if (unlikely(ret != 0))
+ goto delete_exit_unlock_list;
+
+ if (WARN_ON(t->refcount < 0)) {
+ ret = -EBADFD;
+ goto delete_exit_unlock_refcount;
+ }
+
+ if (t->refcount > 0) {
+ pr_warn("blockdev LED trigger %s still in use\n", t->name);
+ ret = -EBUSY;
+ goto delete_exit_unlock_refcount;
+ }
+
+ led_trigger_unregister(&t->trigger);
+ list_del(&t->list_node);
+
+ ret = 0;
+
+delete_exit_unlock_refcount:
+ mutex_unlock(&t->refcount_mutex);
+ if (ret == 0)
+ kfree(t);
+delete_exit_unlock_list:
+ mutex_unlock(&blk_ledtrig_list_mutex);
+delete_exit_return:
+ return ret;
+}
+
+/**
+ * blk_ledtrig_delete() - deletes a block device LED trigger
+ * @name: the name of the trigger to be deleted
+ *
+ * Context: Process context (can sleep). Takes and releases
+ * @blk_ledtrig_list_mutex and trigger's @refcount_mutex.
+ *
+ * Return: 0 on success; -@errno on error
+ */
+int blk_ledtrig_delete(const char *const name)
+{
+ return __blk_ledtrig_delete(name, strlen(name));
+}
+EXPORT_SYMBOL_GPL(blk_ledtrig_delete);
diff --git a/include/linux/blk-ledtrig.h b/include/linux/blk-ledtrig.h
new file mode 100644
index 000000000000..6f73635f65ec
--- /dev/null
+++ b/include/linux/blk-ledtrig.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Block device LED triggers
+ *
+ * Copyright 2021 Ian Pilcher <arequipeno@gmail.com>
+ */
+
+#ifndef _LINUX_BLK_LEDTRIG_H
+#define _LINUX_BLK_LEDTRIG_H
+
+#ifdef CONFIG_BLK_LED_TRIGGERS
+
+int blk_ledtrig_create(const char *name);
+int blk_ledtrig_delete(const char *name);
+
+#endif // CONFIG_BLK_LED_TRIGGERS
+
+#endif // _LINUX_BLK_LEDTRIG_H
--
2.31.1
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
next prev parent reply other threads:[~2021-07-29 1:56 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-29 1:53 [RFC PATCH 0/8] Add configurable block device LED triggers Ian Pilcher
2021-07-29 1:53 ` [RFC PATCH 1/8] docs: Add block device LED trigger documentation Ian Pilcher
2021-07-29 3:09 ` Valdis Klētnieks
2021-07-29 15:52 ` Ian Pilcher
2021-07-30 5:22 ` Greg KH
2021-07-29 5:53 ` Greg KH
2021-07-29 11:59 ` Marek Behún
2021-07-29 18:03 ` Ian Pilcher
2021-07-29 1:53 ` [RFC PATCH 2/8] block: Add block device LED trigger list Ian Pilcher
2021-07-29 3:14 ` Valdis Klētnieks
2021-07-29 15:55 ` Ian Pilcher
2021-07-29 1:53 ` Ian Pilcher [this message]
2021-07-29 3:45 ` [RFC PATCH 3/8] block: Add kernel APIs to create & delete block device LED triggers Valdis Klētnieks
2021-07-29 16:16 ` Ian Pilcher
2021-07-29 5:52 ` Greg KH
2021-07-29 1:53 ` [RFC PATCH 4/8] block: Add block class attributes to manage LED trigger list Ian Pilcher
2021-07-29 5:54 ` Greg KH
2021-07-29 1:53 ` [RFC PATCH 5/8] block: Add block device LED trigger info to struct genhd Ian Pilcher
2021-07-29 1:53 ` [RFC PATCH 6/8] block: Add kernel APIs to set & clear per-block device LED triggers Ian Pilcher
2021-07-29 1:53 ` [RFC PATCH 7/8] block: Add block device attributes to set & clear " Ian Pilcher
2021-07-29 1:53 ` [RFC PATCH 8/8] block: Blink device LED when request is sent to low-level driver Ian Pilcher
2021-07-29 8:54 ` [RFC PATCH 0/8] Add configurable block device LED triggers Pavel Machek
2021-07-29 17:03 ` Ian Pilcher
2021-07-29 18:35 ` Pavel Machek
2021-07-29 19:14 ` Ian Pilcher
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=20210729015344.3366750-4-arequipeno@gmail.com \
--to=arequipeno@gmail.com \
--cc=axboe@kernel.dk \
--cc=kernelnewbies@kernelnewbies.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=pavel@ucw.cz \
/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 NNTP newsgroup(s).