<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body>
<br>
Just going through these (thank you, Neal, for more excellent cleanup work), and this one stands out as one someone should look over a bit.  I can do it later if no one who’s familiar with this wants to, but I wanted to highlight it.<br>
<br>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> lustre-devel <lustre-devel-bounces@lists.lustre.org> on behalf of NeilBrown <neilb@suse.com><br>
<b>Sent:</b> Sunday, May 20, 2018 11:35:12 PM<br>
<b>To:</b> Oleg Drokin; Greg Kroah-Hartman; James Simmons; Andreas Dilger<br>
<b>Cc:</b> Linux Kernel Mailing List; Lustre Development List<br>
<b>Subject:</b> [lustre-devel] [PATCH 13/30] staging: lustre: replace libcfs_register_ioctl with a blocking notifier_chain</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">libcfs allows other modules to register handlers for ioctls.<br>
The implementation it uses for this is nearly identical to a<br>
blocking notifier chain, so change to use that.<br>
<br>
The biggest difference is that the return value from notifier has a<br>
defined format, where libcfs_register_ioctl uses -EINVAL to mean<br>
"continue".  This requires a little bit of conversion.<br>
<br>
Signed-off-by: NeilBrown <neilb@suse.com><br>
---<br>
 .../staging/lustre/include/linux/libcfs/libcfs.h   |   19 ++----<br>
 drivers/staging/lustre/lnet/libcfs/module.c        |   64 ++++----------------<br>
 drivers/staging/lustre/lnet/lnet/module.c          |   38 ++++++++----<br>
 drivers/staging/lustre/lnet/selftest/conctl.c      |   27 +++++---<br>
 drivers/staging/lustre/lnet/selftest/console.c     |   10 ++-<br>
 drivers/staging/lustre/lnet/selftest/console.h     |    3 +<br>
 6 files changed, 70 insertions(+), 91 deletions(-)<br>
<br>
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h<br>
index d9002e7424d4..63ea0e99ec58 100644<br>
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h<br>
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h<br>
@@ -93,19 +93,14 @@<br>
 #define LNET_ACCEPTOR_MIN_RESERVED_PORT    512<br>
 #define LNET_ACCEPTOR_MAX_RESERVED_PORT    1023<br>
 <br>
-struct libcfs_ioctl_handler {<br>
-       struct list_head item;<br>
-       int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);<br>
-};<br>
-<br>
-#define DECLARE_IOCTL_HANDLER(ident, func)                     \<br>
-       struct libcfs_ioctl_handler ident = {                   \<br>
-               .item           = LIST_HEAD_INIT(ident.item),   \<br>
-               .handle_ioctl   = func                          \<br>
-       }<br>
+extern struct blocking_notifier_head libcfs_ioctl_list;<br>
+static inline int notifier_from_ioctl_errno(int err)<br>
+{<br>
+       if (err == -EINVAL)<br>
+               return NOTIFY_OK;<br>
+       return notifier_from_errno(err) | NOTIFY_STOP_MASK;<br>
+}<br>
 <br>
-int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);<br>
-int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);<br>
 int libcfs_setup(void);<br>
 <br>
 #define _LIBCFS_H<br>
diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c<br>
index 3e51aae751c5..b3a7c1a912ba 100644<br>
--- a/drivers/staging/lustre/lnet/libcfs/module.c<br>
+++ b/drivers/staging/lustre/lnet/libcfs/module.c<br>
@@ -62,38 +62,8 @@<br>
 <br>
 static struct dentry *lnet_debugfs_root;<br>
 <br>
-static DECLARE_RWSEM(ioctl_list_sem);<br>
-static LIST_HEAD(ioctl_list);<br>
-<br>
-int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)<br>
-{<br>
-       int rc = 0;<br>
-<br>
-       down_write(&ioctl_list_sem);<br>
-       if (!list_empty(&hand->item))<br>
-               rc = -EBUSY;<br>
-       else<br>
-               list_add_tail(&hand->item, &ioctl_list);<br>
-       up_write(&ioctl_list_sem);<br>
-<br>
-       return rc;<br>
-}<br>
-EXPORT_SYMBOL(libcfs_register_ioctl);<br>
-<br>
-int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)<br>
-{<br>
-       int rc = 0;<br>
-<br>
-       down_write(&ioctl_list_sem);<br>
-       if (list_empty(&hand->item))<br>
-               rc = -ENOENT;<br>
-       else<br>
-               list_del_init(&hand->item);<br>
-       up_write(&ioctl_list_sem);<br>
-<br>
-       return rc;<br>
-}<br>
-EXPORT_SYMBOL(libcfs_deregister_ioctl);<br>
+BLOCKING_NOTIFIER_HEAD(libcfs_ioctl_list);<br>
+EXPORT_SYMBOL(libcfs_ioctl_list);<br>
 <br>
 static inline size_t libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)<br>
 {<br>
@@ -268,24 +238,18 @@ static int libcfs_ioctl(unsigned long cmd, void __user *uparam)<br>
                 libcfs_debug_mark_buffer(data->ioc_inlbuf1);<br>
                 break;<br>
 <br>
-       default: {<br>
-               struct libcfs_ioctl_handler *hand;<br>
-<br>
-               err = -EINVAL;<br>
-               down_read(&ioctl_list_sem);<br>
-               list_for_each_entry(hand, &ioctl_list, item) {<br>
-                       err = hand->handle_ioctl(cmd, hdr);<br>
-                       if (err == -EINVAL)<br>
-                               continue;<br>
-<br>
-                       if (!err) {<br>
-                               if (copy_to_user(uparam, hdr, hdr->ioc_len))<br>
-                                       err = -EFAULT;<br>
-                       }<br>
-                       break;<br>
-               }<br>
-               up_read(&ioctl_list_sem);<br>
-               break; }<br>
+       default:<br>
+               err = blocking_notifier_call_chain(&libcfs_ioctl_list,<br>
+                                                  cmd, hdr);<br>
+               if (!(err & NOTIFY_STOP_MASK))<br>
+                       /* No-one claimed the ioctl */<br>
+                       err = -EINVAL;<br>
+               else<br>
+                       err = notifier_to_errno(err);<br>
+               if (!err)<br>
+                       if (copy_to_user(uparam, hdr, hdr->ioc_len))<br>
+                               err = -EFAULT;<br>
+               break;<br>
         }<br>
 out:<br>
         kvfree(hdr);<br>
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c<br>
index f6e912e79ca7..9d06664f0c17 100644<br>
--- a/drivers/staging/lustre/lnet/lnet/module.c<br>
+++ b/drivers/staging/lustre/lnet/lnet/module.c<br>
@@ -136,30 +136,37 @@ lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr)<br>
 }<br>
 <br>
 static int<br>
-lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)<br>
+lnet_ioctl(struct notifier_block *nb,<br>
+          unsigned long cmd, void *vdata)<br>
 {<br>
         int rc;<br>
+       struct libcfs_ioctl_hdr *hdr = vdata;<br>
 <br>
         switch (cmd) {<br>
         case IOC_LIBCFS_CONFIGURE: {<br>
                 struct libcfs_ioctl_data *data =<br>
                         (struct libcfs_ioctl_data *)hdr;<br>
 <br>
-               if (data->ioc_hdr.ioc_len < sizeof(*data))<br>
-                       return -EINVAL;<br>
-<br>
-               the_lnet.ln_nis_from_mod_params = data->ioc_flags;<br>
-               return lnet_configure(NULL);<br>
+               if (data->ioc_hdr.ioc_len < sizeof(*data)) {<br>
+                       rc = -EINVAL;<br>
+               } else {<br>
+                       the_lnet.ln_nis_from_mod_params = data->ioc_flags;<br>
+                       rc = lnet_configure(NULL);<br>
+               }<br>
+               break;<br>
         }<br>
 <br>
         case IOC_LIBCFS_UNCONFIGURE:<br>
-               return lnet_unconfigure();<br>
+               rc = lnet_unconfigure();<br>
+               break;<br>
 <br>
         case IOC_LIBCFS_ADD_NET:<br>
-               return lnet_dyn_configure(hdr);<br>
+               rc = lnet_dyn_configure(hdr);<br>
+               break;<br>
 <br>
         case IOC_LIBCFS_DEL_NET:<br>
-               return lnet_dyn_unconfigure(hdr);<br>
+               rc = lnet_dyn_unconfigure(hdr);<br>
+               break;<br>
 <br>
         default:<br>
                 /*<br>
@@ -172,11 +179,14 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)<br>
                         rc = LNetCtl(cmd, hdr);<br>
                         LNetNIFini();<br>
                 }<br>
-               return rc;<br>
+               break;<br>
         }<br>
+       return notifier_from_ioctl_errno(rc);<br>
 }<br>
 <br>
-static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);<br>
+static struct notifier_block lnet_ioctl_handler = {<br>
+       .notifier_call = lnet_ioctl,<br>
+};<br>
 <br>
 static int __init lnet_init(void)<br>
 {<br>
@@ -194,7 +204,8 @@ static int __init lnet_init(void)<br>
                 return rc;<br>
         }<br>
 <br>
-       rc = libcfs_register_ioctl(&lnet_ioctl_handler);<br>
+       rc = blocking_notifier_chain_register(&libcfs_ioctl_list,<br>
+                                             &lnet_ioctl_handler);<br>
         LASSERT(!rc);<br>
 <br>
         if (config_on_load) {<br>
@@ -212,7 +223,8 @@ static void __exit lnet_exit(void)<br>
 {<br>
         int rc;<br>
 <br>
-       rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);<br>
+       rc = blocking_notifier_chain_unregister(&libcfs_ioctl_list,<br>
+                                               &lnet_ioctl_handler);<br>
         LASSERT(!rc);<br>
 <br>
         lnet_lib_exit();<br>
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c<br>
index a2d8092bdeb7..f22b01e390d3 100644<br>
--- a/drivers/staging/lustre/lnet/selftest/conctl.c<br>
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c<br>
@@ -680,32 +680,34 @@ static int lst_test_add_ioctl(struct lstio_test_args *args)<br>
 }<br>
 <br>
 int<br>
-lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)<br>
+lstcon_ioctl_entry(struct notifier_block *nb,<br>
+                  unsigned long cmd, void *vdata)<br>
 {<br>
-       char *buf;<br>
+       struct libcfs_ioctl_hdr *hdr = vdata;<br>
+       char *buf = NULL;<br>
         struct libcfs_ioctl_data *data;<br>
         int opc;<br>
-       int rc;<br>
+       int rc = -EINVAL;<br>
 <br>
         if (cmd != IOC_LIBCFS_LNETST)<br>
-               return -EINVAL;<br>
+               goto err;<br>
 <br>
         data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);<br>
 <br>
         opc = data->ioc_u32[0];<br>
 <br>
         if (data->ioc_plen1 > PAGE_SIZE)<br>
-               return -EINVAL;<br>
+               goto err;<br>
 <br>
         buf = kmalloc(data->ioc_plen1, GFP_KERNEL);<br>
+       rc = -ENOMEM;<br>
         if (!buf)<br>
-               return -ENOMEM;<br>
+               goto err;<br>
 <br>
         /* copy in parameter */<br>
-       if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {<br>
-               kfree(buf);<br>
-               return -EFAULT;<br>
-       }<br>
+       rc = -EFAULT;<br>
+       if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1))<br>
+               goto err;<br>
 <br>
         mutex_lock(&console_session.ses_mutex);<br>
 <br>
@@ -785,6 +787,7 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)<br>
                 break;<br>
         default:<br>
                 rc = -EINVAL;<br>
+               goto out;<br>
         }<br>
 <br>
         if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,<br>
@@ -792,8 +795,8 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)<br>
                 rc = -EFAULT;<br>
 out:<br>
         mutex_unlock(&console_session.ses_mutex);<br>
-<br>
+err:<br>
         kfree(buf);<br>
 <br>
-       return rc;<br>
+       return notifier_from_ioctl_errno(rc);<br>
 }<br>
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c<br>
index 1889f1e86473..9fd6013354c6 100644<br>
--- a/drivers/staging/lustre/lnet/selftest/console.c<br>
+++ b/drivers/staging/lustre/lnet/selftest/console.c<br>
@@ -1996,7 +1996,9 @@ static void lstcon_init_acceptor_service(void)<br>
         lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;<br>
 }<br>
 <br>
-static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);<br>
+static struct notifier_block lstcon_ioctl_handler = {<br>
+       .notifier_call = lstcon_ioctl_entry,<br>
+};<br>
 <br>
 /* initialize console */<br>
 int<br>
@@ -2048,7 +2050,8 @@ lstcon_console_init(void)<br>
                 goto out;<br>
         }<br>
 <br>
-       rc = libcfs_register_ioctl(&lstcon_ioctl_handler);<br>
+       rc = blocking_notifier_chain_register(&libcfs_ioctl_list,<br>
+                                             &lstcon_ioctl_handler);<br>
 <br>
         if (!rc) {<br>
                 lstcon_rpc_module_init();<br>
@@ -2071,7 +2074,8 @@ lstcon_console_fini(void)<br>
 {<br>
         int i;<br>
 <br>
-       libcfs_deregister_ioctl(&lstcon_ioctl_handler);<br>
+       blocking_notifier_chain_unregister(&libcfs_ioctl_list,<br>
+                                          &lstcon_ioctl_handler);<br>
 <br>
         mutex_lock(&console_session.ses_mutex);<br>
 <br>
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h<br>
index 3933ed4cca93..d65b8d942bac 100644<br>
--- a/drivers/staging/lustre/lnet/selftest/console.h<br>
+++ b/drivers/staging/lustre/lnet/selftest/console.h<br>
@@ -187,7 +187,8 @@ lstcon_id2hash(struct lnet_process_id id, struct list_head *hash)<br>
         return &hash[idx];<br>
 }<br>
 <br>
-int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);<br>
+int lstcon_ioctl_entry(struct notifier_block *nb,<br>
+                      unsigned long cmd, void *vdata);<br>
 int lstcon_console_init(void);<br>
 int lstcon_console_fini(void);<br>
 int lstcon_session_match(struct lst_sid sid);<br>
<br>
<br>
_______________________________________________<br>
lustre-devel mailing list<br>
lustre-devel@lists.lustre.org<br>
<a href="http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org">http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org</a><br>
</div>
</span></font></div>
</body>
</html>