mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 18:30:06 +00:00
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:
parent
a43c83161a
commit
53766defb8
1 changed files with 47 additions and 30 deletions
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue