Skip to content

Commit 62f97b8

Browse files
benlwalkerEugeneKochetov
authored andcommitted
fsdev/aio: Handle io_submit failures appropriately
There are several cases to handle here. One is an outright failure return code. Some of these only apply to the first iocb submitted, so in this case we make sure to queue up the remaining iocbs to try again. The other is fewer being submitted than we intended, forcing is to queue back up the excess. Change-Id: I0e0d5c5e32d3d6dd4fa8fafbb06b75b6dbae658e Signed-off-by: Ben Walker <[email protected]>
1 parent 3628ebe commit 62f97b8

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

module/fsdev/aio/fsdev_aio.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,7 +3951,7 @@ aio_io_poll(void *arg)
39513951
{
39523952
struct aio_fsdev_io *vfsdev_io, *tmp;
39533953
struct aio_io_channel *ch = arg;
3954-
TAILQ_HEAD(, aio_fsdev_io) ios = TAILQ_HEAD_INITIALIZER(ios);
3954+
TAILQ_HEAD(aio_tmp_list, aio_fsdev_io) ios = TAILQ_HEAD_INITIALIZER(ios);
39553955
struct io_event events[32];
39563956
struct iocb *iocbs[32];
39573957
long to_submit = 0;
@@ -3978,29 +3978,30 @@ aio_io_poll(void *arg)
39783978
struct spdk_fsdev_io *fsdev_io = aio_to_fsdev_io(vfsdev_io);
39793979
enum spdk_fsdev_io_type type = spdk_fsdev_io_get_type(fsdev_io);
39803980

3981-
TAILQ_REMOVE(&ios, vfsdev_io, link);
3982-
39833981
rc = -EOPNOTSUPP;
39843982
res = SPDK_POLLER_BUSY;
39853983

39863984
switch (type) {
39873985
case SPDK_FSDEV_IO_READ:
39883986
case SPDK_FSDEV_IO_WRITE:
3989-
TAILQ_INSERT_TAIL(&ch->ios_in_progress, vfsdev_io, link);
39903987
iocbs[to_submit++] = &vfsdev_io->io;
39913988
rc = IO_STATUS_ASYNC;
39923989
break;
39933990
case SPDK_FSDEV_IO_POLL:
3991+
TAILQ_REMOVE(&ios, vfsdev_io, link);
39943992
rc = fsdev_aio_do_poll(ch, fsdev_io);
39953993
break;
39963994
case SPDK_FSDEV_IO_SETLK:
3995+
TAILQ_REMOVE(&ios, vfsdev_io, link);
39973996
rc = fsdev_aio_do_setlk(ch, fsdev_io);
39983997
break;
39993998
default:
3999+
TAILQ_REMOVE(&ios, vfsdev_io, link);
40004000
break;
40014001
}
40024002

40034003
if (rc != IO_STATUS_ASYNC) {
4004+
vfsdev_io->status = rc;
40044005
TAILQ_INSERT_TAIL(&ch->ios_to_complete, vfsdev_io, link);
40054006
}
40064007

@@ -4011,9 +4012,42 @@ aio_io_poll(void *arg)
40114012

40124013
if (to_submit > 0) {
40134014
rc = io_submit(ch->io_ctx, to_submit, iocbs);
4014-
if (rc < to_submit) {
4015-
/* TODO: Need to handle this error. Just blow up for now. */
4016-
assert(false);
4015+
if (rc < 0) {
4016+
res = rc;
4017+
rc = 0; /* 0 were submitted. This will get them all queued back up. */
4018+
4019+
if (res != -EAGAIN) {
4020+
/* The failures typically apply to the first iocb. Fail that one, but let the others
4021+
* queue back up to be resubmitted. */
4022+
SPDK_ERRLOG("Failed io_submit: %s (%d)\n", spdk_strerror(-res), res);
4023+
vfsdev_io = TAILQ_FIRST(&ios);
4024+
TAILQ_REMOVE(&ios, vfsdev_io, link);
4025+
vfsdev_io->status = res;
4026+
TAILQ_INSERT_TAIL(&ch->ios_to_complete, vfsdev_io, link);
4027+
}
4028+
}
4029+
4030+
/* For each request actually submitted, shift it into the in progress list. */
4031+
i = 0;
4032+
TAILQ_FOREACH_SAFE(vfsdev_io, &ios, link, tmp) {
4033+
if (i == rc) {
4034+
break;
4035+
}
4036+
4037+
assert(&vfsdev_io->io == iocbs[i]);
4038+
4039+
TAILQ_REMOVE(&ios, vfsdev_io, link);
4040+
TAILQ_INSERT_TAIL(&ch->ios_in_progress, vfsdev_io, link);
4041+
4042+
i++;
4043+
}
4044+
4045+
/* For all remaining requests, put them back into the ios_for_submit list */
4046+
vfsdev_io = TAILQ_LAST(&ios, aio_tmp_list);
4047+
while (vfsdev_io != NULL) {
4048+
TAILQ_REMOVE(&ios, vfsdev_io, link);
4049+
TAILQ_INSERT_HEAD(&ch->ios_for_submit, vfsdev_io, link);
4050+
vfsdev_io = TAILQ_LAST(&ios, aio_tmp_list);
40174051
}
40184052
}
40194053

0 commit comments

Comments
 (0)