um: Clean-up command processing in UML UBD driver

Clean-up command processing and return BLK_STS_NOTSUP for
uknown commands.

Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Anton Ivanov 2018-11-14 18:41:07 +00:00 committed by Richard Weinberger
parent a43c83161a
commit 53766defb8
1 changed files with 47 additions and 30 deletions

View File

@ -1306,65 +1306,82 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,
io_req->fds[0] = dev->fd;
io_req->error = 0;
if (req_op(req) != REQ_OP_FLUSH) {
io_req->fds[1] = dev->fd;
io_req->cow_offset = -1;
io_req->offset = off;
io_req->length = bvec->bv_len;
io_req->sector_mask = 0;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
if (bvec != NULL) {
io_req->buffer = page_address(bvec->bv_page) + bvec->bv_offset;
io_req->sectorsize = SECTOR_SIZE;
if (dev->cow.file) {
cowify_req(io_req, dev->cow.bitmap,
dev->cow.bitmap_offset, dev->cow.bitmap_len);
}
io_req->length = bvec->bv_len;
} else {
io_req->buffer = NULL;
io_req->length = blk_rq_bytes(req);
}
io_req->sectorsize = SECTOR_SIZE;
io_req->fds[1] = dev->fd;
io_req->cow_offset = -1;
io_req->offset = off;
io_req->sector_mask = 0;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
if (dev->cow.file)
cowify_req(io_req, dev->cow.bitmap,
dev->cow.bitmap_offset, dev->cow.bitmap_len);
ret = os_write_file(thread_fd, &io_req, sizeof(io_req));
if (ret != sizeof(io_req)) {
if (ret != -EAGAIN)
pr_err("write to io thread failed: %d\n", -ret);
kfree(io_req);
}
return ret;
}
static int queue_rw_req(struct blk_mq_hw_ctx *hctx, struct request *req)
{
struct req_iterator iter;
struct bio_vec bvec;
int ret;
u64 off = (u64)blk_rq_pos(req) << SECTOR_SHIFT;
rq_for_each_segment(bvec, req, iter) {
ret = ubd_queue_one_vec(hctx, req, off, &bvec);
if (ret < 0)
return ret;
off += bvec.bv_len;
}
return 0;
}
static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{
struct ubd *ubd_dev = hctx->queue->queuedata;
struct request *req = bd->rq;
int ret = 0;
int ret = 0, res = BLK_STS_OK;
blk_mq_start_request(req);
spin_lock_irq(&ubd_dev->lock);
if (req_op(req) == REQ_OP_FLUSH) {
switch (req_op(req)) {
/* operations with no lentgth/offset arguments */
case REQ_OP_FLUSH:
ret = ubd_queue_one_vec(hctx, req, 0, NULL);
} else {
struct req_iterator iter;
struct bio_vec bvec;
u64 off = (u64)blk_rq_pos(req) << SECTOR_SHIFT;
rq_for_each_segment(bvec, req, iter) {
ret = ubd_queue_one_vec(hctx, req, off, &bvec);
if (ret < 0)
goto out;
off += bvec.bv_len;
}
break;
case REQ_OP_READ:
case REQ_OP_WRITE:
ret = queue_rw_req(hctx, req);
break;
default:
WARN_ON_ONCE(1);
res = BLK_STS_NOTSUPP;
}
out:
spin_unlock_irq(&ubd_dev->lock);
if (ret < 0)
blk_mq_requeue_request(req, true);
return BLK_STS_OK;
return res;
}
static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)