in core/ms_block.c [1876:1941]
static void msb_io_work(struct work_struct *work)
{
struct msb_data *msb = container_of(work, struct msb_data, io_work);
int page, error, len;
sector_t lba;
struct scatterlist *sg = msb->prealloc_sg;
struct request *req;
dbg_verbose("IO: work started");
while (1) {
spin_lock_irq(&msb->q_lock);
if (msb->need_flush_cache) {
msb->need_flush_cache = false;
spin_unlock_irq(&msb->q_lock);
msb_cache_flush(msb);
continue;
}
req = msb->req;
if (!req) {
dbg_verbose("IO: no more requests exiting");
spin_unlock_irq(&msb->q_lock);
return;
}
spin_unlock_irq(&msb->q_lock);
/* process the request */
dbg_verbose("IO: processing new request");
blk_rq_map_sg(msb->queue, req, sg);
lba = blk_rq_pos(req);
sector_div(lba, msb->page_size / 512);
page = sector_div(lba, msb->pages_in_block);
if (rq_data_dir(msb->req) == READ)
error = msb_do_read_request(msb, lba, page, sg,
blk_rq_bytes(req), &len);
else
error = msb_do_write_request(msb, lba, page, sg,
blk_rq_bytes(req), &len);
if (len && !blk_update_request(req, BLK_STS_OK, len)) {
__blk_mq_end_request(req, BLK_STS_OK);
spin_lock_irq(&msb->q_lock);
msb->req = NULL;
spin_unlock_irq(&msb->q_lock);
}
if (error && msb->req) {
blk_status_t ret = errno_to_blk_status(error);
dbg_verbose("IO: ending one sector of the request with error");
blk_mq_end_request(req, ret);
spin_lock_irq(&msb->q_lock);
msb->req = NULL;
spin_unlock_irq(&msb->q_lock);
}
if (msb->req)
dbg_verbose("IO: request still pending");
}
}