[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] linux/blkfront: don't access freed struct xenbus_device



Unfortunately c/s 983 still wasn't quite right - there was a reference
to freed memory left from blkfront_closing().

As usual, written against 2.6.32.7 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- a/drivers/xen/blkfront/blkfront.c   2010-02-04 09:29:42.000000000 +0100
+++ b/drivers/xen/blkfront/blkfront.c   2010-02-04 09:31:52.000000000 +0100
@@ -63,7 +63,7 @@
 #define GRANT_INVALID_REF      0
 
 static void connect(struct blkfront_info *);
-static void blkfront_closing(struct xenbus_device *);
+static void blkfront_closing(struct blkfront_info *);
 static int blkfront_remove(struct xenbus_device *);
 static int talk_to_backend(struct xenbus_device *, struct blkfront_info *);
 static int setup_blkring(struct xenbus_device *, struct blkfront_info *);
@@ -302,7 +302,7 @@ static void backend_changed(struct xenbu
                        xenbus_dev_error(dev, -EBUSY,
                                         "Device in use; refusing to close");
                else
-                       blkfront_closing(dev);
+                       blkfront_closing(info);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
                up(&bd->bd_sem);
 #else
@@ -387,12 +387,11 @@ static void connect(struct blkfront_info
  * the backend.  Once is this done, we can switch to Closed in
  * acknowledgement.
  */
-static void blkfront_closing(struct xenbus_device *dev)
+static void blkfront_closing(struct blkfront_info *info)
 {
-       struct blkfront_info *info = dev->dev.driver_data;
        unsigned long flags;
 
-       DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
+       DPRINTK("blkfront_closing: %d removed\n", info->vdevice);
 
        if (info->rq == NULL)
                goto out;
@@ -414,7 +413,8 @@ static void blkfront_closing(struct xenb
        xlvbd_del(info);
 
  out:
-       xenbus_frontend_closed(dev);
+       if (info->xbdev)
+               xenbus_frontend_closed(info->xbdev);
 }
 
 
@@ -429,7 +429,7 @@ static int blkfront_remove(struct xenbus
        if(info->users == 0)
                kfree(info);
        else
-               info->is_ready = -1;
+               info->xbdev = NULL;
 
        return 0;
 }
@@ -498,7 +498,7 @@ int blkif_open(struct block_device *bd, 
 {
        struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
 
-       if(info->is_ready < 0)
+       if (!info->xbdev)
                return -ENODEV;
        info->users++;
        return 0;
@@ -521,13 +521,13 @@ int blkif_release(struct gendisk *disk, 
                   have ignored this request initially, as the device was
                   still mounted. */
                struct xenbus_device * dev = info->xbdev;
-               enum xenbus_state state = 
xenbus_read_driver_state(dev->otherend);
 
-               if(info->is_ready < 0) {
-                       blkfront_closing(dev);
+               if (!dev) {
+                       blkfront_closing(info);
                        kfree(info);
-               } else if (state == XenbusStateClosing && info->is_ready)
-                       blkfront_closing(dev);
+               } else if (xenbus_read_driver_state(dev->otherend)
+                          == XenbusStateClosing && info->is_ready)
+                       blkfront_closing(info);
        }
        return 0;
 }
@@ -920,7 +920,7 @@ int blkfront_is_ready(struct xenbus_devi
 {
        struct blkfront_info *info = dev->dev.driver_data;
 
-       return info->is_ready > 0;
+       return info->is_ready && info->xbdev;
 }
 
 



Attachment: xenlinux-blkfront-forced-detach-2.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.