Commit 19051c5035d217e572672a2ca9db06c1cef50e9b

Authored by Greg Kroah-Hartman
1 parent 8882b39421

mm: bdi: fix race in bdi_class device creation

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>

Showing 1 changed file with 2 additions and 10 deletions Side-by-side Diff

... ... @@ -172,30 +172,22 @@
172 172 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
173 173 const char *fmt, ...)
174 174 {
175   - char *name;
176 175 va_list args;
177 176 int ret = 0;
178 177 struct device *dev;
179 178  
180 179 va_start(args, fmt);
181   - name = kvasprintf(GFP_KERNEL, fmt, args);
  180 + dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args);
182 181 va_end(args);
183   -
184   - if (!name)
185   - return -ENOMEM;
186   -
187   - dev = device_create(bdi_class, parent, MKDEV(0, 0), name);
188 182 if (IS_ERR(dev)) {
189 183 ret = PTR_ERR(dev);
190 184 goto exit;
191 185 }
192 186  
193 187 bdi->dev = dev;
194   - dev_set_drvdata(bdi->dev, bdi);
195   - bdi_debug_register(bdi, name);
  188 + bdi_debug_register(bdi, dev_name(dev));
196 189  
197 190 exit:
198   - kfree(name);
199 191 return ret;
200 192 }
201 193 EXPORT_SYMBOL(bdi_register);