Upon call of device_destroy_namespace we walk over namespace devices
looking for one which match on both device maj/min and VE itself,
but the thing is that if device belong to another VE we continue
iteration with never released get_device call.

Thus rework device_destroy_namespace (thanks to vdavydov@
for idea) -- pass __match_devt_ns matcher which would
test for namespace inside class_find_device itself.

https://jira.sw.ru/browse/PSBM-34777

Signed-off-by: Cyrill Gorcunov <gorcu...@virtuozzo.com>
CC: Andrey Vagin <ava...@virtuozzo.com>
CC: Vladimir Davydov <vdavy...@virtuozzo.com>
CC: Konstantin Khorenko <khore...@virtuozzo.com>
---
 drivers/base/core.c |   30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

Index: linux-pcs7.git/drivers/base/core.c
===================================================================
--- linux-pcs7.git.orig/drivers/base/core.c
+++ linux-pcs7.git/drivers/base/core.c
@@ -1836,19 +1836,29 @@ void device_destroy(struct class *class,
 }
 EXPORT_SYMBOL_GPL(device_destroy);
 
-void device_destroy_namespace(struct class *class, dev_t devt, void *ns)
+struct __match_devt_ns_arg {
+       dev_t   devt;
+       void    *ns;
+};
+
+static int __match_devt_ns(struct device *dev, const void *data)
 {
-       struct device *dev = NULL;
+       const struct __match_devt_ns_arg *arg = data;
+
+       return dev->devt == arg->devt &&
+               (!dev->class->namespace ||
+                dev->class->namespace(dev) == arg->ns);
+}
 
-       for (;;) {
-               dev = class_find_device(class, dev, &devt, __match_devt);
-               if (!dev)
-                       break;
-               if (!class->namespace ||
-                   (class->namespace(dev) == ns))
-                       break;
-       }
+void device_destroy_namespace(struct class *class, dev_t devt, void *ns)
+{
+       struct __match_devt_ns_arg arg = {
+               .devt   = devt,
+               .ns     = ns,
+       };
+       struct device *dev;
 
+       dev = class_find_device(class, NULL, &arg, __match_devt_ns);
        if (dev) {
                put_device(dev);
                device_unregister(dev);
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to