aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Limpach <Christian.Limpach@xensource.com>2008-04-02 13:54:04 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-24 17:57:33 -0400
commit1d78d7055629e3f6300d6b8d7028259ee2bffc0e (patch)
tree20bf47ccdd80ead20c69f8a536849c9cf8dd3223
parent53f0e8afcb0d57cfaff06b89eb8b5302f167577e (diff)
xen blkfront: Delay wait for block devices until after the disk is added
When the xen block frontend driver is built as a module the module load is only synchronous up to the point where the frontend and the backend become connected rather than when the disk is added. This means that there can be a race on boot between loading the module and loading the dm-* modules and doing the scan for LVM physical volumes (all in the initrd). In the failure case the disk is not present until after the scan for physical volumes is complete. Taken from: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/11483a00c017 Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com> Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/block/xen-blkfront.c11
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c5
-rw-r--r--include/xen/xenbus.h1
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4497ff84f64a..dfe61afe676a 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -88,6 +88,7 @@ struct blkfront_info
88 struct blk_shadow shadow[BLK_RING_SIZE]; 88 struct blk_shadow shadow[BLK_RING_SIZE];
89 unsigned long shadow_free; 89 unsigned long shadow_free;
90 int feature_barrier; 90 int feature_barrier;
91 int is_ready;
91 92
92 /** 93 /**
93 * The number of people holding this device open. We won't allow a 94 * The number of people holding this device open. We won't allow a
@@ -839,6 +840,8 @@ static void blkfront_connect(struct blkfront_info *info)
839 spin_unlock_irq(&blkif_io_lock); 840 spin_unlock_irq(&blkif_io_lock);
840 841
841 add_disk(info->gd); 842 add_disk(info->gd);
843
844 info->is_ready = 1;
842} 845}
843 846
844/** 847/**
@@ -931,6 +934,13 @@ static int blkfront_remove(struct xenbus_device *dev)
931 return 0; 934 return 0;
932} 935}
933 936
937static int blkfront_is_ready(struct xenbus_device *dev)
938{
939 struct blkfront_info *info = dev->dev.driver_data;
940
941 return info->is_ready;
942}
943
934static int blkif_open(struct inode *inode, struct file *filep) 944static int blkif_open(struct inode *inode, struct file *filep)
935{ 945{
936 struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; 946 struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
@@ -977,6 +987,7 @@ static struct xenbus_driver blkfront = {
977 .remove = blkfront_remove, 987 .remove = blkfront_remove,
978 .resume = blkfront_resume, 988 .resume = blkfront_resume,
979 .otherend_changed = backend_changed, 989 .otherend_changed = backend_changed,
990 .is_ready = blkfront_is_ready,
980}; 991};
981 992
982static int __init xlblk_init(void) 993static int __init xlblk_init(void)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 4750de316ad3..88fc5ec665f5 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -846,6 +846,7 @@ static int is_disconnected_device(struct device *dev, void *data)
846{ 846{
847 struct xenbus_device *xendev = to_xenbus_device(dev); 847 struct xenbus_device *xendev = to_xenbus_device(dev);
848 struct device_driver *drv = data; 848 struct device_driver *drv = data;
849 struct xenbus_driver *xendrv;
849 850
850 /* 851 /*
851 * A device with no driver will never connect. We care only about 852 * A device with no driver will never connect. We care only about
@@ -858,7 +859,9 @@ static int is_disconnected_device(struct device *dev, void *data)
858 if (drv && (dev->driver != drv)) 859 if (drv && (dev->driver != drv))
859 return 0; 860 return 0;
860 861
861 return (xendev->state != XenbusStateConnected); 862 xendrv = to_xenbus_driver(dev->driver);
863 return (xendev->state != XenbusStateConnected ||
864 (xendrv->is_ready && !xendrv->is_ready(xendev)));
862} 865}
863 866
864static int exists_disconnected_device(struct device_driver *drv) 867static int exists_disconnected_device(struct device_driver *drv)
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 6f7c290651ae..6369d89c25d5 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -97,6 +97,7 @@ struct xenbus_driver {
97 int (*uevent)(struct xenbus_device *, char **, int, char *, int); 97 int (*uevent)(struct xenbus_device *, char **, int, char *, int);
98 struct device_driver driver; 98 struct device_driver driver;
99 int (*read_otherend_details)(struct xenbus_device *dev); 99 int (*read_otherend_details)(struct xenbus_device *dev);
100 int (*is_ready)(struct xenbus_device *dev);
100}; 101};
101 102
102static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv) 103static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)