[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] More cleanups and fix free_blkif from wrong context bug (thanks Keir!).
# HG changeset patch # User cl349@xxxxxxxxxxxxxxxxxxxx # Node ID 49b67f0f67355c4e3f1f30912811c600309aa78d # Parent a826ad59b3eaf35a4ceed7fda47f1a550e1d62e7 More cleanups and fix free_blkif from wrong context bug (thanks Keir!). Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> diff -r a826ad59b3ea -r 49b67f0f6735 linux-2.6-xen-sparse/drivers/xen/blkback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Aug 23 15:43:04 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Aug 23 16:37:59 2005 @@ -5,7 +5,6 @@ #include <linux/config.h> #include <linux/version.h> #include <linux/module.h> -#include <linux/rbtree.h> #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/blkdev.h> @@ -30,12 +29,19 @@ #define DPRINTK(_f, _a...) ((void)0) #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -typedef struct rb_root rb_root_t; -typedef struct rb_node rb_node_t; -#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) struct block_device; #endif + +struct vbd { + blkif_vdev_t handle; /* what the domain refers to this vbd as */ + unsigned char readonly; /* Non-zero -> read-only */ + unsigned char type; /* VDISK_xxx */ + blkif_pdev_t pdevice; /* phys device that this vbd maps to */ + struct block_device *bdev; + + int active; +}; typedef struct blkif_st { /* Unique identifier for this interface. */ @@ -48,7 +54,7 @@ /* Comms information. */ blkif_back_ring_t blk_ring; /* VBDs attached to this interface. */ - struct vbd *vbd; + struct vbd vbd; /* Private fields. */ enum { DISCONNECTED, CONNECTED } status; /* @@ -64,7 +70,7 @@ spinlock_t blk_ring_lock; atomic_t refcnt; - struct work_struct work; + struct work_struct free_work; u16 shmem_handle; unsigned long shmem_vaddr; grant_ref_t shmem_ref; @@ -76,23 +82,22 @@ int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id); void blkif_disconnect_complete(blkif_t *blkif); blkif_t *alloc_blkif(domid_t domid); -void free_blkif(blkif_t *blkif); +void free_blkif_callback(blkif_t *blkif); int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) #define blkif_put(_b) \ do { \ if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - free_blkif(_b); \ + free_blkif_callback(_b); \ } while (0) -struct vbd; -void vbd_free(blkif_t *blkif, struct vbd *vbd); - /* Creates inactive vbd. */ -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly); +int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, + int readonly); int vbd_is_active(struct vbd *vbd); -void vbd_activate(blkif_t *blkif, struct vbd *vbd); +void vbd_activate(struct vbd *vbd); +void vbd_free(struct vbd *vbd); unsigned long vbd_size(struct vbd *vbd); unsigned int vbd_info(struct vbd *vbd); diff -r a826ad59b3ea -r 49b67f0f6735 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Aug 23 15:43:04 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Aug 23 16:37:59 2005 @@ -108,9 +108,10 @@ return 0; } -void free_blkif(blkif_t *blkif) +static void free_blkif(void *arg) { evtchn_op_t op = { .cmd = EVTCHNOP_close }; + blkif_t *blkif = (blkif_t *)arg; op.u.close.port = blkif->evtchn; op.u.close.dom = DOMID_SELF; @@ -118,6 +119,9 @@ op.u.close.port = blkif->remote_evtchn; op.u.close.dom = blkif->domid; HYPERVISOR_event_channel_op(&op); + + if (vbd_is_active(&blkif->vbd)) + vbd_free(&blkif->vbd); if (blkif->evtchn) unbind_evtchn_from_irqhandler(blkif->evtchn, blkif); @@ -130,6 +134,12 @@ kmem_cache_free(blkif_cachep, blkif); } +void free_blkif_callback(blkif_t *blkif) +{ + INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif); + schedule_work(&blkif->free_work); +} + void __init blkif_interface_init(void) { blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), diff -r a826ad59b3ea -r 49b67f0f6735 linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Tue Aug 23 15:43:04 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Tue Aug 23 16:37:59 2005 @@ -8,16 +8,6 @@ #include "common.h" #include <asm-xen/xenbus.h> - -struct vbd { - blkif_vdev_t handle; /* what the domain refers to this vbd as */ - unsigned char readonly; /* Non-zero -> read-only */ - unsigned char type; /* VDISK_xxx */ - blkif_pdev_t pdevice; /* phys device that this vbd maps to */ - struct block_device *bdev; - - int active; -}; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static inline dev_t vbd_map_devnum(blkif_pdev_t cookie) @@ -53,18 +43,12 @@ return vbd->active; } -struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle, - blkif_pdev_t pdevice, int readonly) +int vbd_create(blkif_t *blkif, blkif_vdev_t handle, + blkif_pdev_t pdevice, int readonly) { - struct vbd *vbd, *err; + struct vbd *vbd; - if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) ) - { - DPRINTK("vbd_create: out of memory\n"); - return ERR_PTR(-ENOMEM); - } - - blkif->vbd = vbd; + vbd = &blkif->vbd; vbd->handle = handle; vbd->readonly = readonly; vbd->type = 0; @@ -79,16 +63,14 @@ if ( IS_ERR(vbd->bdev) ) { DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); - err = ERR_PTR(-ENOENT); - goto out; + return -ENOENT; } if ( (vbd->bdev->bd_disk == NULL) ) { DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); bdev_put(vbd->bdev); - err = ERR_PTR(-ENOENT); - goto out; + return -ENOENT; } if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD ) @@ -99,41 +81,33 @@ if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) ) { DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); - err = ERR_PTR(-ENOENT); - goto out; + return -ENOENT; } #endif DPRINTK("Successful creation of handle=%04x (dom=%u)\n", handle, blkif->domid); - return vbd; - - out: - kfree(vbd); - return err; + return 0; } -void vbd_activate(blkif_t *blkif, struct vbd *vbd) +void vbd_activate(struct vbd *vbd) { BUG_ON(vbd_is_active(vbd)); /* Now we're active. */ vbd->active = 1; - blkif_get(blkif); } -void vbd_free(blkif_t *blkif, struct vbd *vbd) +void vbd_free(struct vbd *vbd) { - if (vbd_is_active(vbd)) { - blkif_put(blkif); - } + if (vbd_is_active(vbd)) + vbd->active = 0; bdev_put(vbd->bdev); - kfree(vbd); } int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) { - struct vbd *vbd = blkif->vbd; + struct vbd *vbd = &blkif->vbd; int rc = -EACCES; if ((operation == WRITE) && vbd->readonly) diff -r a826ad59b3ea -r 49b67f0f6735 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Aug 23 15:43:04 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Aug 23 16:37:59 2005 @@ -26,7 +26,6 @@ /* our communications channel */ blkif_t *blkif; - struct vbd *vbd; long int frontend_id; long int pdev; @@ -47,8 +46,6 @@ if (be->watch.node) unregister_xenbus_watch(&be->watch); unregister_xenbus_watch(&be->backend_watch); - if (be->vbd) - vbd_free(be->blkif, be->vbd); if (be->blkif) blkif_put(be->blkif); if (be->frontpath) @@ -72,7 +69,7 @@ device_unregister(&be->dev->dev); return; } - if (vbd_is_active(be->vbd)) + if (vbd_is_active(&be->blkif->vbd)) return; err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn, @@ -105,7 +102,7 @@ } err = xenbus_printf(be->dev->nodename, "sectors", "%lu", - vbd_size(be->vbd)); + vbd_size(&be->blkif->vbd)); if (err) { xenbus_dev_error(be->dev, err, "writing %s/sectors", be->dev->nodename); @@ -114,14 +111,14 @@ /* FIXME: use a typename instead */ err = xenbus_printf(be->dev->nodename, "info", "%u", - vbd_info(be->vbd)); + vbd_info(&be->blkif->vbd)); if (err) { xenbus_dev_error(be->dev, err, "writing %s/info", be->dev->nodename); goto abort; } err = xenbus_printf(be->dev->nodename, "sector-size", "%lu", - vbd_secsize(be->vbd)); + vbd_secsize(&be->blkif->vbd)); if (err) { xenbus_dev_error(be->dev, err, "writing %s/sector-size", be->dev->nodename); @@ -140,7 +137,7 @@ } /* We're ready, activate. */ - vbd_activate(be->blkif, be->vbd); + vbd_activate(&be->blkif->vbd); xenbus_transaction_end(0); xenbus_dev_ok(be->dev); @@ -235,13 +232,9 @@ goto device_fail; } - be->vbd = vbd_create(be->blkif, handle, be->pdev, - be->readonly); - if (IS_ERR(be->vbd)) { - err = PTR_ERR(be->vbd); - be->vbd = NULL; + err = vbd_create(be->blkif, handle, be->pdev, be->readonly); + if (err) goto device_fail; - } frontend_changed(&be->watch, be->frontpath); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |