diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_iblock.c | 35 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.h | 1 |
2 files changed, 29 insertions, 7 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 244fff4aaf5a..c2d4ccbb7133 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -96,6 +96,7 @@ static struct se_device *iblock_create_virtdevice( | |||
96 | struct request_queue *q; | 96 | struct request_queue *q; |
97 | struct queue_limits *limits; | 97 | struct queue_limits *limits; |
98 | u32 dev_flags = 0; | 98 | u32 dev_flags = 0; |
99 | fmode_t mode; | ||
99 | int ret = -EINVAL; | 100 | int ret = -EINVAL; |
100 | 101 | ||
101 | if (!ib_dev) { | 102 | if (!ib_dev) { |
@@ -117,8 +118,11 @@ static struct se_device *iblock_create_virtdevice( | |||
117 | pr_debug( "IBLOCK: Claiming struct block_device: %s\n", | 118 | pr_debug( "IBLOCK: Claiming struct block_device: %s\n", |
118 | ib_dev->ibd_udev_path); | 119 | ib_dev->ibd_udev_path); |
119 | 120 | ||
120 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, | 121 | mode = FMODE_READ|FMODE_EXCL; |
121 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); | 122 | if (!ib_dev->ibd_readonly) |
123 | mode |= FMODE_WRITE; | ||
124 | |||
125 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); | ||
122 | if (IS_ERR(bd)) { | 126 | if (IS_ERR(bd)) { |
123 | ret = PTR_ERR(bd); | 127 | ret = PTR_ERR(bd); |
124 | goto failed; | 128 | goto failed; |
@@ -323,11 +327,12 @@ static int iblock_do_discard(struct se_device *dev, sector_t lba, u32 range) | |||
323 | } | 327 | } |
324 | 328 | ||
325 | enum { | 329 | enum { |
326 | Opt_udev_path, Opt_force, Opt_err | 330 | Opt_udev_path, Opt_readonly, Opt_force, Opt_err |
327 | }; | 331 | }; |
328 | 332 | ||
329 | static match_table_t tokens = { | 333 | static match_table_t tokens = { |
330 | {Opt_udev_path, "udev_path=%s"}, | 334 | {Opt_udev_path, "udev_path=%s"}, |
335 | {Opt_readonly, "readonly=%d"}, | ||
331 | {Opt_force, "force=%d"}, | 336 | {Opt_force, "force=%d"}, |
332 | {Opt_err, NULL} | 337 | {Opt_err, NULL} |
333 | }; | 338 | }; |
@@ -340,6 +345,7 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, | |||
340 | char *orig, *ptr, *arg_p, *opts; | 345 | char *orig, *ptr, *arg_p, *opts; |
341 | substring_t args[MAX_OPT_ARGS]; | 346 | substring_t args[MAX_OPT_ARGS]; |
342 | int ret = 0, token; | 347 | int ret = 0, token; |
348 | unsigned long tmp_readonly; | ||
343 | 349 | ||
344 | opts = kstrdup(page, GFP_KERNEL); | 350 | opts = kstrdup(page, GFP_KERNEL); |
345 | if (!opts) | 351 | if (!opts) |
@@ -372,6 +378,22 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, | |||
372 | ib_dev->ibd_udev_path); | 378 | ib_dev->ibd_udev_path); |
373 | ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; | 379 | ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; |
374 | break; | 380 | break; |
381 | case Opt_readonly: | ||
382 | arg_p = match_strdup(&args[0]); | ||
383 | if (!arg_p) { | ||
384 | ret = -ENOMEM; | ||
385 | break; | ||
386 | } | ||
387 | ret = strict_strtoul(arg_p, 0, &tmp_readonly); | ||
388 | kfree(arg_p); | ||
389 | if (ret < 0) { | ||
390 | pr_err("strict_strtoul() failed for" | ||
391 | " readonly=\n"); | ||
392 | goto out; | ||
393 | } | ||
394 | ib_dev->ibd_readonly = tmp_readonly; | ||
395 | pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly); | ||
396 | break; | ||
375 | case Opt_force: | 397 | case Opt_force: |
376 | break; | 398 | break; |
377 | default: | 399 | default: |
@@ -411,11 +433,10 @@ static ssize_t iblock_show_configfs_dev_params( | |||
411 | if (bd) | 433 | if (bd) |
412 | bl += sprintf(b + bl, "iBlock device: %s", | 434 | bl += sprintf(b + bl, "iBlock device: %s", |
413 | bdevname(bd, buf)); | 435 | bdevname(bd, buf)); |
414 | if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH) { | 436 | if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH) |
415 | bl += sprintf(b + bl, " UDEV PATH: %s\n", | 437 | bl += sprintf(b + bl, " UDEV PATH: %s", |
416 | ibd->ibd_udev_path); | 438 | ibd->ibd_udev_path); |
417 | } else | 439 | bl += sprintf(b + bl, " readonly: %d\n", ibd->ibd_readonly); |
418 | bl += sprintf(b + bl, "\n"); | ||
419 | 440 | ||
420 | bl += sprintf(b + bl, " "); | 441 | bl += sprintf(b + bl, " "); |
421 | if (bd) { | 442 | if (bd) { |
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h index 66cf7b9e205e..533627ae79ec 100644 --- a/drivers/target/target_core_iblock.h +++ b/drivers/target/target_core_iblock.h | |||
@@ -18,6 +18,7 @@ struct iblock_dev { | |||
18 | u32 ibd_flags; | 18 | u32 ibd_flags; |
19 | struct bio_set *ibd_bio_set; | 19 | struct bio_set *ibd_bio_set; |
20 | struct block_device *ibd_bd; | 20 | struct block_device *ibd_bd; |
21 | bool ibd_readonly; | ||
21 | } ____cacheline_aligned; | 22 | } ____cacheline_aligned; |
22 | 23 | ||
23 | #endif /* TARGET_CORE_IBLOCK_H */ | 24 | #endif /* TARGET_CORE_IBLOCK_H */ |