usb: gadget: f_mass_storage: forced_eject attribute

It allows to reset prevent_medium_removal flag and "eject" the image.
This can be useful to free the drive from a hunging host or if the host
continues to use the drive even after unmounting (Linux does this).
It's also a bit like using an unfolded paperclip on an optical drive.

Previously, the undocumented method of sending SIGUSR1 to a special
"file-storage" kernel thread could be used for these purposes,
but when using multiple storages there was no way to distinguish
one from the other, so we had to send a signal to everyone.

Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
Link: https://lore.kernel.org/r/20220711102956.19642-1-mdevaev@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Maxim Devaev
2022-07-11 13:29:57 +03:00
committed by Greg Kroah-Hartman
parent 8097cf2fb3
commit 421c8d9a20
6 changed files with 63 additions and 0 deletions

View File

@@ -2651,10 +2651,21 @@ static ssize_t file_store(struct device *dev, struct device_attribute *attr,
return fsg_store_file(curlun, filesem, buf, count);
}
static ssize_t forced_eject_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
struct rw_semaphore *filesem = dev_get_drvdata(dev);
return fsg_store_forced_eject(curlun, filesem, buf, count);
}
static DEVICE_ATTR_RW(nofua);
/* mode wil be set in fsg_lun_attr_is_visible() */
static DEVICE_ATTR(ro, 0, ro_show, ro_store);
static DEVICE_ATTR(file, 0, file_show, file_store);
static DEVICE_ATTR_WO(forced_eject);
/****************************** FSG COMMON ******************************/
@@ -2808,6 +2819,7 @@ static struct attribute *fsg_lun_dev_attrs[] = {
&dev_attr_ro.attr,
&dev_attr_file.attr,
&dev_attr_nofua.attr,
&dev_attr_forced_eject.attr,
NULL
};
@@ -3221,6 +3233,18 @@ static ssize_t fsg_lun_opts_inquiry_string_store(struct config_item *item,
CONFIGFS_ATTR(fsg_lun_opts_, inquiry_string);
static ssize_t fsg_lun_opts_forced_eject_store(struct config_item *item,
const char *page, size_t len)
{
struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
return fsg_store_forced_eject(opts->lun, &fsg_opts->common->filesem,
page, len);
}
CONFIGFS_ATTR_WO(fsg_lun_opts_, forced_eject);
static struct configfs_attribute *fsg_lun_attrs[] = {
&fsg_lun_opts_attr_file,
&fsg_lun_opts_attr_ro,
@@ -3228,6 +3252,7 @@ static struct configfs_attribute *fsg_lun_attrs[] = {
&fsg_lun_opts_attr_cdrom,
&fsg_lun_opts_attr_nofua,
&fsg_lun_opts_attr_inquiry_string,
&fsg_lun_opts_attr_forced_eject,
NULL,
};