From patchwork Fri Jul 8 12:23:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 9220761 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9DDE66044F for ; Fri, 8 Jul 2016 12:24:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62137269E2 for ; Fri, 8 Jul 2016 12:24:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 541A72861B; Fri, 8 Jul 2016 12:24:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E4939269E2 for ; Fri, 8 Jul 2016 12:24:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754847AbcGHMYO (ORCPT ); Fri, 8 Jul 2016 08:24:14 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:52025 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754180AbcGHMYO (ORCPT ); Fri, 8 Jul 2016 08:24:14 -0400 Received: from i60-34-157-115.s41.a006.ap.plala.or.jp ([60.34.157.115] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.85_2 #1 (Red Hat Linux)) id 1bLUpI-0005bv-Lu; Fri, 08 Jul 2016 12:24:13 +0000 From: Christoph Hellwig To: dm-devel@redhat.com, linux-scsi@vger.kernel.org Cc: linux-block@vger.kernel.org Subject: [PATCH 2/2] dm: call PR reserve/unreserve on each underlying device Date: Fri, 8 Jul 2016 21:23:51 +0900 Message-Id: <1467980631-18945-3-git-send-email-hch@lst.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1467980631-18945-1-git-send-email-hch@lst.de> References: <1467980631-18945-1-git-send-email-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP So far we tried to rely on the SCSI 'all target ports' bit to register all path, but for many setups this didn't work properly as the different path aren seen as separate initiators to the target instead of multiple ports of the same initiator. Because of that we'll stop setting the 'all target ports' bit in SCSI, and let device mapper handle iterating over the device for each path and register it manually. Signed-off-by: Christoph Hellwig Reviewed-by: Mike Christie --- drivers/md/dm.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 1b2f962..e4e98b7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -3601,26 +3601,81 @@ void dm_free_md_mempools(struct dm_md_mempools *pools) kfree(pools); } -static int dm_pr_register(struct block_device *bdev, u64 old_key, u64 new_key, - u32 flags) +struct dm_pr { + u64 old_key; + u64 new_key; + u32 flags; + bool fail_early; +}; + +static int dm_call_pr(struct block_device *bdev, iterate_devices_callout_fn fn, + void *data) { struct mapped_device *md = bdev->bd_disk->private_data; - const struct pr_ops *ops; - fmode_t mode; - int r; + struct dm_table *table; + struct dm_target *ti; + int ret = 0, srcu_idx; - r = dm_grab_bdev_for_ioctl(md, &bdev, &mode); - if (r < 0) - return r; + table = dm_get_live_table(md, &srcu_idx); + if (!table || !dm_table_get_size(table)) + return -ENOTTY; - ops = bdev->bd_disk->fops->pr_ops; - if (ops && ops->pr_register) - r = ops->pr_register(bdev, old_key, new_key, flags); - else - r = -EOPNOTSUPP; + /* We only support devices that have a single target */ + ret = -ENOTTY; + if (dm_table_get_num_targets(table) != 1) + goto out; + ti = dm_table_get_target(table, 0); - bdput(bdev); - return r; + ret = -EINVAL; + if (!ti->type->iterate_devices) + goto out; + + ret = ti->type->iterate_devices(ti, fn, data); + if (ret) + goto out; + + ret = 0; +out: + dm_put_live_table(md, srcu_idx); + return ret; +} + +/* + * For register / unregister we need to manually call out to every path. + */ +static int __dm_pr_register(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) +{ + struct dm_pr *pr = data; + const struct pr_ops *ops = dev->bdev->bd_disk->fops->pr_ops; + + if (!ops || !ops->pr_register) + return -EOPNOTSUPP; + return ops->pr_register(dev->bdev, pr->old_key, pr->new_key, pr->flags); +} + +static int dm_pr_register(struct block_device *bdev, u64 old_key, u64 new_key, + u32 flags) +{ + struct dm_pr pr = { + .old_key = old_key, + .new_key = new_key, + .flags = flags, + .fail_early = true, + }; + int ret; + + ret = dm_call_pr(bdev, __dm_pr_register, &pr); + if (ret && new_key) { + /* unregister all paths if we failed to register any path */ + pr.old_key = new_key; + pr.new_key = 0; + pr.flags = 0; + pr.fail_early = false; + dm_call_pr(bdev, __dm_pr_register, &pr); + } + + return ret; } static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,