pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \
__FUNCTION__, __LINE__, ##args)
+static DEFINE_RWLOCK(sysfs_read_lock);
+
struct backend_info
{
struct xenbus_device *dev;
struct device_attribute *attr, \
char *buf) \
{ \
- struct xenbus_device *dev = to_xenbus_device(_dev); \
- struct backend_info *be = dev->dev.driver_data; \
+ ssize_t ret = -ENODEV; \
+ struct xenbus_device *dev; \
+ struct backend_info *be; \
\
- return sprintf(buf, format, ##args); \
+ if (!get_device(_dev)) \
+ return ret; \
+ dev = to_xenbus_device(_dev); \
+ read_lock(&sysfs_read_lock); \
+ if ((be = dev->dev.driver_data) != NULL) \
+ ret = sprintf(buf, format, ##args); \
+ read_unlock(&sysfs_read_lock); \
+ put_device(_dev); \
+ return ret; \
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
DPRINTK("");
+ write_lock(&sysfs_read_lock);
if (be->major || be->minor)
xenvbd_sysfs_delif(dev);
kfree(be);
dev->dev.driver_data = NULL;
+ write_unlock(&sysfs_read_lock);
return 0;
}
int group_added;
};
+static DEFINE_RWLOCK(sysfs_read_lock);
static void connect(struct backend_info *);
static int connect_ring(struct backend_info *);
struct device_attribute *attr, \
char *buf) \
{ \
- struct xenbus_device *dev = to_xenbus_device(_dev); \
- struct backend_info *be = dev->dev.driver_data; \
+ ssize_t ret = -ENODEV; \
+ struct xenbus_device *dev; \
+ struct backend_info *be; \
\
- return sprintf(buf, format, ##args); \
+ if (!get_device(_dev)) \
+ return ret; \
+ dev = to_xenbus_device(_dev); \
+ read_lock(&sysfs_read_lock); \
+ if ((be = dev->dev.driver_data) != NULL) \
+ ret = sprintf(buf, format, ##args); \
+ read_unlock(&sysfs_read_lock); \
+ put_device(_dev); \
+ return ret; \
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
{
struct backend_info *be = dev->dev.driver_data;
+ write_lock(&sysfs_read_lock);
if (be->group_added)
xentap_sysfs_delif(be->dev);
if (be->backend_watch.node) {
}
kfree(be);
dev->dev.driver_data = NULL;
+ write_unlock(&sysfs_read_lock);
return 0;
}