mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
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>
This commit is contained in:
parent
78bff3c65d
commit
d9385b6352
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user