MFC r273809:

Implement better handling for ENOSPC error for both CTL and CAM.

This makes VMWare VAAI Thin Provisioning Stun primitive activate, pausing
the virtual machine, when backing storage (ZFS pool) is getting overflowed.
This commit is contained in:
mav 2014-11-03 03:45:41 +00:00
parent 131eff3491
commit edabf036a2
4 changed files with 24 additions and 8 deletions

View File

@ -504,6 +504,8 @@ ctl_be_block_biodone(struct bio *bio)
if (beio->num_errors > 0) {
if (error == EOPNOTSUPP) {
ctl_set_invalid_opcode(&io->scsiio);
} else if (error == ENOSPC) {
ctl_set_space_alloc_fail(&io->scsiio);
} else if (beio->bio_cmd == BIO_FLUSH) {
/* XXX KDM is there is a better error here? */
ctl_set_internal_failure(&io->scsiio,
@ -714,14 +716,12 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun,
char path_str[32];
ctl_scsi_path_string(io, path_str, sizeof(path_str));
/*
* XXX KDM ZFS returns ENOSPC when the underlying
* filesystem fills up. What kind of SCSI error should we
* return for that?
*/
printf("%s%s command returned errno %d\n", path_str,
(beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", error);
ctl_set_medium_error(&io->scsiio);
if (error == ENOSPC) {
ctl_set_space_alloc_fail(&io->scsiio);
} else
ctl_set_medium_error(&io->scsiio);
ctl_complete_beio(beio);
return;
}
@ -807,7 +807,10 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun,
* return the I/O to the user.
*/
if (error != 0) {
ctl_set_medium_error(&io->scsiio);
if (error == ENOSPC) {
ctl_set_space_alloc_fail(&io->scsiio);
} else
ctl_set_medium_error(&io->scsiio);
ctl_complete_beio(beio);
return;
}

View File

@ -805,6 +805,18 @@ ctl_set_task_aborted(struct ctl_scsiio *ctsio)
ctsio->io_hdr.status = CTL_CMD_ABORTED;
}
void
ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio)
{
/* "Space allocation failed write protect" */
ctl_set_sense(ctsio,
/*current_error*/ 1,
/*sense_key*/ SSD_KEY_DATA_PROTECT,
/*asc*/ 0x27,
/*ascq*/ 0x07,
SSD_ELEM_NONE);
}
void
ctl_set_success(struct ctl_scsiio *ctsio)
{

View File

@ -81,6 +81,7 @@ void ctl_set_reservation_conflict(struct ctl_scsiio *ctsio);
void ctl_set_queue_full(struct ctl_scsiio *ctsio);
void ctl_set_busy(struct ctl_scsiio *ctsio);
void ctl_set_task_aborted(struct ctl_scsiio *ctsio);
void ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio);
void ctl_set_success(struct ctl_scsiio *ctsio);
#endif /* _CTL_ERROR_H_ */

View File

@ -1733,7 +1733,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x27, 0x06, SS_RDEF, /* XXX TBD */
"Conditional write protect") },
/* D B */
{ SST(0x27, 0x07, SS_RDEF, /* XXX TBD */
{ SST(0x27, 0x07, SS_FATAL | ENOSPC,
"Space allocation failed write protect") },
/* DTLPWROMAEBKVF */
{ SST(0x28, 0x00, SS_FATAL | ENXIO,