lib/ftl: added ftl_io_call_foreach_child

As the name suggests, the function calls a function passed as the
argument for all children IOs.

Change-Id: Idd7b6013e68fdd188db6e682bb9ba9ec2e6f52f1
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455526
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Konrad Sztyber 2019-05-15 11:18:10 +02:00 committed by Darek Stojaczyk
parent 2646670781
commit 8f9aed50c2
2 changed files with 36 additions and 0 deletions

View File

@ -463,3 +463,38 @@ ftl_io_free(struct ftl_io *io)
_ftl_io_free(io);
}
void
ftl_io_call_foreach_child(struct ftl_io *io, int (*callback)(struct ftl_io *))
{
struct ftl_io *child, *tmp;
assert(!io->done);
/*
* If the IO doesn't have any children, it means that it directly describes a request (i.e.
* all of the buffers, LBAs, etc. are filled). Otherwise the IO only groups together several
* requests and may be partially filled, so the callback needs to be called on all of its
* children instead.
*/
if (LIST_EMPTY(&io->children)) {
callback(io);
return;
}
LIST_FOREACH_SAFE(child, &io->children, child_entry, tmp) {
int rc = callback(child);
if (rc) {
assert(rc != -EAGAIN);
ftl_io_fail(io, rc);
break;
}
}
/*
* If all the callbacks were processed or an error occurred, treat this IO as completed.
* Multiple calls to ftl_io_call_foreach_child are not supported, resubmissions are supposed
* to be handled in the callback.
*/
ftl_io_complete(io);
}

View File

@ -281,5 +281,6 @@ void ftl_io_complete(struct ftl_io *io);
void ftl_io_shrink_iovec(struct ftl_io *io, size_t lbk_cnt);
void ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status);
void ftl_io_reset(struct ftl_io *io);
void ftl_io_call_foreach_child(struct ftl_io *io, int (*callback)(struct ftl_io *));
#endif /* FTL_IO_H */