summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-08-19 17:47:47 +0000
committermav <mav@FreeBSD.org>2015-08-19 17:47:47 +0000
commit699edef127c5a40ad50328dc97f0b8c8372085cf (patch)
treebd142abfd895b1dd4314697ef9ec464f5766aecc
parent30b552e57c142e038b817ae038cad9c248673e86 (diff)
downloadFreeBSD-src-699edef127c5a40ad50328dc97f0b8c8372085cf.zip
FreeBSD-src-699edef127c5a40ad50328dc97f0b8c8372085cf.tar.gz
MFC r286353: Pass SYNCHRONIZE CACHE command parameters to backends.
At this point IMMED flag is translated to MNT_NOWAIT flag of VOP_FSYNC(), hoping that file system implements that (ZFS seems doesn't).
-rw-r--r--sys/cam/ctl/ctl.c9
-rw-r--r--sys/cam/ctl/ctl_backend_block.c88
-rw-r--r--sys/cam/ctl/ctl_cmd_table.c4
3 files changed, 49 insertions, 52 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index fcd0954..8f3dd95 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -5504,9 +5504,11 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
{
struct ctl_lun *lun;
struct ctl_softc *softc;
+ struct ctl_lba_len_flags *lbalen;
uint64_t starting_lba;
uint32_t block_count;
int retval;
+ uint8_t byte2;
CTL_DEBUG_PRINT(("ctl_sync_cache\n"));
@@ -5521,6 +5523,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
starting_lba = scsi_4btoul(cdb->begin_lba);
block_count = scsi_2btoul(cdb->lb_count);
+ byte2 = cdb->byte2;
break;
}
case SYNCHRONIZE_CACHE_16: {
@@ -5529,6 +5532,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
starting_lba = scsi_8btou64(cdb->begin_lba);
block_count = scsi_4btoul(cdb->lb_count);
+ byte2 = cdb->byte2;
break;
}
default:
@@ -5559,6 +5563,11 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
goto bailout;
}
+ lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
+ lbalen->lba = starting_lba;
+ lbalen->len = block_count;
+ lbalen->flags = byte2;
+
/*
* Check to see whether we're configured to send the SYNCHRONIZE
* CACHE command directly to the back end.
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 2ec8ba7..18e9dad 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -226,6 +226,7 @@ struct ctl_be_block_io {
devstat_trans_flags ds_trans_type;
uint64_t io_len;
uint64_t io_offset;
+ int io_arg;
struct ctl_be_block_softc *softc;
struct ctl_be_block_lun *lun;
void (*beio_cont)(struct ctl_be_block_io *beio); /* to continue processing */
@@ -584,7 +585,8 @@ ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun,
vn_lock(be_lun->vn, lock_flags | LK_RETRY);
- error = VOP_FSYNC(be_lun->vn, MNT_WAIT, curthread);
+ error = VOP_FSYNC(be_lun->vn, beio->io_arg ? MNT_NOWAIT : MNT_WAIT,
+ curthread);
VOP_UNLOCK(be_lun->vn, 0);
vn_finished_write(mountpoint);
@@ -677,9 +679,6 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
* ZFS pays attention to IO_SYNC (which translates into the
* Solaris define FRSYNC for zfs_read()) for reads. It
* attempts to sync the file before reading.
- *
- * 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, file_data->cred);
@@ -714,9 +713,6 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
* ZFS pays attention to IO_SYNC (a.k.a. FSYNC or FRSYNC)
* for writes. It will flush the transaction from the
* cache before returning.
- *
- * 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, file_data->cred);
VOP_UNLOCK(be_lun->vn, 0);
@@ -981,7 +977,6 @@ ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun,
bio = g_alloc_bio();
bio->bio_cmd = BIO_FLUSH;
- bio->bio_flags |= BIO_ORDERED;
bio->bio_dev = dev_data->cdev;
bio->bio_offset = 0;
bio->bio_data = 0;
@@ -1167,6 +1162,26 @@ ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun, const char *attrname)
}
static void
+ctl_be_block_cw_dispatch_sync(struct ctl_be_block_lun *be_lun,
+ union ctl_io *io)
+{
+ struct ctl_be_block_io *beio;
+ struct ctl_lba_len_flags *lbalen;
+
+ DPRINTF("entered\n");
+ beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
+ lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
+
+ beio->io_len = lbalen->len * be_lun->blocksize;
+ beio->io_offset = lbalen->lba * be_lun->blocksize;
+ beio->io_arg = (lbalen->flags & SSC_IMMED) != 0;
+ beio->bio_cmd = BIO_FLUSH;
+ beio->ds_trans_type = DEVSTAT_NO_DATA;
+ DPRINTF("SYNC\n");
+ be_lun->lun_flush(be_lun, beio);
+}
+
+static void
ctl_be_block_cw_done_ws(struct ctl_be_block_io *beio)
{
union ctl_io *io;
@@ -1188,7 +1203,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
union ctl_io *io)
{
struct ctl_be_block_io *beio;
- struct ctl_be_block_softc *softc;
struct ctl_lba_len_flags *lbalen;
uint64_t len_left, lba;
uint32_t pb, pbo, adj;
@@ -1198,7 +1212,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
DPRINTF("entered\n");
beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
- softc = be_lun->softc;
lbalen = ARGS(beio->io);
if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP | SWS_ANCHOR | SWS_NDOB) ||
@@ -1214,21 +1227,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun,
return;
}
- switch (io->scsiio.tag_type) {
- case CTL_TAG_ORDERED:
- beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
- break;
- case CTL_TAG_HEAD_OF_QUEUE:
- beio->ds_tag_type = DEVSTAT_TAG_HEAD;
- break;
- case CTL_TAG_UNTAGGED:
- case CTL_TAG_SIMPLE:
- case CTL_TAG_ACA:
- default:
- beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
- break;
- }
-
if (lbalen->flags & (SWS_UNMAP | SWS_ANCHOR)) {
beio->io_offset = lbalen->lba * be_lun->blocksize;
beio->io_len = (uint64_t)lbalen->len * be_lun->blocksize;
@@ -1303,13 +1301,11 @@ ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun,
union ctl_io *io)
{
struct ctl_be_block_io *beio;
- struct ctl_be_block_softc *softc;
struct ctl_ptr_len_flags *ptrlen;
DPRINTF("entered\n");
beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
- softc = be_lun->softc;
ptrlen = (struct ctl_ptr_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
if ((ptrlen->flags & ~SU_ANCHOR) != 0 || be_lun->unmap == NULL) {
@@ -1324,29 +1320,11 @@ ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun,
return;
}
- switch (io->scsiio.tag_type) {
- case CTL_TAG_ORDERED:
- beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
- break;
- case CTL_TAG_HEAD_OF_QUEUE:
- beio->ds_tag_type = DEVSTAT_TAG_HEAD;
- break;
- case CTL_TAG_UNTAGGED:
- case CTL_TAG_SIMPLE:
- case CTL_TAG_ACA:
- default:
- beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
- break;
- }
-
beio->io_len = 0;
beio->io_offset = -1;
-
beio->bio_cmd = BIO_DELETE;
beio->ds_trans_type = DEVSTAT_FREE;
-
DPRINTF("UNMAP\n");
-
be_lun->unmap(be_lun, beio);
}
@@ -1417,16 +1395,26 @@ ctl_be_block_cw_dispatch(struct ctl_be_block_lun *be_lun,
beio->io = io;
beio->lun = be_lun;
beio->beio_cont = ctl_be_block_cw_done;
+ switch (io->scsiio.tag_type) {
+ case CTL_TAG_ORDERED:
+ beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
+ break;
+ case CTL_TAG_HEAD_OF_QUEUE:
+ beio->ds_tag_type = DEVSTAT_TAG_HEAD;
+ break;
+ case CTL_TAG_UNTAGGED:
+ case CTL_TAG_SIMPLE:
+ case CTL_TAG_ACA:
+ default:
+ beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
+ break;
+ }
PRIV(io)->ptr = (void *)beio;
switch (io->scsiio.cdb[0]) {
case SYNCHRONIZE_CACHE:
case SYNCHRONIZE_CACHE_16:
- beio->bio_cmd = BIO_FLUSH;
- beio->ds_trans_type = DEVSTAT_NO_DATA;
- beio->ds_tag_type = DEVSTAT_TAG_ORDERED;
- beio->io_len = 0;
- be_lun->lun_flush(be_lun, beio);
+ ctl_be_block_cw_dispatch_sync(be_lun, io);
break;
case WRITE_SAME_10:
case WRITE_SAME_16:
diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c
index fbf0d12..08ff88a 100644
--- a/sys/cam/ctl/ctl_cmd_table.c
+++ b/sys/cam/ctl/ctl_cmd_table.c
@@ -788,7 +788,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_NONE,
CTL_LUN_PAT_NONE,
- 10, {0, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
+ 10, {0x02, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
/* 36 LOCK UNLOCK CACHE(10) */
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
@@ -1141,7 +1141,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_NONE,
CTL_LUN_PAT_NONE,
- 16, {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 16, {0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 92 LOCK UNLOCK CACHE(16) */
OpenPOWER on IntegriCloud