RDMA/rnbd: Fix compilation error when CONFIG_MODULES is disabled
authorDanil Kipnis <danil.kipnis@cloud.ionos.com>
Thu, 21 May 2020 18:59:09 +0000 (20:59 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 22 May 2020 18:50:22 +0000 (15:50 -0300)
module_is_live function is only defined when CONFIG_MODULES is enabled.
Use try_module_get instead to check whether the module is being removed.

When module unload and manuall unmapping is happening in parallel, we can
try removing the symlink twice: rnbd_client_exit
vs. rnbd_clt_unmap_dev_store.

This is probably not the best way to deal with this race in general, but
for now this fixes the compilation issue when CONFIG_MODULES is disabled
and has no functional impact. Regression tests passed.

Fixes: 1eb54f8f5dd8 ("block/rnbd: client: sysfs interface functions")
Link: https://lore.kernel.org/r/20200521185909.457245-1-danil.kipnis@cloud.ionos.com
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Suggested-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Danil Kipnis <danil.kipnis@cloud.ionos.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/block/rnbd/rnbd-clt-sysfs.c

index a4508fcc7ffe2d7793a8637c5bee25b74e7267f5..4f4474eecadb76b3fa6e4f180a030d70f2695dd4 100644 (file)
@@ -428,12 +428,15 @@ static struct attribute *rnbd_dev_attrs[] = {
 void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev)
 {
        /*
-        * The module_is_live() check is crucial and helps to avoid annoying
-        * sysfs warning raised in sysfs_remove_link(), when the whole sysfs
-        * path was just removed, see rnbd_close_sessions().
+        * The module unload rnbd_client_exit path is racing with unmapping of
+        * the last single device from the sysfs manually
+        * i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because
+        * of sysfs link already was removed already.
         */
-       if (strlen(dev->blk_symlink_name) && module_is_live(THIS_MODULE))
+       if (strlen(dev->blk_symlink_name) && try_module_get(THIS_MODULE)) {
                sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name);
+               module_put(THIS_MODULE);
+       }
 }
 
 static struct kobj_type rnbd_dev_ktype = {