Skip to content

Commit

Permalink
USB: gadget: file_storage: put_device() in error recovery
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michal Nazarewicz authored and Greg Kroah-Hartman committed Nov 11, 2010
1 parent 78bff3c commit d9385b6
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions drivers/usb/gadget/file_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -3392,25 +3392,28 @@ static int __init fsg_bind(struct usb_gadget *gadget)
dev_set_name(&curlun->dev,"%s-lun%d",
dev_name(&gadget->dev), i);

if ((rc = device_register(&curlun->dev)) != 0) {
kref_get(&fsg->ref);
rc = device_register(&curlun->dev);
if (rc) {
INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
goto out;
}
if ((rc = device_create_file(&curlun->dev,
&dev_attr_ro)) != 0 ||
(rc = device_create_file(&curlun->dev,
&dev_attr_nofua)) != 0 ||
(rc = device_create_file(&curlun->dev,
&dev_attr_file)) != 0) {
device_unregister(&curlun->dev);
put_device(&curlun->dev);
goto out;
}
curlun->registered = 1;
kref_get(&fsg->ref);

rc = device_create_file(&curlun->dev, &dev_attr_ro);
if (rc)
goto out;
rc = device_create_file(&curlun->dev, &dev_attr_nofua);
if (rc)
goto out;
rc = device_create_file(&curlun->dev, &dev_attr_file);
if (rc)
goto out;

if (mod_data.file[i] && *mod_data.file[i]) {
if ((rc = fsg_lun_open(curlun,
mod_data.file[i])) != 0)
rc = fsg_lun_open(curlun, mod_data.file[i]);
if (rc)
goto out;
} else if (!mod_data.removable) {
ERROR(fsg, "no file given for LUN%d\n", i);
Expand Down

0 comments on commit d9385b6

Please sign in to comment.