Skip to content

Commit b1d8929

Browse files
author
Mike Christie
committed
sync handle_cmd and io callout return/completion behavior
This syncs the handle_cmd and io callout return/completion behavior for handlers that are using tcmu-runner's threading and/or generic command handling. For compat, we support old style handle_cmd handlers if they are not using the tcmu-runner aio threading. Signed-off-by: Mike Christie <[email protected]>
1 parent 652d300 commit b1d8929

10 files changed

+217
-171
lines changed

Diff for: file_example.c

+31-14
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
#include <fcntl.h>
3939
#include <endian.h>
4040
#include <errno.h>
41+
#include <scsi/scsi.h>
4142

43+
#include "scsi_defs.h"
4244
#include "tcmu-runner.h"
4345

4446
struct file_state {
@@ -130,57 +132,72 @@ static void file_close(struct tcmu_device *dev)
130132
free(state);
131133
}
132134

133-
static ssize_t file_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
134-
struct iovec *iov, size_t iov_cnt, size_t length,
135-
off_t offset)
135+
static int file_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
136+
struct iovec *iov, size_t iov_cnt, size_t length,
137+
off_t offset)
136138
{
137139
struct file_state *state = tcmu_get_dev_private(dev);
138140
size_t remaining = length;
139-
int ret;
141+
ssize_t ret;
140142

141143
while (remaining) {
142144
ret = preadv(state->fd, iov, iov_cnt, offset);
143145
if (ret < 0) {
144146
tcmu_err("read failed: %m\n");
145-
return -EIO;
147+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
148+
ASC_READ_ERROR, NULL);
149+
goto done;
146150
}
147151
tcmu_seek_in_iovec(iov, ret);
148152
offset += ret;
149153
remaining -= ret;
150154
}
151-
return length;
155+
ret = SAM_STAT_GOOD;
156+
done:
157+
cmd->done(dev, cmd, ret);
158+
return 0;
152159
}
153160

154-
static ssize_t file_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
155-
struct iovec *iov, size_t iov_cnt, size_t length,
156-
off_t offset)
161+
static int file_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
162+
struct iovec *iov, size_t iov_cnt, size_t length,
163+
off_t offset)
157164
{
158165
struct file_state *state = tcmu_get_dev_private(dev);
159166
size_t remaining = length;
160-
int ret;
167+
ssize_t ret;
161168

162169
while (remaining) {
163170
ret = pwritev(state->fd, iov, iov_cnt, offset);
164171
if (ret < 0) {
165172
tcmu_err("write failed: %m\n");
166-
return -EIO;
173+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
174+
ASC_WRITE_ERROR, NULL);
175+
goto done;
167176
}
168177
tcmu_seek_in_iovec(iov, ret);
169178
offset += ret;
170179
remaining -= ret;
171180
}
172-
return length;
181+
ret = SAM_STAT_GOOD;
182+
done:
183+
cmd->done(dev, cmd, ret);
184+
return 0;
173185
}
174186

175187
static int file_flush(struct tcmu_device *dev, struct tcmulib_cmd *cmd)
176188
{
177189
struct file_state *state = tcmu_get_dev_private(dev);
190+
int ret;
178191

179192
if (fsync(state->fd)) {
180193
tcmu_err("sync failed\n");
181-
return -EIO;
194+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
195+
ASC_WRITE_ERROR, NULL);
196+
goto done;
182197
}
183-
198+
ret = SAM_STAT_GOOD;
199+
done:
200+
cmd->done(dev, cmd, ret);
184201
return 0;
185202
}
186203

Diff for: file_optical.c

+49-38
Original file line numberDiff line numberDiff line change
@@ -1565,103 +1565,114 @@ static int fbo_handle_cmd(struct tcmu_device *dev, struct tcmulib_cmd *cmd)
15651565
uint8_t *sense = cmd->sense_buf;
15661566
struct fbo_state *state = tcmu_get_dev_private(dev);
15671567
bool do_verify = false;
1568+
int ret;
15681569

15691570
/* Check for format in progress */
15701571
/* Certain commands can be executed even if a format is in progress */
15711572
if (state->flags & FBO_FORMATTING &&
15721573
cdb[0] != INQUIRY &&
15731574
cdb[0] != REQUEST_SENSE &&
15741575
cdb[0] != GET_CONFIGURATION &&
1575-
cdb[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION)
1576-
return tcmu_set_sense_data(sense, NOT_READY,
1577-
ASC_NOT_READY_FORMAT_IN_PROGRESS,
1578-
&state->format_progress);
1576+
cdb[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
1577+
ret = tcmu_set_sense_data(sense, NOT_READY,
1578+
ASC_NOT_READY_FORMAT_IN_PROGRESS,
1579+
&state->format_progress);
1580+
cmd->done(dev, cmd, ret);
1581+
return 0;
1582+
}
15791583

15801584
switch(cdb[0]) {
15811585
case TEST_UNIT_READY:
1582-
return tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense);
1586+
ret = tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense);
15831587
break;
15841588
case REQUEST_SENSE:
1585-
return fbo_emulate_request_sense(dev, cdb, iovec, iov_cnt, sense);
1589+
ret = fbo_emulate_request_sense(dev, cdb, iovec, iov_cnt, sense);
1590+
break;
15861591
case FORMAT_UNIT:
1587-
return fbo_emulate_format_unit(dev, cdb, iovec, iov_cnt, sense);
1592+
ret = fbo_emulate_format_unit(dev, cdb, iovec, iov_cnt, sense);
1593+
break;
15881594
case READ_6:
15891595
case READ_10:
15901596
case READ_12:
1591-
return fbo_read(dev, cdb, iovec, iov_cnt, sense);
1597+
ret = fbo_read(dev, cdb, iovec, iov_cnt, sense);
15921598
break;
15931599
case WRITE_VERIFY:
15941600
do_verify = true;
15951601
case WRITE_6:
15961602
case WRITE_10:
15971603
case WRITE_12:
1598-
return fbo_write(dev, cdb, iovec, iov_cnt, sense, do_verify);
1604+
ret = fbo_write(dev, cdb, iovec, iov_cnt, sense, do_verify);
15991605
break;
16001606
case INQUIRY:
1601-
return fbo_emulate_inquiry(cdb, iovec, iov_cnt, sense);
1607+
ret = fbo_emulate_inquiry(cdb, iovec, iov_cnt, sense);
16021608
break;
16031609
case MODE_SELECT:
16041610
case MODE_SELECT_10:
1605-
return fbo_emulate_mode_select(cdb, iovec, iov_cnt, sense);
1611+
ret = fbo_emulate_mode_select(cdb, iovec, iov_cnt, sense);
16061612
break;
16071613
case MODE_SENSE:
16081614
case MODE_SENSE_10:
1609-
return fbo_emulate_mode_sense(cdb, iovec, iov_cnt, sense);
1615+
ret = fbo_emulate_mode_sense(cdb, iovec, iov_cnt, sense);
16101616
break;
16111617
case START_STOP:
1612-
return tcmu_emulate_start_stop(dev, cdb, sense);
1618+
ret = tcmu_emulate_start_stop(dev, cdb, sense);
16131619
break;
16141620
case ALLOW_MEDIUM_REMOVAL:
1615-
return fbo_emulate_allow_medium_removal(dev, cdb, sense);
1621+
ret = fbo_emulate_allow_medium_removal(dev, cdb, sense);
16161622
break;
16171623
case READ_FORMAT_CAPACITIES:
1618-
return fbo_emulate_read_format_capacities(dev, cdb, iovec,
1619-
iov_cnt, sense);
1624+
ret = fbo_emulate_read_format_capacities(dev, cdb, iovec,
1625+
iov_cnt, sense);
1626+
break;
16201627
case READ_CAPACITY:
16211628
if ((cdb[1] & 0x01) || (cdb[8] & 0x01))
16221629
/* Reserved bits for MM logical units */
1623-
return tcmu_set_sense_data(sense, ILLEGAL_REQUEST,
1624-
ASC_INVALID_FIELD_IN_CDB,
1625-
NULL);
1630+
ret = tcmu_set_sense_data(sense, ILLEGAL_REQUEST,
1631+
ASC_INVALID_FIELD_IN_CDB,
1632+
NULL);
16261633
else
1627-
return tcmu_emulate_read_capacity_10(state->num_lbas,
1628-
state->block_size,
1629-
cdb, iovec,
1630-
iov_cnt, sense);
1634+
ret = tcmu_emulate_read_capacity_10(state->num_lbas,
1635+
state->block_size,
1636+
cdb, iovec,
1637+
iov_cnt, sense);
1638+
break;
16311639
case VERIFY:
1632-
return fbo_verify(dev, cdb, iovec, iov_cnt, sense);
1640+
ret = fbo_verify(dev, cdb, iovec, iov_cnt, sense);
16331641
break;
16341642
case SYNCHRONIZE_CACHE:
1635-
return fbo_synchronize_cache(dev, cdb, sense);
1643+
ret = fbo_synchronize_cache(dev, cdb, sense);
16361644
break;
16371645
case READ_TOC:
1638-
return fbo_emulate_read_toc(dev, cdb, iovec, iov_cnt, sense);
1646+
ret = fbo_emulate_read_toc(dev, cdb, iovec, iov_cnt, sense);
16391647
break;
16401648
case GET_CONFIGURATION:
1641-
return fbo_emulate_get_configuration(dev, cdb, iovec, iov_cnt,
1642-
sense);
1649+
ret = fbo_emulate_get_configuration(dev, cdb, iovec, iov_cnt,
1650+
sense);
16431651
break;
16441652
case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
1645-
return fbo_emulate_get_event_status_notification(dev, cdb,
1646-
iovec, iov_cnt,
1647-
sense);
1653+
ret = fbo_emulate_get_event_status_notification(dev, cdb,
1654+
iovec, iov_cnt,
1655+
sense);
16481656
break;
16491657
case READ_DISC_INFORMATION:
1650-
return fbo_emulate_read_disc_information(dev, cdb, iovec,
1651-
iov_cnt, sense);
1658+
ret = fbo_emulate_read_disc_information(dev, cdb, iovec,
1659+
iov_cnt, sense);
16521660
break;
16531661
case READ_DVD_STRUCTURE:
1654-
return fbo_emulate_read_dvd_structure(dev, cdb, iovec, iov_cnt,
1655-
sense);
1662+
ret = fbo_emulate_read_dvd_structure(dev, cdb, iovec, iov_cnt,
1663+
sense);
16561664
break;
16571665
case MECHANISM_STATUS:
1658-
return fbo_emulate_mechanism_status(dev, cdb, iovec, iov_cnt,
1659-
sense);
1666+
ret = fbo_emulate_mechanism_status(dev, cdb, iovec, iov_cnt,
1667+
sense);
16601668
break;
16611669
default:
16621670
tcmu_err("unknown command 0x%x\n", cdb[0]);
1663-
return TCMU_NOT_HANDLED;
1671+
ret = TCMU_NOT_HANDLED;
16641672
}
1673+
1674+
cmd->done(dev, cmd, ret);
1675+
return 0;
16651676
}
16661677

16671678
static const char fbo_cfg_desc[] =

Diff for: glfs.c

+35-13
Original file line numberDiff line numberDiff line change
@@ -539,32 +539,54 @@ static void tcmu_glfs_close(struct tcmu_device *dev)
539539
free(gfsp);
540540
}
541541

542-
static ssize_t tcmu_glfs_read(struct tcmu_device *dev,
543-
struct tcmulib_cmd *tcmulib_cmd,
544-
struct iovec *iov, size_t iov_cnt, size_t length,
545-
off_t offset)
542+
static int tcmu_glfs_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
543+
struct iovec *iov, size_t iov_cnt, size_t length,
544+
off_t offset)
546545
{
547546
struct glfs_state *state = tcmu_get_dev_private(dev);
547+
ssize_t ret;
548548

549-
return glfs_preadv(state->gfd, iov, iov_cnt, offset, SEEK_SET);
549+
ret = glfs_preadv(state->gfd, iov, iov_cnt, offset, SEEK_SET);
550+
if (ret != length) {
551+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
552+
ASC_READ_ERROR, NULL);
553+
} else {
554+
ret = SAM_STAT_GOOD;
555+
}
556+
557+
cmd->done(dev, cmd, ret);
558+
return 0;
550559
}
551560

552-
static ssize_t tcmu_glfs_write(struct tcmu_device *dev,
553-
struct tcmulib_cmd *tcmulib_cmd,
554-
struct iovec *iov, size_t iov_cnt, size_t length,
555-
off_t offset)
561+
static int tcmu_glfs_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
562+
struct iovec *iov, size_t iov_cnt, size_t length,
563+
off_t offset)
556564
{
557565
struct glfs_state *state = tcmu_get_dev_private(dev);
566+
ssize_t ret;
558567

559-
return glfs_pwritev(state->gfd, iov, iov_cnt, offset, ALLOWED_BSOFLAGS);
568+
ret = glfs_pwritev(state->gfd, iov, iov_cnt, offset, ALLOWED_BSOFLAGS);
569+
if (ret != length) {
570+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
571+
ASC_WRITE_ERROR, NULL);
572+
} else {
573+
ret = SAM_STAT_GOOD;
574+
}
575+
576+
cmd->done(dev, cmd, ret);
577+
return 0;
560578
}
561579

562-
static int tcmu_glfs_flush(struct tcmu_device *dev,
563-
struct tcmulib_cmd *tcmulib_cmd)
580+
static int tcmu_glfs_flush(struct tcmu_device *dev, struct tcmulib_cmd *cmd)
564581
{
565582
struct glfs_state *state = tcmu_get_dev_private(dev);
583+
int ret = SAM_STAT_GOOD;
566584

567-
return glfs_fdatasync(state->gfd);
585+
if (glfs_fdatasync(state->gfd))
586+
ret = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
587+
ASC_WRITE_ERROR, NULL);
588+
cmd->done(dev, cmd, ret);
589+
return 0;
568590
}
569591

570592
static const char glfs_cfg_desc[] =

0 commit comments

Comments
 (0)