summaryrefslogtreecommitdiff
path: root/drivers/target/target_core_iblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/target_core_iblock.c')
-rw-r--r--drivers/target/target_core_iblock.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 73564efd11d2..66c292b7d74b 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -64,6 +64,7 @@ static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *nam
pr_err("Unable to allocate struct iblock_dev\n");
return NULL;
}
+ ib_dev->ibd_exclusive = true;
ib_dev->ibd_plug = kcalloc(nr_cpu_ids, sizeof(*ib_dev->ibd_plug),
GFP_KERNEL);
@@ -95,6 +96,7 @@ static int iblock_configure_device(struct se_device *dev)
struct block_device *bd;
struct blk_integrity *bi;
blk_mode_t mode = BLK_OPEN_READ;
+ void *holder = ib_dev;
unsigned int max_write_zeroes_sectors;
int ret;
@@ -109,15 +111,18 @@ static int iblock_configure_device(struct se_device *dev)
goto out;
}
- pr_debug( "IBLOCK: Claiming struct block_device: %s\n",
- ib_dev->ibd_udev_path);
+ pr_debug("IBLOCK: Claiming struct block_device: %s: %d\n",
+ ib_dev->ibd_udev_path, ib_dev->ibd_exclusive);
if (!ib_dev->ibd_readonly)
mode |= BLK_OPEN_WRITE;
else
dev->dev_flags |= DF_READ_ONLY;
- bdev_file = bdev_file_open_by_path(ib_dev->ibd_udev_path, mode, ib_dev,
+ if (!ib_dev->ibd_exclusive)
+ holder = NULL;
+
+ bdev_file = bdev_file_open_by_path(ib_dev->ibd_udev_path, mode, holder,
NULL);
if (IS_ERR(bdev_file)) {
ret = PTR_ERR(bdev_file);
@@ -560,13 +565,14 @@ fail:
}
enum {
- Opt_udev_path, Opt_readonly, Opt_force, Opt_err
+ Opt_udev_path, Opt_readonly, Opt_force, Opt_exclusive, Opt_err,
};
static match_table_t tokens = {
{Opt_udev_path, "udev_path=%s"},
{Opt_readonly, "readonly=%d"},
{Opt_force, "force=%d"},
+ {Opt_exclusive, "exclusive=%d"},
{Opt_err, NULL}
};
@@ -576,7 +582,7 @@ static ssize_t iblock_set_configfs_dev_params(struct se_device *dev,
struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
char *orig, *ptr, *arg_p, *opts;
substring_t args[MAX_OPT_ARGS];
- int ret = 0, token;
+ int ret = 0, token, tmp_exclusive;
unsigned long tmp_readonly;
opts = kstrdup(page, GFP_KERNEL);
@@ -623,6 +629,22 @@ static ssize_t iblock_set_configfs_dev_params(struct se_device *dev,
ib_dev->ibd_readonly = tmp_readonly;
pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly);
break;
+ case Opt_exclusive:
+ arg_p = match_strdup(&args[0]);
+ if (!arg_p) {
+ ret = -ENOMEM;
+ break;
+ }
+ ret = kstrtoint(arg_p, 0, &tmp_exclusive);
+ kfree(arg_p);
+ if (ret < 0) {
+ pr_err("kstrtoul() failed for exclusive=\n");
+ goto out;
+ }
+ ib_dev->ibd_exclusive = tmp_exclusive;
+ pr_debug("IBLOCK: exclusive: %d\n",
+ ib_dev->ibd_exclusive);
+ break;
case Opt_force:
break;
default:
@@ -647,6 +669,7 @@ static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
bl += sprintf(b + bl, " UDEV PATH: %s",
ib_dev->ibd_udev_path);
bl += sprintf(b + bl, " readonly: %d\n", ib_dev->ibd_readonly);
+ bl += sprintf(b + bl, " exclusive: %d\n", ib_dev->ibd_exclusive);
bl += sprintf(b + bl, " ");
if (bd) {