aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_req.c2
-rw-r--r--drivers/block/drbd/drbd_req.h1
-rw-r--r--drivers/block/drbd/drbd_state.c7
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c24
-rw-r--r--drivers/block/virtio_blk.c7
-rw-r--r--drivers/block/xen-blkback/blkback.c25
-rw-r--r--drivers/block/xen-blkback/xenbus.c49
-rw-r--r--drivers/block/xen-blkfront.c21
8 files changed, 87 insertions, 49 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index f58a4a4b4dfb..2b8303ad63c9 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -168,7 +168,7 @@ static void wake_all_senders(struct drbd_tconn *tconn) {
168} 168}
169 169
170/* must hold resource->req_lock */ 170/* must hold resource->req_lock */
171static void start_new_tl_epoch(struct drbd_tconn *tconn) 171void start_new_tl_epoch(struct drbd_tconn *tconn)
172{ 172{
173 /* no point closing an epoch, if it is empty, anyways. */ 173 /* no point closing an epoch, if it is empty, anyways. */
174 if (tconn->current_tle_writes == 0) 174 if (tconn->current_tle_writes == 0)
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 016de6b8bb57..c08d22964d06 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -267,6 +267,7 @@ struct bio_and_error {
267 int error; 267 int error;
268}; 268};
269 269
270extern void start_new_tl_epoch(struct drbd_tconn *tconn);
270extern void drbd_req_destroy(struct kref *kref); 271extern void drbd_req_destroy(struct kref *kref);
271extern void _req_may_be_done(struct drbd_request *req, 272extern void _req_may_be_done(struct drbd_request *req,
272 struct bio_and_error *m); 273 struct bio_and_error *m);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 53bf6182bac4..0fe220cfb9e9 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -931,6 +931,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
931 enum drbd_state_rv rv = SS_SUCCESS; 931 enum drbd_state_rv rv = SS_SUCCESS;
932 enum sanitize_state_warnings ssw; 932 enum sanitize_state_warnings ssw;
933 struct after_state_chg_work *ascw; 933 struct after_state_chg_work *ascw;
934 bool did_remote, should_do_remote;
934 935
935 os = drbd_read_state(mdev); 936 os = drbd_read_state(mdev);
936 937
@@ -981,11 +982,17 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
981 (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) 982 (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
982 atomic_inc(&mdev->local_cnt); 983 atomic_inc(&mdev->local_cnt);
983 984
985 did_remote = drbd_should_do_remote(mdev->state);
984 mdev->state.i = ns.i; 986 mdev->state.i = ns.i;
987 should_do_remote = drbd_should_do_remote(mdev->state);
985 mdev->tconn->susp = ns.susp; 988 mdev->tconn->susp = ns.susp;
986 mdev->tconn->susp_nod = ns.susp_nod; 989 mdev->tconn->susp_nod = ns.susp_nod;
987 mdev->tconn->susp_fen = ns.susp_fen; 990 mdev->tconn->susp_fen = ns.susp_fen;
988 991
992 /* put replicated vs not-replicated requests in seperate epochs */
993 if (did_remote != should_do_remote)
994 start_new_tl_epoch(mdev->tconn);
995
989 if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) 996 if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING)
990 drbd_print_uuids(mdev, "attached to UUIDs"); 997 drbd_print_uuids(mdev, "attached to UUIDs");
991 998
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 9790666f90f2..11cc9522cdd4 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -629,12 +629,13 @@ static void mtip_timeout_function(unsigned long int data)
629 } 629 }
630 } 630 }
631 631
632 if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { 632 if (cmdto_cnt) {
633 print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); 633 print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
634 634 if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
635 mtip_restart_port(port); 635 mtip_restart_port(port);
636 wake_up_interruptible(&port->svc_wait);
637 }
636 clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); 638 clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
637 wake_up_interruptible(&port->svc_wait);
638 } 639 }
639 640
640 if (port->ic_pause_timer) { 641 if (port->ic_pause_timer) {
@@ -4017,7 +4018,12 @@ static int mtip_block_remove(struct driver_data *dd)
4017 * Delete our gendisk structure. This also removes the device 4018 * Delete our gendisk structure. This also removes the device
4018 * from /dev 4019 * from /dev
4019 */ 4020 */
4020 del_gendisk(dd->disk); 4021 if (dd->disk) {
4022 if (dd->disk->queue)
4023 del_gendisk(dd->disk);
4024 else
4025 put_disk(dd->disk);
4026 }
4021 4027
4022 spin_lock(&rssd_index_lock); 4028 spin_lock(&rssd_index_lock);
4023 ida_remove(&rssd_index_ida, dd->index); 4029 ida_remove(&rssd_index_ida, dd->index);
@@ -4051,7 +4057,13 @@ static int mtip_block_shutdown(struct driver_data *dd)
4051 "Shutting down %s ...\n", dd->disk->disk_name); 4057 "Shutting down %s ...\n", dd->disk->disk_name);
4052 4058
4053 /* Delete our gendisk structure, and cleanup the blk queue. */ 4059 /* Delete our gendisk structure, and cleanup the blk queue. */
4054 del_gendisk(dd->disk); 4060 if (dd->disk) {
4061 if (dd->disk->queue)
4062 del_gendisk(dd->disk);
4063 else
4064 put_disk(dd->disk);
4065 }
4066
4055 4067
4056 spin_lock(&rssd_index_lock); 4068 spin_lock(&rssd_index_lock);
4057 ida_remove(&rssd_index_ida, dd->index); 4069 ida_remove(&rssd_index_ida, dd->index);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 9d8409c02082..8ad21a25bc0d 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -889,6 +889,7 @@ static void virtblk_remove(struct virtio_device *vdev)
889{ 889{
890 struct virtio_blk *vblk = vdev->priv; 890 struct virtio_blk *vblk = vdev->priv;
891 int index = vblk->index; 891 int index = vblk->index;
892 int refc;
892 893
893 /* Prevent config work handler from accessing the device. */ 894 /* Prevent config work handler from accessing the device. */
894 mutex_lock(&vblk->config_lock); 895 mutex_lock(&vblk->config_lock);
@@ -903,11 +904,15 @@ static void virtblk_remove(struct virtio_device *vdev)
903 904
904 flush_work(&vblk->config_work); 905 flush_work(&vblk->config_work);
905 906
907 refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount);
906 put_disk(vblk->disk); 908 put_disk(vblk->disk);
907 mempool_destroy(vblk->pool); 909 mempool_destroy(vblk->pool);
908 vdev->config->del_vqs(vdev); 910 vdev->config->del_vqs(vdev);
909 kfree(vblk); 911 kfree(vblk);
910 ida_simple_remove(&vd_index_ida, index); 912
913 /* Only free device id if we don't have any users */
914 if (refc == 1)
915 ida_simple_remove(&vd_index_ida, index);
911} 916}
912 917
913#ifdef CONFIG_PM 918#ifdef CONFIG_PM
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 74374fb762aa..de1f319f7bd7 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -46,6 +46,7 @@
46#include <xen/xen.h> 46#include <xen/xen.h>
47#include <asm/xen/hypervisor.h> 47#include <asm/xen/hypervisor.h>
48#include <asm/xen/hypercall.h> 48#include <asm/xen/hypercall.h>
49#include <xen/balloon.h>
49#include "common.h" 50#include "common.h"
50 51
51/* 52/*
@@ -161,10 +162,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
161static void make_response(struct xen_blkif *blkif, u64 id, 162static void make_response(struct xen_blkif *blkif, u64 id,
162 unsigned short op, int st); 163 unsigned short op, int st);
163 164
164#define foreach_grant(pos, rbtree, node) \ 165#define foreach_grant_safe(pos, n, rbtree, node) \
165 for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node); \ 166 for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \
167 (n) = rb_next(&(pos)->node); \
166 &(pos)->node != NULL; \ 168 &(pos)->node != NULL; \
167 (pos) = container_of(rb_next(&(pos)->node), typeof(*(pos)), node)) 169 (pos) = container_of(n, typeof(*(pos)), node), \
170 (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
168 171
169 172
170static void add_persistent_gnt(struct rb_root *root, 173static void add_persistent_gnt(struct rb_root *root,
@@ -217,10 +220,11 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
217 struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 220 struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
218 struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 221 struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
219 struct persistent_gnt *persistent_gnt; 222 struct persistent_gnt *persistent_gnt;
223 struct rb_node *n;
220 int ret = 0; 224 int ret = 0;
221 int segs_to_unmap = 0; 225 int segs_to_unmap = 0;
222 226
223 foreach_grant(persistent_gnt, root, node) { 227 foreach_grant_safe(persistent_gnt, n, root, node) {
224 BUG_ON(persistent_gnt->handle == 228 BUG_ON(persistent_gnt->handle ==
225 BLKBACK_INVALID_HANDLE); 229 BLKBACK_INVALID_HANDLE);
226 gnttab_set_unmap_op(&unmap[segs_to_unmap], 230 gnttab_set_unmap_op(&unmap[segs_to_unmap],
@@ -230,17 +234,19 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
230 persistent_gnt->handle); 234 persistent_gnt->handle);
231 235
232 pages[segs_to_unmap] = persistent_gnt->page; 236 pages[segs_to_unmap] = persistent_gnt->page;
233 rb_erase(&persistent_gnt->node, root);
234 kfree(persistent_gnt);
235 num--;
236 237
237 if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || 238 if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST ||
238 !rb_next(&persistent_gnt->node)) { 239 !rb_next(&persistent_gnt->node)) {
239 ret = gnttab_unmap_refs(unmap, NULL, pages, 240 ret = gnttab_unmap_refs(unmap, NULL, pages,
240 segs_to_unmap); 241 segs_to_unmap);
241 BUG_ON(ret); 242 BUG_ON(ret);
243 free_xenballooned_pages(segs_to_unmap, pages);
242 segs_to_unmap = 0; 244 segs_to_unmap = 0;
243 } 245 }
246
247 rb_erase(&persistent_gnt->node, root);
248 kfree(persistent_gnt);
249 num--;
244 } 250 }
245 BUG_ON(num != 0); 251 BUG_ON(num != 0);
246} 252}
@@ -523,8 +529,8 @@ static int xen_blkbk_map(struct blkif_request *req,
523 GFP_KERNEL); 529 GFP_KERNEL);
524 if (!persistent_gnt) 530 if (!persistent_gnt)
525 return -ENOMEM; 531 return -ENOMEM;
526 persistent_gnt->page = alloc_page(GFP_KERNEL); 532 if (alloc_xenballooned_pages(1, &persistent_gnt->page,
527 if (!persistent_gnt->page) { 533 false)) {
528 kfree(persistent_gnt); 534 kfree(persistent_gnt);
529 return -ENOMEM; 535 return -ENOMEM;
530 } 536 }
@@ -875,7 +881,6 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
875 goto fail_response; 881 goto fail_response;
876 } 882 }
877 883
878 preq.dev = req->u.rw.handle;
879 preq.sector_number = req->u.rw.sector_number; 884 preq.sector_number = req->u.rw.sector_number;
880 preq.nr_sects = 0; 885 preq.nr_sects = 0;
881 886
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 63980722db41..5e237f630c47 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -367,6 +367,7 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
367 be->blkif = NULL; 367 be->blkif = NULL;
368 } 368 }
369 369
370 kfree(be->mode);
370 kfree(be); 371 kfree(be);
371 dev_set_drvdata(&dev->dev, NULL); 372 dev_set_drvdata(&dev->dev, NULL);
372 return 0; 373 return 0;
@@ -502,6 +503,7 @@ static void backend_changed(struct xenbus_watch *watch,
502 = container_of(watch, struct backend_info, backend_watch); 503 = container_of(watch, struct backend_info, backend_watch);
503 struct xenbus_device *dev = be->dev; 504 struct xenbus_device *dev = be->dev;
504 int cdrom = 0; 505 int cdrom = 0;
506 unsigned long handle;
505 char *device_type; 507 char *device_type;
506 508
507 DPRINTK(""); 509 DPRINTK("");
@@ -521,10 +523,10 @@ static void backend_changed(struct xenbus_watch *watch,
521 return; 523 return;
522 } 524 }
523 525
524 if ((be->major || be->minor) && 526 if (be->major | be->minor) {
525 ((be->major != major) || (be->minor != minor))) { 527 if (be->major != major || be->minor != minor)
526 pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", 528 pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
527 be->major, be->minor, major, minor); 529 be->major, be->minor, major, minor);
528 return; 530 return;
529 } 531 }
530 532
@@ -542,36 +544,33 @@ static void backend_changed(struct xenbus_watch *watch,
542 kfree(device_type); 544 kfree(device_type);
543 } 545 }
544 546
545 if (be->major == 0 && be->minor == 0) { 547 /* Front end dir is a number, which is used as the handle. */
546 /* Front end dir is a number, which is used as the handle. */ 548 err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle);
547 549 if (err)
548 char *p = strrchr(dev->otherend, '/') + 1; 550 return;
549 long handle;
550 err = strict_strtoul(p, 0, &handle);
551 if (err)
552 return;
553 551
554 be->major = major; 552 be->major = major;
555 be->minor = minor; 553 be->minor = minor;
556 554
557 err = xen_vbd_create(be->blkif, handle, major, minor, 555 err = xen_vbd_create(be->blkif, handle, major, minor,
558 (NULL == strchr(be->mode, 'w')), cdrom); 556 !strchr(be->mode, 'w'), cdrom);
559 if (err) {
560 be->major = 0;
561 be->minor = 0;
562 xenbus_dev_fatal(dev, err, "creating vbd structure");
563 return;
564 }
565 557
558 if (err)
559 xenbus_dev_fatal(dev, err, "creating vbd structure");
560 else {
566 err = xenvbd_sysfs_addif(dev); 561 err = xenvbd_sysfs_addif(dev);
567 if (err) { 562 if (err) {
568 xen_vbd_free(&be->blkif->vbd); 563 xen_vbd_free(&be->blkif->vbd);
569 be->major = 0;
570 be->minor = 0;
571 xenbus_dev_fatal(dev, err, "creating sysfs entries"); 564 xenbus_dev_fatal(dev, err, "creating sysfs entries");
572 return;
573 } 565 }
566 }
574 567
568 if (err) {
569 kfree(be->mode);
570 be->mode = NULL;
571 be->major = 0;
572 be->minor = 0;
573 } else {
575 /* We're potentially connected now */ 574 /* We're potentially connected now */
576 xen_update_blkif_status(be->blkif); 575 xen_update_blkif_status(be->blkif);
577 } 576 }
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 96e9b00db081..c3dae2e0f290 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -791,7 +791,8 @@ static void blkif_restart_queue(struct work_struct *work)
791static void blkif_free(struct blkfront_info *info, int suspend) 791static void blkif_free(struct blkfront_info *info, int suspend)
792{ 792{
793 struct llist_node *all_gnts; 793 struct llist_node *all_gnts;
794 struct grant *persistent_gnt; 794 struct grant *persistent_gnt, *tmp;
795 struct llist_node *n;
795 796
796 /* Prevent new requests being issued until we fix things up. */ 797 /* Prevent new requests being issued until we fix things up. */
797 spin_lock_irq(&info->io_lock); 798 spin_lock_irq(&info->io_lock);
@@ -804,10 +805,17 @@ static void blkif_free(struct blkfront_info *info, int suspend)
804 /* Remove all persistent grants */ 805 /* Remove all persistent grants */
805 if (info->persistent_gnts_c) { 806 if (info->persistent_gnts_c) {
806 all_gnts = llist_del_all(&info->persistent_gnts); 807 all_gnts = llist_del_all(&info->persistent_gnts);
807 llist_for_each_entry(persistent_gnt, all_gnts, node) { 808 persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node);
809 while (persistent_gnt) {
808 gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); 810 gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
809 __free_page(pfn_to_page(persistent_gnt->pfn)); 811 __free_page(pfn_to_page(persistent_gnt->pfn));
810 kfree(persistent_gnt); 812 tmp = persistent_gnt;
813 n = persistent_gnt->node.next;
814 if (n)
815 persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node);
816 else
817 persistent_gnt = NULL;
818 kfree(tmp);
811 } 819 }
812 info->persistent_gnts_c = 0; 820 info->persistent_gnts_c = 0;
813 } 821 }
@@ -835,7 +843,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
835static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, 843static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
836 struct blkif_response *bret) 844 struct blkif_response *bret)
837{ 845{
838 int i; 846 int i = 0;
839 struct bio_vec *bvec; 847 struct bio_vec *bvec;
840 struct req_iterator iter; 848 struct req_iterator iter;
841 unsigned long flags; 849 unsigned long flags;
@@ -852,7 +860,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
852 */ 860 */
853 rq_for_each_segment(bvec, s->request, iter) { 861 rq_for_each_segment(bvec, s->request, iter) {
854 BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE); 862 BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
855 i = offset >> PAGE_SHIFT; 863 if (bvec->bv_offset < offset)
864 i++;
856 BUG_ON(i >= s->req.u.rw.nr_segments); 865 BUG_ON(i >= s->req.u.rw.nr_segments);
857 shared_data = kmap_atomic( 866 shared_data = kmap_atomic(
858 pfn_to_page(s->grants_used[i]->pfn)); 867 pfn_to_page(s->grants_used[i]->pfn));
@@ -861,7 +870,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
861 bvec->bv_len); 870 bvec->bv_len);
862 bvec_kunmap_irq(bvec_data, &flags); 871 bvec_kunmap_irq(bvec_data, &flags);
863 kunmap_atomic(shared_data); 872 kunmap_atomic(shared_data);
864 offset += bvec->bv_len; 873 offset = bvec->bv_offset + bvec->bv_len;
865 } 874 }
866 } 875 }
867 /* Add the persistent grant into the list of free grants */ 876 /* Add the persistent grant into the list of free grants */