]> xenbits.xensource.com Git - people/ssmith/nc2-2.6.27.bak/.git/commitdiff
commit 3976878f6d3c6faa1aed3a9d40ccf8c10647cd36
authorSteven Smith <ssmith@weybridge.uk.xensource.com>
Thu, 28 May 2009 10:54:19 +0000 (11:54 +0100)
committerSteven Smith <ssmith@weybridge.uk.xensource.com>
Thu, 28 May 2009 10:54:19 +0000 (11:54 +0100)
Author: Ian Campbell <Ian.Campbell@citrix.com>
Date:   Fri Mar 27 15:44:31 2009 +0000

    blktap: cleanup usage of sysfs
    - do not deadock when writing to remove node
    - check __must_check function return values

drivers/xen/blktap2/sysfs.c

index 3a396ac5b185f8495b8df9a2d2b5d5f6a66c97d4..5d5eb2adfc5dd0c6679b84df8842778855b558db 100644 (file)
@@ -154,7 +154,7 @@ blktap_sysfs_pause_device(struct device *dev,
        err = blktap_device_pause(tap);
        if (!err) {
                device_remove_file(dev, &dev_attr_pause);
-               device_create_file(dev, &dev_attr_resume);
+               err = device_create_file(dev, &dev_attr_resume);
        }
 
 out:
@@ -187,7 +187,7 @@ blktap_sysfs_resume_device(struct device *dev,
        err = blktap_device_resume(tap);
        if (!err) {
                device_remove_file(dev, &dev_attr_resume);
-               device_create_file(dev, &dev_attr_pause);
+               err = device_create_file(dev, &dev_attr_pause);
        }
 
 out:
@@ -297,6 +297,7 @@ blktap_sysfs_create(struct blktap *tap)
 {
        struct blktap_ring *ring;
        struct device *dev;
+       int err;
 
        if (!class)
                return -ENODEV;
@@ -308,18 +309,35 @@ blktap_sysfs_create(struct blktap *tap)
        if (IS_ERR(dev))
                return PTR_ERR(dev);
 
-       ring->dev       = dev;
+       ring->dev = dev;
        dev_set_drvdata(dev, tap);
 
        mutex_init(&ring->sysfs_mutex);
        atomic_set(&ring->sysfs_refcnt, 0);
 
-       device_create_file(dev, &dev_attr_name);
-       device_create_file(dev, &dev_attr_remove);
-       device_create_file(dev, &dev_attr_pause);
-       device_create_file(dev, &dev_attr_debug);
+       err = device_create_file(dev, &dev_attr_name);
+       if (err)
+               goto out;
+       err = device_create_file(dev, &dev_attr_remove);
+       if (err)
+               goto out_unregister_name;
+       err = device_create_file(dev, &dev_attr_pause);
+       if (err)
+               goto out_unregister_remove;
+       err = device_create_file(dev, &dev_attr_debug);
+       if (err)
+               goto out_unregister_pause;
 
        return 0;
+
+out_unregister_pause:
+       device_remove_file(dev, &dev_attr_pause);
+out_unregister_remove:
+       device_remove_file(dev, &dev_attr_remove);
+out_unregister_name:
+       device_remove_file(dev, &dev_attr_name);
+out:
+       return err;
 }
 
 int
@@ -338,13 +356,7 @@ blktap_sysfs_destroy(struct blktap *tap)
                                     !atomic_read(&tap->ring.sysfs_refcnt)))
                return -EAGAIN;
 
-       /* XXX: is it safe to remove the class from a sysfs attribute? */
-       device_remove_file(dev, &dev_attr_name);
-       device_remove_file(dev, &dev_attr_remove);
-       device_remove_file(dev, &dev_attr_pause);
-       device_remove_file(dev, &dev_attr_resume);
-       device_remove_file(dev, &dev_attr_debug);
-       device_destroy(class, ring->devno);
+       device_schedule_callback(dev, device_unregister);
 
        clear_bit(BLKTAP_SYSFS, &tap->dev_inuse);
 
@@ -413,6 +425,7 @@ int
 blktap_sysfs_init(void)
 {
        struct class *cls;
+       int err;
 
        if (class)
                return -EEXIST;
@@ -421,9 +434,16 @@ blktap_sysfs_init(void)
        if (IS_ERR(cls))
                return PTR_ERR(cls);
 
-       class_create_file(cls, &class_attr_verbosity);
-       class_create_file(cls, &class_attr_devices);
+       err = class_create_file(cls, &class_attr_verbosity);
+       if (err)
+               goto out_unregister;
+       err = class_create_file(cls, &class_attr_devices);
+       if (err)
+               goto out_unregister;
 
        class = cls;
        return 0;
+out_unregister:
+       class_destroy(cls);
+       return err;
 }