# 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
|