1 1.37 tkusumi /* $NetBSD: dm_target_linear.c,v 1.37 2020/01/21 16:27:53 tkusumi Exp $ */ 2 1.2 haad 3 1.2 haad /* 4 1.2 haad * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 1.2 haad * All rights reserved. 6 1.2 haad * 7 1.2 haad * This code is derived from software contributed to The NetBSD Foundation 8 1.2 haad * by Adam Hamsik. 9 1.2 haad * 10 1.2 haad * Redistribution and use in source and binary forms, with or without 11 1.2 haad * modification, are permitted provided that the following conditions 12 1.2 haad * are met: 13 1.2 haad * 1. Redistributions of source code must retain the above copyright 14 1.2 haad * notice, this list of conditions and the following disclaimer. 15 1.2 haad * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 haad * notice, this list of conditions and the following disclaimer in the 17 1.2 haad * documentation and/or other materials provided with the distribution. 18 1.2 haad * 19 1.2 haad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 haad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 haad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 haad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 haad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 haad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 haad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 haad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 haad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 haad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 haad * POSSIBILITY OF SUCH DAMAGE. 30 1.2 haad */ 31 1.17 christos #include <sys/cdefs.h> 32 1.37 tkusumi __KERNEL_RCSID(0, "$NetBSD: dm_target_linear.c,v 1.37 2020/01/21 16:27:53 tkusumi Exp $"); 33 1.2 haad 34 1.2 haad /* 35 1.36 tkusumi * This file implements initial version of device-mapper linear target. 36 1.2 haad */ 37 1.2 haad 38 1.2 haad #include <sys/types.h> 39 1.2 haad #include <sys/param.h> 40 1.2 haad #include <sys/buf.h> 41 1.2 haad #include <sys/kmem.h> 42 1.11 uebayasi #include <sys/lwp.h> 43 1.2 haad 44 1.2 haad #include <machine/int_fmtio.h> 45 1.2 haad 46 1.2 haad #include "dm.h" 47 1.2 haad 48 1.2 haad /* 49 1.2 haad * Allocate target specific config data, and link them to table. 50 1.2 haad * This function is called only when, flags is not READONLY and 51 1.9 haad * therefore we can add things to pdev list. This should not a 52 1.6 yamt * problem because this routine is called only from dm_table_load_ioctl. 53 1.2 haad * @argv[0] is name, 54 1.2 haad * @argv[1] is physical data offset. 55 1.2 haad */ 56 1.2 haad int 57 1.27 tkusumi dm_target_linear_init(dm_table_entry_t *table_en, int argc, char **argv) 58 1.2 haad { 59 1.2 haad dm_target_linear_config_t *tlc; 60 1.2 haad dm_pdev_t *dmp; 61 1.2 haad 62 1.27 tkusumi if (argc != 2) { 63 1.33 tkusumi printf("Linear target takes 2 args, %d given\n", argc); 64 1.8 haad return EINVAL; 65 1.8 haad } 66 1.2 haad 67 1.8 haad aprint_debug("Linear target init function called %s--%s!!\n", 68 1.8 haad argv[0], argv[1]); 69 1.9 haad 70 1.2 haad /* Insert dmp to global pdev list */ 71 1.8 haad if ((dmp = dm_pdev_insert(argv[0])) == NULL) 72 1.2 haad return ENOENT; 73 1.9 haad 74 1.15 chs tlc = kmem_alloc(sizeof(dm_target_linear_config_t), KM_SLEEP); 75 1.2 haad tlc->pdev = dmp; 76 1.32 tkusumi tlc->offset = atoi64(argv[1]); 77 1.2 haad 78 1.35 tkusumi dm_table_add_deps(table_en, dmp); 79 1.25 tkusumi table_en->target_config = tlc; 80 1.2 haad 81 1.2 haad return 0; 82 1.2 haad } 83 1.17 christos 84 1.2 haad /* 85 1.29 tkusumi * Table routine is called to get params string, which is target 86 1.2 haad * specific. When dm_table_status_ioctl is called with flag 87 1.2 haad * DM_STATUS_TABLE_FLAG I have to sent params string back. 88 1.2 haad */ 89 1.2 haad char * 90 1.29 tkusumi dm_target_linear_table(void *target_config) 91 1.2 haad { 92 1.2 haad dm_target_linear_config_t *tlc; 93 1.2 haad char *params; 94 1.8 haad tlc = target_config; 95 1.8 haad 96 1.29 tkusumi aprint_debug("Linear target table function called\n"); 97 1.2 haad 98 1.18 chs params = kmem_alloc(DM_MAX_PARAMS_SIZE, KM_SLEEP); 99 1.9 haad snprintf(params, DM_MAX_PARAMS_SIZE, "%s %" PRIu64, 100 1.34 tkusumi tlc->pdev->udev_name, tlc->offset); 101 1.8 haad 102 1.2 haad return params; 103 1.2 haad } 104 1.17 christos 105 1.2 haad /* 106 1.2 haad * Do IO operation, called from dmstrategy routine. 107 1.2 haad */ 108 1.2 haad int 109 1.24 tkusumi dm_target_linear_strategy(dm_table_entry_t *table_en, struct buf *bp) 110 1.2 haad { 111 1.2 haad dm_target_linear_config_t *tlc; 112 1.2 haad 113 1.2 haad tlc = table_en->target_config; 114 1.9 haad 115 1.2 haad bp->b_blkno += tlc->offset; 116 1.9 haad 117 1.2 haad VOP_STRATEGY(tlc->pdev->pdev_vnode, bp); 118 1.9 haad 119 1.2 haad return 0; 120 1.2 haad } 121 1.17 christos 122 1.2 haad /* 123 1.10 haad * Sync underlying disk caches. 124 1.10 haad */ 125 1.10 haad int 126 1.24 tkusumi dm_target_linear_sync(dm_table_entry_t *table_en) 127 1.10 haad { 128 1.10 haad int cmd; 129 1.10 haad dm_target_linear_config_t *tlc; 130 1.10 haad 131 1.10 haad tlc = table_en->target_config; 132 1.10 haad 133 1.10 haad cmd = 1; 134 1.23 tkusumi 135 1.10 haad return VOP_IOCTL(tlc->pdev->pdev_vnode, DIOCCACHESYNC, &cmd, 136 1.23 tkusumi FREAD|FWRITE, kauth_cred_get()); 137 1.10 haad } 138 1.17 christos 139 1.10 haad /* 140 1.2 haad * Destroy target specific data. Decrement table pdevs. 141 1.2 haad */ 142 1.2 haad int 143 1.24 tkusumi dm_target_linear_destroy(dm_table_entry_t *table_en) 144 1.2 haad { 145 1.2 haad 146 1.2 haad /* 147 1.2 haad * Destroy function is called for every target even if it 148 1.2 haad * doesn't have target_config. 149 1.2 haad */ 150 1.2 haad if (table_en->target_config == NULL) 151 1.17 christos goto out; 152 1.9 haad 153 1.17 christos dm_target_linear_config_t *tlc = table_en->target_config; 154 1.9 haad 155 1.2 haad /* Decrement pdev ref counter if 0 remove it */ 156 1.2 haad dm_pdev_decr(tlc->pdev); 157 1.9 haad 158 1.17 christos kmem_free(tlc, sizeof(*tlc)); 159 1.17 christos 160 1.17 christos out: 161 1.3 haad /* Unbusy target so we can unload it */ 162 1.3 haad dm_target_unbusy(table_en->target); 163 1.2 haad return 0; 164 1.2 haad } 165 1.17 christos 166 1.37 tkusumi #if 0 167 1.2 haad /* 168 1.2 haad * Register upcall device. 169 1.2 haad * Linear target doesn't need any upcall devices but other targets like 170 1.2 haad * mirror, snapshot, multipath, stripe will use this functionality. 171 1.2 haad */ 172 1.2 haad int 173 1.24 tkusumi dm_target_linear_upcall(dm_table_entry_t *table_en, struct buf *bp) 174 1.2 haad { 175 1.31 tkusumi 176 1.2 haad return 0; 177 1.2 haad } 178 1.37 tkusumi #endif 179 1.17 christos 180 1.2 haad /* 181 1.12 mlelstv * Query physical block size of this target 182 1.12 mlelstv * For a linear target this is just the sector size of the underlying device 183 1.12 mlelstv */ 184 1.12 mlelstv int 185 1.30 tkusumi dm_target_linear_secsize(dm_table_entry_t *table_en, unsigned int *secsizep) 186 1.12 mlelstv { 187 1.12 mlelstv dm_target_linear_config_t *tlc; 188 1.30 tkusumi unsigned int secsize; 189 1.12 mlelstv 190 1.12 mlelstv secsize = 0; 191 1.12 mlelstv 192 1.12 mlelstv tlc = table_en->target_config; 193 1.12 mlelstv if (tlc != NULL) 194 1.12 mlelstv secsize = tlc->pdev->pdev_secsize; 195 1.12 mlelstv 196 1.12 mlelstv *secsizep = secsize; 197 1.12 mlelstv 198 1.12 mlelstv return 0; 199 1.12 mlelstv } 200