umap_uaddr(&init_mm, idx_to_kaddr(mmap_idx,
pending_idx, i));
req = (struct request *)(unsigned long)pending_req->id;
- ret = end_that_request_first(req, 0, req->hard_nr_sectors);
+ ret = __blk_end_request(req, -EIO, blk_rq_bytes(req));
BUG_ON(ret);
- end_that_request_last(req, 0);
}
start_queue:
pte_t *pte = (pte_t *)data;
DPRINTK("map_uaddr ptep %p -> %012llx/%012llx\n", ptep, pte_val(*pte),
- pte_val_ma(*pte));
+ __pte_val(*pte));
set_pte(ptep, *pte);
xen_invlpg(addr);
return 0;
static void
process_backdev_request(struct tap_blkif *uinfo, struct backdev_info *info)
{
- request_queue_t *rq;
+ struct request_queue *rq;
struct request *req;
blkif_request_t blkif_req;
blkif_request_t *target;
unsigned long uvaddr, kvaddr;
pte_t pte;
unsigned int fsect, lsect;
- struct bio *bio;
struct bio_vec *bvec;
- int idx;
+ struct req_iterator iter;
int usr_idx;
int pending_idx;
uint16_t mmap_idx;
BLKIF_OP_WRITE : BLKIF_OP_READ;
blkif_req.nr_segments = 0;
- rq_for_each_bio (bio, req) {
- bio_for_each_segment (bvec, bio, idx) {
+ rq_for_each_segment(bvec, req, iter) {
BUG_ON(blkif_req.nr_segments ==
BLKIF_MAX_SEGMENTS_PER_REQUEST);
fsect = bvec->bv_offset >> 9;
INVALID_GRANT_HANDLE;
blkif_req.nr_segments++;
- }
}
pending_req->id = (unsigned long)req;
}
static void
-do_backdev_request(request_queue_t *rq)
+do_backdev_request(struct request_queue *rq)
{
struct backdev_info *info;
struct request *req;
struct pending_req *pending_req)
{
struct request *req;
- int uptodate, ret;
+ int ret;
int pending_idx, mmap_idx;
int i;
req = (struct request *)(unsigned long)pending_req->id;
DPRINTK("req %p res status %d operation %d/%d id %lld\n", req,
res->status, res->operation, pending_req->operation, res->id);
- uptodate = (res->status == BLKIF_RSP_OKAY);
+ ret = res->status == BLKIF_RSP_OKAY ? 0 : -EIO;
switch (pending_req->operation) {
#if 0
case BLKIF_OP_WRITE_BARRIER:
if (unlikely(res->status == BLKIF_RSP_EOPNOTSUPP)) {
printk("backdev: %s: write barrier op failed\n",
info->gd->disk_name);
- uptodate = -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
info->feature_barrier = 0;
xlvbd_barrier(info);
}
DPRINTK("Bad return from blkdev data "
"request: %x\n", res->status);
- ret = end_that_request_first(req, uptodate,
- req->hard_nr_sectors);
+ ret = __blk_end_request(req, ret, blk_rq_bytes(req));
BUG_ON(ret);
- end_that_request_last(req, uptodate);
break;
default:
BUG();
wait_queue_head_t poll_wait;
dev_t devno;
- struct class_device *dev;
+ struct device *dev;
atomic_t sysfs_refcnt;
struct mutex sysfs_mutex;
};
command, (long)argument, inode->i_rdev);
switch (command) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
- case HDIO_GETGEO: {
- struct block_device *bd = inode->i_bdev;
- struct hd_geometry geo;
- int ret;
-
- if (!argument)
- return -EINVAL;
-
- geo.start = get_start_sect(bd);
- ret = blktap_device_getgeo(bd, &geo);
- if (ret)
- return ret;
-
- if (copy_to_user((struct hd_geometry __user *)argument, &geo,
- sizeof(geo)))
- return -EFAULT;
-
- return 0;
- }
-#endif
case CDROMMULTISESSION:
BTDBG("FIXME: support multisession CDs later\n");
for (i = 0; i < sizeof(struct cdrom_multisession); i++)
.open = blktap_device_open,
.release = blktap_device_release,
.ioctl = blktap_device_ioctl,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
.getgeo = blktap_device_getgeo
-#endif
};
static int
static void
blktap_device_end_dequeued_request(struct blktap_device *dev,
- struct request *req, int uptodate)
+ struct request *req, int error)
{
+ unsigned long flags;
int ret;
- ret = end_that_request_first(req, uptodate, req->hard_nr_sectors);
- BUG_ON(ret);
+ spin_lock_irqsave(dev->gd->queue->queue_lock, flags);
+ ret = __blk_end_request(req, error, blk_rq_bytes(req));
+ spin_unlock_irqrestore(dev->gd->queue->queue_lock, flags);
- spin_lock_irq(&dev->lock);
- end_that_request_last(req, uptodate);
- spin_unlock_irq(&dev->lock);
+ BUG_ON(ret);
}
/*
blktap_unmap(tap, request);
req = (struct request *)(unsigned long)request->id;
- blktap_device_end_dequeued_request(dev, req, 0);
+ blktap_device_end_dequeued_request(dev, req, -EIO);
blktap_request_free(tap, request);
}
blkif_response_t *res,
struct blktap_request *request)
{
- int uptodate;
+ int ret;
struct request *req;
struct blktap_device *dev;
blktap_unmap(tap, request);
req = (struct request *)(unsigned long)request->id;
- uptodate = (res->status == BLKIF_RSP_OKAY);
+ ret = res->status == BLKIF_RSP_OKAY ? 0 : -EIO;
BTDBG("req %p res status %d operation %d/%d id %lld\n", req,
res->status, res->operation, request->operation, res->id);
if (unlikely(res->status != BLKIF_RSP_OKAY))
BTERR("Bad return from device data "
"request: %x\n", res->status);
- blktap_device_end_dequeued_request(dev, req, uptodate);
+ blktap_device_end_dequeued_request(dev, req, ret);
break;
default:
BUG();
struct blktap_request *request,
struct request *req)
{
- struct bio *bio;
struct page *page;
struct bio_vec *bvec;
- int idx, usr_idx, err;
+ int usr_idx, err;
+ struct req_iterator iter;
struct blktap_ring *ring;
struct blktap_grant_table table;
unsigned int fsect, lsect, nr_sects;
nr_sects = 0;
request->nr_pages = 0;
blkif_req.nr_segments = 0;
- rq_for_each_bio(bio, req) {
- bio_for_each_segment(bvec, bio, idx) {
+ rq_for_each_segment(bvec, req, iter) {
BUG_ON(blkif_req.nr_segments ==
BLKIF_MAX_SEGMENTS_PER_REQUEST);
blkif_req.nr_segments++;
request->nr_pages++;
- }
}
if (blktap_map_foreign(tap, request, &blkif_req, &table))
blktap_device_run_queue(struct blktap *tap)
{
int queued, err;
- request_queue_t *rq;
+ struct request_queue *rq;
struct request *req;
struct blktap_ring *ring;
struct blktap_device *dev;
if (!err)
queued++;
else {
- blktap_device_end_dequeued_request(dev, req, 0);
+ blktap_device_end_dequeued_request(dev, req, -EIO);
blktap_request_free(tap, request);
}
* dev->lock held on entry
*/
static void
-blktap_device_do_request(request_queue_t *rq)
+blktap_device_do_request(struct request_queue *rq)
{
struct request *req;
struct blktap *tap;
if (!rq)
goto error;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
elevator_init(rq, "noop");
-#else
- elevator_init(rq, &elevator_noop);
-#endif
gd->queue = rq;
rq->queuedata = dev;
blktap_device_free(void)
{
if (blktap_device_major)
- if (unregister_blkdev(blktap_device_major, "tapdev"))
- BTERR("blktap device unregister failed\n");
+ unregister_blkdev(blktap_device_major, "tapdev");
}
return 0;
}
-static struct page *
-blktap_ring_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int blktap_ring_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
/*
* if the page has not been mapped in by the driver then return
- * NOPAGE_SIGBUS to the domain.
+ * VM_FAULT_SIGBUS to the domain.
*/
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
static pte_t
static struct vm_operations_struct blktap_ring_vm_operations = {
.close = blktap_ring_vm_close,
.unmap = blktap_ring_vm_unmap,
- .nopage = blktap_ring_nopage,
+ .fault = blktap_ring_fault,
.zap_pte = blktap_ring_clear_pte,
};
blktap_sysfs_put(tap);
}
-static ssize_t blktap_sysfs_pause_device(struct class_device *, const char *, size_t);
+#define CLASS_DEVICE_ATTR(a,b,c,d) DEVICE_ATTR(a,b,c,d)
+
+static ssize_t blktap_sysfs_pause_device(struct device *, struct device_attribute *, const char *, size_t);
CLASS_DEVICE_ATTR(pause, S_IWUSR, NULL, blktap_sysfs_pause_device);
-static ssize_t blktap_sysfs_resume_device(struct class_device *, const char *, size_t);
+static ssize_t blktap_sysfs_resume_device(struct device *, struct device_attribute *, const char *, size_t);
CLASS_DEVICE_ATTR(resume, S_IWUSR, NULL, blktap_sysfs_resume_device);
static ssize_t
-blktap_sysfs_set_name(struct class_device *dev, const char *buf, size_t size)
+blktap_sysfs_set_name(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
int err;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
blktap_sysfs_enter(tap);
}
static ssize_t
-blktap_sysfs_get_name(struct class_device *dev, char *buf)
+blktap_sysfs_get_name(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t size;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
blktap_sysfs_enter(tap);
blktap_sysfs_get_name, blktap_sysfs_set_name);
static ssize_t
-blktap_sysfs_remove_device(struct class_device *dev,
+blktap_sysfs_remove_device(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t size)
{
int err;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
if (!tap->ring.dev)
return size;
CLASS_DEVICE_ATTR(remove, S_IWUSR, NULL, blktap_sysfs_remove_device);
static ssize_t
-blktap_sysfs_pause_device(struct class_device *dev,
+blktap_sysfs_pause_device(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t size)
{
int err;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
blktap_sysfs_enter(tap);
err = blktap_device_pause(tap);
if (!err) {
- class_device_remove_file(dev, &class_device_attr_pause);
- class_device_create_file(dev, &class_device_attr_resume);
+ device_remove_file(dev, &dev_attr_pause);
+ device_create_file(dev, &dev_attr_resume);
}
out:
}
static ssize_t
-blktap_sysfs_resume_device(struct class_device *dev,
+blktap_sysfs_resume_device(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t size)
{
int err;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
blktap_sysfs_enter(tap);
err = blktap_device_resume(tap);
if (!err) {
- class_device_remove_file(dev, &class_device_attr_resume);
- class_device_create_file(dev, &class_device_attr_pause);
+ device_remove_file(dev, &dev_attr_resume);
+ device_create_file(dev, &dev_attr_pause);
}
out:
#ifdef ENABLE_PASSTHROUGH
static ssize_t
-blktap_sysfs_enable_passthrough(struct class_device *dev,
+blktap_sysfs_enable_passthrough(struct device *dev,
const char *buf, size_t size)
{
int err;
unsigned major, minor;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
BTINFO("passthrough request enabled\n");
#endif
static ssize_t
-blktap_sysfs_debug_device(struct class_device *dev, char *buf)
+blktap_sysfs_debug_device(struct device *dev, struct device_attribute *attr, char *buf)
{
char *tmp;
int i, ret;
- struct blktap *tap = (struct blktap *)dev->class_data;
+ struct blktap *tap = (struct blktap *)dev_get_drvdata(dev);
tmp = buf;
blktap_sysfs_get(tap);
blktap_sysfs_create(struct blktap *tap)
{
struct blktap_ring *ring;
- struct class_device *dev;
+ struct device *dev;
if (!class)
return -ENODEV;
ring = &tap->ring;
- dev = class_device_create(class, NULL, ring->devno,
- NULL, "blktap%d", tap->minor);
+ dev = device_create(class, NULL, ring->devno,
+ NULL, "blktap%d", tap->minor);
if (IS_ERR(dev))
return PTR_ERR(dev);
ring->dev = dev;
- dev->class_data = tap;
+ dev_set_drvdata(dev, tap);
mutex_init(&ring->sysfs_mutex);
atomic_set(&ring->sysfs_refcnt, 0);
- set_bit(BLKTAP_SYSFS, &tap->dev_inuse);
- class_device_create_file(dev, &class_device_attr_name);
- class_device_create_file(dev, &class_device_attr_remove);
- class_device_create_file(dev, &class_device_attr_pause);
- class_device_create_file(dev, &class_device_attr_debug);
+ device_create_file(dev, &dev_attr_name);
+ device_create_file(dev, &dev_attr_remove);
+ device_create_file(dev, &dev_attr_pause);
+ device_create_file(dev, &dev_attr_debug);
return 0;
}
blktap_sysfs_destroy(struct blktap *tap)
{
struct blktap_ring *ring;
- struct class_device *dev;
+ struct device *dev;
ring = &tap->ring;
dev = ring->dev;
return -EAGAIN;
/* XXX: is it safe to remove the class from a sysfs attribute? */
- class_device_remove_file(dev, &class_device_attr_name);
- class_device_remove_file(dev, &class_device_attr_remove);
- class_device_remove_file(dev, &class_device_attr_pause);
- class_device_remove_file(dev, &class_device_attr_resume);
- class_device_remove_file(dev, &class_device_attr_debug);
- class_device_destroy(class, ring->devno);
+ device_remove_file(dev, &dev_attr_name);
+ device_remove_file(dev, &dev_attr_remove);
+ device_remove_file(dev, &dev_attr_pause);
+ device_remove_file(dev, &dev_attr_resume);
+ device_remove_file(dev, &dev_attr_debug);
+ device_destroy(class, ring->devno);
clear_bit(BLKTAP_SYSFS, &tap->dev_inuse);