mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.com>
To: Oleg Drokin <oleg.drokin@intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	James Simmons <jsimmons@infradead.org>,
	Andreas Dilger <andreas.dilger@intel.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Lustre Development List <lustre-devel@lists.lustre.org>
Subject: [PATCH 13/30] staging: lustre: replace libcfs_register_ioctl with a blocking notifier_chain
Date: Mon, 21 May 2018 14:35:12 +1000	[thread overview]
Message-ID: <152687731283.24196.5413466102459843186.stgit@noble> (raw)
In-Reply-To: <152687724799.24196.7718555295926047576.stgit@noble>

libcfs allows other modules to register handlers for ioctls.
The implementation it uses for this is nearly identical to a
blocking notifier chain, so change to use that.

The biggest difference is that the return value from notifier has a
defined format, where libcfs_register_ioctl uses -EINVAL to mean
"continue".  This requires a little bit of conversion.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 .../staging/lustre/include/linux/libcfs/libcfs.h   |   19 ++----
 drivers/staging/lustre/lnet/libcfs/module.c        |   64 ++++----------------
 drivers/staging/lustre/lnet/lnet/module.c          |   38 ++++++++----
 drivers/staging/lustre/lnet/selftest/conctl.c      |   27 +++++---
 drivers/staging/lustre/lnet/selftest/console.c     |   10 ++-
 drivers/staging/lustre/lnet/selftest/console.h     |    3 +
 6 files changed, 70 insertions(+), 91 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index d9002e7424d4..63ea0e99ec58 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -93,19 +93,14 @@
 #define LNET_ACCEPTOR_MIN_RESERVED_PORT    512
 #define LNET_ACCEPTOR_MAX_RESERVED_PORT    1023
 
-struct libcfs_ioctl_handler {
-	struct list_head item;
-	int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
-};
-
-#define DECLARE_IOCTL_HANDLER(ident, func)			\
-	struct libcfs_ioctl_handler ident = {			\
-		.item		= LIST_HEAD_INIT(ident.item),	\
-		.handle_ioctl	= func				\
-	}
+extern struct blocking_notifier_head libcfs_ioctl_list;
+static inline int notifier_from_ioctl_errno(int err)
+{
+	if (err == -EINVAL)
+		return NOTIFY_OK;
+	return notifier_from_errno(err) | NOTIFY_STOP_MASK;
+}
 
-int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
-int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
 int libcfs_setup(void);
 
 #define _LIBCFS_H
diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c
index 3e51aae751c5..b3a7c1a912ba 100644
--- a/drivers/staging/lustre/lnet/libcfs/module.c
+++ b/drivers/staging/lustre/lnet/libcfs/module.c
@@ -62,38 +62,8 @@
 
 static struct dentry *lnet_debugfs_root;
 
-static DECLARE_RWSEM(ioctl_list_sem);
-static LIST_HEAD(ioctl_list);
-
-int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
-{
-	int rc = 0;
-
-	down_write(&ioctl_list_sem);
-	if (!list_empty(&hand->item))
-		rc = -EBUSY;
-	else
-		list_add_tail(&hand->item, &ioctl_list);
-	up_write(&ioctl_list_sem);
-
-	return rc;
-}
-EXPORT_SYMBOL(libcfs_register_ioctl);
-
-int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
-{
-	int rc = 0;
-
-	down_write(&ioctl_list_sem);
-	if (list_empty(&hand->item))
-		rc = -ENOENT;
-	else
-		list_del_init(&hand->item);
-	up_write(&ioctl_list_sem);
-
-	return rc;
-}
-EXPORT_SYMBOL(libcfs_deregister_ioctl);
+BLOCKING_NOTIFIER_HEAD(libcfs_ioctl_list);
+EXPORT_SYMBOL(libcfs_ioctl_list);
 
 static inline size_t libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
 {
@@ -268,24 +238,18 @@ static int libcfs_ioctl(unsigned long cmd, void __user *uparam)
 		libcfs_debug_mark_buffer(data->ioc_inlbuf1);
 		break;
 
-	default: {
-		struct libcfs_ioctl_handler *hand;
-
-		err = -EINVAL;
-		down_read(&ioctl_list_sem);
-		list_for_each_entry(hand, &ioctl_list, item) {
-			err = hand->handle_ioctl(cmd, hdr);
-			if (err == -EINVAL)
-				continue;
-
-			if (!err) {
-				if (copy_to_user(uparam, hdr, hdr->ioc_len))
-					err = -EFAULT;
-			}
-			break;
-		}
-		up_read(&ioctl_list_sem);
-		break; }
+	default:
+		err = blocking_notifier_call_chain(&libcfs_ioctl_list,
+						   cmd, hdr);
+		if (!(err & NOTIFY_STOP_MASK))
+			/* No-one claimed the ioctl */
+			err = -EINVAL;
+		else
+			err = notifier_to_errno(err);
+		if (!err)
+			if (copy_to_user(uparam, hdr, hdr->ioc_len))
+				err = -EFAULT;
+		break;
 	}
 out:
 	kvfree(hdr);
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c
index f6e912e79ca7..9d06664f0c17 100644
--- a/drivers/staging/lustre/lnet/lnet/module.c
+++ b/drivers/staging/lustre/lnet/lnet/module.c
@@ -136,30 +136,37 @@ lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr)
 }
 
 static int
-lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
+lnet_ioctl(struct notifier_block *nb,
+	   unsigned long cmd, void *vdata)
 {
 	int rc;
+	struct libcfs_ioctl_hdr *hdr = vdata;
 
 	switch (cmd) {
 	case IOC_LIBCFS_CONFIGURE: {
 		struct libcfs_ioctl_data *data =
 			(struct libcfs_ioctl_data *)hdr;
 
-		if (data->ioc_hdr.ioc_len < sizeof(*data))
-			return -EINVAL;
-
-		the_lnet.ln_nis_from_mod_params = data->ioc_flags;
-		return lnet_configure(NULL);
+		if (data->ioc_hdr.ioc_len < sizeof(*data)) {
+			rc = -EINVAL;
+		} else {
+			the_lnet.ln_nis_from_mod_params = data->ioc_flags;
+			rc = lnet_configure(NULL);
+		}
+		break;
 	}
 
 	case IOC_LIBCFS_UNCONFIGURE:
-		return lnet_unconfigure();
+		rc = lnet_unconfigure();
+		break;
 
 	case IOC_LIBCFS_ADD_NET:
-		return lnet_dyn_configure(hdr);
+		rc = lnet_dyn_configure(hdr);
+		break;
 
 	case IOC_LIBCFS_DEL_NET:
-		return lnet_dyn_unconfigure(hdr);
+		rc = lnet_dyn_unconfigure(hdr);
+		break;
 
 	default:
 		/*
@@ -172,11 +179,14 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
 			rc = LNetCtl(cmd, hdr);
 			LNetNIFini();
 		}
-		return rc;
+		break;
 	}
+	return notifier_from_ioctl_errno(rc);
 }
 
-static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
+static struct notifier_block lnet_ioctl_handler = {
+	.notifier_call = lnet_ioctl,
+};
 
 static int __init lnet_init(void)
 {
@@ -194,7 +204,8 @@ static int __init lnet_init(void)
 		return rc;
 	}
 
-	rc = libcfs_register_ioctl(&lnet_ioctl_handler);
+	rc = blocking_notifier_chain_register(&libcfs_ioctl_list,
+					      &lnet_ioctl_handler);
 	LASSERT(!rc);
 
 	if (config_on_load) {
@@ -212,7 +223,8 @@ static void __exit lnet_exit(void)
 {
 	int rc;
 
-	rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
+	rc = blocking_notifier_chain_unregister(&libcfs_ioctl_list,
+						&lnet_ioctl_handler);
 	LASSERT(!rc);
 
 	lnet_lib_exit();
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index a2d8092bdeb7..f22b01e390d3 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -680,32 +680,34 @@ static int lst_test_add_ioctl(struct lstio_test_args *args)
 }
 
 int
-lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
+lstcon_ioctl_entry(struct notifier_block *nb,
+		   unsigned long cmd, void *vdata)
 {
-	char *buf;
+	struct libcfs_ioctl_hdr *hdr = vdata;
+	char *buf = NULL;
 	struct libcfs_ioctl_data *data;
 	int opc;
-	int rc;
+	int rc = -EINVAL;
 
 	if (cmd != IOC_LIBCFS_LNETST)
-		return -EINVAL;
+		goto err;
 
 	data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
 
 	opc = data->ioc_u32[0];
 
 	if (data->ioc_plen1 > PAGE_SIZE)
-		return -EINVAL;
+		goto err;
 
 	buf = kmalloc(data->ioc_plen1, GFP_KERNEL);
+	rc = -ENOMEM;
 	if (!buf)
-		return -ENOMEM;
+		goto err;
 
 	/* copy in parameter */
-	if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
-		kfree(buf);
-		return -EFAULT;
-	}
+	rc = -EFAULT;
+	if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1))
+		goto err;
 
 	mutex_lock(&console_session.ses_mutex);
 
@@ -785,6 +787,7 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
 		break;
 	default:
 		rc = -EINVAL;
+		goto out;
 	}
 
 	if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
@@ -792,8 +795,8 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
 		rc = -EFAULT;
 out:
 	mutex_unlock(&console_session.ses_mutex);
-
+err:
 	kfree(buf);
 
-	return rc;
+	return notifier_from_ioctl_errno(rc);
 }
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 1889f1e86473..9fd6013354c6 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -1996,7 +1996,9 @@ static void lstcon_init_acceptor_service(void)
 	lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;
 }
 
-static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
+static struct notifier_block lstcon_ioctl_handler = {
+	.notifier_call = lstcon_ioctl_entry,
+};
 
 /* initialize console */
 int
@@ -2048,7 +2050,8 @@ lstcon_console_init(void)
 		goto out;
 	}
 
-	rc = libcfs_register_ioctl(&lstcon_ioctl_handler);
+	rc = blocking_notifier_chain_register(&libcfs_ioctl_list,
+					      &lstcon_ioctl_handler);
 
 	if (!rc) {
 		lstcon_rpc_module_init();
@@ -2071,7 +2074,8 @@ lstcon_console_fini(void)
 {
 	int i;
 
-	libcfs_deregister_ioctl(&lstcon_ioctl_handler);
+	blocking_notifier_chain_unregister(&libcfs_ioctl_list,
+					   &lstcon_ioctl_handler);
 
 	mutex_lock(&console_session.ses_mutex);
 
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h
index 3933ed4cca93..d65b8d942bac 100644
--- a/drivers/staging/lustre/lnet/selftest/console.h
+++ b/drivers/staging/lustre/lnet/selftest/console.h
@@ -187,7 +187,8 @@ lstcon_id2hash(struct lnet_process_id id, struct list_head *hash)
 	return &hash[idx];
 }
 
-int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
+int lstcon_ioctl_entry(struct notifier_block *nb,
+		       unsigned long cmd, void *vdata);
 int lstcon_console_init(void);
 int lstcon_console_fini(void);
 int lstcon_session_match(struct lst_sid sid);

  parent reply	other threads:[~2018-05-21  4:39 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-21  4:35 [PATCH 00/30] staging: lustre: tidy up - module init and includes NeilBrown
2018-05-21  4:35 ` [PATCH 04/30] staging: lustre: rename cfs_cpt_table to cfs_cpt_tab NeilBrown
2018-05-21  4:35 ` [PATCH 10/30] staging: lustre: discard CFS_TICK NeilBrown
2018-05-21  4:35 ` [PATCH 05/30] staging: lustre: remove conditional compilation from libcfs_cpu.c NeilBrown
2018-05-21  4:35 ` [PATCH 06/30] staging: lustre: remove current_pid() and current_comm() NeilBrown
2018-05-21  4:35 ` [PATCH 02/30] staging: lustre: refactor libcfs initialization NeilBrown
2018-05-21  4:35 ` [PATCH 14/30] staging: lustre: clean up __LIBCFS_H macro NeilBrown
2018-05-21  4:35 ` [PATCH 16/30] staging: lustre: move lnet_debug_log_upcall declaration to tracefile.h NeilBrown
2018-05-21  4:35 ` [PATCH 15/30] staging: lustre: make lnet_debugfs_symlink_def local to libcfs/modules.c NeilBrown
2018-05-21  4:35 ` [PATCH 01/30] staging: lustre: osc: tidy up osc_init() NeilBrown
2018-05-21  4:35 ` [PATCH 07/30] staging: lustre: simplify capability dropping NeilBrown
2018-05-21  4:35 ` NeilBrown [this message]
2018-05-21 16:06   ` [lustre-devel] [PATCH 13/30] staging: lustre: replace libcfs_register_ioctl with a blocking notifier_chain Patrick Farrell
2018-05-22 21:06     ` NeilBrown
2018-05-21  4:35 ` [PATCH 09/30] staging: lustre: discard LOWEST_BIT_SET() NeilBrown
2018-05-21  4:35 ` [PATCH 03/30] staging: lustre: move files out of lustre/lnet/libcfs/linux/ NeilBrown
2018-05-21  4:35 ` [PATCH 12/30] staging: lustre: discard cfs_block_sigsinv() NeilBrown
2018-05-21  4:35 ` [PATCH 08/30] staging: lustre: discard cfs_cap_t, use kernel_cap_t NeilBrown
2018-05-21  4:35 ` [PATCH 11/30] staging: lustre: move LERRCHKSUM() to libcfs_debug.h NeilBrown
2018-05-21  4:35 ` [PATCH 19/30] staging: lustre: discard libcfs_prim.h NeilBrown
2018-05-21  4:35 ` [PATCH 23/30] staging: lustre: remove libcfs_all.h from includes lustre/lnet NeilBrown
2018-05-21  4:35 ` [PATCH 17/30] staging: lustre: move RESV_PORT definitions to lnet/lib-lnet.h NeilBrown
2018-05-21  4:35 ` [PATCH 24/30] staging: lustre: remove libcfs_all.h from lustre/include/*.h NeilBrown
2018-05-21  4:35 ` [PATCH 30/30] staging: lustre: remove libcfs_all.h NeilBrown
2018-05-21  4:35 ` [PATCH 25/30] staging: lustre: remove libcfs_all.h from remaining .h files NeilBrown
2018-05-21  4:35 ` [PATCH 28/30] staging: lustre: remove remaining libcfs_all.h includes from lustre/lustre NeilBrown
2018-05-21  4:35 ` [PATCH 27/30] staging: lustre: remove libcfs_all.h from fid, fld, obdclass NeilBrown
2018-05-21  4:35 ` [PATCH 26/30] staging: lustre: remove libcfs_all from ptlrpc NeilBrown
2018-05-21  4:35 ` [PATCH 18/30] staging: lustre: replace memory_presure funcitons by standard interfaces NeilBrown
2018-05-21  4:35 ` [PATCH 29/30] staging: lustre: move all libcfs_all includes except in lustre/lnet/libcfs/ NeilBrown
2018-05-21  4:35 ` [PATCH 21/30] staging: lustre: don't include libcfs.h in lnet/lib-lnet.h NeilBrown
2018-05-21  4:35 ` [PATCH 22/30] staging: lustre: remove libcfs_all.h includes from lnet/klnd NeilBrown
2018-05-21  4:35 ` [PATCH 20/30] staging: lustre: start moving includes out of libcfs.h NeilBrown

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=152687731283.24196.5413466102459843186.stgit@noble \
    --to=neilb@suse.com \
    --cc=andreas.dilger@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jsimmons@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lustre-devel@lists.lustre.org \
    --cc=oleg.drokin@intel.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

all inboxes | Powered by JetHome®