2 * Copyright (C) 2018 Red Hat Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
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
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. */
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
);
58 else if (strcmp (key
, "range") == 0) {
59 range
= nbdkit_parse_size (value
);
65 return next (nxdata
, key
, value
);
68 /* Check the user did pass both parameters. */
70 offset_config_complete (nbdkit_next_config_complete
*next
, void *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. */
81 offset_get_size (struct nbdkit_next_ops
*next_ops
, void *nxdata
,
84 int64_t real_size
= next_ops
->get_size (nxdata
);
87 if (offset
+ range
> real_size
) {
88 nbdkit_error ("offset+range is larger than the real size of the underlying file or device");
94 return real_size
- offset
;
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
);
108 offset_pwrite (struct nbdkit_next_ops
*next_ops
, void *nxdata
,
110 const void *buf
, uint32_t count
, uint64_t offs
, uint32_t flags
,
113 return next_ops
->pwrite (nxdata
, buf
, count
, offs
+ offset
, flags
, err
);
118 offset_trim (struct nbdkit_next_ops
*next_ops
, void *nxdata
,
119 void *handle
, uint32_t count
, uint64_t offs
, uint32_t flags
,
122 return next_ops
->trim (nxdata
, count
, offs
+ offset
, flags
, err
);
127 offset_zero (struct nbdkit_next_ops
*next_ops
, void *nxdata
,
128 void *handle
, uint32_t count
, uint64_t offs
, uint32_t flags
,
131 return next_ops
->zero (nxdata
, count
, offs
+ offset
, flags
, err
);
134 static struct nbdkit_filter filter
= {
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
,
148 NBDKIT_REGISTER_FILTER(filter
)