1 /* nbdkit 2 * Copyright (C) 2013-2020 Red Hat Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * * Neither the name of Red Hat nor the names of its contributors may be 16 * used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* See nbdkit-filter(3) for documentation and how to write a filter. */ 34 35 #ifndef NBDKIT_FILTER_H 36 #define NBDKIT_FILTER_H 37 38 #include <stdlib.h> 39 40 #include <nbdkit-common.h> 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 #define NBDKIT_FILTER_API_VERSION 6 /* Corresponding to v1.16+ */ 47 48 #define NBDKIT_ZERO_NONE 0 49 #define NBDKIT_ZERO_EMULATE 1 50 #define NBDKIT_ZERO_NATIVE 2 51 52 #ifdef NBDKIT_INTERNAL 53 /* Opaque type encapsulating all information needed for calling into 54 * the next filter or plugin. 55 */ 56 typedef struct backend nbdkit_backend; 57 #else 58 typedef void nbdkit_backend; 59 #endif 60 61 /* Next ops. */ 62 typedef int nbdkit_next_config (nbdkit_backend *nxdata, 63 const char *key, const char *value); 64 typedef int nbdkit_next_config_complete (nbdkit_backend *nxdata); 65 typedef int nbdkit_next_get_ready (nbdkit_backend *nxdata); 66 typedef int nbdkit_next_preconnect (nbdkit_backend *nxdata, int readonly); 67 typedef int nbdkit_next_open (nbdkit_backend *nxdata, int readonly); 68 69 struct nbdkit_next_ops { 70 /* Performs close + open on the underlying chain. 71 * Used by the retry filter. 72 */ 73 int (*reopen) (nbdkit_backend *nxdata, int readonly); 74 75 /* The rest of the next ops are the same as normal plugin operations. */ 76 int64_t (*get_size) (nbdkit_backend *nxdata); 77 78 int (*can_write) (nbdkit_backend *nxdata); 79 int (*can_flush) (nbdkit_backend *nxdata); 80 int (*is_rotational) (nbdkit_backend *nxdata); 81 int (*can_trim) (nbdkit_backend *nxdata); 82 int (*can_zero) (nbdkit_backend *nxdata); 83 int (*can_fast_zero) (nbdkit_backend *nxdata); 84 int (*can_extents) (nbdkit_backend *nxdata); 85 int (*can_fua) (nbdkit_backend *nxdata); 86 int (*can_multi_conn) (nbdkit_backend *nxdata); 87 int (*can_cache) (nbdkit_backend *nxdata); 88 89 int (*pread) (nbdkit_backend *nxdata, 90 void *buf, uint32_t count, uint64_t offset, 91 uint32_t flags, int *err); 92 int (*pwrite) (nbdkit_backend *nxdata, 93 const void *buf, uint32_t count, uint64_t offset, 94 uint32_t flags, int *err); 95 int (*flush) (nbdkit_backend *nxdata, uint32_t flags, int *err); 96 int (*trim) (nbdkit_backend *nxdata, uint32_t count, uint64_t offset, 97 uint32_t flags, int *err); 98 int (*zero) (nbdkit_backend *nxdata, uint32_t count, uint64_t offset, 99 uint32_t flags, int *err); 100 int (*extents) (nbdkit_backend *nxdata, uint32_t count, uint64_t offset, 101 uint32_t flags, struct nbdkit_extents *extents, int *err); 102 int (*cache) (nbdkit_backend *nxdata, uint32_t count, uint64_t offset, 103 uint32_t flags, int *err); 104 }; 105 106 /* Extent functions. */ 107 struct nbdkit_extent { 108 uint64_t offset; 109 uint64_t length; 110 uint32_t type; 111 }; 112 113 extern struct nbdkit_extents *nbdkit_extents_new (uint64_t start, uint64_t end); 114 extern void nbdkit_extents_free (struct nbdkit_extents *); 115 extern size_t nbdkit_extents_count (const struct nbdkit_extents *); 116 extern struct nbdkit_extent nbdkit_get_extent (const struct nbdkit_extents *, 117 size_t); 118 119 /* Filter struct. */ 120 struct nbdkit_filter { 121 /* Do not set these fields directly; use NBDKIT_REGISTER_FILTER. 122 * They exist so that we can diagnose filters compiled against one 123 * version of the header with a runtime compiled against a different 124 * version. As of API version 6, _version is also part of the 125 * guaranteed ABI, so we no longer have to remember to bump API 126 * versions regardless of other API/ABI changes later in the struct. 127 */ 128 int _api_version; 129 const char *_version; 130 131 /* Because there is no ABI guarantee, new fields may be added where 132 * logically appropriate. 133 */ 134 const char *name; 135 const char *longname; 136 const char *description; 137 138 void (*load) (void); 139 void (*unload) (void); 140 141 int (*config) (nbdkit_next_config *next, nbdkit_backend *nxdata, 142 const char *key, const char *value); 143 int (*config_complete) (nbdkit_next_config_complete *next, 144 nbdkit_backend *nxdata); 145 const char *config_help; 146 int (*thread_model) (void); 147 int (*get_ready) (nbdkit_next_get_ready *next, nbdkit_backend *nxdata); 148 int (*preconnect) (nbdkit_next_preconnect *next, nbdkit_backend *nxdata, 149 int readonly); 150 151 void * (*open) (nbdkit_next_open *next, nbdkit_backend *nxdata, 152 int readonly); 153 void (*close) (void *handle); 154 155 int (*prepare) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 156 void *handle, int readonly); 157 int (*finalize) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 158 void *handle); 159 160 int64_t (*get_size) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 161 void *handle); 162 163 int (*can_write) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 164 void *handle); 165 int (*can_flush) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 166 void *handle); 167 int (*is_rotational) (struct nbdkit_next_ops *next_ops, 168 nbdkit_backend *nxdata, void *handle); 169 int (*can_trim) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 170 void *handle); 171 int (*can_zero) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 172 void *handle); 173 int (*can_fast_zero) (struct nbdkit_next_ops *next_ops, 174 nbdkit_backend *nxdata, void *handle); 175 int (*can_extents) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 176 void *handle); 177 int (*can_fua) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 178 void *handle); 179 int (*can_multi_conn) (struct nbdkit_next_ops *next_ops, 180 nbdkit_backend *nxdata, void *handle); 181 int (*can_cache) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 182 void *handle); 183 184 int (*pread) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 185 void *handle, void *buf, uint32_t count, uint64_t offset, 186 uint32_t flags, int *err); 187 int (*pwrite) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 188 void *handle, 189 const void *buf, uint32_t count, uint64_t offset, 190 uint32_t flags, int *err); 191 int (*flush) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 192 void *handle, uint32_t flags, int *err); 193 int (*trim) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 194 void *handle, uint32_t count, uint64_t offset, uint32_t flags, 195 int *err); 196 int (*zero) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 197 void *handle, uint32_t count, uint64_t offset, uint32_t flags, 198 int *err); 199 int (*extents) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 200 void *handle, uint32_t count, uint64_t offset, uint32_t flags, 201 struct nbdkit_extents *extents, int *err); 202 int (*cache) (struct nbdkit_next_ops *next_ops, nbdkit_backend *nxdata, 203 void *handle, uint32_t count, uint64_t offset, uint32_t flags, 204 int *err); 205 }; 206 207 #define NBDKIT_REGISTER_FILTER(filter) \ 208 NBDKIT_CXX_LANG_C \ 209 struct nbdkit_filter * \ 210 filter_init (void) \ 211 { \ 212 (filter)._api_version = NBDKIT_FILTER_API_VERSION; \ 213 (filter)._version = NBDKIT_VERSION_STRING; \ 214 return &(filter); \ 215 } 216 217 #ifdef __cplusplus 218 } 219 #endif 220 221 #endif /* NBDKIT_FILTER_H */ 222