ia64/xen-unstable

changeset 6368:49b67f0f6735

More cleanups and fix free_blkif from wrong context bug (thanks Keir!).
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Tue Aug 23 16:37:59 2005 +0000 (2005-08-23)
parents a826ad59b3ea
children d7b79cac9ea9
files linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/interface.c linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Aug 23 15:43:04 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Aug 23 16:37:59 2005 +0000
     1.3 @@ -5,7 +5,6 @@
     1.4  #include <linux/config.h>
     1.5  #include <linux/version.h>
     1.6  #include <linux/module.h>
     1.7 -#include <linux/rbtree.h>
     1.8  #include <linux/interrupt.h>
     1.9  #include <linux/slab.h>
    1.10  #include <linux/blkdev.h>
    1.11 @@ -30,13 +29,20 @@
    1.12  #define DPRINTK(_f, _a...) ((void)0)
    1.13  #endif
    1.14  
    1.15 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    1.16 -typedef struct rb_root rb_root_t;
    1.17 -typedef struct rb_node rb_node_t;
    1.18 -#else
    1.19 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    1.20  struct block_device;
    1.21  #endif
    1.22  
    1.23 +struct vbd {
    1.24 +    blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
    1.25 +    unsigned char  readonly;    /* Non-zero -> read-only */
    1.26 +    unsigned char  type;        /* VDISK_xxx */
    1.27 +    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
    1.28 +    struct block_device *bdev;
    1.29 +
    1.30 +    int active;
    1.31 +}; 
    1.32 +
    1.33  typedef struct blkif_st {
    1.34      /* Unique identifier for this interface. */
    1.35      domid_t           domid;
    1.36 @@ -48,7 +54,7 @@ typedef struct blkif_st {
    1.37      /* Comms information. */
    1.38      blkif_back_ring_t blk_ring;
    1.39      /* VBDs attached to this interface. */
    1.40 -    struct vbd *vbd;
    1.41 +    struct vbd        vbd;
    1.42      /* Private fields. */
    1.43      enum { DISCONNECTED, CONNECTED } status;
    1.44      /*
    1.45 @@ -64,7 +70,7 @@ typedef struct blkif_st {
    1.46      spinlock_t       blk_ring_lock;
    1.47      atomic_t         refcnt;
    1.48  
    1.49 -    struct work_struct work;
    1.50 +    struct work_struct free_work;
    1.51      u16 shmem_handle;
    1.52      unsigned long shmem_vaddr;
    1.53      grant_ref_t shmem_ref;
    1.54 @@ -76,23 +82,22 @@ void blkif_connect(blkif_be_connect_t *c
    1.55  int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
    1.56  void blkif_disconnect_complete(blkif_t *blkif);
    1.57  blkif_t *alloc_blkif(domid_t domid);
    1.58 -void free_blkif(blkif_t *blkif);
    1.59 +void free_blkif_callback(blkif_t *blkif);
    1.60  int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
    1.61  
    1.62  #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
    1.63  #define blkif_put(_b)                             \
    1.64      do {                                          \
    1.65          if ( atomic_dec_and_test(&(_b)->refcnt) ) \
    1.66 -            free_blkif(_b);			  \
    1.67 +            free_blkif_callback(_b);		  \
    1.68      } while (0)
    1.69  
    1.70 -struct vbd;
    1.71 -void vbd_free(blkif_t *blkif, struct vbd *vbd);
    1.72 -
    1.73  /* Creates inactive vbd. */
    1.74 -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly);
    1.75 +int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice,
    1.76 +	       int readonly);
    1.77  int vbd_is_active(struct vbd *vbd);
    1.78 -void vbd_activate(blkif_t *blkif, struct vbd *vbd);
    1.79 +void vbd_activate(struct vbd *vbd);
    1.80 +void vbd_free(struct vbd *vbd);
    1.81  
    1.82  unsigned long vbd_size(struct vbd *vbd);
    1.83  unsigned int vbd_info(struct vbd *vbd);
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Tue Aug 23 15:43:04 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Tue Aug 23 16:37:59 2005 +0000
     2.3 @@ -108,9 +108,10 @@ int blkif_map(blkif_t *blkif, unsigned l
     2.4      return 0;
     2.5  }
     2.6  
     2.7 -void free_blkif(blkif_t *blkif)
     2.8 +static void free_blkif(void *arg)
     2.9  {
    2.10      evtchn_op_t op = { .cmd = EVTCHNOP_close };
    2.11 +    blkif_t *blkif = (blkif_t *)arg;
    2.12  
    2.13      op.u.close.port = blkif->evtchn;
    2.14      op.u.close.dom = DOMID_SELF;
    2.15 @@ -119,6 +120,9 @@ void free_blkif(blkif_t *blkif)
    2.16      op.u.close.dom = blkif->domid;
    2.17      HYPERVISOR_event_channel_op(&op);
    2.18  
    2.19 +    if (vbd_is_active(&blkif->vbd))
    2.20 +	vbd_free(&blkif->vbd);
    2.21 +
    2.22      if (blkif->evtchn)
    2.23          unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
    2.24  
    2.25 @@ -130,6 +134,12 @@ void free_blkif(blkif_t *blkif)
    2.26      kmem_cache_free(blkif_cachep, blkif);
    2.27  }
    2.28  
    2.29 +void free_blkif_callback(blkif_t *blkif)
    2.30 +{
    2.31 +    INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
    2.32 +    schedule_work(&blkif->free_work);
    2.33 +}
    2.34 +
    2.35  void __init blkif_interface_init(void)
    2.36  {
    2.37      blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 23 15:43:04 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 23 16:37:59 2005 +0000
     3.3 @@ -9,16 +9,6 @@
     3.4  #include "common.h"
     3.5  #include <asm-xen/xenbus.h>
     3.6  
     3.7 -struct vbd {
     3.8 -    blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
     3.9 -    unsigned char  readonly;    /* Non-zero -> read-only */
    3.10 -    unsigned char  type;        /* VDISK_xxx */
    3.11 -    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
    3.12 -    struct block_device *bdev;
    3.13 -
    3.14 -    int active;
    3.15 -}; 
    3.16 -
    3.17  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    3.18  static inline dev_t vbd_map_devnum(blkif_pdev_t cookie)
    3.19  {
    3.20 @@ -53,18 +43,12 @@ int vbd_is_active(struct vbd *vbd)
    3.21  	return vbd->active;
    3.22  }
    3.23  
    3.24 -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
    3.25 -		       blkif_pdev_t pdevice, int readonly)
    3.26 +int vbd_create(blkif_t *blkif, blkif_vdev_t handle,
    3.27 +	       blkif_pdev_t pdevice, int readonly)
    3.28  {
    3.29 -    struct vbd *vbd, *err; 
    3.30 +    struct vbd *vbd;
    3.31  
    3.32 -    if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
    3.33 -    {
    3.34 -        DPRINTK("vbd_create: out of memory\n");
    3.35 -	return ERR_PTR(-ENOMEM);
    3.36 -    }
    3.37 -
    3.38 -    blkif->vbd = vbd;
    3.39 +    vbd = &blkif->vbd;
    3.40      vbd->handle   = handle; 
    3.41      vbd->readonly = readonly;
    3.42      vbd->type     = 0;
    3.43 @@ -79,16 +63,14 @@ struct vbd *vbd_create(blkif_t *blkif, b
    3.44      if ( IS_ERR(vbd->bdev) )
    3.45      {
    3.46          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
    3.47 -        err = ERR_PTR(-ENOENT);
    3.48 -	goto out;
    3.49 +        return -ENOENT;
    3.50      }
    3.51  
    3.52      if ( (vbd->bdev->bd_disk == NULL) )
    3.53      {
    3.54          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
    3.55          bdev_put(vbd->bdev);
    3.56 -        err = ERR_PTR(-ENOENT);
    3.57 -	goto out;
    3.58 +        return -ENOENT;
    3.59      }
    3.60  
    3.61      if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
    3.62 @@ -99,41 +81,33 @@ struct vbd *vbd_create(blkif_t *blkif, b
    3.63      if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
    3.64      {
    3.65          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
    3.66 -        err = ERR_PTR(-ENOENT);
    3.67 -	goto out;
    3.68 +        return -ENOENT;
    3.69      }
    3.70  #endif
    3.71  
    3.72      DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
    3.73              handle, blkif->domid);
    3.74 -    return vbd;
    3.75 -
    3.76 - out:
    3.77 -    kfree(vbd);
    3.78 -    return err;
    3.79 +    return 0;
    3.80  }
    3.81  
    3.82 -void vbd_activate(blkif_t *blkif, struct vbd *vbd)
    3.83 +void vbd_activate(struct vbd *vbd)
    3.84  {
    3.85      BUG_ON(vbd_is_active(vbd));
    3.86  
    3.87      /* Now we're active. */
    3.88      vbd->active = 1;
    3.89 -    blkif_get(blkif);
    3.90  }
    3.91  
    3.92 -void vbd_free(blkif_t *blkif, struct vbd *vbd)
    3.93 +void vbd_free(struct vbd *vbd)
    3.94  {
    3.95 -    if (vbd_is_active(vbd)) {
    3.96 -	blkif_put(blkif);
    3.97 -    }
    3.98 +    if (vbd_is_active(vbd))
    3.99 +	vbd->active = 0;
   3.100      bdev_put(vbd->bdev);
   3.101 -    kfree(vbd);
   3.102  }
   3.103  
   3.104  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
   3.105  {
   3.106 -    struct vbd *vbd = blkif->vbd;
   3.107 +    struct vbd *vbd = &blkif->vbd;
   3.108      int rc = -EACCES;
   3.109  
   3.110      if ((operation == WRITE) && vbd->readonly)
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Aug 23 15:43:04 2005 +0000
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Aug 23 16:37:59 2005 +0000
     4.3 @@ -26,7 +26,6 @@ struct backend_info
     4.4  
     4.5  	/* our communications channel */
     4.6  	blkif_t *blkif;
     4.7 -	struct vbd *vbd;
     4.8  
     4.9  	long int frontend_id;
    4.10  	long int pdev;
    4.11 @@ -47,8 +46,6 @@ static int blkback_remove(struct xenbus_
    4.12  	if (be->watch.node)
    4.13  		unregister_xenbus_watch(&be->watch);
    4.14  	unregister_xenbus_watch(&be->backend_watch);
    4.15 -	if (be->vbd)
    4.16 -		vbd_free(be->blkif, be->vbd);
    4.17  	if (be->blkif)
    4.18  		blkif_put(be->blkif);
    4.19  	if (be->frontpath)
    4.20 @@ -72,7 +69,7 @@ static void frontend_changed(struct xenb
    4.21  		device_unregister(&be->dev->dev);
    4.22  		return;
    4.23  	}
    4.24 -	if (vbd_is_active(be->vbd))
    4.25 +	if (vbd_is_active(&be->blkif->vbd))
    4.26  		return;
    4.27  
    4.28  	err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
    4.29 @@ -105,7 +102,7 @@ static void frontend_changed(struct xenb
    4.30  	}
    4.31  
    4.32  	err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
    4.33 -			    vbd_size(be->vbd));
    4.34 +			    vbd_size(&be->blkif->vbd));
    4.35  	if (err) {
    4.36  		xenbus_dev_error(be->dev, err, "writing %s/sectors",
    4.37  				 be->dev->nodename);
    4.38 @@ -114,14 +111,14 @@ static void frontend_changed(struct xenb
    4.39  
    4.40  	/* FIXME: use a typename instead */
    4.41  	err = xenbus_printf(be->dev->nodename, "info", "%u",
    4.42 -			    vbd_info(be->vbd));
    4.43 +			    vbd_info(&be->blkif->vbd));
    4.44  	if (err) {
    4.45  		xenbus_dev_error(be->dev, err, "writing %s/info",
    4.46  				 be->dev->nodename);
    4.47  		goto abort;
    4.48  	}
    4.49  	err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
    4.50 -			    vbd_secsize(be->vbd));
    4.51 +			    vbd_secsize(&be->blkif->vbd));
    4.52  	if (err) {
    4.53  		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
    4.54  				 be->dev->nodename);
    4.55 @@ -140,7 +137,7 @@ static void frontend_changed(struct xenb
    4.56  	}
    4.57  
    4.58  	/* We're ready, activate. */
    4.59 -	vbd_activate(be->blkif, be->vbd);
    4.60 +	vbd_activate(&be->blkif->vbd);
    4.61  
    4.62  	xenbus_transaction_end(0);
    4.63  	xenbus_dev_ok(be->dev);
    4.64 @@ -235,13 +232,9 @@ static void backend_changed(struct xenbu
    4.65  			goto device_fail;
    4.66  		}
    4.67  
    4.68 -		be->vbd = vbd_create(be->blkif, handle, be->pdev,
    4.69 -				     be->readonly);
    4.70 -		if (IS_ERR(be->vbd)) {
    4.71 -			err = PTR_ERR(be->vbd);
    4.72 -			be->vbd = NULL;
    4.73 +		err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
    4.74 +		if (err)
    4.75  			goto device_fail;
    4.76 -		}
    4.77  
    4.78  		frontend_changed(&be->watch, be->frontpath);
    4.79  	}