summaryrefslogtreecommitdiffstats
path: root/sys/cam/ctl/ctl_backend_ramdisk.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2012-03-06 13:43:57 +0000
committertrasz <trasz@FreeBSD.org>2012-03-06 13:43:57 +0000
commit1d720144fdb563ad9f7045262dffe76fda283e23 (patch)
tree21a7004b7ca48373596470e3a58af3c4b396cd5a /sys/cam/ctl/ctl_backend_ramdisk.c
parent1c33114ffdd61c716e728a416a6e816ebcb7f135 (diff)
downloadFreeBSD-src-1d720144fdb563ad9f7045262dffe76fda283e23.zip
FreeBSD-src-1d720144fdb563ad9f7045262dffe76fda283e23.tar.gz
Add LUN resizing to CTL. Also make it possible to explicitly set
size when creating file-backed or device-backed LUN. Reviewed by: ken (earlier version) Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/cam/ctl/ctl_backend_ramdisk.c')
-rw-r--r--sys/cam/ctl/ctl_backend_ramdisk.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
index 88b5008..b1d4502 100644
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -1,7 +1,11 @@
/*-
* Copyright (c) 2003, 2008 Silicon Graphics International Corp.
+ * Copyright (c) 2012 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by Edward Tomasz Napierala
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -102,6 +106,8 @@ static int ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc,
struct ctl_lun_req *req);
static int ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
struct ctl_lun_req *req, int do_wait);
+static int ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc,
+ struct ctl_lun_req *req);
static void ctl_backend_ramdisk_lun_shutdown(void *be_lun);
static void ctl_backend_ramdisk_lun_config_status(void *be_lun,
ctl_lun_config_status status);
@@ -376,6 +382,9 @@ ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
case CTL_LUNREQ_RM:
retval = ctl_backend_ramdisk_rm(softc, lun_req);
break;
+ case CTL_LUNREQ_MODIFY:
+ retval = ctl_backend_ramdisk_modify(softc, lun_req);
+ break;
default:
lun_req->status = CTL_LUN_ERROR;
snprintf(lun_req->error_str, sizeof(lun_req->error_str),
@@ -666,6 +675,73 @@ bailout_error:
return (retval);
}
+static int
+ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc,
+ struct ctl_lun_req *req)
+{
+ struct ctl_be_ramdisk_lun *be_lun;
+ struct ctl_lun_modify_params *params;
+ uint32_t blocksize;
+
+ params = &req->reqdata.modify;
+
+ be_lun = NULL;
+
+ mtx_lock(&softc->lock);
+ STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
+ if (be_lun->ctl_be_lun.lun_id == params->lun_id)
+ break;
+ }
+ mtx_unlock(&softc->lock);
+
+ if (be_lun == NULL) {
+ snprintf(req->error_str, sizeof(req->error_str),
+ "%s: LUN %u is not managed by the ramdisk backend",
+ __func__, params->lun_id);
+ goto bailout_error;
+ }
+
+ if (params->lun_size_bytes == 0) {
+ snprintf(req->error_str, sizeof(req->error_str),
+ "%s: LUN size \"auto\" not supported "
+ "by the ramdisk backend", __func__);
+ goto bailout_error;
+ }
+
+ blocksize = be_lun->ctl_be_lun.blocksize;
+
+ if (params->lun_size_bytes < blocksize) {
+ snprintf(req->error_str, sizeof(req->error_str),
+ "%s: LUN size %ju < blocksize %u", __func__,
+ params->lun_size_bytes, blocksize);
+ goto bailout_error;
+ }
+
+ be_lun->size_blocks = params->lun_size_bytes / blocksize;
+ be_lun->size_bytes = be_lun->size_blocks * blocksize;
+
+ /*
+ * The maximum LBA is the size - 1.
+ *
+ * XXX: Note that this field is being updated without locking,
+ * which might cause problems on 32-bit architectures.
+ */
+ be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1;
+ ctl_lun_capacity_changed(&be_lun->ctl_be_lun);
+
+ /* Tell the user the exact size we ended up using */
+ params->lun_size_bytes = be_lun->size_bytes;
+
+ req->status = CTL_LUN_OK;
+
+ return (0);
+
+bailout_error:
+ req->status = CTL_LUN_ERROR;
+
+ return (0);
+}
+
static void
ctl_backend_ramdisk_lun_shutdown(void *be_lun)
{
OpenPOWER on IntegriCloud