filters: Adjust callback API for flags/errors
[nbdkit/ericb.git] / filters / offset / offset.c
blobbb63ed42b954a2d450ed52fd7f30229dc1d0a367
1 /* nbdkit
2 * Copyright (C) 2018 Red Hat Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of Red Hat nor the names of its contributors may be
17 * used to endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <config.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdint.h>
39 #include <string.h>
41 #include <nbdkit-filter.h>
43 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
45 static int64_t offset = 0, range = -1;
47 /* Called for each key=value passed on the command line. */
48 static int
49 offset_config (nbdkit_next_config *next, void *nxdata,
50 const char *key, const char *value)
52 if (strcmp (key, "offset") == 0) {
53 offset = nbdkit_parse_size (value);
54 if (offset == -1)
55 return -1;
56 return 0;
58 else if (strcmp (key, "range") == 0) {
59 range = nbdkit_parse_size (value);
60 if (range == -1)
61 return -1;
62 return 0;
64 else
65 return next (nxdata, key, value);
68 /* Check the user did pass both parameters. */
69 static int
70 offset_config_complete (nbdkit_next_config_complete *next, void *nxdata)
72 return next (nxdata);
75 #define offset_config_help \
76 "offset=<OFFSET> (required) The start offset to serve.\n" \
77 "range=<LENGTH> The total size to serve."
79 /* Get the file size. */
80 static int64_t
81 offset_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
82 void *handle)
84 int64_t real_size = next_ops->get_size (nxdata);
86 if (range >= 0) {
87 if (offset + range > real_size) {
88 nbdkit_error ("offset+range is larger than the real size of the underlying file or device");
89 return -1;
91 return range;
93 else
94 return real_size - offset;
97 /* Read data. */
98 static int
99 offset_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
100 void *handle, void *buf, uint32_t count, uint64_t offs,
101 uint32_t flags, int *err)
103 return next_ops->pread (nxdata, buf, count, offs + offset, flags, err);
106 /* Write data. */
107 static int
108 offset_pwrite (struct nbdkit_next_ops *next_ops, void *nxdata,
109 void *handle,
110 const void *buf, uint32_t count, uint64_t offs, uint32_t flags,
111 int *err)
113 return next_ops->pwrite (nxdata, buf, count, offs + offset, flags, err);
116 /* Trim data. */
117 static int
118 offset_trim (struct nbdkit_next_ops *next_ops, void *nxdata,
119 void *handle, uint32_t count, uint64_t offs, uint32_t flags,
120 int *err)
122 return next_ops->trim (nxdata, count, offs + offset, flags, err);
125 /* Zero data. */
126 static int
127 offset_zero (struct nbdkit_next_ops *next_ops, void *nxdata,
128 void *handle, uint32_t count, uint64_t offs, uint32_t flags,
129 int *err)
131 return next_ops->zero (nxdata, count, offs + offset, flags, err);
134 static struct nbdkit_filter filter = {
135 .name = "offset",
136 .longname = "nbdkit offset filter",
137 .version = PACKAGE_VERSION,
138 .config = offset_config,
139 .config_complete = offset_config_complete,
140 .config_help = offset_config_help,
141 .get_size = offset_get_size,
142 .pread = offset_pread,
143 .pwrite = offset_pwrite,
144 .trim = offset_trim,
145 .zero = offset_zero,
148 NBDKIT_REGISTER_FILTER(filter)