1 /* 2 * Copyright (c) 2007, XenSource Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of XenSource Inc. nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Some notes on the tap_disk interface: 29 * 30 * tap_disk aims to provide a generic interface to easily implement new 31 * types of image accessors. The structure-of-function-calls is similar 32 * to disk interfaces used in qemu/denali/etc, with the significant 33 * difference being the expectation of asynchronous rather than synchronous 34 * I/O. The asynchronous interface is intended to allow lots of requests to 35 * be pipelined through a disk, without the disk requiring any of its own 36 * threads of control. As such, a batch of requests is delivered to the disk 37 * using: 38 * 39 * td_queue_[read,write]() 40 * 41 * and passing in a completion callback, which the disk is responsible for 42 * tracking. Disks should transform these requests as necessary and return 43 * the resulting iocbs to tapdisk using td_prep_[read,write]() and 44 * td_queue_tiocb(). 45 * 46 * NOTE: tapdisk uses the number of sectors submitted per request as a 47 * ref count. Plugins must use the callback function to communicate the 48 * completion -- or error -- of every sector submitted to them. 49 * 50 * td_get_parent_id returns: 51 * 0 if parent id successfully retrieved 52 * TD_NO_PARENT if no parent exists 53 * -errno on error 54 */ 55 56 #ifndef _TAPDISK_H_ 57 #define _TAPDISK_H_ 58 59 #include <time.h> 60 #include <stdint.h> 61 62 #include "list.h" 63 #include "blktaplib.h" 64 #include "tapdisk-log.h" 65 #include "tapdisk-utils.h" 66 67 #ifdef MEMSHR 68 #include "memshr.h" 69 #endif 70 71 #define DPRINTF(_f, _a...) syslog(LOG_INFO, _f, ##_a) 72 #define EPRINTF(_f, _a...) syslog(LOG_ERR, "tap-err:%s: " _f, __func__, ##_a) 73 #define PERROR(_f, _a...) EPRINTF(_f ": %s", ##_a, strerror(errno)) 74 75 #define MAX_SEGMENTS_PER_REQ 11 76 #define SECTOR_SHIFT 9 77 #define DEFAULT_SECTOR_SIZE 512 78 79 #define TAPDISK_DATA_REQUESTS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ) 80 81 //#define BLK_NOT_ALLOCATED (-99) 82 #define TD_NO_PARENT 1 83 84 #define MAX_RAMDISK_SIZE 1024000 /*500MB disk limit*/ 85 86 #define TD_OP_READ 0 87 #define TD_OP_WRITE 1 88 89 #define TD_OPEN_QUIET 0x00001 90 #define TD_OPEN_QUERY 0x00002 91 #define TD_OPEN_RDONLY 0x00004 92 #define TD_OPEN_STRICT 0x00008 93 #define TD_OPEN_SHAREABLE 0x00010 94 #define TD_OPEN_ADD_CACHE 0x00020 95 #define TD_OPEN_VHD_INDEX 0x00040 96 #define TD_OPEN_LOG_DIRTY 0x00080 97 98 #define TD_CREATE_SPARSE 0x00001 99 #define TD_CREATE_MULTITYPE 0x00002 100 101 #define td_flag_set(word, flag) ((word) |= (flag)) 102 #define td_flag_clear(word, flag) ((word) &= ~(flag)) 103 #define td_flag_test(word, flag) ((word) & (flag)) 104 105 typedef uint16_t td_uuid_t; 106 typedef uint32_t td_flag_t; 107 typedef uint64_t td_sector_t; 108 typedef struct td_disk_id td_disk_id_t; 109 typedef struct td_disk_info td_disk_info_t; 110 typedef struct td_request td_request_t; 111 typedef struct td_driver_handle td_driver_t; 112 typedef struct td_image_handle td_image_t; 113 114 struct td_disk_id { 115 char *name; 116 int drivertype; 117 }; 118 119 struct td_disk_info { 120 td_sector_t size; 121 uint64_t sector_size; 122 uint32_t info; 123 }; 124 125 struct td_request { 126 int op; 127 char *buf; 128 td_sector_t sec; 129 int secs; 130 131 uint8_t blocked; /* blocked on a dependency */ 132 133 td_image_t *image; 134 135 void * /*td_callback_t*/ cb; 136 void *cb_data; 137 138 uint64_t id; 139 int sidx; 140 void *private; 141 142 #ifdef MEMSHR 143 share_tuple_t memshr_hnd; 144 #endif 145 }; 146 147 /* 148 * Prototype of the callback to activate as requests complete. 149 */ 150 typedef void (*td_callback_t)(td_request_t, int); 151 152 /* 153 * Structure describing the interface to a virtual disk implementation. 154 * See note at the top of this file describing this interface. 155 */ 156 struct tap_disk { 157 const char *disk_type; 158 td_flag_t flags; 159 int private_data_size; 160 int (*td_open) (td_driver_t *, const char *, td_flag_t); 161 int (*td_close) (td_driver_t *); 162 int (*td_get_parent_id) (td_driver_t *, td_disk_id_t *); 163 int (*td_validate_parent) (td_driver_t *, td_driver_t *, td_flag_t); 164 void (*td_queue_read) (td_driver_t *, td_request_t); 165 void (*td_queue_write) (td_driver_t *, td_request_t); 166 void (*td_debug) (td_driver_t *); 167 }; 168 169 #endif 170