]> xenbits.xensource.com Git - legacy/linux-2.6.18-xen.git/commitdiff
xen/blkfront: don't access freed struct xenbus_device
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Feb 2010 13:08:27 +0000 (13:08 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Feb 2010 13:08:27 +0000 (13:08 +0000)
Unfortunately c/s 983 still wasn't quite right - there was a reference
to freed memory left from blkfront_closing().

Signed-off-by: Jan Beulich <jbeulich@novell.com>
drivers/xen/blkfront/blkfront.c

index 678a76090b5373410e1aaccb4cd76f986749a39f..40d746d68edfd667cc81c1128d37e699cf7e9b4d 100644 (file)
@@ -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 *);
@@ -298,7 +298,7 @@ static void backend_changed(struct xenbus_device *dev,
                        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
@@ -381,12 +381,11 @@ static void connect(struct blkfront_info *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;
@@ -406,7 +405,8 @@ static void blkfront_closing(struct xenbus_device *dev)
        xlvbd_del(info);
 
  out:
-       xenbus_frontend_closed(dev);
+       if (info->xbdev)
+               xenbus_frontend_closed(info->xbdev);
 }
 
 
@@ -421,7 +421,7 @@ static int blkfront_remove(struct xenbus_device *dev)
        if(info->users == 0)
                kfree(info);
        else
-               info->is_ready = -1;
+               info->xbdev = NULL;
 
        return 0;
 }
@@ -484,7 +484,7 @@ int blkif_open(struct inode *inode, struct file *filep)
 {
        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;
@@ -500,13 +500,13 @@ int blkif_release(struct inode *inode, struct file *filep)
                   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;
 }
@@ -896,7 +896,7 @@ int blkfront_is_ready(struct xenbus_device *dev)
 {
        struct blkfront_info *info = dev->dev.driver_data;
 
-       return info->is_ready > 0;
+       return info->is_ready && info->xbdev;
 }