1 /* 2 * Copyright (c) 2008, 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 29 #ifndef TAPDISK_QUEUE_H 30 #define TAPDISK_QUEUE_H 31 32 #include <libaio.h> 33 34 #include "io-optimize.h" 35 #include "scheduler.h" 36 37 struct tiocb; 38 struct tfilter; 39 40 typedef void (*td_queue_callback_t)(void *arg, struct tiocb *, int err); 41 42 43 struct tiocb { 44 td_queue_callback_t cb; 45 void *arg; 46 47 struct iocb iocb; 48 struct tiocb *next; 49 }; 50 51 struct tlist { 52 struct tiocb *head; 53 struct tiocb *tail; 54 }; 55 56 struct tqueue { 57 int size; 58 59 const struct tio *tio; 60 void *tio_data; 61 62 struct opioctx opioctx; 63 64 int queued; 65 struct iocb **iocbs; 66 67 /* number of iocbs pending in the aio layer */ 68 int iocbs_pending; 69 70 /* number of tiocbs pending in the queue -- 71 * this is likely to be larger than iocbs_pending 72 * due to request coalescing */ 73 int tiocbs_pending; 74 75 /* iocbs may be deferred if the aio ring is full. 76 * tapdisk_queue_complete will ensure deferred 77 * iocbs are queued as slots become available. */ 78 struct tlist deferred; 79 int tiocbs_deferred; 80 81 /* optional tapdisk filter */ 82 struct tfilter *filter; 83 84 uint64_t deferrals; 85 }; 86 87 struct tio { 88 const char *name; 89 size_t data_size; 90 91 int (*tio_setup) (struct tqueue *queue, int qlen); 92 void (*tio_destroy) (struct tqueue *queue); 93 int (*tio_submit) (struct tqueue *queue); 94 }; 95 96 enum { 97 TIO_DRV_LIO = 1, 98 TIO_DRV_RWIO = 2, 99 }; 100 101 /* 102 * Interface for request producer (i.e., tapdisk) 103 * NB: the following functions may cause additional tiocbs to be queued: 104 * - tapdisk_submit_tiocbs 105 * - tapdisk_cancel_tiocbs 106 * - tapdisk_complete_tiocbs 107 * The *_all_tiocbs variants will handle the first two cases; 108 * be sure to call submit after calling complete in the third case. 109 */ 110 #define tapdisk_queue_count(q) ((q)->queued) 111 #define tapdisk_queue_empty(q) ((q)->queued == 0) 112 #define tapdisk_queue_full(q) \ 113 (((q)->tiocbs_pending + (q)->queued) >= (q)->size) 114 int tapdisk_init_queue(struct tqueue *, int size, int drv, struct tfilter *); 115 void tapdisk_free_queue(struct tqueue *); 116 void tapdisk_debug_queue(struct tqueue *); 117 void tapdisk_queue_tiocb(struct tqueue *, struct tiocb *); 118 int tapdisk_submit_tiocbs(struct tqueue *); 119 int tapdisk_submit_all_tiocbs(struct tqueue *); 120 int tapdisk_cancel_tiocbs(struct tqueue *); 121 int tapdisk_cancel_all_tiocbs(struct tqueue *); 122 void tapdisk_prep_tiocb(struct tiocb *, int, int, char *, size_t, 123 long long, td_queue_callback_t, void *); 124 125 #endif 126