* response queued for it, with the saved 'id' passed back.
*/
struct pending_req {
- struct blkif_st *blkif;
+ struct xen_blkif *blkif;
u64 id;
int nr_pages;
atomic_t pendcnt;
(blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)])
-static int do_block_io_op(struct blkif_st *blkif);
-static int dispatch_rw_block_io(struct blkif_st *blkif,
+static int do_block_io_op(struct xen_blkif *blkif);
+static int dispatch_rw_block_io(struct xen_blkif *blkif,
struct blkif_request *req,
struct pending_req *pending_req);
-static void make_response(struct blkif_st *blkif, u64 id,
+static void make_response(struct xen_blkif *blkif, u64 id,
unsigned short op, int st);
/*
/*
* Routines for managing virtual block devices (vbds).
*/
-static int vbd_translate(struct phys_req *req, struct blkif_st *blkif,
- int operation)
+static int xen_vbd_translate(struct phys_req *req, struct xen_blkif *blkif,
+ int operation)
{
- struct vbd *vbd = &blkif->vbd;
+ struct xen_vbd *vbd = &blkif->vbd;
int rc = -EACCES;
if ((operation != READ) && vbd->readonly)
goto out;
- if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
- goto out;
+ if (likely(req->nr_sects)) {
+ blkif_sector_t end = req->sector_number + req->nr_sects;
+
+ if (unlikely(end < req->sector_number))
+ goto out;
+ if (unlikely(end > vbd_sz(vbd)))
+ goto out;
+ }
req->dev = vbd->pdevice;
req->bdev = vbd->bdev;
return rc;
}
-static void vbd_resize(struct blkif_st *blkif)
+static void xen_vbd_resize(struct xen_blkif *blkif)
{
- struct vbd *vbd = &blkif->vbd;
+ struct xen_vbd *vbd = &blkif->vbd;
struct xenbus_transaction xbt;
int err;
struct xenbus_device *dev = xen_blkbk_xenbus(blkif->be);
goto again;
if (err)
pr_warn(DRV_PFX "Error ending transaction");
+ return;
abort:
xenbus_transaction_end(xbt, 1);
}
/*
* Notification from the guest OS.
*/
-static void blkif_notify_work(struct blkif_st *blkif)
+static void blkif_notify_work(struct xen_blkif *blkif)
{
blkif->waiting_reqs = 1;
wake_up(&blkif->wq);
* SCHEDULER FUNCTIONS
*/
-static void print_stats(struct blkif_st *blkif)
+static void print_stats(struct xen_blkif *blkif)
{
- pr_debug("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d\n",
+ pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d\n",
current->comm, blkif->st_oo_req,
blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req);
blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
int xen_blkif_schedule(void *arg)
{
- struct blkif_st *blkif = arg;
- struct vbd *vbd = &blkif->vbd;
+ struct xen_blkif *blkif = arg;
+ struct xen_vbd *vbd = &blkif->vbd;
xen_blkif_get(blkif);
if (try_to_freeze())
continue;
if (unlikely(vbd->size != vbd_sz(vbd)))
- vbd_resize(blkif);
+ xen_vbd_resize(blkif);
wait_event_interruptible(
blkif->wq,
* (which has the sectors we want, number of them, grant references, etc),
* and transmute it to the block API to hand it over to the proper block disk.
*/
-static int do_block_io_op(struct blkif_st *blkif)
+static int do_block_io_op(struct xen_blkif *blkif)
{
union blkif_back_rings *blk_rings = &blkif->blk_rings;
struct blkif_request req;
* Transmutation of the 'struct blkif_request' to a proper 'struct bio'
* and call the 'submit_bio' to pass it to the underlying storage.
*/
-static int dispatch_rw_block_io(struct blkif_st *blkif,
- struct blkif_request *req,
- struct pending_req *pending_req)
+static int dispatch_rw_block_io(struct xen_blkif *blkif,
+ struct blkif_request *req,
+ struct pending_req *pending_req)
{
struct phys_req preq;
struct seg_buf seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
case BLKIF_OP_FLUSH_DISKCACHE:
blkif->st_f_req++;
operation = WRITE_FLUSH;
- /*
- * The frontend likes to set this to -1, which vbd_translate
- * is alergic too.
- */
- req->u.rw.sector_number = 0;
break;
case BLKIF_OP_WRITE_BARRIER:
default:
}
- if (vbd_translate(&preq, blkif, operation) != 0) {
+ if (xen_vbd_translate(&preq, blkif, operation) != 0) {
pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n",
operation == READ ? "read" : "write",
preq.sector_number,
}
/*
- * This check _MUST_ be done after vbd_translate as the preq.bdev
+ * This check _MUST_ be done after xen_vbd_translate as the preq.bdev
* is set there.
*/
for (i = 0; i < nseg; i++) {
/*
* Put a response on the ring on how the operation fared.
*/
-static void make_response(struct blkif_st *blkif, u64 id,
+static void make_response(struct xen_blkif *blkif, u64 id,
unsigned short op, int st)
{
struct blkif_response resp;
failed_init:
kfree(blkbk->pending_reqs);
kfree(blkbk->pending_grant_handles);
- for (i = 0; i < mmap_pages; i++) {
- if (blkbk->pending_pages[i])
- __free_page(blkbk->pending_pages[i]);
+ if (blkbk->pending_pages) {
+ for (i = 0; i < mmap_pages; i++) {
+ if (blkbk->pending_pages[i])
+ __free_page(blkbk->pending_pages[i]);
+ }
+ kfree(blkbk->pending_pages);
}
- kfree(blkbk->pending_pages);
kfree(blkbk);
blkbk = NULL;
return rc;