diff options
author | mav <mav@FreeBSD.org> | 2015-08-19 17:47:47 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-08-19 17:47:47 +0000 |
commit | 699edef127c5a40ad50328dc97f0b8c8372085cf (patch) | |
tree | bd142abfd895b1dd4314697ef9ec464f5766aecc | |
parent | 30b552e57c142e038b817ae038cad9c248673e86 (diff) | |
download | FreeBSD-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.c | 9 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_backend_block.c | 88 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_cmd_table.c | 4 |
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) */ |