xref: /dflybsd-src/sys/dev/disk/dm/linear/dm_target_linear.c (revision f603807b2c8b9b8ca8a7a99e36eeb70cd39b460d)
1*f603807bSTomohiro Kusumi /*        $NetBSD: dm_target_linear.c,v 1.9 2010/01/04 00:14:41 haad Exp $      */
2*f603807bSTomohiro Kusumi 
3*f603807bSTomohiro Kusumi /*
4*f603807bSTomohiro Kusumi  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5*f603807bSTomohiro Kusumi  * All rights reserved.
6*f603807bSTomohiro Kusumi  *
7*f603807bSTomohiro Kusumi  * This code is derived from software contributed to The NetBSD Foundation
8*f603807bSTomohiro Kusumi  * by Adam Hamsik.
9*f603807bSTomohiro Kusumi  *
10*f603807bSTomohiro Kusumi  * Redistribution and use in source and binary forms, with or without
11*f603807bSTomohiro Kusumi  * modification, are permitted provided that the following conditions
12*f603807bSTomohiro Kusumi  * are met:
13*f603807bSTomohiro Kusumi  * 1. Redistributions of source code must retain the above copyright
14*f603807bSTomohiro Kusumi  *    notice, this list of conditions and the following disclaimer.
15*f603807bSTomohiro Kusumi  * 2. Redistributions in binary form must reproduce the above copyright
16*f603807bSTomohiro Kusumi  *    notice, this list of conditions and the following disclaimer in the
17*f603807bSTomohiro Kusumi  *    documentation and/or other materials provided with the distribution.
18*f603807bSTomohiro Kusumi  *
19*f603807bSTomohiro Kusumi  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*f603807bSTomohiro Kusumi  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*f603807bSTomohiro Kusumi  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*f603807bSTomohiro Kusumi  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*f603807bSTomohiro Kusumi  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*f603807bSTomohiro Kusumi  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*f603807bSTomohiro Kusumi  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*f603807bSTomohiro Kusumi  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*f603807bSTomohiro Kusumi  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*f603807bSTomohiro Kusumi  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*f603807bSTomohiro Kusumi  * POSSIBILITY OF SUCH DAMAGE.
30*f603807bSTomohiro Kusumi  */
31*f603807bSTomohiro Kusumi 
32*f603807bSTomohiro Kusumi 
33*f603807bSTomohiro Kusumi /*
34*f603807bSTomohiro Kusumi  * This file implements initial version of device-mapper dklinear target.
35*f603807bSTomohiro Kusumi  */
36*f603807bSTomohiro Kusumi 
37*f603807bSTomohiro Kusumi #include <sys/malloc.h>
38*f603807bSTomohiro Kusumi 
39*f603807bSTomohiro Kusumi #include <dev/disk/dm/dm.h>
40*f603807bSTomohiro Kusumi MALLOC_DEFINE(M_DMLINEAR, "dm_linear", "Device Mapper Target Linear");
41*f603807bSTomohiro Kusumi 
42*f603807bSTomohiro Kusumi typedef struct target_linear_config {
43*f603807bSTomohiro Kusumi 	dm_pdev_t *pdev;
44*f603807bSTomohiro Kusumi 	uint64_t offset;
45*f603807bSTomohiro Kusumi } dm_target_linear_config_t;
46*f603807bSTomohiro Kusumi 
47*f603807bSTomohiro Kusumi /*
48*f603807bSTomohiro Kusumi  * Allocate target specific config data, and link them to table.
49*f603807bSTomohiro Kusumi  * This function is called only when, flags is not READONLY and
50*f603807bSTomohiro Kusumi  * therefore we can add things to pdev list. This should not a
51*f603807bSTomohiro Kusumi  * problem because this routine is called only from dm_table_load_ioctl.
52*f603807bSTomohiro Kusumi  * @argv[0] is name,
53*f603807bSTomohiro Kusumi  * @argv[1] is physical data offset.
54*f603807bSTomohiro Kusumi  */
55*f603807bSTomohiro Kusumi static int
56*f603807bSTomohiro Kusumi dm_target_linear_init(dm_table_entry_t *table_en, int argc, char **argv)
57*f603807bSTomohiro Kusumi {
58*f603807bSTomohiro Kusumi 	dm_target_linear_config_t *tlc;
59*f603807bSTomohiro Kusumi 	dm_pdev_t *dmp;
60*f603807bSTomohiro Kusumi 
61*f603807bSTomohiro Kusumi 	if (argc != 2) {
62*f603807bSTomohiro Kusumi 		kprintf("Linear target takes 2 args\n");
63*f603807bSTomohiro Kusumi 		return EINVAL;
64*f603807bSTomohiro Kusumi 	}
65*f603807bSTomohiro Kusumi 
66*f603807bSTomohiro Kusumi 	dmdebug("Linear target init function called %s--%s!!\n",
67*f603807bSTomohiro Kusumi 	    argv[0], argv[1]);
68*f603807bSTomohiro Kusumi 
69*f603807bSTomohiro Kusumi 	/* Insert dmp to global pdev list */
70*f603807bSTomohiro Kusumi 	if ((dmp = dm_pdev_insert(argv[0])) == NULL)
71*f603807bSTomohiro Kusumi 		return ENOENT;
72*f603807bSTomohiro Kusumi 
73*f603807bSTomohiro Kusumi 	if ((tlc = kmalloc(sizeof(dm_target_linear_config_t), M_DMLINEAR, M_WAITOK))
74*f603807bSTomohiro Kusumi 	    == NULL)
75*f603807bSTomohiro Kusumi 		return ENOMEM;
76*f603807bSTomohiro Kusumi 
77*f603807bSTomohiro Kusumi 	tlc->pdev = dmp;
78*f603807bSTomohiro Kusumi 	tlc->offset = atoi64(argv[1]);
79*f603807bSTomohiro Kusumi 
80*f603807bSTomohiro Kusumi 	dm_table_add_deps(table_en, dmp);
81*f603807bSTomohiro Kusumi 
82*f603807bSTomohiro Kusumi 	dm_table_init_target(table_en, DM_LINEAR_DEV, tlc);
83*f603807bSTomohiro Kusumi 
84*f603807bSTomohiro Kusumi 	return 0;
85*f603807bSTomohiro Kusumi }
86*f603807bSTomohiro Kusumi 
87*f603807bSTomohiro Kusumi /*
88*f603807bSTomohiro Kusumi  * Table routine is called to get params string, which is target
89*f603807bSTomohiro Kusumi  * specific. When dm_table_status_ioctl is called with flag
90*f603807bSTomohiro Kusumi  * DM_STATUS_TABLE_FLAG I have to sent params string back.
91*f603807bSTomohiro Kusumi  */
92*f603807bSTomohiro Kusumi static char *
93*f603807bSTomohiro Kusumi dm_target_linear_table(void *target_config)
94*f603807bSTomohiro Kusumi {
95*f603807bSTomohiro Kusumi 	dm_target_linear_config_t *tlc;
96*f603807bSTomohiro Kusumi 	char *params;
97*f603807bSTomohiro Kusumi 	tlc = target_config;
98*f603807bSTomohiro Kusumi 
99*f603807bSTomohiro Kusumi 	dmdebug("Linear target table function called\n");
100*f603807bSTomohiro Kusumi 
101*f603807bSTomohiro Kusumi 	params = dm_alloc_string(DM_MAX_PARAMS_SIZE);
102*f603807bSTomohiro Kusumi 
103*f603807bSTomohiro Kusumi 	ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s %" PRIu64,
104*f603807bSTomohiro Kusumi 	    tlc->pdev->udev_name, tlc->offset);
105*f603807bSTomohiro Kusumi 
106*f603807bSTomohiro Kusumi 	return params;
107*f603807bSTomohiro Kusumi }
108*f603807bSTomohiro Kusumi 
109*f603807bSTomohiro Kusumi /*
110*f603807bSTomohiro Kusumi  * Do IO operation, called from dmstrategy routine.
111*f603807bSTomohiro Kusumi  */
112*f603807bSTomohiro Kusumi static int
113*f603807bSTomohiro Kusumi dm_target_linear_strategy(dm_table_entry_t *table_en, struct buf *bp)
114*f603807bSTomohiro Kusumi {
115*f603807bSTomohiro Kusumi 	dm_target_linear_config_t *tlc;
116*f603807bSTomohiro Kusumi 
117*f603807bSTomohiro Kusumi 	tlc = table_en->target_config;
118*f603807bSTomohiro Kusumi 
119*f603807bSTomohiro Kusumi /*	kprintf("Linear target read function called %" PRIu64 "!!\n",
120*f603807bSTomohiro Kusumi 	tlc->offset);*/
121*f603807bSTomohiro Kusumi 
122*f603807bSTomohiro Kusumi 	bp->b_bio1.bio_offset += tlc->offset * DEV_BSIZE;
123*f603807bSTomohiro Kusumi 
124*f603807bSTomohiro Kusumi 	vn_strategy(tlc->pdev->pdev_vnode, &bp->b_bio1);
125*f603807bSTomohiro Kusumi 
126*f603807bSTomohiro Kusumi 	return 0;
127*f603807bSTomohiro Kusumi 
128*f603807bSTomohiro Kusumi }
129*f603807bSTomohiro Kusumi 
130*f603807bSTomohiro Kusumi static int
131*f603807bSTomohiro Kusumi dm_target_linear_dump(dm_table_entry_t *table_en, void *data, size_t length, off_t offset)
132*f603807bSTomohiro Kusumi {
133*f603807bSTomohiro Kusumi 	dm_target_linear_config_t *tlc;
134*f603807bSTomohiro Kusumi 
135*f603807bSTomohiro Kusumi 	tlc = table_en->target_config;
136*f603807bSTomohiro Kusumi 
137*f603807bSTomohiro Kusumi 	offset += tlc->offset * DEV_BSIZE;
138*f603807bSTomohiro Kusumi 	offset = dm_pdev_correct_dump_offset(tlc->pdev, offset);
139*f603807bSTomohiro Kusumi 
140*f603807bSTomohiro Kusumi 	if (tlc->pdev->pdev_vnode->v_rdev == NULL)
141*f603807bSTomohiro Kusumi 		return ENXIO;
142*f603807bSTomohiro Kusumi 
143*f603807bSTomohiro Kusumi 	return dev_ddump(tlc->pdev->pdev_vnode->v_rdev, data, 0, offset, length);
144*f603807bSTomohiro Kusumi }
145*f603807bSTomohiro Kusumi 
146*f603807bSTomohiro Kusumi /*
147*f603807bSTomohiro Kusumi  * Destroy target specific data. Decrement table pdevs.
148*f603807bSTomohiro Kusumi  */
149*f603807bSTomohiro Kusumi static int
150*f603807bSTomohiro Kusumi dm_target_linear_destroy(dm_table_entry_t *table_en)
151*f603807bSTomohiro Kusumi {
152*f603807bSTomohiro Kusumi 	dm_target_linear_config_t *tlc;
153*f603807bSTomohiro Kusumi 
154*f603807bSTomohiro Kusumi 	/*
155*f603807bSTomohiro Kusumi 	 * Destroy function is called for every target even if it
156*f603807bSTomohiro Kusumi 	 * doesn't have target_config.
157*f603807bSTomohiro Kusumi 	 */
158*f603807bSTomohiro Kusumi 
159*f603807bSTomohiro Kusumi 	if (table_en->target_config == NULL)
160*f603807bSTomohiro Kusumi 		return 0;
161*f603807bSTomohiro Kusumi 
162*f603807bSTomohiro Kusumi 	tlc = table_en->target_config;
163*f603807bSTomohiro Kusumi 
164*f603807bSTomohiro Kusumi 	/* Decrement pdev ref counter if 0 remove it */
165*f603807bSTomohiro Kusumi 	dm_pdev_decr(tlc->pdev);
166*f603807bSTomohiro Kusumi 
167*f603807bSTomohiro Kusumi 	kfree(table_en->target_config, M_DMLINEAR);
168*f603807bSTomohiro Kusumi 
169*f603807bSTomohiro Kusumi 	return 0;
170*f603807bSTomohiro Kusumi }
171*f603807bSTomohiro Kusumi 
172*f603807bSTomohiro Kusumi static int
173*f603807bSTomohiro Kusumi dmtl_mod_handler(module_t mod, int type, void *unused)
174*f603807bSTomohiro Kusumi {
175*f603807bSTomohiro Kusumi 	dm_target_t *dmt = NULL;
176*f603807bSTomohiro Kusumi 	int err = 0;
177*f603807bSTomohiro Kusumi 
178*f603807bSTomohiro Kusumi 	switch(type) {
179*f603807bSTomohiro Kusumi 	case MOD_LOAD:
180*f603807bSTomohiro Kusumi 		if ((dmt = dm_target_lookup("linear")) != NULL) {
181*f603807bSTomohiro Kusumi 			dm_target_unbusy(dmt);
182*f603807bSTomohiro Kusumi 			return EEXIST;
183*f603807bSTomohiro Kusumi 		}
184*f603807bSTomohiro Kusumi 		dmt = dm_target_alloc("linear");
185*f603807bSTomohiro Kusumi 		dmt->version[0] = 1;
186*f603807bSTomohiro Kusumi 		dmt->version[1] = 0;
187*f603807bSTomohiro Kusumi 		dmt->version[2] = 2;
188*f603807bSTomohiro Kusumi 		dmt->init = &dm_target_linear_init;
189*f603807bSTomohiro Kusumi 		dmt->destroy = &dm_target_linear_destroy;
190*f603807bSTomohiro Kusumi 		dmt->strategy = &dm_target_linear_strategy;
191*f603807bSTomohiro Kusumi 		dmt->table = &dm_target_linear_table;
192*f603807bSTomohiro Kusumi 		dmt->dump = &dm_target_linear_dump;
193*f603807bSTomohiro Kusumi 
194*f603807bSTomohiro Kusumi 		err = dm_target_insert(dmt);
195*f603807bSTomohiro Kusumi 		if (err == 0)
196*f603807bSTomohiro Kusumi 			kprintf("dm_target_linear: Successfully initialized\n");
197*f603807bSTomohiro Kusumi 		break;
198*f603807bSTomohiro Kusumi 
199*f603807bSTomohiro Kusumi 	case MOD_UNLOAD:
200*f603807bSTomohiro Kusumi 		err = dm_target_remove("linear");
201*f603807bSTomohiro Kusumi 		if (err == 0)
202*f603807bSTomohiro Kusumi 			kprintf("dm_target_linear: unloaded\n");
203*f603807bSTomohiro Kusumi 		break;
204*f603807bSTomohiro Kusumi 	}
205*f603807bSTomohiro Kusumi 
206*f603807bSTomohiro Kusumi 	return err;
207*f603807bSTomohiro Kusumi }
208*f603807bSTomohiro Kusumi 
209*f603807bSTomohiro Kusumi DM_TARGET_MODULE(dm_target_linear, dmtl_mod_handler);
210