aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/file_storage.c
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2010-10-28 11:31:18 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-11 08:58:48 -0500
commitd9385b6352da7fed50981f375c2ccb60354039a6 (patch)
tree2b9c8dc9fcb6b6452634c853712bba71993ac797 /drivers/usb/gadget/file_storage.c
parent78bff3c65df33da47e93736bd8847b694084e5a9 (diff)
USB: gadget: file_storage: put_device() in error recovery
This commit fixes some issues with File-backed Storage Gadget error recovery when registering LUN's devices. First of all, when device_register() fails the device still needs to be put. However, because lun_release() decreases fsg->ref reference counter the counter must be incremented beforehand. Second of all, after any of the device_create_file()s fails, device_unregister() is called which in turn (indirectly) calls lun_release() which decrements fsg->ref. So, again, the reference counter must be incremented beforehand. Lastly, if the first or the second device_create_file() succeeds, the files are never removed. To fix it, device_remove_file() needs to be called. This is done by simply marking LUN as registered prior to creating files so that fsg_unbind() can handle removing files. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Reported-by: Rahul Ruikar <rahul.ruikar@gmail.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r--drivers/usb/gadget/file_storage.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index d4fdf65fb925..a6eacb59571b 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3392,25 +3392,28 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3392 dev_set_name(&curlun->dev,"%s-lun%d", 3392 dev_set_name(&curlun->dev,"%s-lun%d",
3393 dev_name(&gadget->dev), i); 3393 dev_name(&gadget->dev), i);
3394 3394
3395 if ((rc = device_register(&curlun->dev)) != 0) { 3395 kref_get(&fsg->ref);
3396 rc = device_register(&curlun->dev);
3397 if (rc) {
3396 INFO(fsg, "failed to register LUN%d: %d\n", i, rc); 3398 INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
3397 goto out; 3399 put_device(&curlun->dev);
3398 }
3399 if ((rc = device_create_file(&curlun->dev,
3400 &dev_attr_ro)) != 0 ||
3401 (rc = device_create_file(&curlun->dev,
3402 &dev_attr_nofua)) != 0 ||
3403 (rc = device_create_file(&curlun->dev,
3404 &dev_attr_file)) != 0) {
3405 device_unregister(&curlun->dev);
3406 goto out; 3400 goto out;
3407 } 3401 }
3408 curlun->registered = 1; 3402 curlun->registered = 1;
3409 kref_get(&fsg->ref); 3403
3404 rc = device_create_file(&curlun->dev, &dev_attr_ro);
3405 if (rc)
3406 goto out;
3407 rc = device_create_file(&curlun->dev, &dev_attr_nofua);
3408 if (rc)
3409 goto out;
3410 rc = device_create_file(&curlun->dev, &dev_attr_file);
3411 if (rc)
3412 goto out;
3410 3413
3411 if (mod_data.file[i] && *mod_data.file[i]) { 3414 if (mod_data.file[i] && *mod_data.file[i]) {
3412 if ((rc = fsg_lun_open(curlun, 3415 rc = fsg_lun_open(curlun, mod_data.file[i]);
3413 mod_data.file[i])) != 0) 3416 if (rc)
3414 goto out; 3417 goto out;
3415 } else if (!mod_data.removable) { 3418 } else if (!mod_data.removable) {
3416 ERROR(fsg, "no file given for LUN%d\n", i); 3419 ERROR(fsg, "no file given for LUN%d\n", i);