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