mm: bdi: fix race in bdi_class device creation
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 15 May 2008 20:44:08 +0000 (13:44 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 20 May 2008 20:31:53 +0000 (13:31 -0700)
There is a race from when a device is created with device_create() and
then the drvdata is set with a call to dev_set_drvdata() in which a
sysfs file could be open, yet the drvdata will be NULL, causing all
sorts of bad things to happen.

This patch fixes the problem by using the new function,
device_create_vargs().

Many thanks to Arthur Jones <ajones@riverbed.com> for reporting the bug,
and testing patches out.

Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Arthur Jones <ajones@riverbed.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
mm/backing-dev.c

index 7c4f9e0..f2e574d 100644 (file)
@@ -172,30 +172,22 @@ postcore_initcall(bdi_class_init);
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
                const char *fmt, ...)
 {
-       char *name;
        va_list args;
        int ret = 0;
        struct device *dev;
 
        va_start(args, fmt);
-       name = kvasprintf(GFP_KERNEL, fmt, args);
+       dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args);
        va_end(args);
-
-       if (!name)
-               return -ENOMEM;
-
-       dev = device_create(bdi_class, parent, MKDEV(0, 0), name);
        if (IS_ERR(dev)) {
                ret = PTR_ERR(dev);
                goto exit;
        }
 
        bdi->dev = dev;
-       dev_set_drvdata(bdi->dev, bdi);
-       bdi_debug_register(bdi, name);
+       bdi_debug_register(bdi, dev_name(dev));
 
 exit:
-       kfree(name);
        return ret;
 }
 EXPORT_SYMBOL(bdi_register);