Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: target: iblock: Allow iblock devices to be shared

We might be running a local application that also interacts with the
backing device. In this setup we have some clustering type of software
that manages the ownwer of it, so we don't want the kernel to restrict
us. This patch allows the user to control if the driver gets exclusive
access.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20250721185145.20913-1-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Mike Christie and committed by
Martin K. Petersen
7ffbf335 35dabf45

+29 -5
+28 -5
drivers/target/target_core_iblock.c
··· 64 64 pr_err("Unable to allocate struct iblock_dev\n"); 65 65 return NULL; 66 66 } 67 + ib_dev->ibd_exclusive = true; 67 68 68 69 ib_dev->ibd_plug = kcalloc(nr_cpu_ids, sizeof(*ib_dev->ibd_plug), 69 70 GFP_KERNEL); ··· 96 95 struct block_device *bd; 97 96 struct blk_integrity *bi; 98 97 blk_mode_t mode = BLK_OPEN_READ; 98 + void *holder = ib_dev; 99 99 unsigned int max_write_zeroes_sectors; 100 100 int ret; 101 101 ··· 111 109 goto out; 112 110 } 113 111 114 - pr_debug( "IBLOCK: Claiming struct block_device: %s\n", 115 - ib_dev->ibd_udev_path); 112 + pr_debug("IBLOCK: Claiming struct block_device: %s: %d\n", 113 + ib_dev->ibd_udev_path, ib_dev->ibd_exclusive); 116 114 117 115 if (!ib_dev->ibd_readonly) 118 116 mode |= BLK_OPEN_WRITE; 119 117 else 120 118 dev->dev_flags |= DF_READ_ONLY; 121 119 122 - bdev_file = bdev_file_open_by_path(ib_dev->ibd_udev_path, mode, ib_dev, 120 + if (!ib_dev->ibd_exclusive) 121 + holder = NULL; 122 + 123 + bdev_file = bdev_file_open_by_path(ib_dev->ibd_udev_path, mode, holder, 123 124 NULL); 124 125 if (IS_ERR(bdev_file)) { 125 126 ret = PTR_ERR(bdev_file); ··· 565 560 } 566 561 567 562 enum { 568 - Opt_udev_path, Opt_readonly, Opt_force, Opt_err 563 + Opt_udev_path, Opt_readonly, Opt_force, Opt_exclusive, Opt_err, 569 564 }; 570 565 571 566 static match_table_t tokens = { 572 567 {Opt_udev_path, "udev_path=%s"}, 573 568 {Opt_readonly, "readonly=%d"}, 574 569 {Opt_force, "force=%d"}, 570 + {Opt_exclusive, "exclusive=%d"}, 575 571 {Opt_err, NULL} 576 572 }; 577 573 ··· 582 576 struct iblock_dev *ib_dev = IBLOCK_DEV(dev); 583 577 char *orig, *ptr, *arg_p, *opts; 584 578 substring_t args[MAX_OPT_ARGS]; 585 - int ret = 0, token; 579 + int ret = 0, token, tmp_exclusive; 586 580 unsigned long tmp_readonly; 587 581 588 582 opts = kstrdup(page, GFP_KERNEL); ··· 629 623 ib_dev->ibd_readonly = tmp_readonly; 630 624 pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly); 631 625 break; 626 + case Opt_exclusive: 627 + arg_p = match_strdup(&args[0]); 628 + if (!arg_p) { 629 + ret = -ENOMEM; 630 + break; 631 + } 632 + ret = kstrtoint(arg_p, 0, &tmp_exclusive); 633 + kfree(arg_p); 634 + if (ret < 0) { 635 + pr_err("kstrtoul() failed for exclusive=\n"); 636 + goto out; 637 + } 638 + ib_dev->ibd_exclusive = tmp_exclusive; 639 + pr_debug("IBLOCK: exclusive: %d\n", 640 + ib_dev->ibd_exclusive); 641 + break; 632 642 case Opt_force: 633 643 break; 634 644 default: ··· 669 647 bl += sprintf(b + bl, " UDEV PATH: %s", 670 648 ib_dev->ibd_udev_path); 671 649 bl += sprintf(b + bl, " readonly: %d\n", ib_dev->ibd_readonly); 650 + bl += sprintf(b + bl, " exclusive: %d\n", ib_dev->ibd_exclusive); 672 651 673 652 bl += sprintf(b + bl, " "); 674 653 if (bd) {
+1
drivers/target/target_core_iblock.h
··· 34 34 struct block_device *ibd_bd; 35 35 struct file *ibd_bdev_file; 36 36 bool ibd_readonly; 37 + bool ibd_exclusive; 37 38 struct iblock_dev_plug *ibd_plug; 38 39 } ____cacheline_aligned; 39 40