All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Pilcher <arequipeno@gmail.com>
To: linux-block@vger.kernel.org, linux-leds@vger.kernel.org
Cc: axboe@kernel.dk, pavel@ucw.cz, linux-kernel@vger.kernel.org,
	kernelnewbies@kernelnewbies.org,
	Ian Pilcher <arequipeno@gmail.com>
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


WARNING: multiple messages have this Message-ID (diff)
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

  parent reply	other threads:[~2021-07-29  1:54 UTC|newest]

Thread overview: 50+ 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 ` Ian Pilcher
2021-07-29  1:53 ` [RFC PATCH 1/8] docs: Add block device LED trigger documentation Ian Pilcher
2021-07-29  1:53   ` Ian Pilcher
2021-07-29  3:09   ` Valdis Klētnieks
2021-07-29  3:09     ` Valdis Klētnieks
2021-07-29 15:52     ` Ian Pilcher
2021-07-29 15:52       ` Ian Pilcher
2021-07-30  5:22       ` Greg KH
2021-07-30  5:22         ` Greg KH
2021-07-29  5:53   ` Greg KH
2021-07-29  5:53     ` Greg KH
2021-07-29 11:59   ` Marek Behún
2021-07-29 11:59     ` Marek Behún
2021-07-29 18:03     ` Ian Pilcher
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  1:53   ` Ian Pilcher
2021-07-29  3:14   ` Valdis Klētnieks
2021-07-29  3:14     ` Valdis Klētnieks
2021-07-29 15:55     ` Ian Pilcher
2021-07-29 15:55       ` Ian Pilcher
2021-07-29  1:53 ` Ian Pilcher [this message]
2021-07-29  1:53   ` [RFC PATCH 3/8] block: Add kernel APIs to create & delete block device LED triggers Ian Pilcher
2021-07-29  3:45   ` Valdis Klētnieks
2021-07-29  3:45     ` Valdis Klētnieks
2021-07-29 16:16     ` Ian Pilcher
2021-07-29 16:16       ` Ian Pilcher
2021-07-29  5:52   ` Greg KH
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  1:53   ` Ian Pilcher
2021-07-29  5:54   ` Greg KH
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   ` 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   ` 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   ` 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  1:53   ` Ian Pilcher
2021-07-29  8:54 ` [RFC PATCH 0/8] Add configurable block device LED triggers Pavel Machek
2021-07-29  8:54   ` Pavel Machek
2021-07-29 17:03   ` Ian Pilcher
2021-07-29 17:03     ` Ian Pilcher
2021-07-29 18:35     ` Pavel Machek
2021-07-29 18:35       ` Pavel Machek
2021-07-29 19:14       ` Ian Pilcher
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.