diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.h | 2 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_bitmap.c | 37 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 7 | ||||
-rw-r--r-- | drivers/block/hd.c | 2 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 2 | ||||
-rw-r--r-- | drivers/block/rbd.c | 46 | ||||
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 37 | ||||
-rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 2 | ||||
-rw-r--r-- | drivers/block/xsysace.c | 98 |
12 files changed, 117 insertions, 126 deletions
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 16b4d58d84dd..c049548e68b7 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -223,7 +223,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) h->ctlr, c->busaddr); #endif /* CCISS_DEBUG */ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); - readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); + readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); h->commands_outstanding++; if ( h->commands_outstanding > h->max_outstanding) h->max_outstanding = h->commands_outstanding; diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 696100241a6f..951a4e33b92b 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -33,7 +33,7 @@ #include <linux/slab.h> #include <linux/string.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 09ef9a878ef0..cf0e63dd97da 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -79,7 +79,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, md_io.error = 0; if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) - rw |= REQ_FUA; + rw |= REQ_FUA | REQ_FLUSH; rw |= REQ_SYNC; bio = bio_alloc(GFP_NOIO, 1); diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index f440a02dfdb1..7b976296b564 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -112,9 +112,6 @@ struct drbd_bitmap { struct task_struct *bm_task; }; -static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, - unsigned long e, int val, const enum km_type km); - #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) { @@ -994,6 +991,9 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must bio_endio(bio, -EIO); } else { submit_bio(rw, bio); + /* this should not count as user activity and cause the + * resync to throttle -- see drbd_rs_should_slow_down(). */ + atomic_add(len >> 9, &mdev->rs_sect_ev); } } @@ -1256,7 +1256,7 @@ unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_f * expected to be called for only a few bits (e - s about BITS_PER_LONG). * Must hold bitmap lock already. */ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, - unsigned long e, int val, const enum km_type km) + unsigned long e, int val) { struct drbd_bitmap *b = mdev->bitmap; unsigned long *p_addr = NULL; @@ -1274,14 +1274,14 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, unsigned int page_nr = bm_bit_to_page_idx(b, bitnr); if (page_nr != last_page_nr) { if (p_addr) - __bm_unmap(p_addr, km); + __bm_unmap(p_addr, KM_IRQ1); if (c < 0) bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); else if (c > 0) bm_set_page_need_writeout(b->bm_pages[last_page_nr]); changed_total += c; c = 0; - p_addr = __bm_map_pidx(b, page_nr, km); + p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1); last_page_nr = page_nr; } if (val) @@ -1290,7 +1290,7 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); } if (p_addr) - __bm_unmap(p_addr, km); + __bm_unmap(p_addr, KM_IRQ1); if (c < 0) bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); else if (c > 0) @@ -1318,7 +1318,7 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags) bm_print_lock_info(mdev); - c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1); + c = __bm_change_bits_to(mdev, s, e, val); spin_unlock_irqrestore(&b->bm_lock, flags); return c; @@ -1343,16 +1343,17 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b, { int i; int bits; - unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0); + unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1); for (i = first_word; i < last_word; i++) { bits = hweight_long(paddr[i]); paddr[i] = ~0UL; b->bm_set += BITS_PER_LONG - bits; } - kunmap_atomic(paddr, KM_USER0); + kunmap_atomic(paddr, KM_IRQ1); } -/* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave. +/* Same thing as drbd_bm_set_bits, + * but more efficient for a large bit range. * You must first drbd_bm_lock(). * Can be called to set the whole bitmap in one go. * Sets bits from s to e _inclusive_. */ @@ -1366,6 +1367,7 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi * Do not use memset, because we must account for changes, * so we need to loop over the words with hweight() anyways. */ + struct drbd_bitmap *b = mdev->bitmap; unsigned long sl = ALIGN(s,BITS_PER_LONG); unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1); int first_page; @@ -1376,15 +1378,19 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi if (e - s <= 3*BITS_PER_LONG) { /* don't bother; el and sl may even be wrong. */ - __bm_change_bits_to(mdev, s, e, 1, KM_USER0); + spin_lock_irq(&b->bm_lock); + __bm_change_bits_to(mdev, s, e, 1); + spin_unlock_irq(&b->bm_lock); return; } /* difference is large enough that we can trust sl and el */ + spin_lock_irq(&b->bm_lock); + /* bits filling the current long */ if (sl) - __bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0); + __bm_change_bits_to(mdev, s, sl-1, 1); first_page = sl >> (3 + PAGE_SHIFT); last_page = el >> (3 + PAGE_SHIFT); @@ -1397,8 +1403,10 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi /* first and full pages, unless first page == last page */ for (page_nr = first_page; page_nr < last_page; page_nr++) { bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word); + spin_unlock_irq(&b->bm_lock); cond_resched(); first_word = 0; + spin_lock_irq(&b->bm_lock); } /* last page (respectively only page, for first page == last page) */ @@ -1411,7 +1419,8 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi * it would trigger an assert in __bm_change_bits_to() */ if (el <= e) - __bm_change_bits_to(mdev, el, e, 1, KM_USER0); + __bm_change_bits_to(mdev, el, e, 1); + spin_unlock_irq(&b->bm_lock); } /* returns bit state diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 25d32c5aa50a..43beaca53179 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4602,6 +4602,11 @@ int drbd_asender(struct drbd_thread *thi) dev_err(DEV, "meta connection shut down by peer.\n"); goto reconnect; } else if (rv == -EAGAIN) { + /* If the data socket received something meanwhile, + * that is good enough: peer is still alive. */ + if (time_after(mdev->last_received, + jiffies - mdev->meta.socket->sk->sk_rcvtimeo)) + continue; if (ping_timeout_active) { dev_err(DEV, "PingAck did not arrive in time.\n"); goto reconnect; @@ -4637,6 +4642,7 @@ int drbd_asender(struct drbd_thread *thi) goto reconnect; } if (received == expect) { + mdev->last_received = jiffies; D_ASSERT(cmd != NULL); if (!cmd->process(mdev, h)) goto reconnect; diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 4d76b06b6b20..4d3e6f6213ba 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -536,12 +536,7 @@ static int w_make_resync_request(struct drbd_conf *mdev, return 1; } - /* starting with drbd 8.3.8, we can handle multi-bio EEs, - * if it should be necessary */ - max_bio_size = - mdev->agreed_pro_version < 94 ? queue_max_hw_sectors(mdev->rq_queue) << 9 : - mdev->agreed_pro_version < 95 ? DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_BIO_SIZE; - + max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9; number = drbd_rs_number_requests(mdev); if (number == 0) goto requeue; diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 007c630904c1..b52c9ca146fc 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -155,7 +155,7 @@ else \ #if (HD_DELAY > 0) -#include <asm/i8253.h> +#include <linux/i8253.h> unsigned long last_req; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 07a382eaf0a8..e133f094ab08 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -1206,7 +1206,7 @@ static int pkt_start_recovery(struct packet_data *pkt) if (!sb) return 0; - if (!sb->s_op || !sb->s_op->relocate_blocks) + if (!sb->s_op->relocate_blocks) goto out; old_block = pkt->sector / (CD_FRAMESIZE >> 9); diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 1278098624e6..15f65b5f3fc7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -630,6 +630,14 @@ static int rbd_get_num_segments(struct rbd_image_header *header, } /* + * returns the size of an object in the image + */ +static u64 rbd_obj_bytes(struct rbd_image_header *header) +{ + return 1 << header->obj_order; +} + +/* * bio helpers */ @@ -1253,6 +1261,35 @@ fail: return ret; } +/* + * Request sync osd unwatch + */ +static int rbd_req_sync_unwatch(struct rbd_device *dev, + const char *obj) +{ + struct ceph_osd_req_op *ops; + + int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_WATCH, 0); + if (ret < 0) + return ret; + + ops[0].watch.ver = 0; + ops[0].watch.cookie = cpu_to_le64(dev->watch_event->cookie); + ops[0].watch.flag = 0; + + ret = rbd_req_sync_op(dev, NULL, + CEPH_NOSNAP, + 0, + CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, + ops, + 1, obj, 0, 0, NULL, NULL, NULL); + + rbd_destroy_ops(ops); + ceph_osdc_cancel_event(dev->watch_event); + dev->watch_event = NULL; + return ret; +} + struct rbd_notify_info { struct rbd_device *dev; }; @@ -1736,6 +1773,13 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) q = blk_init_queue(rbd_rq_fn, &rbd_dev->lock); if (!q) goto out_disk; + + /* set io sizes to object size */ + blk_queue_max_hw_sectors(q, rbd_obj_bytes(&rbd_dev->header) / 512ULL); + blk_queue_max_segment_size(q, rbd_obj_bytes(&rbd_dev->header)); + blk_queue_io_min(q, rbd_obj_bytes(&rbd_dev->header)); + blk_queue_io_opt(q, rbd_obj_bytes(&rbd_dev->header)); + blk_queue_merge_bvec(q, rbd_merge_bvec); disk->queue = q; @@ -2290,7 +2334,7 @@ static void rbd_dev_release(struct device *dev) ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc, rbd_dev->watch_request); if (rbd_dev->watch_event) - ceph_osdc_cancel_event(rbd_dev->watch_event); + rbd_req_sync_unwatch(rbd_dev, rbd_dev->obj_md_name); rbd_put_client(rbd_dev); diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 5cf2993a8338..2330a9ad5e95 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -458,7 +458,8 @@ static void end_block_io_op(struct bio *bio, int error) * (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 xen_blkif *blkif) +static int +__do_block_io_op(struct xen_blkif *blkif) { union blkif_back_rings *blk_rings = &blkif->blk_rings; struct blkif_request req; @@ -515,6 +516,23 @@ static int do_block_io_op(struct xen_blkif *blkif) return more_to_do; } +static int +do_block_io_op(struct xen_blkif *blkif) +{ + union blkif_back_rings *blk_rings = &blkif->blk_rings; + int more_to_do; + + do { + more_to_do = __do_block_io_op(blkif); + if (more_to_do) + break; + + RING_FINAL_CHECK_FOR_REQUESTS(&blk_rings->common, more_to_do); + } while (more_to_do); + + return more_to_do; +} + /* * Transmutation of the 'struct blkif_request' to a proper 'struct bio' * and call the 'submit_bio' to pass it to the underlying storage. @@ -700,7 +718,6 @@ static void make_response(struct xen_blkif *blkif, u64 id, struct blkif_response resp; unsigned long flags; union blkif_back_rings *blk_rings = &blkif->blk_rings; - int more_to_do = 0; int notify; resp.id = id; @@ -727,22 +744,7 @@ static void make_response(struct xen_blkif *blkif, u64 id, } blk_rings->common.rsp_prod_pvt++; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify); - if (blk_rings->common.rsp_prod_pvt == blk_rings->common.req_cons) { - /* - * Tail check for pending requests. Allows frontend to avoid - * notifications if requests are already in flight (lower - * overheads and promotes batching). - */ - RING_FINAL_CHECK_FOR_REQUESTS(&blk_rings->common, more_to_do); - - } else if (RING_HAS_UNCONSUMED_REQUESTS(&blk_rings->common)) { - more_to_do = 1; - } - spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); - - if (more_to_do) - blkif_notify_work(blkif); if (notify) notify_remote_via_irq(blkif->irq); } @@ -824,3 +826,4 @@ static int __init xen_blkif_init(void) module_init(xen_blkif_init); MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("xen-backend:vbd"); diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 6cc0db1bf522..3f129b45451a 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -684,7 +684,7 @@ again: err = xenbus_switch_state(dev, XenbusStateConnected); if (err) - xenbus_dev_fatal(dev, err, "switching to Connected state", + xenbus_dev_fatal(dev, err, "%s: switching to Connected state", dev->nodename); return; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 6c7fd7db6dff..fb1975d82a73 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1155,12 +1155,19 @@ static int __devinit ace_probe(struct platform_device *dev) { resource_size_t physaddr = 0; int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */ - int id = dev->id; + u32 id = dev->id; int irq = NO_IRQ; int i; dev_dbg(&dev->dev, "ace_probe(%p)\n", dev); + /* device id and bus width */ + of_property_read_u32(dev->dev.of_node, "port-number", &id); + if (id < 0) + id = 0; + if (of_find_property(dev->dev.of_node, "8-bit", NULL)) + bus_width = ACE_BUS_WIDTH_8; + for (i = 0; i < dev->num_resources; i++) { if (dev->resource[i].flags & IORESOURCE_MEM) physaddr = dev->resource[i].start; @@ -1181,57 +1188,7 @@ static int __devexit ace_remove(struct platform_device *dev) return 0; } -static struct platform_driver ace_platform_driver = { - .probe = ace_probe, - .remove = __devexit_p(ace_remove), - .driver = { - .owner = THIS_MODULE, - .name = "xsysace", - }, -}; - -/* --------------------------------------------------------------------- - * OF_Platform Bus Support - */ - #if defined(CONFIG_OF) -static int __devinit ace_of_probe(struct platform_device *op) -{ - struct resource res; - resource_size_t physaddr; - const u32 *id; - int irq, bus_width, rc; - - /* device id */ - id = of_get_property(op->dev.of_node, "port-number", NULL); - - /* physaddr */ - rc = of_address_to_resource(op->dev.of_node, 0, &res); - if (rc) { - dev_err(&op->dev, "invalid address\n"); - return rc; - } - physaddr = res.start; - - /* irq */ - irq = irq_of_parse_and_map(op->dev.of_node, 0); - - /* bus width */ - bus_width = ACE_BUS_WIDTH_16; - if (of_find_property(op->dev.of_node, "8-bit", NULL)) - bus_width = ACE_BUS_WIDTH_8; - - /* Call the bus-independent setup code */ - return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0, - physaddr, irq, bus_width); -} - -static int __devexit ace_of_remove(struct platform_device *op) -{ - ace_free(&op->dev); - return 0; -} - /* Match table for of_platform binding */ static const struct of_device_id ace_of_match[] __devinitconst = { { .compatible = "xlnx,opb-sysace-1.00.b", }, @@ -1241,34 +1198,20 @@ static const struct of_device_id ace_of_match[] __devinitconst = { {}, }; MODULE_DEVICE_TABLE(of, ace_of_match); +#else /* CONFIG_OF */ +#define ace_of_match NULL +#endif /* CONFIG_OF */ -static struct platform_driver ace_of_driver = { - .probe = ace_of_probe, - .remove = __devexit_p(ace_of_remove), +static struct platform_driver ace_platform_driver = { + .probe = ace_probe, + .remove = __devexit_p(ace_remove), .driver = { - .name = "xsysace", .owner = THIS_MODULE, + .name = "xsysace", .of_match_table = ace_of_match, }, }; -/* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __init ace_of_register(void) -{ - pr_debug("xsysace: registering OF binding\n"); - return platform_driver_register(&ace_of_driver); -} - -static inline void __exit ace_of_unregister(void) -{ - platform_driver_unregister(&ace_of_driver); -} -#else /* CONFIG_OF */ -/* CONFIG_OF not enabled; do nothing helpers */ -static inline int __init ace_of_register(void) { return 0; } -static inline void __exit ace_of_unregister(void) { } -#endif /* CONFIG_OF */ - /* --------------------------------------------------------------------- * Module init/exit routines */ @@ -1282,11 +1225,6 @@ static int __init ace_init(void) goto err_blk; } - rc = ace_of_register(); - if (rc) - goto err_of; - - pr_debug("xsysace: registering platform binding\n"); rc = platform_driver_register(&ace_platform_driver); if (rc) goto err_plat; @@ -1295,21 +1233,17 @@ static int __init ace_init(void) return 0; err_plat: - ace_of_unregister(); -err_of: unregister_blkdev(ace_major, "xsysace"); err_blk: printk(KERN_ERR "xsysace: registration failed; err=%i\n", rc); return rc; } +module_init(ace_init); static void __exit ace_exit(void) { pr_debug("Unregistering Xilinx SystemACE driver\n"); platform_driver_unregister(&ace_platform_driver); - ace_of_unregister(); unregister_blkdev(ace_major, "xsysace"); } - -module_init(ace_init); module_exit(ace_exit); |