2 #include <linux/blkdev.h>
3 #include <linux/cdrom.h>
4 #include <linux/hdreg.h>
5 #include <linux/module.h>
6 #include <linux/version.h>
7 #include <asm/tlbflush.h>
10 #include <scsi/scsi_ioctl.h>
12 #include <xen/xenbus.h>
13 #include <xen/interface/io/blkif.h>
17 #include "../blkback/blkback-pagemap.h"
20 #define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a)
22 #define DPRINTK_IOCTL(_f, _a...) ((void)0)
25 struct blktap_grant_table {
27 struct gnttab_map_grant_ref grants[BLKIF_MAX_SEGMENTS_PER_REQUEST * 2];
30 static int blktap_device_major;
32 static inline struct blktap *
33 dev_to_blktap(struct blktap_device *dev)
35 return container_of(dev, struct blktap, device);
39 blktap_device_open(struct block_device *bd, fmode_t mode)
42 struct blktap_device *dev = bd->bd_disk->private_data;
47 tap = dev_to_blktap(dev);
48 if (!blktap_active(tap) ||
49 test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
58 blktap_device_release(struct gendisk *disk, fmode_t mode)
60 struct blktap_device *dev = disk->private_data;
61 struct blktap *tap = dev_to_blktap(dev);
64 if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
65 blktap_device_destroy(tap);
71 blktap_device_getgeo(struct block_device *bd, struct hd_geometry *hg)
73 /* We don't have real geometry info, but let's at least return
74 values consistent with the size of the device */
75 sector_t nsect = get_capacity(bd->bd_disk);
76 sector_t cylinders = nsect;
80 sector_div(cylinders, hg->heads * hg->sectors);
81 hg->cylinders = cylinders;
82 if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
83 hg->cylinders = 0xffff;
88 blktap_device_ioctl(struct block_device *bd, fmode_t mode,
89 unsigned command, unsigned long argument)
93 DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx\n",
94 command, (long)argument);
97 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
99 struct hd_geometry geo;
105 geo.start = get_start_sect(bd);
106 ret = blktap_device_getgeo(bd, &geo);
110 if (copy_to_user((struct hd_geometry __user *)argument, &geo,
117 case CDROMMULTISESSION:
118 BTDBG("FIXME: support multisession CDs later\n");
119 for (i = 0; i < sizeof(struct cdrom_multisession); i++)
120 if (put_user(0, (char __user *)(argument + i)))
124 case SCSI_IOCTL_GET_IDLUN:
125 if (!access_ok(VERIFY_WRITE, argument,
126 sizeof(struct scsi_idlun)))
129 /* return 0 for now. */
130 __put_user(0, &((struct scsi_idlun __user *)argument)->dev_id);
132 &((struct scsi_idlun __user *)argument)->host_unique_id);
136 /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
138 return -EINVAL; /* same return as native Linux */
144 static const struct block_device_operations blktap_device_file_operations = {
145 .owner = THIS_MODULE,
146 .open = blktap_device_open,
147 .release = blktap_device_release,
148 .ioctl = blktap_device_ioctl,
149 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
150 .getgeo = blktap_device_getgeo
155 blktap_map_uaddr_fn(pte_t *ptep, struct page *pmd_page,
156 unsigned long addr, void *data)
158 pte_t *pte = (pte_t *)data;
160 BTDBG("ptep %p -> %012llx\n", ptep, (unsigned long long)pte_val(*pte));
166 blktap_map_uaddr(struct vm_area_struct *vma, unsigned long address, pte_t pte)
168 return apply_to_page_range(vma ? vma->vm_mm : NULL, address,
169 PAGE_SIZE, blktap_map_uaddr_fn, &pte);
173 blktap_umap_uaddr_fn(pte_t *ptep, struct page *pmd_page,
174 unsigned long addr, void *data)
176 struct vm_area_struct *vma = data;
178 BTDBG("ptep %p\n", ptep);
179 xen_ptep_get_and_clear_full(vma, addr, ptep, 1);
184 blktap_umap_uaddr(struct vm_area_struct *vma, unsigned long address)
186 struct mm_struct *mm = NULL;
190 if (HYPERVISOR_update_va_mapping(address, __pte(0),
191 UVMF_INVLPG|UVMF_ALL))
197 return apply_to_page_range(mm, address,
198 PAGE_SIZE, blktap_umap_uaddr_fn, vma);
202 flush_tlb_kernel_page(unsigned long kvaddr)
205 xen_invlpg_all(kvaddr);
207 flush_tlb_kernel_range(kvaddr, kvaddr + PAGE_SIZE);
212 * tap->tap_sem held on entry
215 blktap_device_fast_flush(struct blktap *tap, struct blktap_request *request)
220 struct page **map, *page;
221 struct blktap_ring *ring;
222 struct grant_handle_pair *khandle;
223 unsigned long kvaddr, uvaddr, offset;
224 struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST * 2];
225 grant_handle_t self_gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
226 int self_gref_nr = 0;
230 usr_idx = request->usr_idx;
231 map = ring->foreign_map.map;
236 if (xen_feature(XENFEAT_auto_translated_physmap))
237 zap_page_range(ring->vma,
238 MMAP_VADDR(ring->user_vstart, usr_idx, 0),
239 request->nr_pages << PAGE_SHIFT, NULL);
241 for (i = 0; i < request->nr_pages; i++) {
242 kvaddr = request_to_kaddr(request, i);
243 uvaddr = MMAP_VADDR(ring->user_vstart, usr_idx, i);
245 khandle = request->handles + i;
247 if (khandle->kernel != INVALID_GRANT_HANDLE) {
248 gnttab_set_unmap_op(&unmap[cnt], kvaddr,
249 GNTMAP_host_map, khandle->kernel);
251 set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
255 if (khandle->user != INVALID_GRANT_HANDLE) {
256 BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
257 if (create_lookup_pte_addr(ring->vma->vm_mm,
258 uvaddr, &ptep) != 0) {
259 BTERR("Couldn't get a pte addr!\n");
263 gnttab_set_unmap_op(&unmap[cnt], ptep,
265 | GNTMAP_application_map
266 | GNTMAP_contains_pte,
271 offset = (uvaddr - ring->vma->vm_start) >> PAGE_SHIFT;
273 BTDBG("offset: 0x%08lx, page: %p, request: %p, usr_idx: %d, "
274 "seg: %d, kvaddr: 0x%08lx, khandle: %u, uvaddr: "
275 "0x%08lx, handle: %u\n", offset, map[offset], request,
276 usr_idx, i, kvaddr, khandle->kernel, uvaddr,
281 ClearPageReserved(map[offset]);
282 if (PageBlkback(page)) {
283 ClearPageBlkback(page);
284 set_page_private(page, 0);
286 xen_feature(XENFEAT_auto_translated_physmap)) {
287 self_gref[self_gref_nr] = khandle->kernel;
293 khandle->kernel = INVALID_GRANT_HANDLE;
294 khandle->user = INVALID_GRANT_HANDLE;
298 ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
303 if (!xen_feature(XENFEAT_auto_translated_physmap))
304 zap_page_range(ring->vma,
305 MMAP_VADDR(ring->user_vstart, usr_idx, 0),
306 request->nr_pages << PAGE_SHIFT, NULL);
308 for (i = 0; i < self_gref_nr; i++) {
309 gnttab_end_foreign_access_ref(self_gref[i]);
315 * tap->tap_sem held on entry
318 blktap_unmap(struct blktap *tap, struct blktap_request *request)
321 unsigned long kvaddr;
323 usr_idx = request->usr_idx;
324 down_write(&tap->ring.vma->vm_mm->mmap_sem);
326 for (i = 0; i < request->nr_pages; i++) {
327 kvaddr = request_to_kaddr(request, i);
328 BTDBG("request: %p, seg: %d, kvaddr: 0x%08lx, khandle: %u, "
329 "uvaddr: 0x%08lx, uhandle: %u\n", request, i,
330 kvaddr, request->handles[i].kernel,
331 MMAP_VADDR(tap->ring.user_vstart, usr_idx, i),
332 request->handles[i].user);
334 if (!xen_feature(XENFEAT_auto_translated_physmap) &&
335 request->handles[i].kernel == INVALID_GRANT_HANDLE) {
336 if (blktap_umap_uaddr(NULL, kvaddr) == 0)
337 flush_tlb_kernel_page(kvaddr);
338 set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
343 blktap_device_fast_flush(tap, request);
344 up_write(&tap->ring.vma->vm_mm->mmap_sem);
348 * called if the tapdisk process dies unexpectedly.
349 * fail and release any pending requests and disable queue.
352 blktap_device_fail_pending_requests(struct blktap *tap)
356 struct blktap_device *dev;
357 struct blktap_request *request;
359 if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse))
362 down_write(&tap->tap_sem);
365 for (usr_idx = 0; usr_idx < MAX_PENDING_REQS; usr_idx++) {
366 request = tap->pending_requests[usr_idx];
367 if (!request || request->status != BLKTAP_REQUEST_PENDING)
370 BTERR("%u:%u: failing pending %s of %d pages\n",
371 blktap_device_major, tap->minor,
372 (request->operation == BLKIF_OP_PACKET ?
373 "packet" : request->operation == BLKIF_OP_READ ?
374 "read" : "write"), request->nr_pages);
376 blktap_unmap(tap, request);
377 req = (struct request *)(unsigned long)request->id;
378 blk_end_request_all(req, -ENODEV);
379 blktap_request_free(tap, request);
382 up_write(&tap->tap_sem);
384 spin_lock_irq(&dev->lock);
386 /* fail any future requests */
387 dev->gd->queue->queuedata = NULL;
388 blk_start_queue(dev->gd->queue);
390 spin_unlock_irq(&dev->lock);
394 * tap->tap_sem held on entry
397 blktap_device_finish_request(struct blktap *tap,
398 blkif_response_t *res,
399 struct blktap_request *request)
403 blktap_unmap(tap, request);
405 req = (struct request *)(unsigned long)request->id;
407 BTDBG("req %p res status %d operation %d/%d id %lld\n", req,
408 res->status, res->operation, request->operation,
409 (unsigned long long)res->id);
411 switch (request->operation) {
414 case BLKIF_OP_PACKET:
415 if (unlikely(res->status != BLKIF_RSP_OKAY))
416 BTERR("Bad return from device data "
417 "request: %x\n", res->status);
418 blk_end_request_all(req,
419 res->status == BLKIF_RSP_OKAY ? 0 : -EIO);
425 blktap_request_free(tap, request);
429 blktap_prep_foreign(struct blktap *tap,
430 struct blktap_request *request,
431 blkif_request_t *blkif_req,
432 unsigned int seg, struct page *page,
433 struct blktap_grant_table *table)
437 struct page *tap_page;
438 struct blktap_ring *ring;
439 struct blkback_pagemap map;
440 unsigned long uvaddr, kvaddr;
443 map = blkback_pagemap_read(page);
444 blkif_req->seg[seg].gref = map.gref;
446 uvaddr = MMAP_VADDR(ring->user_vstart, request->usr_idx, seg);
447 kvaddr = request_to_kaddr(request, seg);
448 flags = GNTMAP_host_map |
449 (request->operation == BLKIF_OP_WRITE ? GNTMAP_readonly : 0);
451 gnttab_set_map_op(&table->grants[table->cnt],
452 kvaddr, flags, map.gref, map.domid);
455 /* enable chained tap devices */
456 tap_page = request_to_page(request, seg);
457 set_page_private(tap_page, page_private(page));
458 SetPageBlkback(tap_page);
460 if (xen_feature(XENFEAT_auto_translated_physmap))
463 if (create_lookup_pte_addr(ring->vma->vm_mm, uvaddr, &ptep)) {
464 BTERR("couldn't get a pte addr!\n");
468 flags |= GNTMAP_application_map | GNTMAP_contains_pte;
469 gnttab_set_map_op(&table->grants[table->cnt],
470 ptep, flags, map.gref, map.domid);
477 blktap_map_foreign(struct blktap *tap,
478 struct blktap_request *request,
479 blkif_request_t *blkif_req,
480 struct blktap_grant_table *table)
483 int i, grant, err, usr_idx;
484 struct blktap_ring *ring;
485 unsigned long uvaddr, foreign_mfn;
490 err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
491 table->grants, table->cnt);
495 usr_idx = request->usr_idx;
498 for (i = 0; i < request->nr_pages; i++) {
499 if (!blkif_req->seg[i].gref)
502 uvaddr = MMAP_VADDR(ring->user_vstart, usr_idx, i);
504 if (unlikely(table->grants[grant].status)) {
505 BTERR("invalid kernel buffer: could not remap it\n");
506 /* This should never happen: blkback should handle eagain first */
507 BUG_ON(table->grants[grant].status == GNTST_eagain);
509 table->grants[grant].handle = INVALID_GRANT_HANDLE;
512 request->handles[i].kernel = table->grants[grant].handle;
513 foreign_mfn = table->grants[grant].dev_bus_addr >> PAGE_SHIFT;
516 if (xen_feature(XENFEAT_auto_translated_physmap))
519 if (unlikely(table->grants[grant].status)) {
520 BTERR("invalid user buffer: could not remap it\n");
522 table->grants[grant].handle = INVALID_GRANT_HANDLE;
525 request->handles[i].user = table->grants[grant].handle;
532 page = request_to_page(request, i);
534 if (!xen_feature(XENFEAT_auto_translated_physmap))
535 set_phys_to_machine(page_to_pfn(page),
536 FOREIGN_FRAME(foreign_mfn));
537 else if (vm_insert_page(ring->vma, uvaddr, page))
540 BTDBG("pending_req: %p, seg: %d, page: %p, "
541 "kvaddr: 0x%p, khandle: %u, uvaddr: 0x%08lx, "
542 "uhandle: %u\n", request, i, page,
543 pfn_to_kaddr(page_to_pfn(page)),
544 request->handles[i].kernel,
545 uvaddr, request->handles[i].user);
552 blktap_map(struct blktap *tap,
553 struct blktap_request *request,
554 unsigned int seg, struct page *page)
558 struct blktap_ring *ring;
559 unsigned long uvaddr, kvaddr;
563 usr_idx = request->usr_idx;
564 uvaddr = MMAP_VADDR(ring->user_vstart, usr_idx, seg);
565 kvaddr = request_to_kaddr(request, seg);
567 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
568 pte = mk_pte(page, ring->vma->vm_page_prot);
569 blktap_map_uaddr(ring->vma, uvaddr,
570 pte_mkspecial(pte_mkwrite(pte)));
571 flush_tlb_page(ring->vma, uvaddr);
572 blktap_map_uaddr(NULL, kvaddr, mk_pte(page, PAGE_KERNEL));
573 flush_tlb_kernel_page(kvaddr);
575 set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT, pte_mfn(pte));
576 request->handles[seg].kernel = INVALID_GRANT_HANDLE;
578 /* grant this page access to self domain and map it. */
579 domid_t domid = 0; /* XXX my domian id: grant table hypercall
580 doesn't understand DOMID_SELF */
583 struct gnttab_map_grant_ref map;
584 struct page *tap_page;
586 gref = gnttab_grant_foreign_access(
587 domid, page_to_pfn(page),
588 (request->operation == BLKIF_OP_WRITE)?
591 flags = GNTMAP_host_map |
592 (request->operation == BLKIF_OP_WRITE ?
593 GNTMAP_readonly : 0);
595 gnttab_set_map_op(&map, kvaddr, flags, gref, domid);
597 /* enable chained tap devices */
598 tap_page = request_to_page(request, seg);
599 set_page_private(tap_page, page_private(page));
600 SetPageBlkback(tap_page);
602 err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
605 /* We are not expecting the grant op to fail */
606 BUG_ON(map.status != GNTST_okay);
608 err = vm_insert_page(ring->vma, uvaddr, tap_page);
610 struct gnttab_unmap_grant_ref unmap;
611 gnttab_set_unmap_op(&unmap, kvaddr,
612 GNTMAP_host_map, gref);
613 VOID(HYPERVISOR_grant_table_op(
614 GNTTABOP_unmap_grant_ref, &unmap, 1));
616 request->handles[seg].kernel = gref;
618 request->handles[seg].user = INVALID_GRANT_HANDLE;
620 BTDBG("pending_req: %p, seg: %d, page: %p, kvaddr: 0x%08lx, "
621 "uvaddr: 0x%08lx\n", request, seg, page, kvaddr,
628 blktap_device_process_request(struct blktap *tap,
629 struct blktap_request *request,
634 struct blktap_ring *ring;
635 struct scatterlist *sg;
636 struct blktap_grant_table table;
637 unsigned int fsect, lsect, nr_sects;
638 unsigned long offset, uvaddr;
639 struct blkif_request blkif_req, *target;
642 memset(&table, 0, sizeof(table));
644 if (!blktap_active(tap))
648 usr_idx = request->usr_idx;
649 blkif_req.id = usr_idx;
650 blkif_req.sector_number = (blkif_sector_t)blk_rq_pos(req);
651 blkif_req.handle = 0;
652 blkif_req.operation = rq_data_dir(req) ?
653 BLKIF_OP_WRITE : BLKIF_OP_READ;
654 if (unlikely(blk_pc_request(req)))
655 blkif_req.operation = BLKIF_OP_PACKET;
657 request->id = (unsigned long)req;
658 request->operation = blkif_req.operation;
659 request->status = BLKTAP_REQUEST_PENDING;
660 do_gettimeofday(&request->time);
663 request->nr_pages = 0;
664 blkif_req.nr_segments = blk_rq_map_sg(req->q, req, tap->sg);
665 BUG_ON(blkif_req.nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
666 for_each_sg(tap->sg, sg, blkif_req.nr_segments, i) {
667 fsect = sg->offset >> 9;
668 lsect = fsect + (sg->length >> 9) - 1;
669 nr_sects += sg->length >> 9;
672 (struct blkif_request_segment) {
675 .last_sect = lsect };
677 if (PageBlkback(sg_page(sg))) {
678 /* foreign page -- use xen */
679 if (blktap_prep_foreign(tap,
687 /* do it the old fashioned way */
695 uvaddr = MMAP_VADDR(ring->user_vstart, usr_idx, i);
696 offset = (uvaddr - ring->vma->vm_start) >> PAGE_SHIFT;
697 page = request_to_page(request, i);
698 ring->foreign_map.map[offset] = page;
699 SetPageReserved(page);
701 BTDBG("mapped uaddr %08lx to page %p pfn 0x%lx\n",
702 uvaddr, page, page_to_pfn(page));
703 BTDBG("offset: 0x%08lx, pending_req: %p, seg: %d, "
704 "page: %p, kvaddr: %p, uvaddr: 0x%08lx\n",
706 page, pfn_to_kaddr(page_to_pfn(page)), uvaddr);
711 if (blktap_map_foreign(tap, request, &blkif_req, &table))
714 /* Finally, write the request message to the user ring. */
715 target = RING_GET_REQUEST(&ring->ring, ring->ring.req_prod_pvt);
716 memcpy(target, &blkif_req, sizeof(blkif_req));
717 target->id = request->usr_idx;
718 wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
719 ring->ring.req_prod_pvt++;
721 if (unlikely(blk_pc_request(req)))
722 tap->stats.st_pk_req++;
723 else if (rq_data_dir(req)) {
724 tap->stats.st_wr_sect += nr_sects;
725 tap->stats.st_wr_req++;
727 tap->stats.st_rd_sect += nr_sects;
728 tap->stats.st_rd_req++;
735 blktap_device_fast_flush(tap, request);
739 #ifdef ENABLE_PASSTHROUGH
740 #define rq_for_each_bio_safe(_bio, _tmp, _req) \
742 for (_bio = (_req)->bio; \
743 _bio && ((_tmp = _bio->bi_next) || 1); \
747 blktap_device_forward_request(struct blktap *tap, struct request *req)
749 struct bio *bio, *tmp;
750 struct blktap_device *dev;
754 rq_for_each_bio_safe(bio, tmp, req) {
755 bio->bi_bdev = dev->bdev;
756 submit_bio(bio->bi_rw, bio);
761 blktap_device_close_bdev(struct blktap *tap)
763 struct blktap_device *dev;
768 blkdev_put(dev->bdev);
771 clear_bit(BLKTAP_PASSTHROUGH, &tap->dev_inuse);
775 blktap_device_open_bdev(struct blktap *tap, u32 pdev)
777 struct block_device *bdev;
778 struct blktap_device *dev;
782 bdev = open_by_devnum(pdev, FMODE_WRITE);
784 BTERR("opening device %x:%x failed: %ld\n",
785 MAJOR(pdev), MINOR(pdev), PTR_ERR(bdev));
786 return PTR_ERR(bdev);
789 if (!bdev->bd_disk) {
790 BTERR("device %x:%x doesn't exist\n",
791 MAJOR(pdev), MINOR(pdev));
792 blkdev_put(dev->bdev);
797 set_bit(BLKTAP_PASSTHROUGH, &tap->dev_inuse);
799 /* TODO: readjust queue parameters */
801 BTINFO("set device %d to passthrough on %x:%x\n",
802 tap->minor, MAJOR(pdev), MINOR(pdev));
808 blktap_device_enable_passthrough(struct blktap *tap,
809 unsigned major, unsigned minor)
812 struct blktap_device *dev;
815 pdev = MKDEV(major, minor);
817 if (!test_bit(BLKTAP_PAUSED, &tap->dev_inuse))
823 blktap_device_close_bdev(tap);
827 return blktap_device_open_bdev(tap, pdev);
832 * dev->lock held on entry
835 blktap_device_run_queue(struct blktap *tap)
838 struct request_queue *rq;
840 struct blktap_ring *ring;
841 struct blktap_device *dev;
842 struct blktap_request *request;
849 BTDBG("running queue for %d\n", tap->minor);
851 while ((req = blk_peek_request(rq)) != NULL) {
852 if (RING_FULL(&ring->ring)) {
854 /* Avoid pointless unplugs. */
860 blk_start_request(req);
862 if (!blk_fs_request(req)) {
863 __blk_end_request_all(req, -EIO);
867 if (blk_barrier_rq(req)) {
868 __blk_end_request_all(req, -EOPNOTSUPP);
872 #ifdef ENABLE_PASSTHROUGH
873 if (test_bit(BLKTAP_PASSTHROUGH, &tap->dev_inuse)) {
874 blktap_device_forward_request(tap, req);
879 request = blktap_request_allocate(tap);
881 tap->stats.st_oo_req++;
885 BTDBG("req %p: dev %d cmd %p, sec 0x%llx, (0x%x/0x%x) "
886 "buffer:%p [%s], pending: %p\n", req, tap->minor,
887 req->cmd, (unsigned long long)blk_rq_pos(req),
888 blk_rq_cur_sectors(req), blk_rq_sectors(req), req->buffer,
889 rq_data_dir(req) ? "write" : "read", request);
891 spin_unlock_irq(&dev->lock);
892 down_read(&tap->tap_sem);
894 err = blktap_device_process_request(tap, request, req);
898 blk_end_request_all(req, err);
899 blktap_request_free(tap, request);
902 up_read(&tap->tap_sem);
903 spin_lock_irq(&dev->lock);
907 blktap_ring_kick_user(tap);
911 * dev->lock held on entry
914 blktap_device_do_request(struct request_queue *rq)
918 struct blktap_device *dev;
924 tap = dev_to_blktap(dev);
925 if (!blktap_active(tap))
928 if (test_bit(BLKTAP_PAUSED, &tap->dev_inuse) ||
929 test_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse)) {
934 blktap_device_run_queue(tap);
938 while ((req = blk_peek_request(rq))) {
939 BTERR("device closed: failing secs %llu - %llu\n",
940 (unsigned long long)blk_rq_pos(req),
941 (unsigned long long)blk_rq_pos(req)
942 + blk_rq_cur_sectors(req));
943 blk_start_request(req);
944 __blk_end_request_all(req, -EIO);
949 blktap_device_restart(struct blktap *tap)
951 struct blktap_device *dev;
955 if (blktap_active(tap) && RING_FULL(&tap->ring.ring)) {
960 if (test_bit(BLKTAP_PAUSED, &tap->dev_inuse) ||
961 test_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse)) {
966 spin_lock_irq(&dev->lock);
968 /* Re-enable calldowns. */
970 struct request_queue *rq = dev->gd->queue;
972 if (blk_queue_stopped(rq))
975 /* Kick things off immediately. */
976 blktap_device_do_request(rq);
979 spin_unlock_irq(&dev->lock);
983 blktap_device_configure(struct blktap *tap)
985 struct request_queue *rq;
986 struct blktap_device *dev = &tap->device;
988 if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse) || !dev->gd)
994 spin_lock_irq(&dev->lock);
996 set_capacity(dev->gd, tap->params.capacity);
998 /* Hard sector size and max sectors impersonate the equiv. hardware. */
999 blk_queue_logical_block_size(rq, tap->params.sector_size);
1000 blk_queue_max_hw_sectors(rq, 512);
1002 /* Each segment in a request is up to an aligned page in size. */
1003 blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
1004 blk_queue_max_segment_size(rq, PAGE_SIZE);
1006 /* Ensure a merged request will fit in a single I/O ring slot. */
1007 blk_queue_max_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
1009 /* Make sure buffer addresses are sector-aligned. */
1010 blk_queue_dma_alignment(rq, 511);
1012 spin_unlock_irq(&dev->lock);
1016 blktap_device_resume(struct blktap *tap)
1020 if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse) || !blktap_active(tap))
1023 if (!test_bit(BLKTAP_PAUSED, &tap->dev_inuse))
1026 err = blktap_ring_resume(tap);
1030 /* device size may have changed */
1031 blktap_device_configure(tap);
1033 BTDBG("restarting device\n");
1034 blktap_device_restart(tap);
1040 blktap_device_pause(struct blktap *tap)
1042 unsigned long flags;
1043 struct blktap_device *dev = &tap->device;
1045 if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse) || !blktap_active(tap))
1048 if (test_bit(BLKTAP_PAUSED, &tap->dev_inuse))
1051 spin_lock_irqsave(&dev->lock, flags);
1053 blk_stop_queue(dev->gd->queue);
1054 set_bit(BLKTAP_PAUSE_REQUESTED, &tap->dev_inuse);
1056 spin_unlock_irqrestore(&dev->lock, flags);
1058 return blktap_ring_pause(tap);
1062 blktap_device_destroy(struct blktap *tap)
1064 struct blktap_device *dev = &tap->device;
1065 struct gendisk *gd = dev->gd;
1067 if (!test_bit(BLKTAP_DEVICE, &tap->dev_inuse))
1070 BTINFO("destroy device %d users %d\n", tap->minor, dev->users);
1075 spin_lock_irq(&dev->lock);
1076 /* No more blktap_device_do_request(). */
1077 blk_stop_queue(gd->queue);
1078 clear_bit(BLKTAP_DEVICE, &tap->dev_inuse);
1080 spin_unlock_irq(&dev->lock);
1082 #ifdef ENABLE_PASSTHROUGH
1084 blktap_device_close_bdev(tap);
1088 blk_cleanup_queue(gd->queue);
1097 blktap_device_create(struct blktap *tap)
1101 struct request_queue *rq;
1102 struct blktap_device *dev;
1109 if (test_bit(BLKTAP_DEVICE, &tap->dev_inuse))
1112 if (blktap_validate_params(tap, &tap->params))
1115 BTINFO("minor %d sectors %Lu sector-size %lu\n",
1116 minor, tap->params.capacity, tap->params.sector_size);
1125 sprintf(gd->disk_name, "tapdev%c", 'a' + minor);
1127 sprintf(gd->disk_name, "tapdev%c%c",
1128 'a' + ((minor / 26) - 1), 'a' + (minor % 26));
1130 gd->major = blktap_device_major;
1131 gd->first_minor = minor;
1132 gd->fops = &blktap_device_file_operations;
1133 gd->private_data = dev;
1135 spin_lock_init(&dev->lock);
1136 rq = blk_init_queue(blktap_device_do_request, &dev->lock);
1140 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
1141 elevator_init(rq, "noop");
1143 elevator_init(rq, &elevator_noop);
1147 rq->queuedata = dev;
1150 set_bit(BLKTAP_DEVICE, &tap->dev_inuse);
1151 blktap_device_configure(tap);
1162 blk_cleanup_queue(rq);
1165 BTINFO("creation of %u:%u: %d\n", blktap_device_major, tap->minor, err);
1170 blktap_device_init(int *maj)
1174 /* Dynamically allocate a major for this device */
1175 major = register_blkdev(0, "tapdev");
1177 BTERR("Couldn't register blktap device\n");
1181 blktap_device_major = *maj = major;
1182 BTINFO("blktap device major %d\n", major);
1188 blktap_device_free(void)
1190 if (blktap_device_major)
1191 unregister_blkdev(blktap_device_major, "tapdev");