static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
const char *page, size_t len)
{
- return fsg_store_cdrom(opts->lun, page, len);
+ struct fsg_opts *fsg_opts;
+
+ fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+
+ return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
+ len);
}
static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
}
EXPORT_SYMBOL(fsg_show_removable);
+/*
+ * The caller must hold fsg->filesem for reading when calling this function.
+ */
+static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro)
+{
+ if (fsg_lun_is_open(curlun)) {
+ LDBG(curlun, "read-only status change prevented\n");
+ return -EBUSY;
+ }
+
+ curlun->ro = ro;
+ curlun->initially_ro = ro;
+ LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+
+ return 0;
+}
+
ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
const char *buf, size_t count)
{
* backing file is closed.
*/
down_read(filesem);
- if (fsg_lun_is_open(curlun)) {
- LDBG(curlun, "read-only status change prevented\n");
- rc = -EBUSY;
- } else {
- curlun->ro = ro;
- curlun->initially_ro = ro;
- LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+ rc = _fsg_store_ro(curlun, ro);
+ if (!rc)
rc = count;
- }
up_read(filesem);
+
return rc;
}
EXPORT_SYMBOL(fsg_store_ro);
}
EXPORT_SYMBOL(fsg_store_file);
-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ const char *buf, size_t count)
{
bool cdrom;
int ret;
if (ret)
return ret;
- curlun->cdrom = cdrom;
+ down_read(filesem);
+ ret = cdrom ? _fsg_store_ro(curlun, true) : 0;
- return count;
+ if (!ret) {
+ curlun->cdrom = cdrom;
+ ret = count;
+ }
+ up_read(filesem);
+
+ return ret;
}
EXPORT_SYMBOL(fsg_store_cdrom);
ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
const char *buf, size_t count);
-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ const char *buf, size_t count);
ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
size_t count);