WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [TAPDISK] minor changes to tapdisk and pl

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [TAPDISK] minor changes to tapdisk and plugins
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2007 09:50:12 -0800
Delivery-date: Fri, 23 Feb 2007 09:50:19 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jake Wires <jwires@xxxxxxxxxxxxx>
# Date 1172208737 28800
# Node ID 8407279d3751ff27e7f1826298c9adb2c46d71de
# Parent  da37c365b375fbf6335c5d7cdf5429f2bf1259d0
[TAPDISK] minor changes to tapdisk and plugins
* open all parent images read-only
* expose parent image names to tapdisk (needed for locking api)
Signed-off-by: Jake Wires <jwires@xxxxxxxxxxxxx>
---
 tools/blktap/drivers/block-aio.c  |   33 ++++----
 tools/blktap/drivers/block-qcow.c |   85 +++++++++++---------
 tools/blktap/drivers/block-ram.c  |   28 +++---
 tools/blktap/drivers/block-sync.c |   28 +++---
 tools/blktap/drivers/block-vmdk.c |   29 ++++---
 tools/blktap/drivers/img2qcow.c   |    2 
 tools/blktap/drivers/qcow2raw.c   |    4 
 tools/blktap/drivers/tapdisk.c    |  154 +++++++++++++++++++++++---------------
 tools/blktap/drivers/tapdisk.h    |   44 +++++++---
 9 files changed, 244 insertions(+), 163 deletions(-)

diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c  Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/block-aio.c  Thu Feb 22 21:32:17 2007 -0800
@@ -152,9 +152,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-int tdaio_open (struct disk_driver *dd, const char *name)
-{
-       int i, fd, ret = 0;
+int tdaio_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int i, fd, ret = 0, o_flags;
        struct td_state    *s   = dd->td_state;
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
@@ -187,12 +187,15 @@ int tdaio_open (struct disk_driver *dd, 
                prv->iocb_free[i] = &prv->iocb_list[i];
 
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -279,6 +282,9 @@ int tdaio_submit(struct disk_driver *dd)
 {
        int ret;
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
+
+       if (!prv->iocb_queued)
+               return 0;
 
        ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
        
@@ -324,12 +330,13 @@ int tdaio_do_callbacks(struct disk_drive
        return rsp;
 }
 
-int tdaio_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdaio_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdaio_validate_parent(struct disk_driver *dd, 
+                         struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -341,8 +348,8 @@ struct tap_disk tapdisk_aio = {
        .td_queue_read      = tdaio_queue_read,
        .td_queue_write     = tdaio_queue_write,
        .td_submit          = tdaio_submit,
-       .td_has_parent      = tdaio_has_parent,
-       .td_get_parent      = tdaio_get_parent,
        .td_close           = tdaio_close,
        .td_do_callbacks    = tdaio_do_callbacks,
+       .td_get_parent_id   = tdaio_get_parent_id,
+       .td_validate_parent = tdaio_validate_parent
 };
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/block-qcow.c Thu Feb 22 21:32:17 2007 -0800
@@ -207,23 +207,6 @@ static int init_aio_state(struct disk_dr
 
  fail:
        return -1;
-}
-
-/*
- *Test if block is zero. 
- * Return: 
- *       1 for TRUE
- *       0 for FALSE
- */
-static inline int IS_ZERO(char *buf, int len)
-{
-       int i;
-
-       for (i = 0; i < len; i++) {
-               /*if not zero, return false*/
-               if (ZERO_TEST(*(buf + i))) return 0; 
-       }
-       return 1;
 }
 
 static uint32_t gen_cksum(char *ptr, int len)
@@ -825,9 +808,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize qcow state. */
-int tdqcow_open (struct disk_driver *dd, const char *name)
-{
-       int fd, len, i, shift, ret, size, l1_table_size;
+int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int fd, len, i, shift, ret, size, l1_table_size, o_flags;
        struct td_state     *bs = dd->td_state;
        struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
        char *buf;
@@ -838,7 +821,9 @@ int tdqcow_open (struct disk_driver *dd,
 
        DPRINTF("QCOW: Opening %s\n",name);
 
-       fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+       fd = open(name, o_flags);
        if (fd < 0) {
                DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
                return -1;
@@ -1016,7 +1001,8 @@ int tdqcow_queue_read(struct disk_driver
                                 * as busy and try again later */
                                return cb(dd, -EBUSY, sector + n,
                                          nb_sectors - n, id, private);
-                       } else rsp += ret;
+                       } else
+                               rsp += ret;
                } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
                        aio_unlock(s, sector);
                        if (decompress_cluster(s, cluster_offset) < 0) {
@@ -1403,21 +1389,15 @@ int qcow_compress_cluster(struct tdqcow_
        return 0;
 }
 
-int tdqcow_has_parent(struct disk_driver *dd)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
-       return (s->backing_file_offset ? 1 : 0);
-}
-
-int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
+int tdqcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
 {
        off_t off;
        char *buf, *filename;
-       int len, secs, ret = -1;
-       struct tdqcow_state *child  = (struct tdqcow_state *)cdd->private;
+       int len, secs, err = -EINVAL;
+       struct tdqcow_state *child  = (struct tdqcow_state *)dd->private;
 
        if (!child->backing_file_offset)
-               return -1;
+               return TD_NO_PARENT;
 
        /* read the backing file name */
        len  = child->backing_file_size;
@@ -1432,14 +1412,39 @@ int tdqcow_get_parent(struct disk_driver
 
        if (read(child->fd, buf, secs << 9) != secs << 9)
                goto out;
-       filename      = buf + (child->backing_file_offset - off);
-       filename[len] = '\0';
-
-       /*Open backing file*/
-       ret = tdqcow_open(pdd, filename);
+       filename       = buf + (child->backing_file_offset - off);
+       filename[len]  = '\0';
+
+       id->name       = strdup(filename);
+       id->drivertype = DISK_TYPE_QCOW;
+       err            = 0;
  out:
        free(buf);
-       return ret;
+       return err;
+}
+
+int tdqcow_validate_parent(struct disk_driver *child,
+                          struct disk_driver *parent, td_flag_t flags)
+{
+       struct stat stats;
+       uint64_t psize, csize;
+       struct tdqcow_state *c = (struct tdqcow_state *)child->private;
+       struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
+       
+       if (stat(p->name, &stats))
+               return -EINVAL;
+       if (get_filesize(p->name, &psize, &stats))
+               return -EINVAL;
+
+       if (stat(c->name, &stats))
+               return -EINVAL;
+       if (get_filesize(c->name, &csize, &stats))
+               return -EINVAL;
+
+       if (csize != psize)
+               return -EINVAL;
+
+       return 0;
 }
 
 struct tap_disk tapdisk_qcow = {
@@ -1449,8 +1454,8 @@ struct tap_disk tapdisk_qcow = {
        .td_queue_read       = tdqcow_queue_read,
        .td_queue_write      = tdqcow_queue_write,
        .td_submit           = tdqcow_submit,
-       .td_has_parent       = tdqcow_has_parent,
-       .td_get_parent       = tdqcow_get_parent,
        .td_close            = tdqcow_close,
        .td_do_callbacks     = tdqcow_do_callbacks,
+       .td_get_parent_id    = tdqcow_get_parent_id,
+       .td_validate_parent  = tdqcow_validate_parent
 };
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/block-ram.c
--- a/tools/blktap/drivers/block-ram.c  Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/block-ram.c  Thu Feb 22 21:32:17 2007 -0800
@@ -135,11 +135,11 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize ram state. */
-int tdram_open (struct disk_driver *dd, const char *name)
+int tdram_open (struct disk_driver *dd, const char *name, td_flag_t flags)
 {
        char *p;
        uint64_t size;
-       int i, fd, ret = 0, count = 0;
+       int i, fd, ret = 0, count = 0, o_flags;
        struct td_state    *s     = dd->td_state;
        struct tdram_state *prv   = (struct tdram_state *)dd->private;
 
@@ -167,12 +167,15 @@ int tdram_open (struct disk_driver *dd, 
        }
 
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ((fd == -1) && (errno == EINVAL)) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -275,12 +278,13 @@ int tdram_do_callbacks(struct disk_drive
        return 1;
 }
 
-int tdram_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdram_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdram_validate_parent(struct disk_driver *dd, 
+                         struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -292,8 +296,8 @@ struct tap_disk tapdisk_ram = {
        .td_queue_read      = tdram_queue_read,
        .td_queue_write     = tdram_queue_write,
        .td_submit          = tdram_submit,
-       .td_has_parent      = tdram_has_parent,
-       .td_get_parent      = tdram_get_parent,
        .td_close           = tdram_close,
        .td_do_callbacks    = tdram_do_callbacks,
+       .td_get_parent_id   = tdram_get_parent_id,
+       .td_validate_parent = tdram_validate_parent
 };
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/block-sync.c
--- a/tools/blktap/drivers/block-sync.c Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/block-sync.c Thu Feb 22 21:32:17 2007 -0800
@@ -118,9 +118,9 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-int tdsync_open (struct disk_driver *dd, const char *name)
-{
-       int i, fd, ret = 0;
+int tdsync_open (struct disk_driver *dd, const char *name, td_flag_t flags)
+{
+       int i, fd, ret = 0, o_flags;
        struct td_state     *s   = dd->td_state;
        struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        
@@ -130,11 +130,14 @@ int tdsync_open (struct disk_driver *dd,
                return (0 - errno);
        
        /* Open the file */
-        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags);
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
+               o_flags &= ~O_DIRECT;
                 fd = open(name, O_RDWR | O_LARGEFILE);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
@@ -223,12 +226,13 @@ int tdsync_do_callbacks(struct disk_driv
        return 1;
 }
 
-int tdsync_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+int tdsync_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+int tdsync_validate_parent(struct disk_driver *dd, 
+                          struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -240,8 +244,8 @@ struct tap_disk tapdisk_sync = {
        .td_queue_read       = tdsync_queue_read,
        .td_queue_write      = tdsync_queue_write,
        .td_submit           = tdsync_submit,
-       .td_has_parent       = tdsync_has_parent,
-       .td_get_parent       = tdsync_get_parent,
        .td_close            = tdsync_close,
        .td_do_callbacks     = tdsync_do_callbacks,
+       .td_get_parent_id    = tdsync_get_parent_id,
+       .td_validate_parent  = tdsync_validate_parent
 };
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/block-vmdk.c
--- a/tools/blktap/drivers/block-vmdk.c Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/block-vmdk.c Thu Feb 22 21:32:17 2007 -0800
@@ -119,10 +119,11 @@ static inline void init_fds(struct disk_
 }
 
 /* Open the disk file and initialize aio state. */
-static int tdvmdk_open (struct disk_driver *dd, const char *name)
+static int tdvmdk_open (struct disk_driver *dd, 
+                       const char *name, td_flag_t flags)
 {
        int ret, fd;
-       int l1_size, i;
+       int l1_size, i, o_flags;
        uint32_t magic;
        struct td_state     *s   = dd->td_state;
        struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
@@ -133,12 +134,15 @@ static int tdvmdk_open (struct disk_driv
                return -1;
        
        /* Open the file */
-        fd = open(name, O_RDWR | O_LARGEFILE); 
+       o_flags = O_DIRECT | O_LARGEFILE | 
+               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+        fd = open(name, o_flags); 
 
         if ( (fd == -1) && (errno == EINVAL) ) {
 
                 /* Maybe O_DIRECT isn't supported. */
-                fd = open(name, O_RDWR | O_LARGEFILE);
+               o_flags &= ~O_DIRECT;
+                fd = open(name, o_flags);
                 if (fd != -1) DPRINTF("WARNING: Accessing image without"
                                      "O_DIRECT! (%s)\n", name);
 
@@ -394,12 +398,13 @@ static int tdvmdk_do_callbacks(struct di
        return 1;
 }
 
-static int tdvmdk_has_parent(struct disk_driver *dd)
-{
-       return 0;
-}
-
-static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver 
*parent)
+static int tdvmdk_get_parent_id(struct disk_driver *dd, struct disk_id *id)
+{
+       return TD_NO_PARENT;
+}
+
+static int tdvmdk_validate_parent(struct disk_driver *dd, 
+                                 struct disk_driver *parent, td_flag_t flags)
 {
        return -EINVAL;
 }
@@ -411,8 +416,8 @@ struct tap_disk tapdisk_vmdk = {
        .td_queue_read       = tdvmdk_queue_read,
        .td_queue_write      = tdvmdk_queue_write,
        .td_submit           = tdvmdk_submit,
-       .td_has_parent       = tdvmdk_has_parent,
-       .td_get_parent       = tdvmdk_get_parent,
        .td_close            = tdvmdk_close,
        .td_do_callbacks     = tdvmdk_do_callbacks,
+       .td_get_parent_id    = tdvmdk_get_parent_id,
+       .td_validate_parent  = tdvmdk_validate_parent
 };
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/img2qcow.c
--- a/tools/blktap/drivers/img2qcow.c   Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/img2qcow.c   Thu Feb 22 21:32:17 2007 -0800
@@ -201,7 +201,7 @@ int main(int argc, char *argv[])
        dd.private  = malloc(dd.drv->private_data_size);
 
         /*Open qcow file*/
-        if (dd.drv->td_open(&dd, argv[1])!=0) {
+        if (dd.drv->td_open(&dd, argv[1], 0)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
                exit(-1);
        }
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/qcow2raw.c
--- a/tools/blktap/drivers/qcow2raw.c   Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/qcow2raw.c   Thu Feb 22 21:32:17 2007 -0800
@@ -169,7 +169,7 @@ int main(int argc, char *argv[])
        ddqcow.drv = &tapdisk_qcow;
        ddqcow.private = malloc(ddqcow.drv->private_data_size);
 
-        if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
+        if (ddqcow.drv->td_open(&ddqcow, argv[2], TD_RDONLY)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
                exit(-1);
        } else DFPRINTF("QCOW file opened, size %llu\n",
@@ -270,7 +270,7 @@ int main(int argc, char *argv[])
        ddaio.drv = &tapdisk_aio;
        ddaio.private = malloc(ddaio.drv->private_data_size);
 
-        if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
+        if (ddaio.drv->td_open(&ddaio, argv[1], 0)!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
                exit(-1);
        }
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/tapdisk.c    Thu Feb 22 21:32:17 2007 -0800
@@ -81,6 +81,15 @@ void daemonize(void)
        return;
 }
 
+static void free_driver(struct disk_driver *d)
+{
+       if (d->name)
+               free(d->name);
+       if (d->private)
+               free(d->private);
+       free(d);
+}
+
 static void unmap_disk(struct td_state *s)
 {
        tapdev_info_t *info = s->ring_info;
@@ -91,8 +100,7 @@ static void unmap_disk(struct td_state *
        while (dd) {
                tmp = dd->next;
                dd->drv->td_close(dd);
-               free(dd->private);
-               free(dd);
+               free_driver(dd);
                dd = tmp;
        }
 
@@ -112,7 +120,6 @@ static void unmap_disk(struct td_state *
        free(s);
 
        return;
-
 }
 
 void sig_handler(int sig)
@@ -205,26 +212,6 @@ static struct td_state *state_init(void)
        return s;
 }
 
-static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
-{
-       struct disk_driver *dd;
-
-       dd = calloc(1, sizeof(struct disk_driver));
-       if (!dd)
-               return NULL;
-       
-       dd->private = malloc(drv->private_data_size);
-       if (!dd->private) {
-               free(dd);
-               return NULL;
-       }
-
-       dd->drv      = drv;
-       dd->td_state = s;
-
-       return dd;
-}
-
 static int map_new_dev(struct td_state *s, int minor)
 {
        int tap_fd;
@@ -280,49 +267,94 @@ static int map_new_dev(struct td_state *
        return -1;
 }
 
-static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
+static struct disk_driver *disk_init(struct td_state *s, 
+                                    struct tap_disk *drv, char *name)
+{
+       struct disk_driver *dd;
+
+       dd = calloc(1, sizeof(struct disk_driver));
+       if (!dd)
+               return NULL;
+       
+       dd->private = malloc(drv->private_data_size);
+       if (!dd->private) {
+               free(dd);
+               return NULL;
+       }
+
+       dd->drv      = drv;
+       dd->td_state = s;
+       dd->name     = name;
+
+       return dd;
+}
+
+static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
 {
        int err;
-       struct disk_driver *d = dd;
-
-       err = dd->drv->td_open(dd, path);
+       char *dup;
+       struct disk_id id;
+       struct disk_driver *d;
+
+       dup = strdup(path);
+       if (!dup)
+               return -ENOMEM;
+
+       memset(&id, 0, sizeof(struct disk_id));
+       s->disks = d = disk_init(s, drv, dup);
+       if (!d)
+               return -ENOMEM;
+
+       err = drv->td_open(d, path, 0);
        if (err)
-               return err;
+               goto fail;
 
        /* load backing files as necessary */
-       while (d->drv->td_has_parent(d)) {
+       while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
                struct disk_driver *new;
                
-               new = calloc(1, sizeof(struct disk_driver));
+               if (id.drivertype > MAX_DISK_TYPES || 
+                   !get_driver(id.drivertype) || !id.name)
+                       goto fail;
+
+               dup = strdup(id.name);
+               if (!dup)
+                       goto fail;
+
+               new = disk_init(s, get_driver(id.drivertype), dup);
                if (!new)
                        goto fail;
-               new->drv      = d->drv;
-               new->td_state = s;
-               new->private  = malloc(new->drv->private_data_size);
-               if (!new->private) {
-                       free(new);
+
+               err = new->drv->td_open(new, new->name, TD_RDONLY);
+               if (err)
+                       goto fail;
+
+               err = d->drv->td_validate_parent(d, new, 0);
+               if (err) {
+                       d->next = new;
                        goto fail;
                }
-               
-               err = d->drv->td_get_parent(d, new);
-               if (err)
-                       goto fail;
 
                d = d->next = new;
-       }
-
-       return 0;
+               free(id.name);
+       }
+
+       if (err >= 0)
+               return 0;
 
  fail:
        DPRINTF("failed opening disk\n");
-       while (dd) {
-               d = dd->next;
-               dd->drv->td_close(dd);
-               free(dd->private);
-               free(dd);
-               dd = d;
-       }
-       return err;
+       if (id.name)
+               free(id.name);
+       d = s->disks;
+       while (d) {
+               struct disk_driver *tmp = d->next;
+               d->drv->td_close(d);
+               free_driver(d);
+               d = tmp;
+       }
+       s->disks = NULL;
+       return -1;
 }
 
 static int read_msg(char *buf)
@@ -334,7 +366,6 @@ static int read_msg(char *buf)
        msg_newdev_t *msg_dev;
        msg_pid_t *msg_pid;
        struct tap_disk *drv;
-       struct disk_driver *dd;
        int ret = -1;
        struct td_state *s = NULL;
        fd_list_entry_t *entry;
@@ -369,14 +400,8 @@ static int read_msg(char *buf)
                        if (s == NULL)
                                goto params_done;
 
-                       s->disks = dd = disk_init(s, drv);
-                       if (!dd) {
-                               free(s);
-                               goto params_done;
-                       }
-
                        /*Open file*/
-                       ret = open_disk(s, dd, path);
+                       ret = open_disk(s, drv, path);
                        if (ret)
                                goto params_done;
 
@@ -785,6 +810,19 @@ int main(int argc, char *argv[])
                                        }
                                }
 
+                               /* completed io from above may have 
+                                * queued new requests on chained disks */
+                               if (progress_made) {
+                                       td_for_each_disk(ptr->s, dd) {
+                                               dd->early += 
+                                                       dd->drv->td_submit(dd);
+                                               if (dd->early > 0) {
+                                                       io_done(dd, 10);
+                                                       dd->early = 0;
+                                               }
+                                       }
+                               }
+
                                if (FD_ISSET(ptr->tap_fd, &readfds) ||
                                    (info->busy.req && progress_made))
                                        get_io_request(ptr->s);
diff -r da37c365b375 -r 8407279d3751 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Thu Feb 22 22:27:40 2007 +0000
+++ b/tools/blktap/drivers/tapdisk.h    Thu Feb 22 21:32:17 2007 -0800
@@ -42,10 +42,15 @@
  * 
  *   - The fd used for poll is an otherwise unused pipe, which allows poll to 
  *     be safely called without ever returning anything.
- * 
+ *
  * NOTE: tapdisk uses the number of sectors submitted per request as a 
  * ref count.  Plugins must use the callback function to communicate the
  * completion--or error--of every sector submitted to them.
+ *
+ * td_get_parent_id returns:
+ *     0 if parent id successfully retrieved
+ *     TD_NO_PARENT if no parent exists
+ *     -errno on error
  */
 
 #ifndef TAPDISK_H_
@@ -71,12 +76,23 @@
 #define MAX_IOFD                 2
 
 #define BLK_NOT_ALLOCATED       99
+#define TD_NO_PARENT             1
+
+typedef uint32_t td_flag_t;
+
+#define TD_RDONLY                1
 
 struct td_state;
 struct tap_disk;
 
+struct disk_id {
+       char *name;
+       int drivertype;
+};
+
 struct disk_driver {
        int early;
+       char *name;
        void *private;
        int io_fd[MAX_IOFD];
        struct tap_disk *drv;
@@ -105,18 +121,20 @@ struct tap_disk {
 struct tap_disk {
        const char *disk_type;
        int private_data_size;
-       int (*td_open)        (struct disk_driver *dd, const char *name);
-       int (*td_queue_read)  (struct disk_driver *dd, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb, 
-                              int id, void *prv);
-       int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb, 
-                              int id, void *prv);
-       int (*td_submit)      (struct disk_driver *dd);
-       int (*td_has_parent)  (struct disk_driver *dd);
-       int (*td_get_parent)  (struct disk_driver *dd, struct disk_driver *p);
-       int (*td_close)       (struct disk_driver *dd);
-       int (*td_do_callbacks)(struct disk_driver *dd, int sid);
+       int (*td_open)           (struct disk_driver *dd, 
+                                 const char *name, td_flag_t flags);
+       int (*td_queue_read)     (struct disk_driver *dd, uint64_t sector,
+                                 int nb_sectors, char *buf, td_callback_t cb,
+                                 int id, void *prv);
+       int (*td_queue_write)    (struct disk_driver *dd, uint64_t sector,
+                                 int nb_sectors, char *buf, td_callback_t cb, 
+                                 int id, void *prv);
+       int (*td_submit)         (struct disk_driver *dd);
+       int (*td_close)          (struct disk_driver *dd);
+       int (*td_do_callbacks)   (struct disk_driver *dd, int sid);
+       int (*td_get_parent_id)  (struct disk_driver *dd, struct disk_id *id);
+       int (*td_validate_parent)(struct disk_driver *dd, 
+                                 struct disk_driver *p, td_flag_t flags);
 };
 
 typedef struct disk_info {

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [TAPDISK] minor changes to tapdisk and plugins, Xen patchbot-unstable <=