summaryrefslogtreecommitdiffstats
path: root/sys/cam/ctl/ctl_backend_block.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-10-06 12:35:41 +0000
committermav <mav@FreeBSD.org>2014-10-06 12:35:41 +0000
commitf60999f291064970860eab7998ef10b01b2f4590 (patch)
tree1b98664d66421bca202c854e247a7f3c49b374b4 /sys/cam/ctl/ctl_backend_block.c
parente13f201bd6b0303e782cfa6b522e8b9810ee2629 (diff)
downloadFreeBSD-src-f60999f291064970860eab7998ef10b01b2f4590.zip
FreeBSD-src-f60999f291064970860eab7998ef10b01b2f4590.tar.gz
MFC r271309:
Improve cache control support, including DPO/FUA flags and the mode page. At this moment it works only for files and ZVOLs in device mode since BIOs have no respective respective cache control flags (DPO/FUA).
Diffstat (limited to 'sys/cam/ctl/ctl_backend_block.c')
-rw-r--r--sys/cam/ctl/ctl_backend_block.c57
1 files changed, 14 insertions, 43 deletions
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index cf56f84..912f348 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -205,7 +205,6 @@ struct ctl_be_block_io {
struct ctl_sg_entry sg_segs[CTLBLK_MAX_SEGS];
struct iovec xiovecs[CTLBLK_MAX_SEGS];
int bio_cmd;
- int bio_flags;
int num_segs;
int num_bios_sent;
int num_bios_done;
@@ -602,7 +601,11 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
file_data = &be_lun->backend.file;
io = beio->io;
- flags = beio->bio_flags;
+ flags = 0;
+ if (ARGS(io)->flags & CTL_LLF_DPO)
+ flags |= IO_DIRECT;
+ if (beio->bio_cmd == BIO_WRITE && ARGS(io)->flags & CTL_LLF_FUA)
+ flags |= IO_SYNC;
bzero(&xuio, sizeof(xuio));
if (beio->bio_cmd == BIO_READ) {
@@ -652,8 +655,7 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
* So, to attempt to provide some barrier semantics in the
* BIO_ORDERED case, set both IO_DIRECT and IO_SYNC.
*/
- error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
- (IO_DIRECT|IO_SYNC) : 0, file_data->cred);
+ error = VOP_READ(be_lun->vn, &xuio, flags, file_data->cred);
VOP_UNLOCK(be_lun->vn, 0);
SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
@@ -690,8 +692,7 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
* So if we've got the BIO_ORDERED flag set, we want
* IO_SYNC in either the UFS or ZFS case.
*/
- error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
- IO_SYNC : 0, file_data->cred);
+ error = VOP_WRITE(be_lun->vn, &xuio, flags, file_data->cred);
VOP_UNLOCK(be_lun->vn, 0);
vn_finished_write(mountpoint);
@@ -755,7 +756,11 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
dev_data = &be_lun->backend.dev;
io = beio->io;
- flags = beio->bio_flags;
+ flags = 0;
+ if (ARGS(io)->flags & CTL_LLF_DPO)
+ flags |= IO_DIRECT;
+ if (beio->bio_cmd == BIO_WRITE && ARGS(io)->flags & CTL_LLF_FUA)
+ flags |= IO_SYNC;
bzero(&xuio, sizeof(xuio));
if (beio->bio_cmd == BIO_READ) {
@@ -783,10 +788,10 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
mtx_unlock(&be_lun->io_lock);
if (beio->bio_cmd == BIO_READ) {
- error = (*dev_data->csw->d_read)(dev_data->cdev, &xuio, 0);
+ error = (*dev_data->csw->d_read)(dev_data->cdev, &xuio, flags);
SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
} else {
- error = (*dev_data->csw->d_write)(dev_data->cdev, &xuio, 0);
+ error = (*dev_data->csw->d_write)(dev_data->cdev, &xuio, flags);
SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
}
@@ -877,7 +882,6 @@ ctl_be_block_unmap_dev_range(struct ctl_be_block_lun *be_lun,
while (len > 0) {
bio = g_alloc_bio();
bio->bio_cmd = BIO_DELETE;
- bio->bio_flags |= beio->bio_flags;
bio->bio_dev = dev_data->cdev;
bio->bio_offset = off;
bio->bio_length = MIN(len, maxlen);
@@ -976,7 +980,6 @@ ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun,
KASSERT(bio != NULL, ("g_alloc_bio() failed!\n"));
bio->bio_cmd = beio->bio_cmd;
- bio->bio_flags |= beio->bio_flags;
bio->bio_dev = dev_data->cdev;
bio->bio_caller1 = beio;
bio->bio_length = min(cur_size, max_iosize);
@@ -1055,15 +1058,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
return;
}
- /*
- * If the I/O came down with an ordered or head of queue tag, set
- * the BIO_ORDERED attribute. For head of queue tags, that's
- * pretty much the best we can do.
- */
- if ((io->scsiio.tag_type == CTL_TAG_ORDERED)
- || (io->scsiio.tag_type == CTL_TAG_HEAD_OF_QUEUE))
- beio->bio_flags = BIO_ORDERED;
-
switch (io->scsiio.tag_type) {
case CTL_TAG_ORDERED:
beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
@@ -1161,15 +1155,6 @@ ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun,
return;
}
- /*
- * If the I/O came down with an ordered or head of queue tag, set
- * the BIO_ORDERED attribute. For head of queue tags, that's
- * pretty much the best we can do.
- */
- if ((io->scsiio.tag_type == CTL_TAG_ORDERED)
- || (io->scsiio.tag_type == CTL_TAG_HEAD_OF_QUEUE))
- beio->bio_flags = BIO_ORDERED;
-
switch (io->scsiio.tag_type) {
case CTL_TAG_ORDERED:
beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
@@ -1308,20 +1293,6 @@ ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
bptrlen = PRIV(io);
bptrlen->ptr = (void *)beio;
- /*
- * If the I/O came down with an ordered or head of queue tag, set
- * the BIO_ORDERED attribute. For head of queue tags, that's
- * pretty much the best we can do.
- *
- * XXX KDM we don't have a great way to easily know about the FUA
- * bit right now (it is decoded in ctl_read_write(), but we don't
- * pass that knowledge to the backend), and in any case we would
- * need to determine how to handle it.
- */
- if ((io->scsiio.tag_type == CTL_TAG_ORDERED)
- || (io->scsiio.tag_type == CTL_TAG_HEAD_OF_QUEUE))
- beio->bio_flags = BIO_ORDERED;
-
switch (io->scsiio.tag_type) {
case CTL_TAG_ORDERED:
beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
OpenPOWER on IntegriCloud