From 3fe773f332843b76dcd8da6d27251e1cda1ea95d Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Sat, 6 Aug 2011 10:32:38 -0400 Subject: [PATCH] Revert "Merge branch 'stable/for-jens' into linux-next" This reverts commit 9ff94f2f2037323fd0f22871d6a64a9d59b51767, reversing changes made to 6fb8b31b55aa3c2c631c3f1461c089975b118e30. --- drivers/block/Kconfig | 2 +- drivers/block/xen-blkback/blkback.c | 18 +-- drivers/block/xen-blkback/common.h | 5 - drivers/block/xen-blkback/xenbus.c | 206 +++------------------------- drivers/block/xen-blkfront.c | 15 +- 5 files changed, 38 insertions(+), 208 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index a89ebf1b28aa..717d6e4e18d3 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -471,7 +471,7 @@ config XEN_BLKDEV_FRONTEND in another domain which drives the actual block device. config XEN_BLKDEV_BACKEND - tristate "Xen block-device backend driver" + tristate "Block-device backend driver" depends on XEN_BACKEND help The block-device backend driver allows the kernel to export its diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index ed055b403ccb..2330a9ad5e95 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -274,7 +274,7 @@ int xen_blkif_schedule(void *arg) xen_blkif_get(blkif); - while (!blkif->remove_requested) { + while (!kthread_should_stop()) { if (try_to_freeze()) continue; if (unlikely(vbd->size != vbd_sz(vbd))) @@ -282,11 +282,11 @@ int xen_blkif_schedule(void *arg) wait_event_interruptible( blkif->wq, - blkif->waiting_reqs || blkif->remove_requested); + blkif->waiting_reqs || kthread_should_stop()); wait_event_interruptible( blkbk->pending_free_wq, !list_empty(&blkbk->pending_free) || - blkif->remove_requested); + kthread_should_stop()); blkif->waiting_reqs = 0; smp_mb(); /* clear flag *before* checking for work */ @@ -301,8 +301,8 @@ int xen_blkif_schedule(void *arg) if (log_stats) print_stats(blkif); + blkif->xenblkd = NULL; xen_blkif_put(blkif); - xen_blkback_close(blkif); return 0; } @@ -476,7 +476,7 @@ __do_block_io_op(struct xen_blkif *blkif) if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) break; - if (blkif->remove_requested) { + if (kthread_should_stop()) { more_to_do = 1; break; } @@ -561,7 +561,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, break; case BLKIF_OP_FLUSH_DISKCACHE: blkif->st_f_req++; - operation = WRITE_FLUSH_FUA; + operation = WRITE_FLUSH; break; case BLKIF_OP_WRITE_BARRIER: default: @@ -572,7 +572,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, /* Check that the number of segments is sane. */ nseg = req->nr_segments; - if (unlikely(nseg == 0 && operation != WRITE_FLUSH_FUA) || + if (unlikely(nseg == 0 && operation != WRITE_FLUSH) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { pr_debug(DRV_PFX "Bad number of segments in request (%d)\n", nseg); @@ -656,7 +656,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, /* This will be hit if the operation was a flush. */ if (!bio) { - BUG_ON(operation != WRITE_FLUSH_FUA); + BUG_ON(operation != WRITE_FLUSH); bio = bio_alloc(GFP_KERNEL, 0); if (unlikely(bio == NULL)) @@ -685,7 +685,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, if (operation == READ) blkif->st_rd_sect += preq.nr_sects; - else if (operation == WRITE || operation == WRITE_FLUSH_FUA) + else if (operation == WRITE || operation == WRITE_FLUSH) blkif->st_wr_sect += preq.nr_sects; return 0; diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index acda757b461d..9e40b283a468 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -49,7 +49,6 @@ pr_debug(DRV_PFX "(%s:%d) " fmt ".\n", \ __func__, __LINE__, ##args) -#define WPRINTK(fmt, args...) printk(KERN_WARNING "xen-blkback: " fmt, ##args) /* Not a real protocol. Used to generate ring structs which contain * the elements common to all protocols only. This way we get a @@ -146,7 +145,6 @@ struct xen_blkif { /* Back pointer to the backend_info. */ struct backend_info *be; /* Private fields. */ - bool remove_requested; spinlock_t blk_ring_lock; atomic_t refcnt; @@ -200,9 +198,6 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); -void xen_vbd_sync(struct xen_vbd *vbd); -void xen_blkback_close(struct xen_blkif *blkif); - static inline void blkif_get_x86_32_req(struct blkif_request *dst, struct blkif_x86_32_request *src) { diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 1990d1cbc786..3f129b45451a 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -25,25 +25,16 @@ struct backend_info { struct xenbus_device *dev; struct xen_blkif *blkif; struct xenbus_watch backend_watch; - struct xenbus_watch shutdown_watch; unsigned major; unsigned minor; char *mode; - bool group_added; - char *nodename; - atomic_t refcnt; - pid_t kthread_pid; - bool shutdown_signalled; }; -DEFINE_SEMAPHORE(blkback_dev_sem); - static struct kmem_cache *xen_blkif_cachep; static void connect(struct backend_info *); static int connect_ring(struct backend_info *); static void backend_changed(struct xenbus_watch *, const char **, unsigned int); -static void xen_vbd_free(struct xen_vbd *vbd); struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be) { @@ -108,16 +99,6 @@ static void xen_update_blkif_status(struct xen_blkif *blkif) blkif->xenblkd = NULL; xenbus_dev_error(blkif->be->dev, err, "start xenblkd"); } - - blkif->be->kthread_pid = blkif->xenblkd->pid; - atomic_inc(&blkif->be->refcnt); - - err = xenbus_printf(XBT_NIL, blkif->be->dev->nodename, "kthread-pid", - "%d", blkif->xenblkd->pid); - if (err) { - xenbus_dev_error(blkif->be->dev, err, "write kthread-pid"); - return; - } } static struct xen_blkif *xen_blkif_alloc(domid_t domid) @@ -232,6 +213,11 @@ static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page, static void xen_blkif_disconnect(struct xen_blkif *blkif) { + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); + blkif->xenblkd = NULL; + } + atomic_dec(&blkif->refcnt); wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0); atomic_inc(&blkif->refcnt); @@ -310,7 +296,6 @@ VBD_SHOW(mode, "%s\n", be->mode); int xenvbd_sysfs_addif(struct xenbus_device *dev) { int error; - struct backend_info *be = dev_get_drvdata(&dev->dev); error = device_create_file(&dev->dev, &dev_attr_physical_device); if (error) @@ -324,8 +309,6 @@ int xenvbd_sysfs_addif(struct xenbus_device *dev) if (error) goto fail3; - be->group_added = true; - return 0; fail3: sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); @@ -336,73 +319,11 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); void xenvbd_sysfs_delif(struct xenbus_device *dev) { - struct backend_info *be = dev_get_drvdata(&dev->dev); - if (!be->group_added) - return; sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); device_remove_file(&dev->dev, &dev_attr_mode); device_remove_file(&dev->dev, &dev_attr_physical_device); - be->group_added = false; -} - -static int xenvbd_kthread_remove(struct backend_info *be) -{ - struct xen_blkif *blkif = be->blkif; - - if (!blkif || !blkif->xenblkd) - return 0; - - blkif->remove_requested = true; - wake_up_process(blkif->xenblkd); - - return -EBUSY; } -static void xenvbd_signal_shutdown(struct backend_info *be) -{ - int err; - - down(&blkback_dev_sem); - - if (be->shutdown_signalled) - goto out; - - err = xenbus_write(XBT_NIL, be->nodename, "shutdown-done", ""); - if (err) - WPRINTK("Error writing shutdown-done for %s: %d\n", - be->nodename, err); - - if (be->dev) - xenbus_switch_state(be->dev, XenbusStateClosed); - - be->shutdown_signalled = true; - - out: - up(&blkback_dev_sem); -} - -static void backend_release(struct backend_info *be) -{ - struct xen_blkif *blkif = be->blkif; - - if (current->pid == be->kthread_pid) - xenvbd_signal_shutdown(be); - - if (!atomic_dec_and_test(&be->refcnt)) - return; - - xenvbd_signal_shutdown(be); - - if (blkif) { - xen_blkif_disconnect(blkif); - xen_vbd_free(&blkif->vbd); - xen_blkif_free(blkif); - be->blkif = NULL; - } - - kfree(be->nodename); - kfree(be); -} static void xen_vbd_free(struct xen_vbd *vbd) { @@ -411,12 +332,6 @@ static void xen_vbd_free(struct xen_vbd *vbd) vbd->bdev = NULL; } -void xen_vbd_sync(struct xen_vbd *vbd) -{ - if (vbd->bdev) - fsync_bdev(vbd->bdev); -} - static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, unsigned major, unsigned minor, int readonly, int cdrom) @@ -469,9 +384,8 @@ static int xen_blkbk_remove(struct xenbus_device *dev) DPRINTK(""); - down(&blkback_dev_sem); - be->dev = NULL; - up(&blkback_dev_sem); + if (be->major || be->minor) + xenvbd_sysfs_delif(dev); if (be->backend_watch.node) { unregister_xenbus_watch(&be->backend_watch); @@ -479,76 +393,18 @@ static int xen_blkbk_remove(struct xenbus_device *dev) be->backend_watch.node = NULL; } - if (be->shutdown_watch.node) { - unregister_xenbus_watch(&be->shutdown_watch); - kfree(be->shutdown_watch.node); - be->shutdown_watch.node = NULL; + if (be->blkif) { + xen_blkif_disconnect(be->blkif); + xen_vbd_free(&be->blkif->vbd); + xen_blkif_free(be->blkif); + be->blkif = NULL; } - if (xenvbd_kthread_remove(be)) - WPRINTK("BAD REMOVE REQUEST for %s\n", be->nodename); - - xenvbd_sysfs_delif(dev); - backend_release(be); - + kfree(be); dev_set_drvdata(&dev->dev, NULL); - return 0; } -/* - * called by kthread when closing - */ -void xen_blkback_close(struct xen_blkif *blkif) -{ - struct xenbus_device *dev = blkif->be->dev; - - xen_blkif_disconnect(blkif); - xen_vbd_sync(&blkif->vbd); - blkif->remove_requested = false; - - down(&blkback_dev_sem); - if (blkif->be->dev) - xenvbd_sysfs_delif(blkif->be->dev); - up(&blkback_dev_sem); - - backend_release(blkif->be); - blkif->xenblkd = NULL; - device_unregister(&dev->dev); -} - -static void xenvbd_start_shutdown(struct xenbus_watch *watch, - const char **vec, unsigned int length) -{ - int err; - char *type; - unsigned int len; - struct backend_info *be - = container_of(watch, struct backend_info, shutdown_watch); - struct xenbus_device *dev = be->dev; - - if (be->shutdown_signalled) - return; - - type = xenbus_read(XBT_NIL, dev->nodename, "shutdown-request", &len); - err = (IS_ERR(type) ? PTR_ERR(type) : 0); - - if (XENBUS_EXIST_ERR(err)) - return; - - if (err) { - xenbus_dev_fatal(dev, err, "reading shutdown-request"); - return; - } - - xenbus_switch_state(dev, XenbusStateClosing); - - if (len == sizeof("force") - 1 && !memcmp(type, "force", len)) - if (!xenvbd_kthread_remove(be)) - xenvbd_signal_shutdown(be); /* shutdown immediately */ - - kfree(type); -} int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, struct backend_info *be, int state) { @@ -581,15 +437,6 @@ static int xen_blkbk_probe(struct xenbus_device *dev, } be->dev = dev; dev_set_drvdata(&dev->dev, be); - atomic_set(&be->refcnt, 1); - - be->nodename = kasprintf(GFP_KERNEL, "%s", dev->nodename); - if (!be->nodename) { - xenbus_dev_fatal(dev, -ENOMEM, - "allocating backend structure"); - kfree(be); - return -ENOMEM; - } be->blkif = xen_blkif_alloc(dev->otherend_id); if (IS_ERR(be->blkif)) { @@ -607,12 +454,6 @@ static int xen_blkbk_probe(struct xenbus_device *dev, if (err) goto fail; - err = xenbus_watch_pathfmt(dev, &be->shutdown_watch, - xenvbd_start_shutdown, "%s/%s", - dev->nodename, "shutdown-request"); - if (err) - goto fail; - err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) goto fail; @@ -726,17 +567,13 @@ static void frontend_changed(struct xenbus_device *dev, struct backend_info *be = dev_get_drvdata(&dev->dev); int err; - DPRINTK("%s: %s", dev->nodename, xenbus_strstate(frontend_state)); + DPRINTK("%s", xenbus_strstate(frontend_state)); switch (frontend_state) { case XenbusStateInitialising: if (dev->state == XenbusStateClosed) { pr_info(DRV_PFX "%s: prepare for reconnect\n", dev->nodename); - - xenbus_rm(XBT_NIL, dev->nodename, "shutdown-done"); - be->shutdown_signalled = false; - xenbus_switch_state(dev, XenbusStateInitWait); } break; @@ -753,7 +590,7 @@ static void frontend_changed(struct xenbus_device *dev, /* * Enforce precondition before potential leak point. - * xen_blkif_disconnect() is idempotent. + * blkif_disconnect() is idempotent. */ xen_blkif_disconnect(be->blkif); @@ -764,16 +601,17 @@ static void frontend_changed(struct xenbus_device *dev, break; case XenbusStateClosing: + xen_blkif_disconnect(be->blkif); xenbus_switch_state(dev, XenbusStateClosing); break; case XenbusStateClosed: - if (!xenvbd_kthread_remove(be)) - xenvbd_signal_shutdown(be); - break; - + xenbus_switch_state(dev, XenbusStateClosed); + if (xenbus_dev_is_online(dev)) + break; + /* fall through if not online */ case XenbusStateUnknown: - /* implies xen_blkif_disconnect() via blkback_remove() */ + /* implies blkif_disconnect() via blkback_remove() */ device_unregister(&dev->dev); break; @@ -782,8 +620,6 @@ static void frontend_changed(struct xenbus_device *dev, frontend_state); break; } - - DPRINTK("%s: %s", dev->nodename, xenbus_strstate(dev->state)); } diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 67d656b1adc6..b536a9cef917 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -123,8 +123,8 @@ static DEFINE_SPINLOCK(minor_lock); #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) #define EMULATED_HD_DISK_MINOR_OFFSET (0) #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256) -#define EMULATED_SD_DISK_MINOR_OFFSET (0) -#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_SD_DISK_MINOR_OFFSET / 256) +#define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16)) +#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4) #define DEV_NAME "xvd" /* name in /dev */ @@ -529,7 +529,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, minor = BLKIF_MINOR_EXT(info->vdevice); nr_parts = PARTS_PER_EXT_DISK; offset = minor / nr_parts; - if (xen_hvm_domain() && offset < EMULATED_HD_DISK_NAME_OFFSET + 4) + if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " "emulated IDE disks,\n\t choose an xvd device name" "from xvde on\n", info->vdevice); @@ -1148,7 +1148,7 @@ static void blkfront_connect(struct blkfront_info *info) return; } - info->feature_flush = REQ_FLUSH | REQ_FUA; + info->feature_flush = 0; info->flush_op = 0; err = xenbus_gather(XBT_NIL, info->xbdev->otherend, @@ -1163,6 +1163,7 @@ static void blkfront_connect(struct blkfront_info *info) * If there are barriers, then we use flush. */ if (!err && barrier) { + info->feature_flush = REQ_FLUSH | REQ_FUA; info->flush_op = BLKIF_OP_WRITE_BARRIER; } /* @@ -1174,12 +1175,10 @@ static void blkfront_connect(struct blkfront_info *info) NULL); if (!err && flush) { + info->feature_flush = REQ_FLUSH; info->flush_op = BLKIF_OP_FLUSH_DISKCACHE; } - - if (!flush && !barrier) - info->feature_flush = 0; - + err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); if (err) { xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", -- 2.39.2