aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2012-06-07 13:38:51 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-07-16 20:29:11 -0400
commit44bfd0185043c9a92b2f20a4508dd6cd3bb84ded (patch)
tree9875dee43fb666614859f3b0c59aae9c6413db5e /drivers/target
parent7acd57070649da4ac3923f1d2075c084d83da1f4 (diff)
target/iblock: Add parameter to specify read-only devices
see https://bugzilla.redhat.com/show_bug.cgi?id=818855 Adds a parameter so read-only block devices may be registered as LIO backstores. Signed-off-by: Andy Grover <agrover@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_iblock.c35
-rw-r--r--drivers/target/target_core_iblock.h1
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
325enum { 329enum {
326 Opt_udev_path, Opt_force, Opt_err 330 Opt_udev_path, Opt_readonly, Opt_force, Opt_err
327}; 331};
328 332
329static match_table_t tokens = { 333static 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 */