[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1 of 6 v2] blktap3/sring: Headers required for compiling the shared ring



This patch series introduces the headers required for the shared ring library
to compile. The files are:
  * io-optimize.h: imported from blktap2
  * scheduler.h: imported from blktap2, contains definitions for the tapdisk
    scheduler, the component that processes events, be it I/O requests or
    control commands
  * tapdisk.h: imported from blktap2, core header file that contains the
    definition of the I/O request
  * tapdisk-image.h: imported from blktap2, contains the definition of the
    Virtual Disk Image (VDI).
  * tapdisk-log.h: imported from blktap2, contains logging stuff
  * tapdisk-queue.h: imported from blktap2, contains the tapdisk I/O request
    and event queue.
  * tapdisk-server.h: imported from blktap2
  * tapdisk-stats.h: imported from blktap2.5, contains stats stuff
  * tapdisk-utils.h: imported from blktap2.5, contains assorted utility
    functions
  * tapdisk-vbd.h: imported from blktap2, contains the definition of the
    Virtual Block Device (VBD)

Also, the patch series contains the following blktap3-related changes:
  * Update declaration of function tapdisk_image_open_chain as it now uses
    the parent /path/to/file instead of the parent minor number.
  * Update declaration of function tapdisk_server_get_vbd as it now uses
    type:/path/to/file instead of the minor number.

Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx>

diff --git a/tools/blktap3/drivers/io-optimize.h 
b/tools/blktap3/drivers/io-optimize.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/io-optimize.h
@@ -0,0 +1,68 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __IO_OPTIMIZE_H__
+#define __IO_OPTIMIZE_H__
+
+#include <libaio.h>
+
+struct opio;
+
+struct opio_list {
+       struct opio        *head;
+       struct opio        *tail;
+};
+
+struct opio {
+       char               *buf;
+       unsigned long       nbytes;
+       long long           offset;
+       void               *data;
+       struct iocb        *iocb;
+       struct io_event     event;
+       struct opio        *head;
+       struct opio        *next;
+       struct opio_list    list;
+};
+
+struct opioctx {
+       int                 num_opios;
+       int                 free_opio_cnt;
+       struct opio        *opios;
+       struct opio       **free_opios;
+       struct iocb       **iocb_queue;
+       struct io_event    *event_queue;
+};
+
+int opio_init(struct opioctx *ctx, int num_iocbs);
+void opio_free(struct opioctx *ctx);
+int io_merge(struct opioctx *ctx, struct iocb **queue, int num);
+int io_split(struct opioctx *ctx, struct io_event *events, int num);
+int io_expand_iocbs(struct opioctx *ctx, struct iocb **queue, int idx, int 
num);
+
+#endif
diff --git a/tools/blktap3/drivers/scheduler.h 
b/tools/blktap3/drivers/scheduler.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/scheduler.h
@@ -0,0 +1,88 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SCHEDULER_H_
+#define _SCHEDULER_H_
+
+#include <sys/select.h>
+#include "blktap3.h"
+
+#define SCHEDULER_POLL_READ_FD       0x1
+#define SCHEDULER_POLL_WRITE_FD      0x2
+#define SCHEDULER_POLL_EXCEPT_FD     0x4
+#define SCHEDULER_POLL_TIMEOUT       0x8
+
+typedef int                          event_id_t;
+typedef void (*event_cb_t)          (event_id_t id, char mode, void *private);
+
+typedef struct event {
+    char mode;
+    char dead;
+    char pending;
+    char masked;
+
+    event_id_t id;
+
+    int fd;
+    int timeout;
+    int deadline;
+
+    event_cb_t cb;
+    void *private;
+
+    /*
+     * for linked lists
+     */
+     TAILQ_ENTRY(event) entry;
+} event_t;
+
+TAILQ_HEAD(tqh_event, event);
+
+typedef struct scheduler {
+       fd_set                       read_fds;
+       fd_set                       write_fds;
+       fd_set                       except_fds;
+
+       struct tqh_event             events;
+
+       int                          uuid;
+       int                          max_fd;
+       int                          timeout;
+       int                          max_timeout;
+       int                          depth;
+} scheduler_t;
+
+void scheduler_initialize(scheduler_t *);
+event_id_t scheduler_register_event(scheduler_t *, char mode,
+                                    int fd, int timeout,
+                                    event_cb_t cb, void *private);
+void scheduler_unregister_event(scheduler_t *,  event_id_t);
+void scheduler_mask_event(scheduler_t *, event_id_t, int masked);
+void scheduler_set_max_timeout(scheduler_t *, int);
+int scheduler_wait_for_events(scheduler_t *);
+
+#endif
diff --git a/tools/blktap3/drivers/tapdisk-blktap.h 
b/tools/blktap3/drivers/tapdisk-blktap.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-blktap.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010, Citrix Systems, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TAPDISK_BLKTAP_H_
+#define _TAPDISK_BLKTAP_H_
+
+typedef struct td_blktap td_blktap_t;
+typedef struct td_blktap_req td_blktap_req_t;
+
+#include "blktap3.h"
+#include "tapdisk-vbd.h"
+
+#if 0
+struct td_blktap_stats {
+    struct {
+        unsigned long long in;
+        unsigned long long out;
+    } reqs;
+    struct {
+        unsigned long long in;
+        unsigned long long out;
+    } kicks;
+};
+#endif
+
+struct td_blktap {
+    int minor;
+    //td_vbd_t *vbd;
+
+#if 0
+    int fd;
+#endif
+
+#if 0
+    void *vma;
+    size_t vma_size;
+
+    struct blktap_sring *sring;
+    unsigned int req_cons;
+    unsigned int rsp_prod_pvt;
+#endif
+
+#if 0
+    int event_id;
+    void *vstart;
+
+    int n_reqs;
+    td_blktap_req_t *reqs;
+    int n_reqs_free;
+    td_blktap_req_t **reqs_free;
+#endif
+
+    //TAILQ_ENTRY(td_blktap) entry;
+
+    //struct td_blktap_stats stats;
+};
+
+#endif /* _TAPDISK_BLKTAP_H_ */
diff --git a/tools/blktap3/drivers/tapdisk-image.h 
b/tools/blktap3/drivers/tapdisk-image.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-image.h
@@ -0,0 +1,119 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _TAPDISK_IMAGE_H_
+#define _TAPDISK_IMAGE_H_
+
+#include "tapdisk.h"
+
+TAILQ_HEAD(tqh_td_image_handle, td_image_handle);
+
+struct td_image_handle {
+       int                          type;
+       char                        *name;
+
+       td_flag_t                    flags;
+
+       td_driver_t                 *driver;
+       td_disk_info_t               info;
+
+    /*
+     * for linked lists
+     */
+     TAILQ_ENTRY(td_image_handle) entry;
+
+    /*
+     * Basic datapath statistics, in sectors read/written.
+     *
+     * hits:  requests completed by this image.
+     * fail:  requests completed with failure by this image.
+     *
+     * Not that we do not count e.g.
+     * miss:  requests forwarded.
+     * total: requests processed by this image.
+     *
+     * This is because we'd have to compensate for restarts due to
+     * -EBUSY conditions. Those can be extrapolated by following
+     * the chain instead: sum(image[i].hits, i=0..) == vbd.secs;
+     */
+    struct {
+        td_sector_count_t hits;
+        td_sector_count_t fail;
+    } stats;
+};
+
+#define tapdisk_for_each_image(_image, _head)                  \
+       TAILQ_FOREACH(_image, _head, entry)
+
+#define tapdisk_for_each_image_safe(_image, _next, _head)      \
+       TAILQ_FOREACH_SAFE(_image, _head, entry, _next)
+
+#define tapdisk_for_each_image_reverse(_image, _head)          \
+       TAILQ_FOREACH_REVERSE(_image, _head, tqh_td_image_handle, entry)
+
+#define tapdisk_image_entry(_head)             \
+       list_entry(_head, td_image_t, next)
+
+/**
+ * Opens an image.
+ *
+ * @param type the image type (DISK_TYPE_*)
+ * @param name TODO ?
+ * @param flags TODO ?
+ * @param _image output parameter that receives a handle to the opened image
+ * @returns 0 on success
+ */
+int tapdisk_image_open(const int type, const char *name, const int flags,
+                       td_image_t ** _image);
+
+void tapdisk_image_close(td_image_t *, struct tqh_td_image_handle *);
+
+/**
+ * Opens the image chain.
+ *
+ * @param params type:/path/to/file
+ * @param flags
+ * @param prt_path parent /path/to/file (optional)
+ * @param head
+ */
+int tapdisk_image_open_chain(const char *params, int flags,
+        const char* prt_path, struct tqh_td_image_handle *head);
+
+/**
+ * Closes all the images.
+ */
+void tapdisk_image_close_chain(struct tqh_td_image_handle *);
+int tapdisk_image_validate_chain(struct tqh_td_image_handle *);
+
+td_image_t *tapdisk_image_allocate(const char *, int, td_flag_t);
+void tapdisk_image_free(td_image_t *, struct tqh_td_image_handle *head);
+
+int tapdisk_image_check_td_request(td_image_t *, td_request_t);
+int tapdisk_image_check_request(td_image_t *, struct td_vbd_request *);
+void tapdisk_image_stats(td_image_t *, td_stats_t *);
+
+#endif
diff --git a/tools/blktap3/drivers/tapdisk-log.h 
b/tools/blktap3/drivers/tapdisk-log.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-log.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _TAPDISK_LOG_H_
+#define _TAPDISK_LOG_H_
+
+#define TLOG_WARN       0
+#define TLOG_INFO       1
+#define TLOG_DBG        2
+
+#define TLOG_DIR "/var/log/blktap"
+
+#include <stdarg.h>
+#include "blktap3.h"
+
+int tlog_open(const char *, int, int);
+void tlog_close(void);
+void tlog_precious(void);
+void tlog_vsyslog(int, const char *, va_list);
+void tlog_syslog(int, const char *, ...);
+
+#include <syslog.h>
+
+#define EPRINTF(_f, _a...) syslog(LOG_ERR, "%s:%d " _f, __FILE__, __LINE__, \
+    ##_a)
+#define DPRINTF(_f, _a...) syslog(LOG_INFO, "%s:%d "_f, __FILE__, __LINE__, \
+    ##_a)
+#define PERROR(_f, _a...)  EPRINTF(_f ": %s", ##_a, strerror(errno))
+
+void __tlog_write(int, const char *, ...) __printf(2, 3);
+void __tlog_error(const char *fmt, ...) __printf(1, 2);
+
+#define tlog_write(_level, _f, _a...)                  \
+       __tlog_write(_level, "%s: " _f,  __func__, ##_a)
+
+#define tlog_error(_err, _f, _a...)                    \
+       __tlog_error("ERROR: errno %d at %s: " _f,      \
+                    (int)_err, __func__, ##_a)
+
+#define tlog_drv_error(_drv, _err, _f, _a ...) do {    \
+       if (tapdisk_driver_log_pass(_drv, __func__))    \
+               tlog_error(_err, _f, ##_a);             \
+} while (0)
+
+#endif /* __TAPDISK_LOG_H__ */
diff --git a/tools/blktap3/drivers/tapdisk-queue.h 
b/tools/blktap3/drivers/tapdisk-queue.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-queue.h
@@ -0,0 +1,125 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TAPDISK_QUEUE_H
+#define TAPDISK_QUEUE_H
+
+#include <libaio.h>
+
+#include "io-optimize.h"
+#include "scheduler.h"
+
+struct tiocb;
+struct tfilter;
+
+typedef void (*td_queue_callback_t)(void *arg, struct tiocb *, int err);
+
+
+struct tiocb {
+       td_queue_callback_t   cb;
+       void                 *arg;
+
+       struct iocb           iocb;
+       struct tiocb         *next;
+};
+
+struct tlist {
+       struct tiocb         *head;
+       struct tiocb         *tail;
+};
+
+struct tqueue {
+       int                   size;
+
+       const struct tio     *tio;
+       void                 *tio_data;
+
+       struct opioctx        opioctx;
+
+       int                   queued;
+       struct iocb         **iocbs;
+
+       /* number of iocbs pending in the aio layer */
+       int                   iocbs_pending;
+
+       /* number of tiocbs pending in the queue -- 
+        * this is likely to be larger than iocbs_pending 
+        * due to request coalescing */
+       int                   tiocbs_pending;
+
+       /* iocbs may be deferred if the aio ring is full.
+        * tapdisk_queue_complete will ensure deferred
+        * iocbs are queued as slots become available. */
+       struct tlist          deferred;
+       int                   tiocbs_deferred;
+
+       /* optional tapdisk filter */
+       struct tfilter       *filter;
+
+       uint64_t              deferrals;
+};
+
+struct tio {
+       const char           *name;
+       size_t                data_size;
+
+       int  (*tio_setup)    (struct tqueue *queue, int qlen);
+       void (*tio_destroy)  (struct tqueue *queue);
+       int  (*tio_submit)   (struct tqueue *queue);
+};
+
+enum {
+       TIO_DRV_LIO     = 1,
+       TIO_DRV_RWIO    = 2,
+};
+
+/*
+ * Interface for request producer (i.e., tapdisk)
+ * NB: the following functions may cause additional tiocbs to be queued:
+ *        - tapdisk_submit_tiocbs
+ *        - tapdisk_cancel_tiocbs
+ *        - tapdisk_complete_tiocbs
+ * The *_all_tiocbs variants will handle the first two cases;
+ * be sure to call submit after calling complete in the third case.
+ */
+#define tapdisk_queue_count(q) ((q)->queued)
+#define tapdisk_queue_empty(q) ((q)->queued == 0)
+#define tapdisk_queue_full(q)  \
+       (((q)->tiocbs_pending + (q)->queued) >= (q)->size)
+int tapdisk_init_queue(struct tqueue *, int size, int drv, struct tfilter *);
+void tapdisk_free_queue(struct tqueue *);
+void tapdisk_debug_queue(struct tqueue *);
+void tapdisk_queue_tiocb(struct tqueue *, struct tiocb *);
+int tapdisk_submit_tiocbs(struct tqueue *);
+int tapdisk_submit_all_tiocbs(struct tqueue *);
+int tapdisk_cancel_tiocbs(struct tqueue *);
+int tapdisk_cancel_all_tiocbs(struct tqueue *);
+void tapdisk_prep_tiocb(struct tiocb *, int, int, char *, size_t,
+                       long long, td_queue_callback_t, void *);
+
+#endif
diff --git a/tools/blktap3/drivers/tapdisk-server.h 
b/tools/blktap3/drivers/tapdisk-server.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-server.h
@@ -0,0 +1,76 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _TAPDISK_SERVER_H_
+#define _TAPDISK_SERVER_H_
+
+#include "tapdisk-vbd.h"
+#include "tapdisk-queue.h"
+
+struct tap_disk *tapdisk_server_find_driver_interface(int);
+
+td_image_t *tapdisk_server_get_shared_image(td_image_t *);
+
+struct tqh_td_vbd_handle *tapdisk_server_get_all_vbds(void);
+
+/**
+ * Returns the VBD that corresponds to the specified type:/path/to/file.
+ * Returns NULL if such a VBD does not exist.
+ */
+td_vbd_t *tapdisk_server_get_vbd(const char *params);
+
+/**
+ * Adds the VBD to end of the list of VBDs.
+ */
+void tapdisk_server_add_vbd(td_vbd_t *);
+
+/**
+ * Removes the VBDs from the list of VBDs.
+ */
+void tapdisk_server_remove_vbd(td_vbd_t *);
+
+void tapdisk_server_queue_tiocb(struct tiocb *);
+
+void tapdisk_server_check_state(void);
+
+event_id_t tapdisk_server_register_event(char, int, int, event_cb_t, void *);
+void tapdisk_server_unregister_event(event_id_t);
+void tapdisk_server_mask_event(event_id_t, int);
+void tapdisk_server_set_max_timeout(int);
+
+int tapdisk_server_init(void);
+int tapdisk_server_initialize(const char *, const char *);
+int tapdisk_server_complete(void);
+int tapdisk_server_run(void);
+void tapdisk_server_iterate(void);
+
+int tapdisk_server_openlog(const char *, int, int);
+void tapdisk_server_closelog(void);
+void tapdisk_start_logging(const char *, const char *);
+void tapdisk_stop_logging(void);
+
+#endif
diff --git a/tools/blktap3/drivers/tapdisk-stats.h 
b/tools/blktap3/drivers/tapdisk-stats.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-stats.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010, Citrix Systems, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TAPDISK_STATS_H_
+#define _TAPDISK_STATS_H_
+
+#include <string.h>
+
+#define TD_STATS_MAX_DEPTH 8
+
+struct tapdisk_stats_ctx {
+    void *pos;
+
+    void *buf;
+    size_t size;
+
+    int n_elem[TD_STATS_MAX_DEPTH];
+    int depth;
+};
+
+typedef struct tapdisk_stats_ctx td_stats_t;
+
+static inline void
+tapdisk_stats_init(td_stats_t * st, char *buf, size_t size)
+{
+    memset(st, 0, sizeof(*st));
+
+    st->pos = buf;
+    st->buf = buf;
+    st->size = size;
+}
+
+static inline size_t tapdisk_stats_length(td_stats_t * st)
+{
+    return st->pos - st->buf;
+}
+
+void tapdisk_stats_enter(td_stats_t * st, char t);
+void tapdisk_stats_leave(td_stats_t * st, char t);
+void tapdisk_stats_field(td_stats_t * st, const char *key,
+                         const char *conv, ...);
+void tapdisk_stats_val(td_stats_t * st, const char *conv, ...);
+
+#endif /* _TAPDISK_STATS_H_ */
diff --git a/tools/blktap3/drivers/tapdisk-utils.h 
b/tools/blktap3/drivers/tapdisk-utils.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk-utils.h
@@ -0,0 +1,49 @@
+/* 
+ * Copyright (c) 2008, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _TAPDISK_UTILS_H_
+#define _TAPDISK_UTILS_H_
+
+#include <inttypes.h>
+#include <sys/time.h>
+#include <stddef.h>
+
+#define MAX_NAME_LEN          1000
+#define TD_SYSLOG_IDENT_MAX   32
+#define TD_SYSLOG_STRTIME_LEN 15
+
+int tapdisk_syslog_facility(const char *);
+char *tapdisk_syslog_ident(const char *);
+size_t tapdisk_syslog_strftime(char *, size_t, const struct timeval *);
+size_t tapdisk_syslog_strftv(char *, size_t, const struct timeval *);
+int tapdisk_set_resource_limits(void);
+int tapdisk_namedup(char **, const char *);
+int tapdisk_parse_disk_type(const char *, char **, int *);
+int tapdisk_get_image_size(int, uint64_t *, uint32_t *);
+int tapdisk_linux_version(void);
+
+#endif
diff --git a/tools/blktap2/drivers/tapdisk-vbd.h 
b/tools/blktap3/drivers/tapdisk-vbd.h
copy from tools/blktap2/drivers/tapdisk-vbd.h
copy to tools/blktap3/drivers/tapdisk-vbd.h
--- a/tools/blktap2/drivers/tapdisk-vbd.h
+++ b/tools/blktap3/drivers/tapdisk-vbd.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (c) 2008, XenSource Inc.
  * All rights reserved.
  *
@@ -24,18 +24,18 @@
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
 #ifndef _TAPDISK_VBD_H_
 #define _TAPDISK_VBD_H_
 
 #include <sys/time.h>
-#include <xenctrl.h>
-#include <xen/io/blkif.h>
 
 #include "tapdisk.h"
 #include "scheduler.h"
 #include "tapdisk-image.h"
+#include "sring/td-blkif.h"
 
+#define TD_VBD_REQUEST_TIMEOUT      120
 #define TD_VBD_MAX_RETRIES          100
 #define TD_VBD_RETRY_INTERVAL       1
 
@@ -47,75 +47,54 @@
 #define TD_VBD_PAUSED               0x0020
 #define TD_VBD_SHUTDOWN_REQUESTED   0x0040
 #define TD_VBD_LOCKING              0x0080
-#define TD_VBD_RETRY_NEEDED         0x0100
-#define TD_VBD_LOG_DROPPED          0x0200
+#define TD_VBD_LOG_DROPPED          0x0100
 
-typedef struct td_ring              td_ring_t;
-typedef struct td_vbd_request       td_vbd_request_t;
-typedef struct td_vbd_driver_info   td_vbd_driver_info_t;
-typedef struct td_vbd_handle        td_vbd_t;
-typedef void (*td_vbd_cb_t)        (void *, blkif_response_t *);
+#define TD_VBD_SECONDARY_DISABLED   0
+#define TD_VBD_SECONDARY_MIRROR     1
+#define TD_VBD_SECONDARY_STANDBY    2
 
-struct td_ring {
-       int                         fd;
-       char                       *mem;
-       blkif_sring_t              *sring;
-       blkif_back_ring_t           fe_ring;
-       unsigned long               vstart;
-};
-
-struct td_vbd_request {
-       blkif_request_t             req;
-       int16_t                     status;
-
-       int                         error;
-       int                         blocked; /* blocked on a dependency */
-       int                         submitting;
-       int                         secs_pending;
-       int                         num_retries;
-       struct timeval              last_try;
-
-       td_vbd_t                   *vbd;
-       struct list_head            next;
-};
-
-struct td_vbd_driver_info {
-       char                       *params;
-       int                         type;
-       struct list_head            next;
-};
+TAILQ_HEAD(tqh_td_vbd_handle, td_vbd_handle);
 
 struct td_vbd_handle {
+    /**
+     * type:/path/to/file
+     */
        char                       *name;
 
-       td_uuid_t                   uuid;
-       int                         minor;
+    /**
+     * shared ring
+     */
+    struct td_xenblkif         *tap;
 
-       struct list_head            driver_stack;
-
-       int                         storage;
-
-       uint8_t                     reopened;
-       uint8_t                     reactivated;
        td_flag_t                   flags;
        td_flag_t                   state;
 
-       struct list_head            images;
+       struct tqh_td_image_handle  images;
 
-       struct list_head            new_requests;
-       struct list_head            pending_requests;
-       struct list_head            failed_requests;
-       struct list_head            completed_requests;
+       int                         parent_devnum;
+       char                       *secondary_name;
+       td_image_t                 *secondary;
+       uint8_t                     secondary_mode;
 
-       td_vbd_request_t            request_list[MAX_REQUESTS];
+       /* TODO ??? */
+       int                         FIXME_enospc_redirect_count_enabled;
+       uint64_t                    FIXME_enospc_redirect_count;
 
-       td_ring_t                   ring;
-       event_id_t                  ring_event_id;
+       /* when we encounter ENOSPC on the primary leaf image in mirror mode, 
+        * we need to remove it from the VBD chain so that writes start going 
+        * on the secondary leaf. However, we cannot free the image at that 
+        * time since it might still have in-flight treqs referencing it.  
+        * Therefore, we move it into 'retired' until shutdown. */
+       td_image_t                 *retired;
 
-       td_vbd_cb_t                 callback;
-       void                       *argument;
+       struct tqh_td_vbd_request   new_requests;
+       struct tqh_td_vbd_request   pending_requests;
+       struct tqh_td_vbd_request   failed_requests;
+       struct tqh_td_vbd_request   completed_requests;
 
-       struct list_head            next;
+       td_vbd_request_t            request_list[MAX_REQUESTS];    /* XXX */
+
+    TAILQ_ENTRY(td_vbd_handle) entry;
 
        struct timeval              ts;
 
@@ -125,83 +104,119 @@ struct td_vbd_handle {
        uint64_t                    secs_pending;
        uint64_t                    retries;
        uint64_t                    errors;
+       td_sector_count_t           secs;
 };
 
 #define tapdisk_vbd_for_each_request(vreq, tmp, list)                  \
-       list_for_each_entry_safe((vreq), (tmp), (list), next)
+       TAILQ_FOREACH_SAFE((vreq), (list), next, (tmp))
 
 #define tapdisk_vbd_for_each_image(vbd, image, tmp)                    \
-       list_for_each_entry_safe((image), (tmp), &(vbd)->images, next)
+       tapdisk_for_each_image_safe(image, tmp, &vbd->images)
 
+/**
+ * Removes the request from its current queue and inserts it to the specified
+ * one.
+ */
 static inline void
-tapdisk_vbd_move_request(td_vbd_request_t *vreq, struct list_head *dest)
+tapdisk_vbd_move_request(td_vbd_request_t * vreq,
+                         struct tqh_td_vbd_request *dest)
 {
-       list_del(&vreq->next);
-       INIT_LIST_HEAD(&vreq->next);
-       list_add_tail(&vreq->next, dest);
+    assert(vreq);
+    assert(dest);
+
+    assert(vreq->list_head);
+    TAILQ_REMOVE(vreq->list_head, vreq, next);
+
+    TAILQ_INSERT_TAIL(dest, vreq, next);
+
+    vreq->list_head = dest;
 }
 
 static inline void
 tapdisk_vbd_add_image(td_vbd_t *vbd, td_image_t *image)
 {
-       list_add_tail(&image->next, &vbd->images);
+    TAILQ_INSERT_TAIL(&vbd->images, image, entry);
 }
 
 static inline int
 tapdisk_vbd_is_last_image(td_vbd_t *vbd, td_image_t *image)
 {
-       return list_is_last(&image->next, &vbd->images);
+    return TAILQ_LAST(&vbd->images, tqh_td_image_handle) == image;
 }
 
-td_image_t *
-tapdisk_vbd_first_image(td_vbd_t *vbd);
+/**
+ * Retrieves the first image of this VBD.
+ */
+static inline td_image_t *
+tapdisk_vbd_first_image(td_vbd_t *vbd)
+{
+    td_image_t *image = NULL;
+    if (!TAILQ_EMPTY(&vbd->images))
+        image = TAILQ_FIRST(&vbd->images);
+    return image;
+}
 
 static inline td_image_t *
 tapdisk_vbd_last_image(td_vbd_t *vbd)
 {
-       return list_entry(vbd->images.prev, td_image_t, next);
+    td_image_t *image = NULL;
+    if (!TAILQ_EMPTY(&vbd->images))
+        image = TAILQ_LAST(&vbd->images, tqh_td_image_handle);
+    return image;
 }
 
-static inline td_image_t *
-tapdisk_vbd_next_image(td_image_t *image)
+static inline td_image_t *tapdisk_vbd_next_image(td_image_t * image)
 {
-       return list_entry(image->next.next, td_image_t, next);
+    return TAILQ_NEXT(image, entry);
 }
 
-td_vbd_t *tapdisk_vbd_create(td_uuid_t);
-int tapdisk_vbd_initialize(td_uuid_t);
-void tapdisk_vbd_set_callback(td_vbd_t *, td_vbd_cb_t, void *);
-int tapdisk_vbd_parse_stack(td_vbd_t *vbd, const char *path);
-int tapdisk_vbd_open(td_vbd_t *, const char *, uint16_t,
-                    uint16_t, int, const char *, td_flag_t);
+td_vbd_t *tapdisk_vbd_create(void);
+
+int tapdisk_vbd_initialize(int rfd, int wfd, const char * params);
+
+/*
+ * XXX Function definition commented out in blktap2.5.
+ */
+int tapdisk_vbd_open(td_vbd_t *, const char *, int, const char *, td_flag_t);
+
 int tapdisk_vbd_close(td_vbd_t *);
-void tapdisk_vbd_free(td_vbd_t *);
-void tapdisk_vbd_free_stack(td_vbd_t *);
 
-int tapdisk_vbd_open_stack(td_vbd_t *, uint16_t, td_flag_t);
-int tapdisk_vbd_open_vdi(td_vbd_t *, const char *,
-                        uint16_t, uint16_t, td_flag_t);
+/**
+ * Opens a VDI.
+ *
+ * @params vbd output parameter that receives a handle to the opened VDI
+ * @param params type:/path/to/file
+ * @params flags TD_OPEN_* TODO which TD_OPEN_* flags are honored? How does
+ * each flag affect the behavior of this functions? Move TD_OPEN_* flag
+ * definitions close to this function (check if they're used only by this
+ * function)?
+ * @param prt_path parent /path/to/file (optional)
+ * @returns 0 on success
+ */
+int tapdisk_vbd_open_vdi(td_vbd_t * vbd, const char *params, td_flag_t flags,
+        const char * prt_path);
+
+/**
+ * Closes a VDI.
+ */
 void tapdisk_vbd_close_vdi(td_vbd_t *);
 
-int tapdisk_vbd_attach(td_vbd_t *, const char *, int);
-void tapdisk_vbd_detach(td_vbd_t *);
-
+int tapdisk_vbd_queue_request(td_vbd_t *, td_vbd_request_t *);
 void tapdisk_vbd_forward_request(td_request_t);
 
-int tapdisk_vbd_get_image_info(td_vbd_t *, image_t *);
-int tapdisk_vbd_queue_ready(td_vbd_t *);
+int tapdisk_vbd_get_disk_info(td_vbd_t *, td_disk_info_t *);
 int tapdisk_vbd_retry_needed(td_vbd_t *);
 int tapdisk_vbd_quiesce_queue(td_vbd_t *);
 int tapdisk_vbd_start_queue(td_vbd_t *);
 int tapdisk_vbd_issue_requests(td_vbd_t *);
 int tapdisk_vbd_kill_queue(td_vbd_t *);
 int tapdisk_vbd_pause(td_vbd_t *);
-int tapdisk_vbd_resume(td_vbd_t *, const char *, uint16_t);
-int tapdisk_vbd_kick(td_vbd_t *);
+int tapdisk_vbd_resume(td_vbd_t *, const char *);
+void tapdisk_vbd_kick(td_vbd_t *);
 void tapdisk_vbd_check_state(td_vbd_t *);
+int tapdisk_vbd_recheck_state(td_vbd_t *);
 void tapdisk_vbd_check_progress(td_vbd_t *);
 void tapdisk_vbd_debug(td_vbd_t *);
-
-void tapdisk_vbd_complete_vbd_request(td_vbd_t *, td_vbd_request_t *);
+void tapdisk_vbd_stats(td_vbd_t *, td_stats_t *);
 
 #endif
diff --git a/tools/blktap3/drivers/tapdisk.h b/tools/blktap3/drivers/tapdisk.h
new file mode 100644
--- /dev/null
+++ b/tools/blktap3/drivers/tapdisk.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2007, XenSource Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * Some notes on the tap_disk interface:
+ * 
+ * tap_disk aims to provide a generic interface to easily implement new 
+ * types of image accessors.  The structure-of-function-calls is similar
+ * to disk interfaces used in qemu/denali/etc, with the significant 
+ * difference being the expectation of asynchronous rather than synchronous 
+ * I/O.  The asynchronous interface is intended to allow lots of requests to
+ * be pipelined through a disk, without the disk requiring any of its own
+ * threads of control.  As such, a batch of requests is delivered to the disk
+ * using:
+ * 
+ *    td_queue_[read,write]()
+ * 
+ * and passing in a completion callback, which the disk is responsible for 
+ * tracking.  Disks should transform these requests as necessary and return
+ * the resulting iocbs to tapdisk using td_prep_[read,write]() and 
+ * td_queue_tiocb().
+ *
+ * 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_
+#define _TAPDISK_H_
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <assert.h>
+
+// XXX?
+//#include "blktaplib.h"
+#include "blktap3.h"
+
+// TODO necessary?
+#include "tapdisk-log.h"
+#include "tapdisk-utils.h"
+#include "tapdisk-stats.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a)[0])
+
+#define MAX_SEGMENTS_PER_REQ         11
+#define MAX_REQUESTS                 32U
+#define SECTOR_SHIFT                 9
+#define DEFAULT_SECTOR_SIZE          512
+
+#define TAPDISK_DATA_REQUESTS       (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
+
+//#define BLK_NOT_ALLOCATED            (-99)
+#define TD_NO_PARENT                 1
+
+#define MAX_RAMDISK_SIZE             1024000 /*500MB disk limit */
+
+#define TD_OP_READ                   0
+#define TD_OP_WRITE                  1
+
+#define TD_OPEN_QUIET                0x00001
+#define TD_OPEN_QUERY                0x00002
+#define TD_OPEN_RDONLY               0x00004
+#define TD_OPEN_STRICT               0x00008
+#define TD_OPEN_SHAREABLE            0x00010
+#define TD_OPEN_ADD_CACHE            0x00020
+#define TD_OPEN_VHD_INDEX            0x00040
+#define TD_OPEN_LOG_DIRTY            0x00080
+#define TD_OPEN_LOCAL_CACHE          0x00100
+#define TD_OPEN_REUSE_PARENT         0x00200
+#define TD_OPEN_SECONDARY            0x00400
+#define TD_OPEN_STANDBY              0x00800
+#define TD_IGNORE_ENOSPC             0x01000
+
+#define TD_CREATE_SPARSE             0x00001
+#define TD_CREATE_MULTITYPE          0x00002
+
+#define td_flag_set(word, flag)      ((word) |= (flag))
+#define td_flag_clear(word, flag)    ((word) &= ~(flag))
+#define td_flag_test(word, flag)     ((word) & (flag))
+
+typedef uint16_t                     td_uuid_t;
+typedef uint32_t                     td_flag_t;
+typedef uint64_t                     td_sector_t;
+typedef struct td_disk_id            td_disk_id_t;
+typedef struct td_disk_info          td_disk_info_t;
+typedef struct td_request            td_request_t;
+typedef struct td_driver_handle      td_driver_t;
+typedef struct td_image_handle       td_image_t;
+typedef struct td_sector_count       td_sector_count_t;
+typedef struct td_vbd_request        td_vbd_request_t;
+typedef struct td_vbd_handle         td_vbd_t;
+
+/*
+ * Prototype of the callback to activate as requests complete.
+ */
+typedef void (*td_callback_t) (td_request_t, int);
+typedef void (*td_vreq_callback_t) (td_vbd_request_t *, int, void *, int);
+
+struct td_disk_id {
+       char                        *name;
+       int                          type;
+       int                          flags;
+};
+
+struct td_disk_info {
+       td_sector_t                  size;
+       long                         sector_size;
+       uint32_t                     info;
+};
+
+
+TAILQ_HEAD(tqh_td_vbd_request, td_vbd_request);
+
+struct td_vbd_request {
+
+    /**
+     * Operation: read/write
+     */
+       int                          op;
+
+    /**
+     * Start sector.
+     */
+       td_sector_t                  sec;
+
+    /**
+     * Scatter/gather list.
+     */
+       struct td_iovec             *iov;
+       int                          iovcnt;
+
+    /**
+     * Completion callback.
+     */
+       td_vreq_callback_t          cb;
+
+       void                       *token;
+       const char                 *name;
+
+       int                         error;
+       int                         prev_error;
+
+       int                         submitting;
+       int                         secs_pending;
+       int                         num_retries;
+       struct timeval              ts;
+       struct timeval              last_try;
+
+    /**
+     * VBD this request belongs to.
+     */
+       td_vbd_t                   *vbd;
+
+    /*
+     * linked list of struct td_vbd_request
+     */
+       TAILQ_ENTRY(td_vbd_request) next;
+
+    /*
+     * TODO list head of what?
+     */
+       struct tqh_td_vbd_request  *list_head;
+};
+
+/* TODO why have these two types (td_request and td_vbd_request) separate? */
+struct td_request {
+    int                          op;
+    void                        *buf;
+
+    td_sector_t                  sec;
+    int                          secs;
+
+    td_image_t                  *image;
+
+    td_callback_t                cb;
+    void                        *cb_data;
+
+    int                          sidx;
+    td_vbd_request_t            *vreq;
+};
+
+/* 
+ * Structure describing the interface to a virtual disk implementation.
+ * See note at the top of this file describing this interface.
+ */
+struct tap_disk {
+       const char                  *disk_type;
+       td_flag_t                    flags;
+       int                          private_data_size;
+       int (*td_open)               (td_driver_t *, const char *, td_flag_t);
+       int (*td_close)              (td_driver_t *);
+       int (*td_get_parent_id)      (td_driver_t *, td_disk_id_t *);
+       int (*td_validate_parent)    (td_driver_t *, td_driver_t *, td_flag_t);
+       void (*td_queue_read)        (td_driver_t *, td_request_t);
+       void (*td_queue_write)       (td_driver_t *, td_request_t);
+       void (*td_debug)             (td_driver_t *);
+       void (*td_stats)             (td_driver_t *, td_stats_t *);
+};
+
+struct td_sector_count {
+    td_sector_t rd;
+    td_sector_t wr;
+};
+
+static inline void
+td_sector_count_add(td_sector_count_t * s, td_sector_t v, int write)
+{
+    if (write)
+        s->wr += v;
+    else
+        s->rd += v;
+}
+
+void td_panic(void);
+
+/* TODO why not use struct iovec? */
+struct td_iovec {
+    void *base;
+    unsigned int secs;
+};
+
+#endif /* __TAPDISK_H__ */

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.