ctl_backend_ramdisk.c (345007) | ctl_backend_ramdisk.c (361256) |
---|---|
1/*- 2 * Copyright (c) 2003, 2008 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Edward Tomasz Napierala 8 * under sponsorship from the FreeBSD Foundation. --- 27 unchanged lines hidden (view full) --- 36 */ 37/* 38 * CAM Target Layer black hole and RAM disk backend. 39 * 40 * Author: Ken Merry <ken@FreeBSD.org> 41 */ 42 43#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003, 2008 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Edward Tomasz Napierala 8 * under sponsorship from the FreeBSD Foundation. --- 27 unchanged lines hidden (view full) --- 36 */ 37/* 38 * CAM Target Layer black hole and RAM disk backend. 39 * 40 * Author: Ken Merry <ken@FreeBSD.org> 41 */ 42 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/ctl_backend_ramdisk.c 345007 2019-03-11 13:56:51Z mav $"); | 44__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/ctl_backend_ramdisk.c 361256 2020-05-19 14:42:09Z mav $"); |
45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/kernel.h> 49#include <sys/condvar.h> 50#include <sys/types.h> 51#include <sys/limits.h> 52#include <sys/lock.h> --- 40 unchanged lines hidden (view full) --- 93 GP_READ, /* Return data page or zero page. */ 94 GP_WRITE, /* Return data page, try allocate if none. */ 95 GP_ANCHOR, /* Return data page, try anchor if none. */ 96 GP_OTHER, /* Return what present, do not allocate/anchor. */ 97} getpage_op_t; 98 99typedef enum { 100 CTL_BE_RAMDISK_LUN_UNCONFIGURED = 0x01, | 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/kernel.h> 49#include <sys/condvar.h> 50#include <sys/types.h> 51#include <sys/limits.h> 52#include <sys/lock.h> --- 40 unchanged lines hidden (view full) --- 93 GP_READ, /* Return data page or zero page. */ 94 GP_WRITE, /* Return data page, try allocate if none. */ 95 GP_ANCHOR, /* Return data page, try anchor if none. */ 96 GP_OTHER, /* Return what present, do not allocate/anchor. */ 97} getpage_op_t; 98 99typedef enum { 100 CTL_BE_RAMDISK_LUN_UNCONFIGURED = 0x01, |
101 CTL_BE_RAMDISK_LUN_CONFIG_ERR = 0x02, | |
102 CTL_BE_RAMDISK_LUN_WAITING = 0x04 103} ctl_be_ramdisk_lun_flags; 104 105struct ctl_be_ramdisk_lun { 106 struct ctl_lun_create_params params; | 101 CTL_BE_RAMDISK_LUN_WAITING = 0x04 102} ctl_be_ramdisk_lun_flags; 103 104struct ctl_be_ramdisk_lun { 105 struct ctl_lun_create_params params; |
107 char lunname[32]; | |
108 int indir; 109 uint8_t **pages; 110 uint8_t *zero_page; 111 struct sx page_lock; 112 u_int pblocksize; 113 u_int pblockmul; 114 uint64_t size_bytes; 115 uint64_t size_blocks; 116 uint64_t cap_bytes; 117 uint64_t cap_used; 118 struct ctl_be_ramdisk_softc *softc; 119 ctl_be_ramdisk_lun_flags flags; | 106 int indir; 107 uint8_t **pages; 108 uint8_t *zero_page; 109 struct sx page_lock; 110 u_int pblocksize; 111 u_int pblockmul; 112 uint64_t size_bytes; 113 uint64_t size_blocks; 114 uint64_t cap_bytes; 115 uint64_t cap_used; 116 struct ctl_be_ramdisk_softc *softc; 117 ctl_be_ramdisk_lun_flags flags; |
120 STAILQ_ENTRY(ctl_be_ramdisk_lun) links; | 118 SLIST_ENTRY(ctl_be_ramdisk_lun) links; |
121 struct ctl_be_lun cbe_lun; 122 struct taskqueue *io_taskqueue; 123 struct task io_task; 124 STAILQ_HEAD(, ctl_io_hdr) cont_queue; 125 struct mtx_padalign queue_lock; 126}; 127 128struct ctl_be_ramdisk_softc { | 119 struct ctl_be_lun cbe_lun; 120 struct taskqueue *io_taskqueue; 121 struct task io_task; 122 STAILQ_HEAD(, ctl_io_hdr) cont_queue; 123 struct mtx_padalign queue_lock; 124}; 125 126struct ctl_be_ramdisk_softc { |
127 struct sx modify_lock; |
|
129 struct mtx lock; 130 int num_luns; | 128 struct mtx lock; 129 int num_luns; |
131 STAILQ_HEAD(, ctl_be_ramdisk_lun) lun_list; | 130 SLIST_HEAD(, ctl_be_ramdisk_lun) lun_list; |
132}; 133 134static struct ctl_be_ramdisk_softc rd_softc; 135extern struct ctl_softc *control_softc; 136 137static int ctl_backend_ramdisk_init(void); 138static int ctl_backend_ramdisk_shutdown(void); 139static int ctl_backend_ramdisk_move_done(union ctl_io *io); --- 8 unchanged lines hidden (view full) --- 148 caddr_t addr, int flag, struct thread *td); 149static int ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 150 struct ctl_lun_req *req); 151static int ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, 152 struct ctl_lun_req *req); 153static int ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, 154 struct ctl_lun_req *req); 155static void ctl_backend_ramdisk_lun_shutdown(void *be_lun); | 131}; 132 133static struct ctl_be_ramdisk_softc rd_softc; 134extern struct ctl_softc *control_softc; 135 136static int ctl_backend_ramdisk_init(void); 137static int ctl_backend_ramdisk_shutdown(void); 138static int ctl_backend_ramdisk_move_done(union ctl_io *io); --- 8 unchanged lines hidden (view full) --- 147 caddr_t addr, int flag, struct thread *td); 148static int ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 149 struct ctl_lun_req *req); 150static int ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, 151 struct ctl_lun_req *req); 152static int ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, 153 struct ctl_lun_req *req); 154static void ctl_backend_ramdisk_lun_shutdown(void *be_lun); |
156static void ctl_backend_ramdisk_lun_config_status(void *be_lun, 157 ctl_lun_config_status status); | |
158 159static struct ctl_backend_driver ctl_be_ramdisk_driver = 160{ 161 .name = "ramdisk", 162 .flags = CTL_BE_FLAG_HAS_CONFIG, 163 .init = ctl_backend_ramdisk_init, 164 .shutdown = ctl_backend_ramdisk_shutdown, 165 .data_submit = ctl_backend_ramdisk_submit, 166 .data_move_done = ctl_backend_ramdisk_move_done, 167 .config_read = ctl_backend_ramdisk_config_read, 168 .config_write = ctl_backend_ramdisk_config_write, 169 .ioctl = ctl_backend_ramdisk_ioctl, 170 .lun_attr = ctl_backend_ramdisk_lun_attr, 171}; 172 | 155 156static struct ctl_backend_driver ctl_be_ramdisk_driver = 157{ 158 .name = "ramdisk", 159 .flags = CTL_BE_FLAG_HAS_CONFIG, 160 .init = ctl_backend_ramdisk_init, 161 .shutdown = ctl_backend_ramdisk_shutdown, 162 .data_submit = ctl_backend_ramdisk_submit, 163 .data_move_done = ctl_backend_ramdisk_move_done, 164 .config_read = ctl_backend_ramdisk_config_read, 165 .config_write = ctl_backend_ramdisk_config_write, 166 .ioctl = ctl_backend_ramdisk_ioctl, 167 .lun_attr = ctl_backend_ramdisk_lun_attr, 168}; 169 |
173MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk"); | 170MALLOC_DEFINE(M_RAMDISK, "ctlramdisk", "Memory used for CTL RAMdisk"); |
174CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); 175 176static int 177ctl_backend_ramdisk_init(void) 178{ 179 struct ctl_be_ramdisk_softc *softc = &rd_softc; 180 181 memset(softc, 0, sizeof(*softc)); | 171CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); 172 173static int 174ctl_backend_ramdisk_init(void) 175{ 176 struct ctl_be_ramdisk_softc *softc = &rd_softc; 177 178 memset(softc, 0, sizeof(*softc)); |
182 mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF); 183 STAILQ_INIT(&softc->lun_list); | 179 sx_init(&softc->modify_lock, "ctlrammod"); 180 mtx_init(&softc->lock, "ctlram", NULL, MTX_DEF); 181 SLIST_INIT(&softc->lun_list); |
184 return (0); 185} 186 187static int 188ctl_backend_ramdisk_shutdown(void) 189{ 190 struct ctl_be_ramdisk_softc *softc = &rd_softc; | 182 return (0); 183} 184 185static int 186ctl_backend_ramdisk_shutdown(void) 187{ 188 struct ctl_be_ramdisk_softc *softc = &rd_softc; |
191 struct ctl_be_ramdisk_lun *lun, *next_lun; | 189 struct ctl_be_ramdisk_lun *lun; |
192 193 mtx_lock(&softc->lock); | 190 191 mtx_lock(&softc->lock); |
194 STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) { | 192 while ((lun = SLIST_FIRST(&softc->lun_list)) != NULL) { 193 SLIST_REMOVE_HEAD(&softc->lun_list, links); 194 softc->num_luns--; |
195 /* | 195 /* |
196 * Drop our lock here. Since ctl_invalidate_lun() can call | 196 * Drop our lock here. Since ctl_remove_lun() can call |
197 * back into us, this could potentially lead to a recursive 198 * lock of the same mutex, which would cause a hang. 199 */ 200 mtx_unlock(&softc->lock); | 197 * back into us, this could potentially lead to a recursive 198 * lock of the same mutex, which would cause a hang. 199 */ 200 mtx_unlock(&softc->lock); |
201 ctl_disable_lun(&lun->cbe_lun); 202 ctl_invalidate_lun(&lun->cbe_lun); | 201 ctl_remove_lun(&lun->cbe_lun); |
203 mtx_lock(&softc->lock); 204 } 205 mtx_unlock(&softc->lock); 206 mtx_destroy(&softc->lock); | 202 mtx_lock(&softc->lock); 203 } 204 mtx_unlock(&softc->lock); 205 mtx_destroy(&softc->lock); |
206 sx_destroy(&softc->modify_lock); |
|
207 return (0); 208} 209 210static uint8_t * 211ctl_backend_ramdisk_getpage(struct ctl_be_ramdisk_lun *be_lun, off_t pn, 212 getpage_op_t op) 213{ 214 uint8_t **p, ***pp; --- 665 unchanged lines hidden (view full) --- 880ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 881 struct ctl_lun_req *req) 882{ 883 struct ctl_be_ramdisk_lun *be_lun; 884 struct ctl_lun_rm_params *params; 885 int retval; 886 887 params = &req->reqdata.rm; | 207 return (0); 208} 209 210static uint8_t * 211ctl_backend_ramdisk_getpage(struct ctl_be_ramdisk_lun *be_lun, off_t pn, 212 getpage_op_t op) 213{ 214 uint8_t **p, ***pp; --- 665 unchanged lines hidden (view full) --- 880ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, 881 struct ctl_lun_req *req) 882{ 883 struct ctl_be_ramdisk_lun *be_lun; 884 struct ctl_lun_rm_params *params; 885 int retval; 886 887 params = &req->reqdata.rm; |
888 sx_xlock(&softc->modify_lock); |
|
888 mtx_lock(&softc->lock); | 889 mtx_lock(&softc->lock); |
889 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { 890 if (be_lun->cbe_lun.lun_id == params->lun_id) | 890 SLIST_FOREACH(be_lun, &softc->lun_list, links) { 891 if (be_lun->cbe_lun.lun_id == params->lun_id) { 892 SLIST_REMOVE(&softc->lun_list, be_lun, 893 ctl_be_ramdisk_lun, links); 894 softc->num_luns--; |
891 break; | 895 break; |
896 } |
|
892 } 893 mtx_unlock(&softc->lock); | 897 } 898 mtx_unlock(&softc->lock); |
899 sx_xunlock(&softc->modify_lock); |
|
894 if (be_lun == NULL) { 895 snprintf(req->error_str, sizeof(req->error_str), 896 "%s: LUN %u is not managed by the ramdisk backend", 897 __func__, params->lun_id); 898 goto bailout_error; 899 } 900 | 900 if (be_lun == NULL) { 901 snprintf(req->error_str, sizeof(req->error_str), 902 "%s: LUN %u is not managed by the ramdisk backend", 903 __func__, params->lun_id); 904 goto bailout_error; 905 } 906 |
901 retval = ctl_disable_lun(&be_lun->cbe_lun); 902 if (retval != 0) { 903 snprintf(req->error_str, sizeof(req->error_str), 904 "%s: error %d returned from ctl_disable_lun() for " 905 "LUN %d", __func__, retval, params->lun_id); 906 goto bailout_error; 907 } 908 | |
909 /* 910 * Set the waiting flag before we invalidate the LUN. Our shutdown 911 * routine can be called any time after we invalidate the LUN, 912 * and can be called from our context. 913 * 914 * This tells the shutdown routine that we're waiting, or we're 915 * going to wait for the shutdown to happen. 916 */ 917 mtx_lock(&softc->lock); 918 be_lun->flags |= CTL_BE_RAMDISK_LUN_WAITING; 919 mtx_unlock(&softc->lock); 920 | 907 /* 908 * Set the waiting flag before we invalidate the LUN. Our shutdown 909 * routine can be called any time after we invalidate the LUN, 910 * and can be called from our context. 911 * 912 * This tells the shutdown routine that we're waiting, or we're 913 * going to wait for the shutdown to happen. 914 */ 915 mtx_lock(&softc->lock); 916 be_lun->flags |= CTL_BE_RAMDISK_LUN_WAITING; 917 mtx_unlock(&softc->lock); 918 |
921 retval = ctl_invalidate_lun(&be_lun->cbe_lun); | 919 retval = ctl_remove_lun(&be_lun->cbe_lun); |
922 if (retval != 0) { 923 snprintf(req->error_str, sizeof(req->error_str), | 920 if (retval != 0) { 921 snprintf(req->error_str, sizeof(req->error_str), |
924 "%s: error %d returned from ctl_invalidate_lun() for " | 922 "%s: error %d returned from ctl_remove_lun() for " |
925 "LUN %d", __func__, retval, params->lun_id); 926 mtx_lock(&softc->lock); 927 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 928 mtx_unlock(&softc->lock); 929 goto bailout_error; 930 } 931 932 mtx_lock(&softc->lock); 933 while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) { | 923 "LUN %d", __func__, retval, params->lun_id); 924 mtx_lock(&softc->lock); 925 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 926 mtx_unlock(&softc->lock); 927 goto bailout_error; 928 } 929 930 mtx_lock(&softc->lock); 931 while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) { |
934 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0); | 932 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlramrm", 0); |
935 if (retval == EINTR) 936 break; 937 } 938 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; | 933 if (retval == EINTR) 934 break; 935 } 936 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; |
939 940 /* 941 * We only remove this LUN from the list and free it (below) if 942 * retval == 0. If the user interrupted the wait, we just bail out 943 * without actually freeing the LUN. We let the shutdown routine 944 * free the LUN if that happens. 945 */ 946 if (retval == 0) { 947 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun, 948 links); 949 softc->num_luns--; 950 } 951 952 mtx_unlock(&softc->lock); 953 954 if (retval == 0) { 955 taskqueue_drain_all(be_lun->io_taskqueue); 956 taskqueue_free(be_lun->io_taskqueue); 957 ctl_free_opts(&be_lun->cbe_lun.options); 958 free(be_lun->zero_page, M_RAMDISK); 959 ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir); 960 sx_destroy(&be_lun->page_lock); 961 mtx_destroy(&be_lun->queue_lock); | 937 if (be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) { 938 mtx_unlock(&softc->lock); |
962 free(be_lun, M_RAMDISK); | 939 free(be_lun, M_RAMDISK); |
940 } else { 941 mtx_unlock(&softc->lock); 942 return (EINTR); |
|
963 } 964 965 req->status = CTL_LUN_OK; 966 return (retval); 967 968bailout_error: 969 req->status = CTL_LUN_ERROR; 970 return (0); --- 14 unchanged lines hidden (view full) --- 985 retval = 0; 986 params = &req->reqdata.create; 987 988 be_lun = malloc(sizeof(*be_lun), M_RAMDISK, M_ZERO | M_WAITOK); 989 cbe_lun = &be_lun->cbe_lun; 990 cbe_lun->be_lun = be_lun; 991 be_lun->params = req->reqdata.create; 992 be_lun->softc = softc; | 943 } 944 945 req->status = CTL_LUN_OK; 946 return (retval); 947 948bailout_error: 949 req->status = CTL_LUN_ERROR; 950 return (0); --- 14 unchanged lines hidden (view full) --- 965 retval = 0; 966 params = &req->reqdata.create; 967 968 be_lun = malloc(sizeof(*be_lun), M_RAMDISK, M_ZERO | M_WAITOK); 969 cbe_lun = &be_lun->cbe_lun; 970 cbe_lun->be_lun = be_lun; 971 be_lun->params = req->reqdata.create; 972 be_lun->softc = softc; |
993 sprintf(be_lun->lunname, "cram%d", softc->num_luns); | |
994 ctl_init_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args); 995 996 if (params->flags & CTL_LUN_FLAG_DEV_TYPE) 997 cbe_lun->lun_type = params->device_type; 998 else 999 cbe_lun->lun_type = T_DIRECT; | 973 ctl_init_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args); 974 975 if (params->flags & CTL_LUN_FLAG_DEV_TYPE) 976 cbe_lun->lun_type = params->device_type; 977 else 978 cbe_lun->lun_type = T_DIRECT; |
1000 be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED; | 979 be_lun->flags = 0; |
1001 cbe_lun->flags = 0; 1002 value = ctl_get_opt(&cbe_lun->options, "ha_role"); 1003 if (value != NULL) { 1004 if (strcmp(value, "primary") == 0) 1005 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; 1006 } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) 1007 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; 1008 --- 79 unchanged lines hidden (view full) --- 1088 1089 if (params->flags & CTL_LUN_FLAG_ID_REQ) { 1090 cbe_lun->req_lun_id = params->req_lun_id; 1091 cbe_lun->flags |= CTL_LUN_FLAG_ID_REQ; 1092 } else 1093 cbe_lun->req_lun_id = 0; 1094 1095 cbe_lun->lun_shutdown = ctl_backend_ramdisk_lun_shutdown; | 980 cbe_lun->flags = 0; 981 value = ctl_get_opt(&cbe_lun->options, "ha_role"); 982 if (value != NULL) { 983 if (strcmp(value, "primary") == 0) 984 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; 985 } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) 986 cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; 987 --- 79 unchanged lines hidden (view full) --- 1067 1068 if (params->flags & CTL_LUN_FLAG_ID_REQ) { 1069 cbe_lun->req_lun_id = params->req_lun_id; 1070 cbe_lun->flags |= CTL_LUN_FLAG_ID_REQ; 1071 } else 1072 cbe_lun->req_lun_id = 0; 1073 1074 cbe_lun->lun_shutdown = ctl_backend_ramdisk_lun_shutdown; |
1096 cbe_lun->lun_config_status = ctl_backend_ramdisk_lun_config_status; | |
1097 cbe_lun->be = &ctl_be_ramdisk_driver; 1098 if ((params->flags & CTL_LUN_FLAG_SERIAL_NUM) == 0) { 1099 snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d", 1100 softc->num_luns); 1101 strncpy((char *)cbe_lun->serial_num, tmpstr, 1102 MIN(sizeof(cbe_lun->serial_num), sizeof(tmpstr))); 1103 1104 /* Tell the user what we used for a serial number */ --- 14 unchanged lines hidden (view full) --- 1119 MIN(sizeof(params->device_id), sizeof(tmpstr))); 1120 } else { 1121 strncpy((char *)cbe_lun->device_id, params->device_id, 1122 MIN(sizeof(cbe_lun->device_id), 1123 sizeof(params->device_id))); 1124 } 1125 1126 STAILQ_INIT(&be_lun->cont_queue); | 1075 cbe_lun->be = &ctl_be_ramdisk_driver; 1076 if ((params->flags & CTL_LUN_FLAG_SERIAL_NUM) == 0) { 1077 snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d", 1078 softc->num_luns); 1079 strncpy((char *)cbe_lun->serial_num, tmpstr, 1080 MIN(sizeof(cbe_lun->serial_num), sizeof(tmpstr))); 1081 1082 /* Tell the user what we used for a serial number */ --- 14 unchanged lines hidden (view full) --- 1097 MIN(sizeof(params->device_id), sizeof(tmpstr))); 1098 } else { 1099 strncpy((char *)cbe_lun->device_id, params->device_id, 1100 MIN(sizeof(cbe_lun->device_id), 1101 sizeof(params->device_id))); 1102 } 1103 1104 STAILQ_INIT(&be_lun->cont_queue); |
1127 sx_init(&be_lun->page_lock, "cram page lock"); | 1105 sx_init(&be_lun->page_lock, "ctlram page"); |
1128 if (be_lun->cap_bytes == 0) { 1129 be_lun->indir = 0; 1130 be_lun->pages = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK); 1131 } 1132 be_lun->zero_page = malloc(be_lun->pblocksize, M_RAMDISK, 1133 M_WAITOK|M_ZERO); | 1106 if (be_lun->cap_bytes == 0) { 1107 be_lun->indir = 0; 1108 be_lun->pages = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK); 1109 } 1110 be_lun->zero_page = malloc(be_lun->pblocksize, M_RAMDISK, 1111 M_WAITOK|M_ZERO); |
1134 mtx_init(&be_lun->queue_lock, "cram queue lock", NULL, MTX_DEF); | 1112 mtx_init(&be_lun->queue_lock, "ctlram queue", NULL, MTX_DEF); |
1135 TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_backend_ramdisk_worker, 1136 be_lun); 1137 | 1113 TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_backend_ramdisk_worker, 1114 be_lun); 1115 |
1138 be_lun->io_taskqueue = taskqueue_create(be_lun->lunname, M_WAITOK, | 1116 be_lun->io_taskqueue = taskqueue_create("ctlramtq", M_WAITOK, |
1139 taskqueue_thread_enqueue, /*context*/&be_lun->io_taskqueue); 1140 if (be_lun->io_taskqueue == NULL) { 1141 snprintf(req->error_str, sizeof(req->error_str), 1142 "%s: Unable to create taskqueue", __func__); 1143 goto bailout_error; 1144 } 1145 1146 retval = taskqueue_start_threads(&be_lun->io_taskqueue, 1147 /*num threads*/1, 1148 /*priority*/PUSER, | 1117 taskqueue_thread_enqueue, /*context*/&be_lun->io_taskqueue); 1118 if (be_lun->io_taskqueue == NULL) { 1119 snprintf(req->error_str, sizeof(req->error_str), 1120 "%s: Unable to create taskqueue", __func__); 1121 goto bailout_error; 1122 } 1123 1124 retval = taskqueue_start_threads(&be_lun->io_taskqueue, 1125 /*num threads*/1, 1126 /*priority*/PUSER, |
1149 /*thread name*/ 1150 "%s taskq", be_lun->lunname); | 1127 /*thread name*/"ramdisk"); |
1151 if (retval != 0) 1152 goto bailout_error; 1153 | 1128 if (retval != 0) 1129 goto bailout_error; 1130 |
1154 mtx_lock(&softc->lock); 1155 softc->num_luns++; 1156 STAILQ_INSERT_TAIL(&softc->lun_list, be_lun, links); 1157 mtx_unlock(&softc->lock); 1158 | |
1159 retval = ctl_add_lun(&be_lun->cbe_lun); 1160 if (retval != 0) { | 1131 retval = ctl_add_lun(&be_lun->cbe_lun); 1132 if (retval != 0) { |
1161 mtx_lock(&softc->lock); 1162 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun, 1163 links); 1164 softc->num_luns--; 1165 mtx_unlock(&softc->lock); | |
1166 snprintf(req->error_str, sizeof(req->error_str), 1167 "%s: ctl_add_lun() returned error %d, see dmesg for " 1168 "details", __func__, retval); 1169 retval = 0; 1170 goto bailout_error; 1171 } 1172 1173 mtx_lock(&softc->lock); | 1133 snprintf(req->error_str, sizeof(req->error_str), 1134 "%s: ctl_add_lun() returned error %d, see dmesg for " 1135 "details", __func__, retval); 1136 retval = 0; 1137 goto bailout_error; 1138 } 1139 1140 mtx_lock(&softc->lock); |
1174 1175 /* 1176 * Tell the config_status routine that we're waiting so it won't 1177 * clean up the LUN in the event of an error. 1178 */ 1179 be_lun->flags |= CTL_BE_RAMDISK_LUN_WAITING; 1180 1181 while (be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) { 1182 retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0); 1183 if (retval == EINTR) 1184 break; 1185 } 1186 be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING; 1187 1188 if (be_lun->flags & CTL_BE_RAMDISK_LUN_CONFIG_ERR) { 1189 snprintf(req->error_str, sizeof(req->error_str), 1190 "%s: LUN configuration error, see dmesg for details", 1191 __func__); 1192 STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun, 1193 links); 1194 softc->num_luns--; 1195 mtx_unlock(&softc->lock); 1196 goto bailout_error; 1197 } else { 1198 params->req_lun_id = cbe_lun->lun_id; 1199 } | 1141 softc->num_luns++; 1142 SLIST_INSERT_HEAD(&softc->lun_list, be_lun, links); |
1200 mtx_unlock(&softc->lock); 1201 | 1143 mtx_unlock(&softc->lock); 1144 |
1145 params->req_lun_id = cbe_lun->lun_id; 1146 |
|
1202 req->status = CTL_LUN_OK; 1203 return (retval); 1204 1205bailout_error: 1206 req->status = CTL_LUN_ERROR; 1207 if (be_lun != NULL) { 1208 if (be_lun->io_taskqueue != NULL) 1209 taskqueue_free(be_lun->io_taskqueue); --- 14 unchanged lines hidden (view full) --- 1224 struct ctl_be_ramdisk_lun *be_lun; 1225 struct ctl_be_lun *cbe_lun; 1226 struct ctl_lun_modify_params *params; 1227 char *value; 1228 uint32_t blocksize; 1229 int wasprim; 1230 1231 params = &req->reqdata.modify; | 1147 req->status = CTL_LUN_OK; 1148 return (retval); 1149 1150bailout_error: 1151 req->status = CTL_LUN_ERROR; 1152 if (be_lun != NULL) { 1153 if (be_lun->io_taskqueue != NULL) 1154 taskqueue_free(be_lun->io_taskqueue); --- 14 unchanged lines hidden (view full) --- 1169 struct ctl_be_ramdisk_lun *be_lun; 1170 struct ctl_be_lun *cbe_lun; 1171 struct ctl_lun_modify_params *params; 1172 char *value; 1173 uint32_t blocksize; 1174 int wasprim; 1175 1176 params = &req->reqdata.modify; |
1232 | 1177 sx_xlock(&softc->modify_lock); |
1233 mtx_lock(&softc->lock); | 1178 mtx_lock(&softc->lock); |
1234 STAILQ_FOREACH(be_lun, &softc->lun_list, links) { | 1179 SLIST_FOREACH(be_lun, &softc->lun_list, links) { |
1235 if (be_lun->cbe_lun.lun_id == params->lun_id) 1236 break; 1237 } 1238 mtx_unlock(&softc->lock); 1239 if (be_lun == NULL) { 1240 snprintf(req->error_str, sizeof(req->error_str), 1241 "%s: LUN %u is not managed by the ramdisk backend", 1242 __func__, params->lun_id); --- 33 unchanged lines hidden (view full) --- 1276 be_lun->size_blocks = be_lun->params.lun_size_bytes / blocksize; 1277 be_lun->size_bytes = be_lun->size_blocks * blocksize; 1278 be_lun->cbe_lun.maxlba = be_lun->size_blocks - 1; 1279 ctl_lun_capacity_changed(&be_lun->cbe_lun); 1280 1281 /* Tell the user the exact size we ended up using */ 1282 params->lun_size_bytes = be_lun->size_bytes; 1283 | 1180 if (be_lun->cbe_lun.lun_id == params->lun_id) 1181 break; 1182 } 1183 mtx_unlock(&softc->lock); 1184 if (be_lun == NULL) { 1185 snprintf(req->error_str, sizeof(req->error_str), 1186 "%s: LUN %u is not managed by the ramdisk backend", 1187 __func__, params->lun_id); --- 33 unchanged lines hidden (view full) --- 1221 be_lun->size_blocks = be_lun->params.lun_size_bytes / blocksize; 1222 be_lun->size_bytes = be_lun->size_blocks * blocksize; 1223 be_lun->cbe_lun.maxlba = be_lun->size_blocks - 1; 1224 ctl_lun_capacity_changed(&be_lun->cbe_lun); 1225 1226 /* Tell the user the exact size we ended up using */ 1227 params->lun_size_bytes = be_lun->size_bytes; 1228 |
1229 sx_xunlock(&softc->modify_lock); |
|
1284 req->status = CTL_LUN_OK; 1285 return (0); 1286 1287bailout_error: | 1230 req->status = CTL_LUN_OK; 1231 return (0); 1232 1233bailout_error: |
1234 sx_xunlock(&softc->modify_lock); |
|
1288 req->status = CTL_LUN_ERROR; 1289 return (0); 1290} 1291 1292static void | 1235 req->status = CTL_LUN_ERROR; 1236 return (0); 1237} 1238 1239static void |
1293ctl_backend_ramdisk_lun_shutdown(void *be_lun) | 1240ctl_backend_ramdisk_lun_shutdown(void *lun) |
1294{ | 1241{ |
1295 struct ctl_be_ramdisk_lun *lun = be_lun; 1296 struct ctl_be_ramdisk_softc *softc = lun->softc; | 1242 struct ctl_be_ramdisk_lun *be_lun = lun; 1243 struct ctl_be_ramdisk_softc *softc = be_lun->softc; |
1297 | 1244 |
1245 taskqueue_drain_all(be_lun->io_taskqueue); 1246 taskqueue_free(be_lun->io_taskqueue); 1247 ctl_free_opts(&be_lun->cbe_lun.options); 1248 free(be_lun->zero_page, M_RAMDISK); 1249 ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir); 1250 sx_destroy(&be_lun->page_lock); 1251 mtx_destroy(&be_lun->queue_lock); 1252 |
|
1298 mtx_lock(&softc->lock); | 1253 mtx_lock(&softc->lock); |
1299 lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED; 1300 if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) { 1301 wakeup(lun); 1302 } else { 1303 STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun, 1304 links); 1305 softc->num_luns--; | 1254 be_lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED; 1255 if (be_lun->flags & CTL_BE_RAMDISK_LUN_WAITING) 1256 wakeup(be_lun); 1257 else |
1306 free(be_lun, M_RAMDISK); | 1258 free(be_lun, M_RAMDISK); |
1307 } | |
1308 mtx_unlock(&softc->lock); 1309} | 1259 mtx_unlock(&softc->lock); 1260} |
1310 1311static void 1312ctl_backend_ramdisk_lun_config_status(void *be_lun, 1313 ctl_lun_config_status status) 1314{ 1315 struct ctl_be_ramdisk_lun *lun; 1316 struct ctl_be_ramdisk_softc *softc; 1317 1318 lun = (struct ctl_be_ramdisk_lun *)be_lun; 1319 softc = lun->softc; 1320 1321 if (status == CTL_LUN_CONFIG_OK) { 1322 mtx_lock(&softc->lock); 1323 lun->flags &= ~CTL_BE_RAMDISK_LUN_UNCONFIGURED; 1324 if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) 1325 wakeup(lun); 1326 mtx_unlock(&softc->lock); 1327 1328 /* 1329 * We successfully added the LUN, attempt to enable it. 1330 */ 1331 if (ctl_enable_lun(&lun->cbe_lun) != 0) { 1332 printf("%s: ctl_enable_lun() failed!\n", __func__); 1333 if (ctl_invalidate_lun(&lun->cbe_lun) != 0) { 1334 printf("%s: ctl_invalidate_lun() failed!\n", 1335 __func__); 1336 } 1337 } 1338 1339 return; 1340 } 1341 1342 1343 mtx_lock(&softc->lock); 1344 lun->flags &= ~CTL_BE_RAMDISK_LUN_UNCONFIGURED; 1345 1346 /* 1347 * If we have a user waiting, let him handle the cleanup. If not, 1348 * clean things up here. 1349 */ 1350 if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) { 1351 lun->flags |= CTL_BE_RAMDISK_LUN_CONFIG_ERR; 1352 wakeup(lun); 1353 } else { 1354 STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun, 1355 links); 1356 softc->num_luns--; 1357 free(lun, M_RAMDISK); 1358 } 1359 mtx_unlock(&softc->lock); 1360} | |