Deleted Added
full compact
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}