xsegbd/xsegdev: Fix xsegbd/xsegdev memory leak
authorStratos Psomadakis <psomas@grnet.gr>
Sun, 19 Feb 2012 21:09:25 +0000 (23:09 +0200)
committerStratos Psomadakis <psomas@grnet.gr>
Sun, 19 Feb 2012 21:09:25 +0000 (23:09 +0200)
xsegdev_get/put and the associated xsegdev->userfield struct member
were incorrectly used, resulting in a memory leak, where xsegdev
segment wasn't (v)freed at xsegdev unload.

Refs #3

xseg/sys/xsegbd.c
xseg/sys/xsegdev.c

index 90d07ef..2ea1bf5 100644 (file)
@@ -133,6 +133,8 @@ static void *xsegdev_map(const char *name, uint64_t size)
        dev->callback = xseg_callback;
        xseg = (void *)dev->segment;
 
+       goto out;
+
 put_out:
        xsegdev_put(dev);
 out:
@@ -149,6 +151,8 @@ static void xsegdev_unmap(void *ptr, uint64_t size)
        //xsegdev->callarg = NULL;
        xsegdev->callback = NULL;
        xsegdev_put(xsegdev);
+
+       xsegdev_put(xsegdev);
 }
 
 static struct xseg_type xseg_xsegdev = {
@@ -376,8 +380,13 @@ err0:
 
 int xsegbd_xseg_quit(void)
 {
+       struct xsegdev *xsegdev;
+
        /* make sure to unmap the segment first */
+       xsegdev = xsegdev_get(0);
+       clear_bit(XSEGDEV_RESERVED, &xsegdev->flags);
        xsegbd.xseg->type.ops.unmap(xsegbd.xseg, xsegbd.xseg->segment_size);
+       xsegdev_put(xsegdev);
 
        xseg_unregister_peer(xseg_peer_xsegdev.name);
        xseg_unregister_peer(xseg_peer_posix.name);
index d0f6466..232aba8 100644 (file)
@@ -82,7 +82,7 @@ int xsegdev_destroy_segment(struct xsegdev *dev)
                goto out_unlock;
 
        clear_bit(XSEGDEV_READY, &dev->flags);
-       ret = wait_event_interruptible(dev->wq, atomic_read(&dev->usercount) <= 1);
+       ret = wait_event_interruptible(dev->wq, atomic_read(&dev->usercount) < 1);
        if (ret)
                goto out_unlock;