Sun Dec 8 10:50:21 2019 UTC ()
dm: Move targets specific structs to .c files

These don't need to be defined and exposed in dm.h.


(tkusumi)
diff -r1.36 -r1.37 src/sys/dev/dm/dm.h
diff -r1.15 -r1.16 src/sys/dev/dm/dm_target_mirror.c
diff -r1.27 -r1.28 src/sys/dev/dm/dm_target_snapshot.c
diff -r1.31 -r1.32 src/sys/dev/dm/dm_target_stripe.c

cvs diff -r1.36 -r1.37 src/sys/dev/dm/dm.h (switch to unified diff)

--- src/sys/dev/dm/dm.h 2019/12/08 10:35:53 1.36
+++ src/sys/dev/dm/dm.h 2019/12/08 10:50:21 1.37
@@ -1,337 +1,298 @@ @@ -1,337 +1,298 @@
1/* $NetBSD: dm.h,v 1.36 2019/12/08 10:35:53 tkusumi Exp $ */ 1/* $NetBSD: dm.h,v 1.37 2019/12/08 10:50:21 tkusumi Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#ifndef _DM_DEV_H_ 32#ifndef _DM_DEV_H_
33#define _DM_DEV_H_ 33#define _DM_DEV_H_
34 34
35 35
36#ifdef _KERNEL 36#ifdef _KERNEL
37 37
38#include <sys/errno.h> 38#include <sys/errno.h>
39 39
40#include <sys/atomic.h> 40#include <sys/atomic.h>
41#include <sys/fcntl.h> 41#include <sys/fcntl.h>
42#include <sys/condvar.h> 42#include <sys/condvar.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44#include <sys/mutex.h> 44#include <sys/mutex.h>
45#include <sys/rwlock.h> 45#include <sys/rwlock.h>
46#include <sys/queue.h> 46#include <sys/queue.h>
47#include <sys/vnode.h> 47#include <sys/vnode.h>
48 48
49#include <sys/device.h> 49#include <sys/device.h>
50#include <sys/disk.h> 50#include <sys/disk.h>
51#include <sys/disklabel.h> 51#include <sys/disklabel.h>
52 52
53#include <miscfs/specfs/specdev.h> /* for v_rdev */ 53#include <miscfs/specfs/specdev.h> /* for v_rdev */
54 54
55#include <prop/proplib.h> 55#include <prop/proplib.h>
56 56
57#define DM_MAX_TYPE_NAME 16 57#define DM_MAX_TYPE_NAME 16
58#define DM_NAME_LEN 128 58#define DM_NAME_LEN 128
59#define DM_UUID_LEN 129 59#define DM_UUID_LEN 129
60 60
61#define DM_VERSION_MAJOR 4 61#define DM_VERSION_MAJOR 4
62#define DM_VERSION_MINOR 16 62#define DM_VERSION_MINOR 16
63 63
64#define DM_VERSION_PATCHLEVEL 0 64#define DM_VERSION_PATCHLEVEL 0
65 65
66/*** Internal device-mapper structures ***/ 66/*** Internal device-mapper structures ***/
67 67
68/* 68/*
69 * A device mapper table is a list of physical ranges plus the mapping target 69 * A device mapper table is a list of physical ranges plus the mapping target
70 * applied to them. 70 * applied to them.
71 */ 71 */
72 72
73typedef struct dm_table_entry { 73typedef struct dm_table_entry {
74 struct dm_dev *dm_dev; /* backlink */ 74 struct dm_dev *dm_dev; /* backlink */
75 uint64_t start; 75 uint64_t start;
76 uint64_t length; 76 uint64_t length;
77 77
78 struct dm_target *target; /* Link to table target. */ 78 struct dm_target *target; /* Link to table target. */
79 void *target_config; /* Target specific data. */ 79 void *target_config; /* Target specific data. */
80 SLIST_ENTRY(dm_table_entry) next; 80 SLIST_ENTRY(dm_table_entry) next;
81} dm_table_entry_t; 81} dm_table_entry_t;
82 82
83SLIST_HEAD(dm_table, dm_table_entry); 83SLIST_HEAD(dm_table, dm_table_entry);
84 84
85typedef struct dm_table dm_table_t; 85typedef struct dm_table dm_table_t;
86 86
87typedef struct dm_table_head { 87typedef struct dm_table_head {
88 /* Current active table is selected with this. */ 88 /* Current active table is selected with this. */
89 int cur_active_table; 89 int cur_active_table;
90 struct dm_table tables[2]; 90 struct dm_table tables[2];
91 91
92 kmutex_t table_mtx; 92 kmutex_t table_mtx;
93 kcondvar_t table_cv; /*IO waiting cv */ 93 kcondvar_t table_cv; /*IO waiting cv */
94 94
95 uint32_t io_cnt; 95 uint32_t io_cnt;
96} dm_table_head_t; 96} dm_table_head_t;
97 97
98#define MAX_DEV_NAME 32 98#define MAX_DEV_NAME 32
99 99
100/* 100/*
101 * This structure is used to store opened vnodes for disk with name. 101 * This structure is used to store opened vnodes for disk with name.
102 * I need this because devices can be opened only once, but I can 102 * I need this because devices can be opened only once, but I can
103 * have more than one device on one partition. 103 * have more than one device on one partition.
104 */ 104 */
105 105
106typedef struct dm_pdev { 106typedef struct dm_pdev {
107 char name[MAX_DEV_NAME]; 107 char name[MAX_DEV_NAME];
108 108
109 struct vnode *pdev_vnode; 109 struct vnode *pdev_vnode;
110 uint64_t pdev_numsec; 110 uint64_t pdev_numsec;
111 unsigned pdev_secsize; 111 unsigned pdev_secsize;
112 int ref_cnt; /* reference counter for users ofthis pdev */ 112 int ref_cnt; /* reference counter for users ofthis pdev */
113 113
114 SLIST_ENTRY(dm_pdev) next_pdev; 114 SLIST_ENTRY(dm_pdev) next_pdev;
115} dm_pdev_t; 115} dm_pdev_t;
116 116
117/* 117/*
118 * This structure is called for every device-mapper device. 118 * This structure is called for every device-mapper device.
119 * It points to SLIST of device tables and mirrored, snapshoted etc. devices. 119 * It points to SLIST of device tables and mirrored, snapshoted etc. devices.
120 */ 120 */
121TAILQ_HEAD(dm_dev_head, dm_dev); 121TAILQ_HEAD(dm_dev_head, dm_dev);
122//extern struct dm_dev_head dm_devs; 122//extern struct dm_dev_head dm_devs;
123 123
124typedef struct dm_dev { 124typedef struct dm_dev {
125 char name[DM_NAME_LEN]; 125 char name[DM_NAME_LEN];
126 char uuid[DM_UUID_LEN]; 126 char uuid[DM_UUID_LEN];
127 127
128 device_t devt; /* pointer to autoconf device_t structure */ 128 device_t devt; /* pointer to autoconf device_t structure */
129 uint64_t minor; /* Device minor number */ 129 uint64_t minor; /* Device minor number */
130 uint32_t flags; /* store communication protocol flags */ 130 uint32_t flags; /* store communication protocol flags */
131 131
132 kmutex_t dev_mtx; /* mutex for generall device lock */ 132 kmutex_t dev_mtx; /* mutex for generall device lock */
133 kcondvar_t dev_cv; /* cv for between ioctl synchronisation */ 133 kcondvar_t dev_cv; /* cv for between ioctl synchronisation */
134 134
135 uint32_t event_nr; 135 uint32_t event_nr;
136 uint32_t ref_cnt; 136 uint32_t ref_cnt;
137 137
138 dm_table_head_t table_head; 138 dm_table_head_t table_head;
139 139
140 //struct dm_dev_head upcalls; 140 //struct dm_dev_head upcalls;
141 141
142 struct disk *diskp; 142 struct disk *diskp;
143 kmutex_t diskp_mtx; 143 kmutex_t diskp_mtx;
144 144
145 //TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */ 145 //TAILQ_ENTRY(dm_dev) next_upcall; /* LIST of mirrored, snapshoted devices. */
146 146
147 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */ 147 TAILQ_ENTRY(dm_dev) next_devlist; /* Major device list. */
148} dm_dev_t; 148} dm_dev_t;
149 149
150/* for zero, error : dm_target->target_config == NULL */ 150/* for zero, error : dm_target->target_config == NULL */
151 151
152/* 152/*
153 * Target config is initiated with target_init function. 153 * Target config is initiated with target_init function.
154 */ 154 */
155 155
156/* for linear : */ 156/* for linear : */
157typedef struct target_linear_config { 157typedef struct target_linear_config {
158 dm_pdev_t *pdev; 158 dm_pdev_t *pdev;
159 uint64_t offset; 159 uint64_t offset;
160 TAILQ_ENTRY(target_linear_config) entries; 160 TAILQ_ENTRY(target_linear_config) entries;
161} dm_target_linear_config_t; 161} dm_target_linear_config_t;
162 162
163/* 163/*
164 * Striping devices are stored in a linked list, this might be inefficient 164 * Striping devices are stored in a linked list, this might be inefficient
165 * for more than 8 striping devices and can be changed to something more 165 * for more than 8 striping devices and can be changed to something more
166 * scalable. 166 * scalable.
167 * TODO: look for other options than linked list. 167 * TODO: look for other options than linked list.
168 */ 168 */
169TAILQ_HEAD(target_linear_devs, target_linear_config); 169TAILQ_HEAD(target_linear_devs, target_linear_config);
170 170
171typedef struct target_linear_devs dm_target_linear_devs_t; 171typedef struct target_linear_devs dm_target_linear_devs_t;
172 172
173/* for stripe : */ 
174typedef struct target_stripe_config { 
175#define DM_STRIPE_DEV_OFFSET 2 
176 struct target_linear_devs stripe_devs; 
177 uint8_t stripe_num; 
178 uint64_t stripe_chunksize; 
179 size_t params_len; 
180} dm_target_stripe_config_t; 
181 
182/* for mirror : */ 
183typedef struct target_mirror_config { 
184#define MAX_MIRROR_COPIES 4 
185 dm_pdev_t *orig; 
186 dm_pdev_t *copies[MAX_MIRROR_COPIES]; 
187 
188 /* copied blocks bitmaps administration etc*/ 
189 dm_pdev_t *log_pdev; /* for administration */ 
190 uint64_t log_regionsize; /* blocksize of mirror */ 
191 
192 /* list of parts that still need copied etc.; run length encoded? */ 
193} dm_target_mirror_config_t; 
194 
195 
196/* for snapshot : */ 
197typedef struct target_snapshot_config { 
198 dm_pdev_t *tsc_snap_dev; 
199 /* cow dev is set only for persistent snapshot devices */ 
200 dm_pdev_t *tsc_cow_dev; 
201 
202 uint64_t tsc_chunk_size; 
203 uint32_t tsc_persistent_dev; 
204} dm_target_snapshot_config_t; 
205 
206/* for snapshot-origin devices */ 
207typedef struct target_snapshot_origin_config { 
208 dm_pdev_t *tsoc_real_dev; 
209 /* list of snapshots ? */ 
210} dm_target_snapshot_origin_config_t; 
211 
212/* constant dm_target structures for error, zero, linear, stripes etc. */ 173/* constant dm_target structures for error, zero, linear, stripes etc. */
213typedef struct dm_target { 174typedef struct dm_target {
214 char name[DM_MAX_TYPE_NAME]; 175 char name[DM_MAX_TYPE_NAME];
215 /* Initialize target_config area */ 176 /* Initialize target_config area */
216 int (*init)(dm_table_entry_t *, char *); 177 int (*init)(dm_table_entry_t *, char *);
217 178
218 /* Destroy target_config area */ 179 /* Destroy target_config area */
219 int (*destroy)(dm_table_entry_t *); 180 int (*destroy)(dm_table_entry_t *);
220 181
221 int (*deps) (dm_table_entry_t *, prop_array_t); 182 int (*deps) (dm_table_entry_t *, prop_array_t);
222 /* 183 /*
223 * Status routine is called to get params string, which is target 184 * Status routine is called to get params string, which is target
224 * specific. When dm_table_status_ioctl is called with flag 185 * specific. When dm_table_status_ioctl is called with flag
225 * DM_STATUS_TABLE_FLAG I have to sent params string back. 186 * DM_STATUS_TABLE_FLAG I have to sent params string back.
226 */ 187 */
227 char * (*status)(void *); 188 char * (*status)(void *);
228 int (*strategy)(dm_table_entry_t *, struct buf *); 189 int (*strategy)(dm_table_entry_t *, struct buf *);
229 int (*sync)(dm_table_entry_t *); 190 int (*sync)(dm_table_entry_t *);
230 int (*upcall)(dm_table_entry_t *, struct buf *); 191 int (*upcall)(dm_table_entry_t *, struct buf *);
231 int (*secsize)(dm_table_entry_t *, unsigned *); 192 int (*secsize)(dm_table_entry_t *, unsigned *);
232 193
233 uint32_t version[3]; 194 uint32_t version[3];
234 uint32_t ref_cnt; 195 uint32_t ref_cnt;
235 196
236 TAILQ_ENTRY(dm_target) dm_target_next; 197 TAILQ_ENTRY(dm_target) dm_target_next;
237} dm_target_t; 198} dm_target_t;
238 199
239/* Interface structures */ 200/* Interface structures */
240 201
241/* device-mapper */ 202/* device-mapper */
242void dmgetproperties(struct disk *, dm_table_head_t *); 203void dmgetproperties(struct disk *, dm_table_head_t *);
243 204
244/* dm_ioctl.c */ 205/* dm_ioctl.c */
245int dm_dev_create_ioctl(prop_dictionary_t); 206int dm_dev_create_ioctl(prop_dictionary_t);
246int dm_dev_list_ioctl(prop_dictionary_t); 207int dm_dev_list_ioctl(prop_dictionary_t);
247int dm_dev_remove_ioctl(prop_dictionary_t); 208int dm_dev_remove_ioctl(prop_dictionary_t);
248int dm_dev_rename_ioctl(prop_dictionary_t); 209int dm_dev_rename_ioctl(prop_dictionary_t);
249int dm_dev_resume_ioctl(prop_dictionary_t); 210int dm_dev_resume_ioctl(prop_dictionary_t);
250int dm_dev_status_ioctl(prop_dictionary_t); 211int dm_dev_status_ioctl(prop_dictionary_t);
251int dm_dev_suspend_ioctl(prop_dictionary_t); 212int dm_dev_suspend_ioctl(prop_dictionary_t);
252 213
253int dm_check_version(prop_dictionary_t); 214int dm_check_version(prop_dictionary_t);
254int dm_list_versions_ioctl(prop_dictionary_t); 215int dm_list_versions_ioctl(prop_dictionary_t);
255 216
256int dm_table_clear_ioctl(prop_dictionary_t); 217int dm_table_clear_ioctl(prop_dictionary_t);
257int dm_table_deps_ioctl(prop_dictionary_t); 218int dm_table_deps_ioctl(prop_dictionary_t);
258int dm_table_load_ioctl(prop_dictionary_t); 219int dm_table_load_ioctl(prop_dictionary_t);
259int dm_table_status_ioctl(prop_dictionary_t); 220int dm_table_status_ioctl(prop_dictionary_t);
260 221
261/* dm_target.c */ 222/* dm_target.c */
262dm_target_t* dm_target_alloc(const char *); 223dm_target_t* dm_target_alloc(const char *);
263dm_target_t* dm_target_autoload(const char *); 224dm_target_t* dm_target_autoload(const char *);
264int dm_target_destroy(void); 225int dm_target_destroy(void);
265int dm_target_insert(dm_target_t *); 226int dm_target_insert(dm_target_t *);
266prop_array_t dm_target_prop_list(void); 227prop_array_t dm_target_prop_list(void);
267dm_target_t* dm_target_lookup(const char *); 228dm_target_t* dm_target_lookup(const char *);
268int dm_target_rem(const char *); 229int dm_target_rem(const char *);
269void dm_target_unbusy(dm_target_t *); 230void dm_target_unbusy(dm_target_t *);
270void dm_target_busy(dm_target_t *); 231void dm_target_busy(dm_target_t *);
271 232
272/* XXX temporally add */ 233/* XXX temporally add */
273int dm_target_init(void); 234int dm_target_init(void);
274 235
275#define DM_MAX_PARAMS_SIZE 1024 236#define DM_MAX_PARAMS_SIZE 1024
276 237
277/* dm_target_linear.c */ 238/* dm_target_linear.c */
278int dm_target_linear_init(dm_table_entry_t *, char *); 239int dm_target_linear_init(dm_table_entry_t *, char *);
279char *dm_target_linear_status(void *); 240char *dm_target_linear_status(void *);
280int dm_target_linear_strategy(dm_table_entry_t *, struct buf *); 241int dm_target_linear_strategy(dm_table_entry_t *, struct buf *);
281int dm_target_linear_sync(dm_table_entry_t *); 242int dm_target_linear_sync(dm_table_entry_t *);
282int dm_target_linear_deps(dm_table_entry_t *, prop_array_t); 243int dm_target_linear_deps(dm_table_entry_t *, prop_array_t);
283int dm_target_linear_destroy(dm_table_entry_t *); 244int dm_target_linear_destroy(dm_table_entry_t *);
284int dm_target_linear_upcall(dm_table_entry_t *, struct buf *); 245int dm_target_linear_upcall(dm_table_entry_t *, struct buf *);
285int dm_target_linear_secsize(dm_table_entry_t *, unsigned *); 246int dm_target_linear_secsize(dm_table_entry_t *, unsigned *);
286 247
287/* Generic function used to convert char to string */ 248/* Generic function used to convert char to string */
288uint64_t atoi(const char *); 249uint64_t atoi(const char *);
289 250
290/* dm_target_stripe.c */ 251/* dm_target_stripe.c */
291int dm_target_stripe_init(dm_table_entry_t *, char *); 252int dm_target_stripe_init(dm_table_entry_t *, char *);
292char *dm_target_stripe_status(void *); 253char *dm_target_stripe_status(void *);
293int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *); 254int dm_target_stripe_strategy(dm_table_entry_t *, struct buf *);
294int dm_target_stripe_sync(dm_table_entry_t *); 255int dm_target_stripe_sync(dm_table_entry_t *);
295int dm_target_stripe_deps(dm_table_entry_t *, prop_array_t); 256int dm_target_stripe_deps(dm_table_entry_t *, prop_array_t);
296int dm_target_stripe_destroy(dm_table_entry_t *); 257int dm_target_stripe_destroy(dm_table_entry_t *);
297int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *); 258int dm_target_stripe_upcall(dm_table_entry_t *, struct buf *);
298int dm_target_stripe_secsize(dm_table_entry_t *, unsigned *); 259int dm_target_stripe_secsize(dm_table_entry_t *, unsigned *);
299 260
300/* dm_table.c */ 261/* dm_table.c */
301#define DM_TABLE_ACTIVE 0 262#define DM_TABLE_ACTIVE 0
302#define DM_TABLE_INACTIVE 1 263#define DM_TABLE_INACTIVE 1
303 264
304int dm_table_destroy(dm_table_head_t *, uint8_t); 265int dm_table_destroy(dm_table_head_t *, uint8_t);
305uint64_t dm_table_size(dm_table_head_t *); 266uint64_t dm_table_size(dm_table_head_t *);
306uint64_t dm_inactive_table_size(dm_table_head_t *); 267uint64_t dm_inactive_table_size(dm_table_head_t *);
307void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned *); 268void dm_table_disksize(dm_table_head_t *, uint64_t *, unsigned *);
308dm_table_t *dm_table_get_entry(dm_table_head_t *, uint8_t); 269dm_table_t *dm_table_get_entry(dm_table_head_t *, uint8_t);
309int dm_table_get_target_count(dm_table_head_t *, uint8_t); 270int dm_table_get_target_count(dm_table_head_t *, uint8_t);
310void dm_table_release(dm_table_head_t *, uint8_t s); 271void dm_table_release(dm_table_head_t *, uint8_t s);
311void dm_table_switch_tables(dm_table_head_t *); 272void dm_table_switch_tables(dm_table_head_t *);
312void dm_table_head_init(dm_table_head_t *); 273void dm_table_head_init(dm_table_head_t *);
313void dm_table_head_destroy(dm_table_head_t *); 274void dm_table_head_destroy(dm_table_head_t *);
314 275
315/* dm_dev.c */ 276/* dm_dev.c */
316dm_dev_t* dm_dev_alloc(void); 277dm_dev_t* dm_dev_alloc(void);
317void dm_dev_busy(dm_dev_t *); 278void dm_dev_busy(dm_dev_t *);
318int dm_dev_destroy(void); 279int dm_dev_destroy(void);
319dm_dev_t* dm_dev_detach(device_t); 280dm_dev_t* dm_dev_detach(device_t);
320int dm_dev_free(dm_dev_t *); 281int dm_dev_free(dm_dev_t *);
321int dm_dev_init(void); 282int dm_dev_init(void);
322int dm_dev_insert(dm_dev_t *); 283int dm_dev_insert(dm_dev_t *);
323dm_dev_t* dm_dev_lookup(const char *, const char *, int); 284dm_dev_t* dm_dev_lookup(const char *, const char *, int);
324prop_array_t dm_dev_prop_list(void); 285prop_array_t dm_dev_prop_list(void);
325dm_dev_t* dm_dev_rem(const char *, const char *, int); 286dm_dev_t* dm_dev_rem(const char *, const char *, int);
326/*int dm_dev_test_minor(int);*/ 287/*int dm_dev_test_minor(int);*/
327void dm_dev_unbusy(dm_dev_t *); 288void dm_dev_unbusy(dm_dev_t *);
328 289
329/* dm_pdev.c */ 290/* dm_pdev.c */
330int dm_pdev_decr(dm_pdev_t *); 291int dm_pdev_decr(dm_pdev_t *);
331int dm_pdev_destroy(void); 292int dm_pdev_destroy(void);
332int dm_pdev_init(void); 293int dm_pdev_init(void);
333dm_pdev_t* dm_pdev_insert(const char *); 294dm_pdev_t* dm_pdev_insert(const char *);
334 295
335#endif /*_KERNEL*/ 296#endif /*_KERNEL*/
336 297
337#endif /*_DM_DEV_H_*/ 298#endif /*_DM_DEV_H_*/

cvs diff -r1.15 -r1.16 src/sys/dev/dm/dm_target_mirror.c (switch to unified diff)

--- src/sys/dev/dm/dm_target_mirror.c 2019/12/08 04:41:02 1.15
+++ src/sys/dev/dm/dm_target_mirror.c 2019/12/08 10:50:21 1.16
@@ -1,179 +1,191 @@ @@ -1,179 +1,191 @@
1/*$NetBSD: dm_target_mirror.c,v 1.15 2019/12/08 04:41:02 tkusumi Exp $*/ 1/*$NetBSD: dm_target_mirror.c,v 1.16 2019/12/08 10:50:21 tkusumi Exp $*/
2 2
3/* 3/*
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: dm_target_mirror.c,v 1.15 2019/12/08 04:41:02 tkusumi Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: dm_target_mirror.c,v 1.16 2019/12/08 10:50:21 tkusumi Exp $");
33 33
34/* 34/*
35 * This file implements initial version of device-mapper mirror target. 35 * This file implements initial version of device-mapper mirror target.
36 */ 36 */
37#include <sys/types.h> 37#include <sys/types.h>
38#include <sys/param.h> 38#include <sys/param.h>
39 39
40#include <sys/buf.h> 40#include <sys/buf.h>
41 41
42#include "dm.h" 42#include "dm.h"
43 43
44/* dm_target_mirror.c */ 44/* dm_target_mirror.c */
45int dm_target_mirror_init(dm_table_entry_t *, char *); 45int dm_target_mirror_init(dm_table_entry_t *, char *);
46char *dm_target_mirror_status(void *); 46char *dm_target_mirror_status(void *);
47int dm_target_mirror_strategy(dm_table_entry_t *, struct buf *); 47int dm_target_mirror_strategy(dm_table_entry_t *, struct buf *);
48int dm_target_mirror_sync(dm_table_entry_t *); 48int dm_target_mirror_sync(dm_table_entry_t *);
49int dm_target_mirror_deps(dm_table_entry_t *, prop_array_t); 49int dm_target_mirror_deps(dm_table_entry_t *, prop_array_t);
50int dm_target_mirror_destroy(dm_table_entry_t *); 50int dm_target_mirror_destroy(dm_table_entry_t *);
51int dm_target_mirror_upcall(dm_table_entry_t *, struct buf *); 51int dm_target_mirror_upcall(dm_table_entry_t *, struct buf *);
52 52
 53typedef struct target_mirror_config {
 54#define MAX_MIRROR_COPIES 4
 55 dm_pdev_t *orig;
 56 dm_pdev_t *copies[MAX_MIRROR_COPIES];
 57
 58 /* copied blocks bitmaps administration etc*/
 59 dm_pdev_t *log_pdev; /* for administration */
 60 uint64_t log_regionsize; /* blocksize of mirror */
 61
 62 /* list of parts that still need copied etc.; run length encoded? */
 63} dm_target_mirror_config_t;
 64
53#ifdef DM_TARGET_MODULE 65#ifdef DM_TARGET_MODULE
54/* 66/*
55 * Every target can be compiled directly to dm driver or as a 67 * Every target can be compiled directly to dm driver or as a
56 * separate module this part of target is used for loading targets 68 * separate module this part of target is used for loading targets
57 * to dm driver. 69 * to dm driver.
58 * Target can be unloaded from kernel only if there are no users of 70 * Target can be unloaded from kernel only if there are no users of
59 * it e.g. there are no devices which uses that target. 71 * it e.g. there are no devices which uses that target.
60 */ 72 */
61#include <sys/kernel.h> 73#include <sys/kernel.h>
62#include <sys/module.h> 74#include <sys/module.h>
63 75
64MODULE(MODULE_CLASS_MISC, dm_target_mirror, "dm"); 76MODULE(MODULE_CLASS_MISC, dm_target_mirror, "dm");
65 77
66static int 78static int
67dm_target_mirror_modcmd(modcmd_t cmd, void *arg) 79dm_target_mirror_modcmd(modcmd_t cmd, void *arg)
68{ 80{
69 dm_target_t *dmt; 81 dm_target_t *dmt;
70 int r; 82 int r;
71 dmt = NULL; 83 dmt = NULL;
72 84
73 switch (cmd) { 85 switch (cmd) {
74 case MODULE_CMD_INIT: 86 case MODULE_CMD_INIT:
75 if ((dmt = dm_target_lookup("mirror")) != NULL) { 87 if ((dmt = dm_target_lookup("mirror")) != NULL) {
76 dm_target_unbusy(dmt); 88 dm_target_unbusy(dmt);
77 return EEXIST; 89 return EEXIST;
78 } 90 }
79 dmt = dm_target_alloc("mirror"); 91 dmt = dm_target_alloc("mirror");
80 92
81 dmt->version[0] = 1; 93 dmt->version[0] = 1;
82 dmt->version[1] = 0; 94 dmt->version[1] = 0;
83 dmt->version[2] = 0; 95 dmt->version[2] = 0;
84 dmt->init = &dm_target_mirror_init; 96 dmt->init = &dm_target_mirror_init;
85 dmt->status = &dm_target_mirror_status; 97 dmt->status = &dm_target_mirror_status;
86 dmt->strategy = &dm_target_mirror_strategy; 98 dmt->strategy = &dm_target_mirror_strategy;
87 dmt->sync = &dm_target_mirror_sync; 99 dmt->sync = &dm_target_mirror_sync;
88 dmt->deps = &dm_target_mirror_deps; 100 dmt->deps = &dm_target_mirror_deps;
89 dmt->destroy = &dm_target_mirror_destroy; 101 dmt->destroy = &dm_target_mirror_destroy;
90 dmt->upcall = &dm_target_mirror_upcall; 102 dmt->upcall = &dm_target_mirror_upcall;
91 103
92 r = dm_target_insert(dmt); 104 r = dm_target_insert(dmt);
93 105
94 break; 106 break;
95 107
96 case MODULE_CMD_FINI: 108 case MODULE_CMD_FINI:
97 r = dm_target_rem("mirror"); 109 r = dm_target_rem("mirror");
98 break; 110 break;
99 111
100 case MODULE_CMD_STAT: 112 case MODULE_CMD_STAT:
101 return ENOTTY; 113 return ENOTTY;
102 114
103 default: 115 default:
104 return ENOTTY; 116 return ENOTTY;
105 } 117 }
106 118
107 return r; 119 return r;
108} 120}
109#endif 121#endif
110 122
111/* 123/*
112 * Init function called from dm_table_load_ioctl. 124 * Init function called from dm_table_load_ioctl.
113 * start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN 125 * start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN
114 * 0 52428800 mirror clustered_disk 4 253:2 1024 UUID block_on_error 3 253:3 0 253:4 0 253:5 0 126 * 0 52428800 mirror clustered_disk 4 253:2 1024 UUID block_on_error 3 253:3 0 253:4 0 253:5 0
115 */ 127 */
116int 128int
117dm_target_mirror_init(dm_table_entry_t *table_en, char *params) 129dm_target_mirror_init(dm_table_entry_t *table_en, char *params)
118{ 130{
119 131
120 printf("Mirror target init function called!!\n"); 132 printf("Mirror target init function called!!\n");
121 133
122 table_en->target_config = NULL; 134 table_en->target_config = NULL;
123 135
124 return ENOSYS; 136 return ENOSYS;
125} 137}
126 138
127/* Status routine called to get params string. */ 139/* Status routine called to get params string. */
128char * 140char *
129dm_target_mirror_status(void *target_config) 141dm_target_mirror_status(void *target_config)
130{ 142{
131 return NULL; 143 return NULL;
132} 144}
133 145
134/* Strategy routine called from dm_strategy. */ 146/* Strategy routine called from dm_strategy. */
135int 147int
136dm_target_mirror_strategy(dm_table_entry_t *table_en, struct buf *bp) 148dm_target_mirror_strategy(dm_table_entry_t *table_en, struct buf *bp)
137{ 149{
138 150
139 printf("Mirror target read function called!!\n"); 151 printf("Mirror target read function called!!\n");
140 152
141 bp->b_error = EIO; 153 bp->b_error = EIO;
142 bp->b_resid = 0; 154 bp->b_resid = 0;
143 155
144 biodone(bp); 156 biodone(bp);
145 157
146 return 0; 158 return 0;
147} 159}
148 160
149/* Sync underlying disk caches. */ 161/* Sync underlying disk caches. */
150int 162int
151dm_target_mirror_sync(dm_table_entry_t *table_en) 163dm_target_mirror_sync(dm_table_entry_t *table_en)
152{ 164{
153 165
154 return 0; 166 return 0;
155} 167}
156 168
157/* Doesn't do anything here. */ 169/* Doesn't do anything here. */
158int 170int
159dm_target_mirror_destroy(dm_table_entry_t *table_en) 171dm_target_mirror_destroy(dm_table_entry_t *table_en)
160{ 172{
161 /* Unbusy target so we can unload it */ 173 /* Unbusy target so we can unload it */
162 dm_target_unbusy(table_en->target); 174 dm_target_unbusy(table_en->target);
163 175
164 return 0; 176 return 0;
165} 177}
166 178
167/* Doesn't not need to do anything here. */ 179/* Doesn't not need to do anything here. */
168int 180int
169dm_target_mirror_deps(dm_table_entry_t *table_en, prop_array_t prop_array) 181dm_target_mirror_deps(dm_table_entry_t *table_en, prop_array_t prop_array)
170{ 182{
171 return 0; 183 return 0;
172} 184}
173 185
174/* Unsupported for this target. */ 186/* Unsupported for this target. */
175int 187int
176dm_target_mirror_upcall(dm_table_entry_t *table_en, struct buf *bp) 188dm_target_mirror_upcall(dm_table_entry_t *table_en, struct buf *bp)
177{ 189{
178 return 0; 190 return 0;
179} 191}

cvs diff -r1.27 -r1.28 src/sys/dev/dm/dm_target_snapshot.c (switch to unified diff)

--- src/sys/dev/dm/dm_target_snapshot.c 2019/12/08 10:35:53 1.27
+++ src/sys/dev/dm/dm_target_snapshot.c 2019/12/08 10:50:21 1.28
@@ -1,535 +1,549 @@ @@ -1,535 +1,549 @@
1/* $NetBSD: dm_target_snapshot.c,v 1.27 2019/12/08 10:35:53 tkusumi Exp $ */ 1/* $NetBSD: dm_target_snapshot.c,v 1.28 2019/12/08 10:50:21 tkusumi Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: dm_target_snapshot.c,v 1.27 2019/12/08 10:35:53 tkusumi Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: dm_target_snapshot.c,v 1.28 2019/12/08 10:50:21 tkusumi Exp $");
33 33
34/* 34/*
35 * 1. Suspend my_data to temporarily stop any I/O while the snapshot is being 35 * 1. Suspend my_data to temporarily stop any I/O while the snapshot is being
36 * activated. 36 * activated.
37 * dmsetup suspend my_data 37 * dmsetup suspend my_data
38 * 38 *
39 * 2. Create the snapshot-origin device with no table. 39 * 2. Create the snapshot-origin device with no table.
40 * dmsetup create my_data_org 40 * dmsetup create my_data_org
41 * 41 *
42 * 3. Read the table from my_data and load it into my_data_org. 42 * 3. Read the table from my_data and load it into my_data_org.
43 * dmsetup table my_data | dmsetup load my_data_org 43 * dmsetup table my_data | dmsetup load my_data_org
44 * 44 *
45 * 4. Resume this new table. 45 * 4. Resume this new table.
46 * dmsetup resume my_data_org 46 * dmsetup resume my_data_org
47 * 47 *
48 * 5. Create the snapshot device with no table. 48 * 5. Create the snapshot device with no table.
49 * dmsetup create my_data_snap 49 * dmsetup create my_data_snap
50 * 50 *
51 * 6. Load the table into my_data_snap. This uses /dev/hdd1 as the COW device and 51 * 6. Load the table into my_data_snap. This uses /dev/hdd1 as the COW device and
52 * uses a 32kB chunk-size. 52 * uses a 32kB chunk-size.
53 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot \ 53 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot \
54 * /dev/mapper/my_data_org /dev/hdd1 p 64" | dmsetup load my_data_snap 54 * /dev/mapper/my_data_org /dev/hdd1 p 64" | dmsetup load my_data_snap
55 * 55 *
56 * 7. Reload my_data as a snapshot-origin device that points to my_data_org. 56 * 7. Reload my_data as a snapshot-origin device that points to my_data_org.
57 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot-origin \ 57 * echo "0 `blockdev --getsize /dev/mapper/my_data` snapshot-origin \
58 * /dev/mapper/my_data_org" | dmsetup load my_data 58 * /dev/mapper/my_data_org" | dmsetup load my_data
59 * 59 *
60 * 8. Resume the snapshot and origin devices. 60 * 8. Resume the snapshot and origin devices.
61 * dmsetup resume my_data_snap 61 * dmsetup resume my_data_snap
62 * dmsetup resume my_data 62 * dmsetup resume my_data
63 * 63 *
64 * Before snapshot creation 64 * Before snapshot creation
65 * dev_name; dev table 65 * dev_name; dev table
66 * | my_data; 0 1024 linear /dev/sd1a 384| 66 * | my_data; 0 1024 linear /dev/sd1a 384|
67 * 67 *
68 * After snapshot creation 68 * After snapshot creation
69 * |my_data_org;0 1024 linear /dev/sd1a 384| 69 * |my_data_org;0 1024 linear /dev/sd1a 384|
70 * / 70 * /
71 * |my_data; 0 1024 snapshot-origin /dev/vg00/my_data_org| 71 * |my_data; 0 1024 snapshot-origin /dev/vg00/my_data_org|
72 * / 72 * /
73 * |my_data_snap; 0 1024 snapshot /dev/vg00/my_data /dev/mapper/my_data_cow P 8 73 * |my_data_snap; 0 1024 snapshot /dev/vg00/my_data /dev/mapper/my_data_cow P 8
74 * \ 74 * \
75 * |my_data_cow; 0 256 linear /dev/sd1a 1408| 75 * |my_data_cow; 0 256 linear /dev/sd1a 1408|
76 */ 76 */
77 77
78/* 78/*
79 * This file implements initial version of device-mapper snapshot target. 79 * This file implements initial version of device-mapper snapshot target.
80 */ 80 */
81#include <sys/types.h> 81#include <sys/types.h>
82#include <sys/param.h> 82#include <sys/param.h>
83 83
84#include <sys/buf.h> 84#include <sys/buf.h>
85#include <sys/kmem.h> 85#include <sys/kmem.h>
86 86
87#include "dm.h" 87#include "dm.h"
88 88
89/* dm_target_snapshot.c */ 89/* dm_target_snapshot.c */
90int dm_target_snapshot_init(dm_table_entry_t *, char *); 90int dm_target_snapshot_init(dm_table_entry_t *, char *);
91char *dm_target_snapshot_status(void *); 91char *dm_target_snapshot_status(void *);
92int dm_target_snapshot_strategy(dm_table_entry_t *, struct buf *); 92int dm_target_snapshot_strategy(dm_table_entry_t *, struct buf *);
93int dm_target_snapshot_deps(dm_table_entry_t *, prop_array_t); 93int dm_target_snapshot_deps(dm_table_entry_t *, prop_array_t);
94int dm_target_snapshot_destroy(dm_table_entry_t *); 94int dm_target_snapshot_destroy(dm_table_entry_t *);
95int dm_target_snapshot_upcall(dm_table_entry_t *, struct buf *); 95int dm_target_snapshot_upcall(dm_table_entry_t *, struct buf *);
96 96
97/* dm snapshot origin driver */ 97/* dm snapshot origin driver */
98int dm_target_snapshot_orig_init(dm_table_entry_t *, char *); 98int dm_target_snapshot_orig_init(dm_table_entry_t *, char *);
99char *dm_target_snapshot_orig_status(void *); 99char *dm_target_snapshot_orig_status(void *);
100int dm_target_snapshot_orig_strategy(dm_table_entry_t *, struct buf *); 100int dm_target_snapshot_orig_strategy(dm_table_entry_t *, struct buf *);
101int dm_target_snapshot_orig_sync(dm_table_entry_t *); 101int dm_target_snapshot_orig_sync(dm_table_entry_t *);
102int dm_target_snapshot_orig_deps(dm_table_entry_t *, prop_array_t); 102int dm_target_snapshot_orig_deps(dm_table_entry_t *, prop_array_t);
103int dm_target_snapshot_orig_destroy(dm_table_entry_t *); 103int dm_target_snapshot_orig_destroy(dm_table_entry_t *);
104int dm_target_snapshot_orig_upcall(dm_table_entry_t *, struct buf *); 104int dm_target_snapshot_orig_upcall(dm_table_entry_t *, struct buf *);
105 105
 106typedef struct target_snapshot_config {
 107 dm_pdev_t *tsc_snap_dev;
 108 /* cow dev is set only for persistent snapshot devices */
 109 dm_pdev_t *tsc_cow_dev;
 110
 111 uint64_t tsc_chunk_size;
 112 uint32_t tsc_persistent_dev;
 113} dm_target_snapshot_config_t;
 114
 115typedef struct target_snapshot_origin_config {
 116 dm_pdev_t *tsoc_real_dev;
 117 /* list of snapshots ? */
 118} dm_target_snapshot_origin_config_t;
 119
106#ifdef DM_TARGET_MODULE 120#ifdef DM_TARGET_MODULE
107/* 121/*
108 * Every target can be compiled directly to dm driver or as a 122 * Every target can be compiled directly to dm driver or as a
109 * separate module this part of target is used for loading targets 123 * separate module this part of target is used for loading targets
110 * to dm driver. 124 * to dm driver.
111 * Target can be unloaded from kernel only if there are no users of 125 * Target can be unloaded from kernel only if there are no users of
112 * it e.g. there are no devices which uses that target. 126 * it e.g. there are no devices which uses that target.
113 */ 127 */
114#include <sys/kernel.h> 128#include <sys/kernel.h>
115#include <sys/module.h> 129#include <sys/module.h>
116 130
117MODULE(MODULE_CLASS_MISC, dm_target_snapshot, "dm"); 131MODULE(MODULE_CLASS_MISC, dm_target_snapshot, "dm");
118 132
119static int 133static int
120dm_target_snapshot_modcmd(modcmd_t cmd, void *arg) 134dm_target_snapshot_modcmd(modcmd_t cmd, void *arg)
121{ 135{
122 dm_target_t *dmt, *dmt1; 136 dm_target_t *dmt, *dmt1;
123 int r; 137 int r;
124 138
125 dmt = NULL; 139 dmt = NULL;
126 dmt1 = NULL; 140 dmt1 = NULL;
127 141
128 switch (cmd) { 142 switch (cmd) {
129 case MODULE_CMD_INIT: 143 case MODULE_CMD_INIT:
130 if (((dmt = dm_target_lookup("snapshot")) != NULL)) { 144 if (((dmt = dm_target_lookup("snapshot")) != NULL)) {
131 dm_target_unbusy(dmt); 145 dm_target_unbusy(dmt);
132 return EEXIST; 146 return EEXIST;
133 } 147 }
134 if (((dmt = dm_target_lookup("snapshot-origin")) != NULL)) { 148 if (((dmt = dm_target_lookup("snapshot-origin")) != NULL)) {
135 dm_target_unbusy(dmt); 149 dm_target_unbusy(dmt);
136 return EEXIST; 150 return EEXIST;
137 } 151 }
138 dmt = dm_target_alloc("snapshot"); 152 dmt = dm_target_alloc("snapshot");
139 dmt1 = dm_target_alloc("snapshot-origin"); 153 dmt1 = dm_target_alloc("snapshot-origin");
140 154
141 dmt->version[0] = 1; 155 dmt->version[0] = 1;
142 dmt->version[1] = 0; 156 dmt->version[1] = 0;
143 dmt->version[2] = 5; 157 dmt->version[2] = 5;
144 dmt->init = &dm_target_snapshot_init; 158 dmt->init = &dm_target_snapshot_init;
145 dmt->status = &dm_target_snapshot_status; 159 dmt->status = &dm_target_snapshot_status;
146 dmt->strategy = &dm_target_snapshot_strategy; 160 dmt->strategy = &dm_target_snapshot_strategy;
147 dmt->deps = &dm_target_snapshot_deps; 161 dmt->deps = &dm_target_snapshot_deps;
148 dmt->destroy = &dm_target_snapshot_destroy; 162 dmt->destroy = &dm_target_snapshot_destroy;
149 dmt->upcall = &dm_target_snapshot_upcall; 163 dmt->upcall = &dm_target_snapshot_upcall;
150 164
151 r = dm_target_insert(dmt); 165 r = dm_target_insert(dmt);
152 166
153 dmt1->version[0] = 1; 167 dmt1->version[0] = 1;
154 dmt1->version[1] = 0; 168 dmt1->version[1] = 0;
155 dmt1->version[2] = 5; 169 dmt1->version[2] = 5;
156 dmt1->init = &dm_target_snapshot_orig_init; 170 dmt1->init = &dm_target_snapshot_orig_init;
157 dmt1->status = &dm_target_snapshot_orig_status; 171 dmt1->status = &dm_target_snapshot_orig_status;
158 dmt1->strategy = &dm_target_snapshot_orig_strategy; 172 dmt1->strategy = &dm_target_snapshot_orig_strategy;
159 dmt1->sync = &dm_target_snapshot_orig_sync; 173 dmt1->sync = &dm_target_snapshot_orig_sync;
160 dmt1->deps = &dm_target_snapshot_orig_deps; 174 dmt1->deps = &dm_target_snapshot_orig_deps;
161 dmt1->destroy = &dm_target_snapshot_orig_destroy; 175 dmt1->destroy = &dm_target_snapshot_orig_destroy;
162 dmt1->upcall = &dm_target_snapshot_orig_upcall; 176 dmt1->upcall = &dm_target_snapshot_orig_upcall;
163 177
164 r = dm_target_insert(dmt1); 178 r = dm_target_insert(dmt1);
165 break; 179 break;
166 180
167 case MODULE_CMD_FINI: 181 case MODULE_CMD_FINI:
168 /* 182 /*
169 * Try to remove snapshot target if it works remove snap-origin 183 * Try to remove snapshot target if it works remove snap-origin
170 * it is not possible to remove snapshot and do not remove 184 * it is not possible to remove snapshot and do not remove
171 * snap-origin because they are used together. 185 * snap-origin because they are used together.
172 */ 186 */
173 if ((r = dm_target_rem("snapshot")) == 0) 187 if ((r = dm_target_rem("snapshot")) == 0)
174 r = dm_target_rem("snapshot-origin"); 188 r = dm_target_rem("snapshot-origin");
175 189
176 break; 190 break;
177 191
178 case MODULE_CMD_STAT: 192 case MODULE_CMD_STAT:
179 return ENOTTY; 193 return ENOTTY;
180 194
181 default: 195 default:
182 return ENOTTY; 196 return ENOTTY;
183 } 197 }
184 198
185 return r; 199 return r;
186} 200}
187#endif 201#endif
188 202
189/* 203/*
190 * Init function called from dm_table_load_ioctl. 204 * Init function called from dm_table_load_ioctl.
191 * argv: /dev/mapper/my_data_org /dev/mapper/tsc_cow_dev p 64 205 * argv: /dev/mapper/my_data_org /dev/mapper/tsc_cow_dev p 64
192 * snapshot_origin device, cow device, persistent flag, chunk size 206 * snapshot_origin device, cow device, persistent flag, chunk size
193 */ 207 */
194int 208int
195dm_target_snapshot_init(dm_table_entry_t *table_en, char *params) 209dm_target_snapshot_init(dm_table_entry_t *table_en, char *params)
196{ 210{
197 dm_target_snapshot_config_t *tsc; 211 dm_target_snapshot_config_t *tsc;
198 dm_pdev_t *dmp_snap, *dmp_cow; 212 dm_pdev_t *dmp_snap, *dmp_cow;
199 char **ap, *argv[5]; 213 char **ap, *argv[5];
200 214
201 dmp_cow = NULL; 215 dmp_cow = NULL;
202 216
203 if (params == NULL) 217 if (params == NULL)
204 return EINVAL; 218 return EINVAL;
205 /* 219 /*
206 * Parse a string, containing tokens delimited by white space, 220 * Parse a string, containing tokens delimited by white space,
207 * into an argument vector 221 * into an argument vector
208 */ 222 */
209 for (ap = argv; ap < &argv[4] && 223 for (ap = argv; ap < &argv[4] &&
210 (*ap = strsep(&params, " \t")) != NULL;) { 224 (*ap = strsep(&params, " \t")) != NULL;) {
211 if (**ap != '\0') 225 if (**ap != '\0')
212 ap++; 226 ap++;
213 } 227 }
214 228
215 printf("Snapshot target init function called!!\n"); 229 printf("Snapshot target init function called!!\n");
216 printf("Snapshotted device: %s, cow device %s,\n\t persistent flag: %s, " 230 printf("Snapshotted device: %s, cow device %s,\n\t persistent flag: %s, "
217 "chunk size: %s\n", argv[0], argv[1], argv[2], argv[3]); 231 "chunk size: %s\n", argv[0], argv[1], argv[2], argv[3]);
218 232
219 /* Insert snap device to global pdev list */ 233 /* Insert snap device to global pdev list */
220 if ((dmp_snap = dm_pdev_insert(argv[0])) == NULL) 234 if ((dmp_snap = dm_pdev_insert(argv[0])) == NULL)
221 return ENOENT; 235 return ENOENT;
222 236
223 tsc = kmem_alloc(sizeof(*tsc), KM_SLEEP); 237 tsc = kmem_alloc(sizeof(*tsc), KM_SLEEP);
224 tsc->tsc_persistent_dev = 0; 238 tsc->tsc_persistent_dev = 0;
225 239
226 /* There is now cow device for nonpersistent snapshot devices */ 240 /* There is now cow device for nonpersistent snapshot devices */
227 if (strcmp(argv[2], "p") == 0) { 241 if (strcmp(argv[2], "p") == 0) {
228 tsc->tsc_persistent_dev = 1; 242 tsc->tsc_persistent_dev = 1;
229 243
230 /* Insert cow device to global pdev list */ 244 /* Insert cow device to global pdev list */
231 if ((dmp_cow = dm_pdev_insert(argv[1])) == NULL) { 245 if ((dmp_cow = dm_pdev_insert(argv[1])) == NULL) {
232 kmem_free(tsc, sizeof(*tsc)); 246 kmem_free(tsc, sizeof(*tsc));
233 return ENOENT; 247 return ENOENT;
234 } 248 }
235 } 249 }
236 tsc->tsc_chunk_size = atoi(argv[3]); 250 tsc->tsc_chunk_size = atoi(argv[3]);
237 251
238 tsc->tsc_snap_dev = dmp_snap; 252 tsc->tsc_snap_dev = dmp_snap;
239 tsc->tsc_cow_dev = dmp_cow; 253 tsc->tsc_cow_dev = dmp_cow;
240 254
241 table_en->target_config = tsc; 255 table_en->target_config = tsc;
242 256
243 return 0; 257 return 0;
244} 258}
245 259
246/* 260/*
247 * Status routine is called to get params string, which is target 261 * Status routine is called to get params string, which is target
248 * specific. When dm_table_status_ioctl is called with flag 262 * specific. When dm_table_status_ioctl is called with flag
249 * DM_STATUS_TABLE_FLAG I have to sent params string back. 263 * DM_STATUS_TABLE_FLAG I have to sent params string back.
250 */ 264 */
251char * 265char *
252dm_target_snapshot_status(void *target_config) 266dm_target_snapshot_status(void *target_config)
253{ 267{
254 dm_target_snapshot_config_t *tsc; 268 dm_target_snapshot_config_t *tsc;
255 269
256 uint32_t i; 270 uint32_t i;
257 uint32_t count; 271 uint32_t count;
258 size_t prm_len, cow_len; 272 size_t prm_len, cow_len;
259 char *params; 273 char *params;
260 274
261 tsc = target_config; 275 tsc = target_config;
262 276
263 prm_len = 0; 277 prm_len = 0;
264 cow_len = 0; 278 cow_len = 0;
265 count = 0; 279 count = 0;
266 280
267 printf("Snapshot target status function called\n"); 281 printf("Snapshot target status function called\n");
268 282
269 /* count number of chars in offset */ 283 /* count number of chars in offset */
270 for (i = tsc->tsc_chunk_size; i != 0; i /= 10) 284 for (i = tsc->tsc_chunk_size; i != 0; i /= 10)
271 count++; 285 count++;
272 286
273 if (tsc->tsc_persistent_dev) 287 if (tsc->tsc_persistent_dev)
274 cow_len = strlen(tsc->tsc_cow_dev->name); 288 cow_len = strlen(tsc->tsc_cow_dev->name);
275 289
276 /* length of names + count of chars + spaces and null char */ 290 /* length of names + count of chars + spaces and null char */
277 prm_len = strlen(tsc->tsc_snap_dev->name) + cow_len + count + 5; 291 prm_len = strlen(tsc->tsc_snap_dev->name) + cow_len + count + 5;
278 292
279 params = kmem_alloc(prm_len, KM_SLEEP); 293 params = kmem_alloc(prm_len, KM_SLEEP);
280 294
281 printf("%s %s %s %" PRIu64 "\n", tsc->tsc_snap_dev->name, 295 printf("%s %s %s %" PRIu64 "\n", tsc->tsc_snap_dev->name,
282 tsc->tsc_cow_dev->name, tsc->tsc_persistent_dev ? "p" : "n", 296 tsc->tsc_cow_dev->name, tsc->tsc_persistent_dev ? "p" : "n",
283 tsc->tsc_chunk_size); 297 tsc->tsc_chunk_size);
284 298
285 snprintf(params, prm_len, "%s %s %s %" PRIu64, tsc->tsc_snap_dev->name, 299 snprintf(params, prm_len, "%s %s %s %" PRIu64, tsc->tsc_snap_dev->name,
286 tsc->tsc_persistent_dev ? tsc->tsc_cow_dev->name : "", 300 tsc->tsc_persistent_dev ? tsc->tsc_cow_dev->name : "",
287 tsc->tsc_persistent_dev ? "p" : "n", 301 tsc->tsc_persistent_dev ? "p" : "n",
288 tsc->tsc_chunk_size); 302 tsc->tsc_chunk_size);
289 303
290 return params; 304 return params;
291} 305}
292 306
293/* Strategy routine called from dm_strategy. */ 307/* Strategy routine called from dm_strategy. */
294int 308int
295dm_target_snapshot_strategy(dm_table_entry_t *table_en, struct buf *bp) 309dm_target_snapshot_strategy(dm_table_entry_t *table_en, struct buf *bp)
296{ 310{
297 311
298 printf("Snapshot target read function called!!\n"); 312 printf("Snapshot target read function called!!\n");
299 313
300 bp->b_error = EIO; 314 bp->b_error = EIO;
301 bp->b_resid = 0; 315 bp->b_resid = 0;
302 316
303 biodone(bp); 317 biodone(bp);
304 318
305 return 0; 319 return 0;
306} 320}
307 321
308/* Doesn't do anything here. */ 322/* Doesn't do anything here. */
309int 323int
310dm_target_snapshot_destroy(dm_table_entry_t *table_en) 324dm_target_snapshot_destroy(dm_table_entry_t *table_en)
311{ 325{
312 326
313 /* 327 /*
314 * Destroy function is called for every target even if it 328 * Destroy function is called for every target even if it
315 * doesn't have target_config. 329 * doesn't have target_config.
316 */ 330 */
317 if (table_en->target_config == NULL) 331 if (table_en->target_config == NULL)
318 goto out; 332 goto out;
319 333
320 printf("Snapshot target destroy function called\n"); 334 printf("Snapshot target destroy function called\n");
321 335
322 dm_target_snapshot_config_t *tsc = table_en->target_config; 336 dm_target_snapshot_config_t *tsc = table_en->target_config;
323 337
324 /* Decrement pdev ref counter if 0 remove it */ 338 /* Decrement pdev ref counter if 0 remove it */
325 dm_pdev_decr(tsc->tsc_snap_dev); 339 dm_pdev_decr(tsc->tsc_snap_dev);
326 if (tsc->tsc_persistent_dev) 340 if (tsc->tsc_persistent_dev)
327 dm_pdev_decr(tsc->tsc_cow_dev); 341 dm_pdev_decr(tsc->tsc_cow_dev);
328 342
329 kmem_free(tsc, sizeof(*tsc)); 343 kmem_free(tsc, sizeof(*tsc));
330out: 344out:
331 /* Unbusy target so we can unload it */ 345 /* Unbusy target so we can unload it */
332 dm_target_unbusy(table_en->target); 346 dm_target_unbusy(table_en->target);
333 347
334 return 0; 348 return 0;
335} 349}
336 350
337/* Add this target dependencies to prop_array_t */ 351/* Add this target dependencies to prop_array_t */
338int 352int
339dm_target_snapshot_deps(dm_table_entry_t *table_en, prop_array_t prop_array) 353dm_target_snapshot_deps(dm_table_entry_t *table_en, prop_array_t prop_array)
340{ 354{
341 dm_target_snapshot_config_t *tsc; 355 dm_target_snapshot_config_t *tsc;
342 356
343 if (table_en->target_config == NULL) 357 if (table_en->target_config == NULL)
344 return 0; 358 return 0;
345 359
346 tsc = table_en->target_config; 360 tsc = table_en->target_config;
347 361
348 prop_array_add_uint64(prop_array, 362 prop_array_add_uint64(prop_array,
349 (uint64_t) tsc->tsc_snap_dev->pdev_vnode->v_rdev); 363 (uint64_t) tsc->tsc_snap_dev->pdev_vnode->v_rdev);
350 364
351 if (tsc->tsc_persistent_dev) { 365 if (tsc->tsc_persistent_dev) {
352 prop_array_add_uint64(prop_array, 366 prop_array_add_uint64(prop_array,
353 (uint64_t) tsc->tsc_cow_dev->pdev_vnode->v_rdev); 367 (uint64_t) tsc->tsc_cow_dev->pdev_vnode->v_rdev);
354 368
355 } 369 }
356 return 0; 370 return 0;
357} 371}
358 372
359/* Upcall is used to inform other depended devices about IO. */ 373/* Upcall is used to inform other depended devices about IO. */
360int 374int
361dm_target_snapshot_upcall(dm_table_entry_t *table_en, struct buf *bp) 375dm_target_snapshot_upcall(dm_table_entry_t *table_en, struct buf *bp)
362{ 376{
363 printf("dm_target_snapshot_upcall called\n"); 377 printf("dm_target_snapshot_upcall called\n");
364 378
365 printf("upcall buf flags %s %s\n", 379 printf("upcall buf flags %s %s\n",
366 (bp->b_flags & B_WRITE) ? "B_WRITE" : "", 380 (bp->b_flags & B_WRITE) ? "B_WRITE" : "",
367 (bp->b_flags & B_READ) ? "B_READ" : ""); 381 (bp->b_flags & B_READ) ? "B_READ" : "");
368 382
369 return 0; 383 return 0;
370} 384}
371 385
372/* 386/*
373 * dm target snapshot origin routines. 387 * dm target snapshot origin routines.
374 * 388 *
375 * Keep for compatibility with linux lvm2tools. They use two targets 389 * Keep for compatibility with linux lvm2tools. They use two targets
376 * to implement snapshots. Snapshot target will implement exception 390 * to implement snapshots. Snapshot target will implement exception
377 * store and snapshot origin will implement device which calls every 391 * store and snapshot origin will implement device which calls every
378 * snapshot device when write is done on master device. 392 * snapshot device when write is done on master device.
379 */ 393 */
380 394
381/* 395/*
382 * Init function called from dm_table_load_ioctl. 396 * Init function called from dm_table_load_ioctl.
383 * 397 *
384 * argv: /dev/mapper/my_data_real 398 * argv: /dev/mapper/my_data_real
385 */ 399 */
386int 400int
387dm_target_snapshot_orig_init(dm_table_entry_t *table_en, char *params) 401dm_target_snapshot_orig_init(dm_table_entry_t *table_en, char *params)
388{ 402{
389 dm_target_snapshot_origin_config_t *tsoc; 403 dm_target_snapshot_origin_config_t *tsoc;
390 dm_pdev_t *dmp_real; 404 dm_pdev_t *dmp_real;
391 405
392 if (params == NULL) 406 if (params == NULL)
393 return EINVAL; 407 return EINVAL;
394 408
395 printf("Snapshot origin target init function called!!\n"); 409 printf("Snapshot origin target init function called!!\n");
396 printf("Parent device: %s\n", params); 410 printf("Parent device: %s\n", params);
397 411
398 /* Insert snap device to global pdev list */ 412 /* Insert snap device to global pdev list */
399 if ((dmp_real = dm_pdev_insert(params)) == NULL) 413 if ((dmp_real = dm_pdev_insert(params)) == NULL)
400 return ENOENT; 414 return ENOENT;
401 415
402 tsoc = kmem_alloc(sizeof(dm_target_snapshot_origin_config_t), KM_SLEEP); 416 tsoc = kmem_alloc(sizeof(dm_target_snapshot_origin_config_t), KM_SLEEP);
403 tsoc->tsoc_real_dev = dmp_real; 417 tsoc->tsoc_real_dev = dmp_real;
404 418
405 table_en->target_config = tsoc; 419 table_en->target_config = tsoc;
406 420
407 return 0; 421 return 0;
408} 422}
409 423
410/* 424/*
411 * Status routine is called to get params string, which is target 425 * Status routine is called to get params string, which is target
412 * specific. When dm_table_status_ioctl is called with flag 426 * specific. When dm_table_status_ioctl is called with flag
413 * DM_STATUS_TABLE_FLAG I have to sent params string back. 427 * DM_STATUS_TABLE_FLAG I have to sent params string back.
414 */ 428 */
415char * 429char *
416dm_target_snapshot_orig_status(void *target_config) 430dm_target_snapshot_orig_status(void *target_config)
417{ 431{
418 dm_target_snapshot_origin_config_t *tsoc; 432 dm_target_snapshot_origin_config_t *tsoc;
419 433
420 size_t prm_len; 434 size_t prm_len;
421 char *params; 435 char *params;
422 436
423 tsoc = target_config; 437 tsoc = target_config;
424 438
425 prm_len = 0; 439 prm_len = 0;
426 440
427 printf("Snapshot origin target status function called\n"); 441 printf("Snapshot origin target status function called\n");
428 442
429 /* length of names + count of chars + spaces and null char */ 443 /* length of names + count of chars + spaces and null char */
430 prm_len = strlen(tsoc->tsoc_real_dev->name) + 1; 444 prm_len = strlen(tsoc->tsoc_real_dev->name) + 1;
431 445
432 printf("real_dev name %s\n", tsoc->tsoc_real_dev->name); 446 printf("real_dev name %s\n", tsoc->tsoc_real_dev->name);
433 447
434 params = kmem_alloc(prm_len, KM_SLEEP); 448 params = kmem_alloc(prm_len, KM_SLEEP);
435 449
436 printf("%s\n", tsoc->tsoc_real_dev->name); 450 printf("%s\n", tsoc->tsoc_real_dev->name);
437 451
438 snprintf(params, prm_len, "%s", tsoc->tsoc_real_dev->name); 452 snprintf(params, prm_len, "%s", tsoc->tsoc_real_dev->name);
439 453
440 return params; 454 return params;
441} 455}
442 456
443/* Strategy routine called from dm_strategy. */ 457/* Strategy routine called from dm_strategy. */
444int 458int
445dm_target_snapshot_orig_strategy(dm_table_entry_t *table_en, struct buf *bp) 459dm_target_snapshot_orig_strategy(dm_table_entry_t *table_en, struct buf *bp)
446{ 460{
447 461
448 printf("Snapshot_Orig target read function called!!\n"); 462 printf("Snapshot_Orig target read function called!!\n");
449 463
450 bp->b_error = EIO; 464 bp->b_error = EIO;
451 bp->b_resid = 0; 465 bp->b_resid = 0;
452 466
453 biodone(bp); 467 biodone(bp);
454 468
455 return 0; 469 return 0;
456} 470}
457 471
458/* 472/*
459 * Sync underlying disk caches. 473 * Sync underlying disk caches.
460 */ 474 */
461int 475int
462dm_target_snapshot_orig_sync(dm_table_entry_t *table_en) 476dm_target_snapshot_orig_sync(dm_table_entry_t *table_en)
463{ 477{
464 int cmd; 478 int cmd;
465 dm_target_snapshot_origin_config_t *tsoc; 479 dm_target_snapshot_origin_config_t *tsoc;
466 480
467 tsoc = table_en->target_config; 481 tsoc = table_en->target_config;
468 482
469 cmd = 1; 483 cmd = 1;
470 484
471 return VOP_IOCTL(tsoc->tsoc_real_dev->pdev_vnode, DIOCCACHESYNC, 485 return VOP_IOCTL(tsoc->tsoc_real_dev->pdev_vnode, DIOCCACHESYNC,
472 &cmd, FREAD|FWRITE, kauth_cred_get()); 486 &cmd, FREAD|FWRITE, kauth_cred_get());
473} 487}
474 488
475/* Decrement pdev and free allocated space. */ 489/* Decrement pdev and free allocated space. */
476int 490int
477dm_target_snapshot_orig_destroy(dm_table_entry_t *table_en) 491dm_target_snapshot_orig_destroy(dm_table_entry_t *table_en)
478{ 492{
479 493
480 /* 494 /*
481 * Destroy function is called for every target even if it 495 * Destroy function is called for every target even if it
482 * doesn't have target_config. 496 * doesn't have target_config.
483 */ 497 */
484 498
485 if (table_en->target_config == NULL) 499 if (table_en->target_config == NULL)
486 goto out; 500 goto out;
487 501
488 dm_target_snapshot_origin_config_t *tsoc = table_en->target_config; 502 dm_target_snapshot_origin_config_t *tsoc = table_en->target_config;
489 503
490 /* Decrement pdev ref counter if 0 remove it */ 504 /* Decrement pdev ref counter if 0 remove it */
491 dm_pdev_decr(tsoc->tsoc_real_dev); 505 dm_pdev_decr(tsoc->tsoc_real_dev);
492 506
493 kmem_free(tsoc, sizeof(*tsoc)); 507 kmem_free(tsoc, sizeof(*tsoc));
494out: 508out:
495 /* Unbusy target so we can unload it */ 509 /* Unbusy target so we can unload it */
496 dm_target_unbusy(table_en->target); 510 dm_target_unbusy(table_en->target);
497 511
498 return 0; 512 return 0;
499} 513}
500 514
501/* 515/*
502 * Get target deps and add them to prop_array_t. 516 * Get target deps and add them to prop_array_t.
503 */ 517 */
504int 518int
505dm_target_snapshot_orig_deps(dm_table_entry_t *table_en, 519dm_target_snapshot_orig_deps(dm_table_entry_t *table_en,
506 prop_array_t prop_array) 520 prop_array_t prop_array)
507{ 521{
508 dm_target_snapshot_origin_config_t *tsoc; 522 dm_target_snapshot_origin_config_t *tsoc;
509 struct vattr va; 523 struct vattr va;
510 524
511 int error; 525 int error;
512 526
513 if (table_en->target_config == NULL) 527 if (table_en->target_config == NULL)
514 return 0; 528 return 0;
515 529
516 tsoc = table_en->target_config; 530 tsoc = table_en->target_config;
517 531
518 vn_lock(tsoc->tsoc_real_dev->pdev_vnode, LK_SHARED | LK_RETRY); 532 vn_lock(tsoc->tsoc_real_dev->pdev_vnode, LK_SHARED | LK_RETRY);
519 error = VOP_GETATTR(tsoc->tsoc_real_dev->pdev_vnode, &va, 533 error = VOP_GETATTR(tsoc->tsoc_real_dev->pdev_vnode, &va,
520 curlwp->l_cred); 534 curlwp->l_cred);
521 VOP_UNLOCK(tsoc->tsoc_real_dev->pdev_vnode); 535 VOP_UNLOCK(tsoc->tsoc_real_dev->pdev_vnode);
522 if (error != 0) 536 if (error != 0)
523 return error; 537 return error;
524 538
525 prop_array_add_uint64(prop_array, (uint64_t) va.va_rdev); 539 prop_array_add_uint64(prop_array, (uint64_t) va.va_rdev);
526 540
527 return 0; 541 return 0;
528} 542}
529 543
530/* Unsupported for this target. */ 544/* Unsupported for this target. */
531int 545int
532dm_target_snapshot_orig_upcall(dm_table_entry_t *table_en, struct buf *bp) 546dm_target_snapshot_orig_upcall(dm_table_entry_t *table_en, struct buf *bp)
533{ 547{
534 return 0; 548 return 0;
535} 549}

cvs diff -r1.31 -r1.32 src/sys/dev/dm/dm_target_stripe.c (switch to unified diff)

--- src/sys/dev/dm/dm_target_stripe.c 2019/12/08 04:41:02 1.31
+++ src/sys/dev/dm/dm_target_stripe.c 2019/12/08 10:50:21 1.32
@@ -1,372 +1,380 @@ @@ -1,372 +1,380 @@
1/*$NetBSD: dm_target_stripe.c,v 1.31 2019/12/08 04:41:02 tkusumi Exp $*/ 1/*$NetBSD: dm_target_stripe.c,v 1.32 2019/12/08 10:50:21 tkusumi Exp $*/
2 2
3/* 3/*
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: dm_target_stripe.c,v 1.31 2019/12/08 04:41:02 tkusumi Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: dm_target_stripe.c,v 1.32 2019/12/08 10:50:21 tkusumi Exp $");
33 33
34/* 34/*
35 * This file implements initial version of device-mapper stripe target. 35 * This file implements initial version of device-mapper stripe target.
36 */ 36 */
37#include <sys/types.h> 37#include <sys/types.h>
38#include <sys/param.h> 38#include <sys/param.h>
39 39
40#include <sys/buf.h> 40#include <sys/buf.h>
41#include <sys/kmem.h> 41#include <sys/kmem.h>
42#include <sys/lwp.h> 42#include <sys/lwp.h>
43 43
44#include "dm.h" 44#include "dm.h"
45 45
 46typedef struct target_stripe_config {
 47#define DM_STRIPE_DEV_OFFSET 2
 48 struct target_linear_devs stripe_devs;
 49 uint8_t stripe_num;
 50 uint64_t stripe_chunksize;
 51 size_t params_len;
 52} dm_target_stripe_config_t;
 53
46#ifdef DM_TARGET_MODULE 54#ifdef DM_TARGET_MODULE
47/* 55/*
48 * Every target can be compiled directly to dm driver or as a 56 * Every target can be compiled directly to dm driver or as a
49 * separate module this part of target is used for loading targets 57 * separate module this part of target is used for loading targets
50 * to dm driver. 58 * to dm driver.
51 * Target can be unloaded from kernel only if there are no users of 59 * Target can be unloaded from kernel only if there are no users of
52 * it e.g. there are no devices which uses that target. 60 * it e.g. there are no devices which uses that target.
53 */ 61 */
54#include <sys/kernel.h> 62#include <sys/kernel.h>
55#include <sys/module.h> 63#include <sys/module.h>
56 64
57MODULE(MODULE_CLASS_MISC, dm_target_stripe, NULL); 65MODULE(MODULE_CLASS_MISC, dm_target_stripe, NULL);
58 66
59static int 67static int
60dm_target_stripe_modcmd(modcmd_t cmd, void *arg) 68dm_target_stripe_modcmd(modcmd_t cmd, void *arg)
61{ 69{
62 dm_target_t *dmt; 70 dm_target_t *dmt;
63 int r; 71 int r;
64 dmt = NULL; 72 dmt = NULL;
65 73
66 switch (cmd) { 74 switch (cmd) {
67 case MODULE_CMD_INIT: 75 case MODULE_CMD_INIT:
68 if ((dmt = dm_target_lookup("stripe")) != NULL) { 76 if ((dmt = dm_target_lookup("stripe")) != NULL) {
69 dm_target_unbusy(dmt); 77 dm_target_unbusy(dmt);
70 return EEXIST; 78 return EEXIST;
71 } 79 }
72 dmt = dm_target_alloc("stripe"); 80 dmt = dm_target_alloc("stripe");
73 81
74 dmt->version[0] = 1; 82 dmt->version[0] = 1;
75 dmt->version[1] = 0; 83 dmt->version[1] = 0;
76 dmt->version[2] = 0; 84 dmt->version[2] = 0;
77 dmt->init = &dm_target_stripe_init; 85 dmt->init = &dm_target_stripe_init;
78 dmt->status = &dm_target_stripe_status; 86 dmt->status = &dm_target_stripe_status;
79 dmt->strategy = &dm_target_stripe_strategy; 87 dmt->strategy = &dm_target_stripe_strategy;
80 dmt->sync = &dm_target_stripe_sync; 88 dmt->sync = &dm_target_stripe_sync;
81 dmt->deps = &dm_target_stripe_deps; 89 dmt->deps = &dm_target_stripe_deps;
82 dmt->destroy = &dm_target_stripe_destroy; 90 dmt->destroy = &dm_target_stripe_destroy;
83 dmt->upcall = &dm_target_stripe_upcall; 91 dmt->upcall = &dm_target_stripe_upcall;
84 dmt->secsize = &dm_target_stripe_secsize; 92 dmt->secsize = &dm_target_stripe_secsize;
85 93
86 r = dm_target_insert(dmt); 94 r = dm_target_insert(dmt);
87 95
88 break; 96 break;
89 97
90 case MODULE_CMD_FINI: 98 case MODULE_CMD_FINI:
91 r = dm_target_rem("stripe"); 99 r = dm_target_rem("stripe");
92 break; 100 break;
93 101
94 case MODULE_CMD_STAT: 102 case MODULE_CMD_STAT:
95 return ENOTTY; 103 return ENOTTY;
96 104
97 default: 105 default:
98 return ENOTTY; 106 return ENOTTY;
99 } 107 }
100 108
101 return r; 109 return r;
102} 110}
103#endif 111#endif
104 112
105static void 113static void
106dm_target_stripe_fini(dm_target_stripe_config_t *tsc) 114dm_target_stripe_fini(dm_target_stripe_config_t *tsc)
107{ 115{
108 dm_target_linear_config_t *tlc; 116 dm_target_linear_config_t *tlc;
109 117
110 if (tsc == NULL) 118 if (tsc == NULL)
111 return; 119 return;
112 120
113 while ((tlc = TAILQ_FIRST(&tsc->stripe_devs)) != NULL) { 121 while ((tlc = TAILQ_FIRST(&tsc->stripe_devs)) != NULL) {
114 TAILQ_REMOVE(&tsc->stripe_devs, tlc, entries); 122 TAILQ_REMOVE(&tsc->stripe_devs, tlc, entries);
115 dm_pdev_decr(tlc->pdev); 123 dm_pdev_decr(tlc->pdev);
116 kmem_free(tlc, sizeof(*tlc)); 124 kmem_free(tlc, sizeof(*tlc));
117 } 125 }
118 126
119 kmem_free(tsc, sizeof(*tsc)); 127 kmem_free(tsc, sizeof(*tsc));
120} 128}
121 129
122/* 130/*
123 * Init function called from dm_table_load_ioctl. 131 * Init function called from dm_table_load_ioctl.
124 * DM_STRIPE_DEV_OFFSET should always hold the index of the first device-offset 132 * DM_STRIPE_DEV_OFFSET should always hold the index of the first device-offset
125 * pair in the parameters. 133 * pair in the parameters.
126 * Example line sent to dm from lvm tools when using striped target. 134 * Example line sent to dm from lvm tools when using striped target.
127 * start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN 135 * start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN
128 * 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0 136 * 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0
129 */ 137 */
130int 138int
131dm_target_stripe_init(dm_table_entry_t *table_en, char *params) 139dm_target_stripe_init(dm_table_entry_t *table_en, char *params)
132{ 140{
133 dm_target_linear_config_t *tlc; 141 dm_target_linear_config_t *tlc;
134 dm_target_stripe_config_t *tsc; 142 dm_target_stripe_config_t *tsc;
135 size_t len; 143 size_t len;
136 char **ap, *argv[10]; 144 char **ap, *argv[10];
137 int strpc, strpi; 145 int strpc, strpi;
138 146
139 if (params == NULL) 147 if (params == NULL)
140 return EINVAL; 148 return EINVAL;
141 149
142 len = strlen(params) + 1; 150 len = strlen(params) + 1;
143 151
144 /* 152 /*
145 * Parse a string, containing tokens delimited by white space, 153 * Parse a string, containing tokens delimited by white space,
146 * into an argument vector 154 * into an argument vector
147 */ 155 */
148 for (ap = argv; ap <= &argv[9] && 156 for (ap = argv; ap <= &argv[9] &&
149 (*ap = strsep(&params, " \t")) != NULL;) { 157 (*ap = strsep(&params, " \t")) != NULL;) {
150 if (**ap != '\0') 158 if (**ap != '\0')
151 ap++; 159 ap++;
152 } 160 }
153 161
154 printf("Stripe target init function called!!\n"); 162 printf("Stripe target init function called!!\n");
155 163
156 printf("Stripe target chunk size %s number of stripes %s\n", 164 printf("Stripe target chunk size %s number of stripes %s\n",
157 argv[1], argv[0]); 165 argv[1], argv[0]);
158 166
159 tsc = kmem_alloc(sizeof(*tsc), KM_SLEEP); 167 tsc = kmem_alloc(sizeof(*tsc), KM_SLEEP);
160 168
161 /* Initialize linked list for striping devices */ 169 /* Initialize linked list for striping devices */
162 TAILQ_INIT(&tsc->stripe_devs); 170 TAILQ_INIT(&tsc->stripe_devs);
163 171
164 /* Save length of param string */ 172 /* Save length of param string */
165 tsc->params_len = len; 173 tsc->params_len = len;
166 tsc->stripe_chunksize = atoi(argv[1]); 174 tsc->stripe_chunksize = atoi(argv[1]);
167 tsc->stripe_num = (uint8_t) atoi(argv[0]); 175 tsc->stripe_num = (uint8_t) atoi(argv[0]);
168 176
169 strpc = DM_STRIPE_DEV_OFFSET + (tsc->stripe_num * 2); 177 strpc = DM_STRIPE_DEV_OFFSET + (tsc->stripe_num * 2);
170 for (strpi = DM_STRIPE_DEV_OFFSET; strpi < strpc; strpi += 2) { 178 for (strpi = DM_STRIPE_DEV_OFFSET; strpi < strpc; strpi += 2) {
171 printf("Stripe target device name %s -- offset %s\n", 179 printf("Stripe target device name %s -- offset %s\n",
172 argv[strpi], argv[strpi+1]); 180 argv[strpi], argv[strpi+1]);
173 181
174 tlc = kmem_alloc(sizeof(*tlc), KM_SLEEP); 182 tlc = kmem_alloc(sizeof(*tlc), KM_SLEEP);
175 if ((tlc->pdev = dm_pdev_insert(argv[strpi])) == NULL) { 183 if ((tlc->pdev = dm_pdev_insert(argv[strpi])) == NULL) {
176 kmem_free(tlc, sizeof(*tlc)); 184 kmem_free(tlc, sizeof(*tlc));
177 dm_target_stripe_fini(tsc); 185 dm_target_stripe_fini(tsc);
178 return ENOENT; 186 return ENOENT;
179 } 187 }
180 tlc->offset = atoi(argv[strpi+1]); 188 tlc->offset = atoi(argv[strpi+1]);
181 189
182 /* Insert striping device to linked list. */ 190 /* Insert striping device to linked list. */
183 TAILQ_INSERT_TAIL(&tsc->stripe_devs, tlc, entries); 191 TAILQ_INSERT_TAIL(&tsc->stripe_devs, tlc, entries);
184 } 192 }
185 193
186 table_en->target_config = tsc; 194 table_en->target_config = tsc;
187 195
188 return 0; 196 return 0;
189} 197}
190 198
191/* Status routine called to get params string. */ 199/* Status routine called to get params string. */
192char * 200char *
193dm_target_stripe_status(void *target_config) 201dm_target_stripe_status(void *target_config)
194{ 202{
195 dm_target_linear_config_t *tlc; 203 dm_target_linear_config_t *tlc;
196 dm_target_stripe_config_t *tsc; 204 dm_target_stripe_config_t *tsc;
197 char *params, *tmp; 205 char *params, *tmp;
198 206
199 tsc = target_config; 207 tsc = target_config;
200 208
201 params = kmem_alloc(DM_MAX_PARAMS_SIZE, KM_SLEEP); 209 params = kmem_alloc(DM_MAX_PARAMS_SIZE, KM_SLEEP);
202 tmp = kmem_alloc(DM_MAX_PARAMS_SIZE, KM_SLEEP); 210 tmp = kmem_alloc(DM_MAX_PARAMS_SIZE, KM_SLEEP);
203 211
204 snprintf(params, DM_MAX_PARAMS_SIZE, "%d %" PRIu64, 212 snprintf(params, DM_MAX_PARAMS_SIZE, "%d %" PRIu64,
205 tsc->stripe_num, tsc->stripe_chunksize); 213 tsc->stripe_num, tsc->stripe_chunksize);
206 214
207 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) { 215 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) {
208 snprintf(tmp, DM_MAX_PARAMS_SIZE, " %s %" PRIu64, 216 snprintf(tmp, DM_MAX_PARAMS_SIZE, " %s %" PRIu64,
209 tlc->pdev->name, tlc->offset); 217 tlc->pdev->name, tlc->offset);
210 strcat(params, tmp); 218 strcat(params, tmp);
211 } 219 }
212 220
213 kmem_free(tmp, DM_MAX_PARAMS_SIZE); 221 kmem_free(tmp, DM_MAX_PARAMS_SIZE);
214 222
215 return params; 223 return params;
216} 224}
217 225
218/* Strategy routine called from dm_strategy. */ 226/* Strategy routine called from dm_strategy. */
219int 227int
220dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp) 228dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp)
221{ 229{
222 dm_target_linear_config_t *tlc; 230 dm_target_linear_config_t *tlc;
223 dm_target_stripe_config_t *tsc; 231 dm_target_stripe_config_t *tsc;
224 struct buf *nestbuf; 232 struct buf *nestbuf;
225 uint64_t blkno, blkoff; 233 uint64_t blkno, blkoff;
226 uint64_t stripe, stripe_blknr; 234 uint64_t stripe, stripe_blknr;
227 uint32_t stripe_off, stripe_rest, num_blks, issue_blks; 235 uint32_t stripe_off, stripe_rest, num_blks, issue_blks;
228 int i, stripe_devnr; 236 int i, stripe_devnr;
229 237
230 tsc = table_en->target_config; 238 tsc = table_en->target_config;
231 if (tsc == NULL) 239 if (tsc == NULL)
232 return 0; 240 return 0;
233 241
234/* printf("Stripe target read function called %" PRIu64 "!!\n", 242/* printf("Stripe target read function called %" PRIu64 "!!\n",
235 tlc->offset);*/ 243 tlc->offset);*/
236 244
237 /* calculate extent of request */ 245 /* calculate extent of request */
238 KASSERT(bp->b_resid % DEV_BSIZE == 0); 246 KASSERT(bp->b_resid % DEV_BSIZE == 0);
239 247
240 blkno = bp->b_blkno; 248 blkno = bp->b_blkno;
241 blkoff = 0; 249 blkoff = 0;
242 num_blks = bp->b_resid / DEV_BSIZE; 250 num_blks = bp->b_resid / DEV_BSIZE;
243 for (;;) { 251 for (;;) {
244 /* blockno to stripe piece nr */ 252 /* blockno to stripe piece nr */
245 stripe = blkno / tsc->stripe_chunksize; 253 stripe = blkno / tsc->stripe_chunksize;
246 stripe_off = blkno % tsc->stripe_chunksize; 254 stripe_off = blkno % tsc->stripe_chunksize;
247 255
248 /* where we are inside the stripe */ 256 /* where we are inside the stripe */
249 stripe_devnr = stripe % tsc->stripe_num; 257 stripe_devnr = stripe % tsc->stripe_num;
250 stripe_blknr = stripe / tsc->stripe_num; 258 stripe_blknr = stripe / tsc->stripe_num;
251 259
252 /* how much is left before we hit a boundary */ 260 /* how much is left before we hit a boundary */
253 stripe_rest = tsc->stripe_chunksize - stripe_off; 261 stripe_rest = tsc->stripe_chunksize - stripe_off;
254 262
255 /* issue this piece on stripe `stripe' */ 263 /* issue this piece on stripe `stripe' */
256 issue_blks = MIN(stripe_rest, num_blks); 264 issue_blks = MIN(stripe_rest, num_blks);
257 nestbuf = getiobuf(NULL, true); 265 nestbuf = getiobuf(NULL, true);
258 266
259 nestiobuf_setup(bp, nestbuf, blkoff, issue_blks * DEV_BSIZE); 267 nestiobuf_setup(bp, nestbuf, blkoff, issue_blks * DEV_BSIZE);
260 nestbuf->b_blkno = stripe_blknr * tsc->stripe_chunksize + stripe_off; 268 nestbuf->b_blkno = stripe_blknr * tsc->stripe_chunksize + stripe_off;
261 269
262 tlc = TAILQ_FIRST(&tsc->stripe_devs); 270 tlc = TAILQ_FIRST(&tsc->stripe_devs);
263 for (i = 0; i < stripe_devnr && tlc != NULL; i++) 271 for (i = 0; i < stripe_devnr && tlc != NULL; i++)
264 tlc = TAILQ_NEXT(tlc, entries); 272 tlc = TAILQ_NEXT(tlc, entries);
265 273
266 /* by this point we should have an tlc */ 274 /* by this point we should have an tlc */
267 KASSERT(tlc != NULL); 275 KASSERT(tlc != NULL);
268 276
269 nestbuf->b_blkno += tlc->offset; 277 nestbuf->b_blkno += tlc->offset;
270 278
271 VOP_STRATEGY(tlc->pdev->pdev_vnode, nestbuf); 279 VOP_STRATEGY(tlc->pdev->pdev_vnode, nestbuf);
272 280
273 blkno += issue_blks; 281 blkno += issue_blks;
274 blkoff += issue_blks * DEV_BSIZE; 282 blkoff += issue_blks * DEV_BSIZE;
275 num_blks -= issue_blks; 283 num_blks -= issue_blks;
276 284
277 if (num_blks <= 0) 285 if (num_blks <= 0)
278 break; 286 break;
279 } 287 }
280 288
281 return 0; 289 return 0;
282} 290}
283 291
284/* Sync underlying disk caches. */ 292/* Sync underlying disk caches. */
285int 293int
286dm_target_stripe_sync(dm_table_entry_t *table_en) 294dm_target_stripe_sync(dm_table_entry_t *table_en)
287{ 295{
288 int cmd, err; 296 int cmd, err;
289 dm_target_stripe_config_t *tsc; 297 dm_target_stripe_config_t *tsc;
290 dm_target_linear_config_t *tlc; 298 dm_target_linear_config_t *tlc;
291 299
292 tsc = table_en->target_config; 300 tsc = table_en->target_config;
293 301
294 err = 0; 302 err = 0;
295 cmd = 1; 303 cmd = 1;
296 304
297 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) { 305 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) {
298 if ((err = VOP_IOCTL(tlc->pdev->pdev_vnode, DIOCCACHESYNC, 306 if ((err = VOP_IOCTL(tlc->pdev->pdev_vnode, DIOCCACHESYNC,
299 &cmd, FREAD|FWRITE, kauth_cred_get())) != 0) 307 &cmd, FREAD|FWRITE, kauth_cred_get())) != 0)
300 return err; 308 return err;
301 } 309 }
302 310
303 return err; 311 return err;
304 312
305} 313}
306 314
307/* Destroy target specific data. */ 315/* Destroy target specific data. */
308int 316int
309dm_target_stripe_destroy(dm_table_entry_t *table_en) 317dm_target_stripe_destroy(dm_table_entry_t *table_en)
310{ 318{
311 dm_target_stripe_fini(table_en->target_config); 319 dm_target_stripe_fini(table_en->target_config);
312 320
313 /* Unbusy target so we can unload it */ 321 /* Unbusy target so we can unload it */
314 dm_target_unbusy(table_en->target); 322 dm_target_unbusy(table_en->target);
315 323
316 return 0; 324 return 0;
317} 325}
318 326
319/* Doesn't not need to do anything here. */ 327/* Doesn't not need to do anything here. */
320int 328int
321dm_target_stripe_deps(dm_table_entry_t *table_en, prop_array_t prop_array) 329dm_target_stripe_deps(dm_table_entry_t *table_en, prop_array_t prop_array)
322{ 330{
323 dm_target_stripe_config_t *tsc; 331 dm_target_stripe_config_t *tsc;
324 dm_target_linear_config_t *tlc; 332 dm_target_linear_config_t *tlc;
325 333
326 if (table_en->target_config == NULL) 334 if (table_en->target_config == NULL)
327 return ENOENT; 335 return ENOENT;
328 336
329 tsc = table_en->target_config; 337 tsc = table_en->target_config;
330 338
331 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) { 339 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) {
332 prop_array_add_uint64(prop_array, 340 prop_array_add_uint64(prop_array,
333 (uint64_t) tlc->pdev->pdev_vnode->v_rdev); 341 (uint64_t) tlc->pdev->pdev_vnode->v_rdev);
334 } 342 }
335 343
336 return 0; 344 return 0;
337} 345}
338 346
339/* Unsupported for this target. */ 347/* Unsupported for this target. */
340int 348int
341dm_target_stripe_upcall(dm_table_entry_t *table_en, struct buf *bp) 349dm_target_stripe_upcall(dm_table_entry_t *table_en, struct buf *bp)
342{ 350{
343 return 0; 351 return 0;
344} 352}
345 353
346/* 354/*
347 * Compute physical block size 355 * Compute physical block size
348 * For a stripe target we chose the maximum sector size of all 356 * For a stripe target we chose the maximum sector size of all
349 * stripe devices. For the supported power-of-2 sizes this is equivalent 357 * stripe devices. For the supported power-of-2 sizes this is equivalent
350 * to the least common multiple. 358 * to the least common multiple.
351 */ 359 */
352int 360int
353dm_target_stripe_secsize(dm_table_entry_t *table_en, unsigned *secsizep) 361dm_target_stripe_secsize(dm_table_entry_t *table_en, unsigned *secsizep)
354{ 362{
355 dm_target_linear_config_t *tlc; 363 dm_target_linear_config_t *tlc;
356 dm_target_stripe_config_t *tsc; 364 dm_target_stripe_config_t *tsc;
357 unsigned secsize; 365 unsigned secsize;
358 366
359 secsize = 0; 367 secsize = 0;
360 368
361 tsc = table_en->target_config; 369 tsc = table_en->target_config;
362 if (tsc != NULL) { 370 if (tsc != NULL) {
363 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) { 371 TAILQ_FOREACH(tlc, &tsc->stripe_devs, entries) {
364 if (secsize < tlc->pdev->pdev_secsize) 372 if (secsize < tlc->pdev->pdev_secsize)
365 secsize = tlc->pdev->pdev_secsize; 373 secsize = tlc->pdev->pdev_secsize;
366 } 374 }
367 } 375 }
368 376
369 *secsizep = secsize; 377 *secsizep = secsize;
370 378
371 return 0; 379 return 0;
372} 380}