Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp2359694pxb; Thu, 11 Feb 2021 10:19:12 -0800 (PST) X-Google-Smtp-Source: ABdhPJx2Cq2wmq4Tf8fpQFy8DkHLU6IvhTPP/YyoXYHqdd7ggm1X7C45QdtyYbp/hNr+pn7SBOZH X-Received: by 2002:a05:6402:2553:: with SMTP id l19mr9465044edb.326.1613067552335; Thu, 11 Feb 2021 10:19:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613067552; cv=none; d=google.com; s=arc-20160816; b=zM5MNuIWmc60OCUHT5+7TTFkfpLyMCVDNXS1EHdoosSILUli1Rm53FpzW3rUfnHPI7 wuJompkqzBJAC5Bx5rUFq7j1FNFrZLimSfY5szrn42xUywsNamSYa1h2uLNPKpExHaeu OpxjDcR4+bA6K7d8uEyTEBExjlmquMB1sosy4AmaKLRyY0kk6L7KGhxI9rrMpxQtvS6M iweCmq/Eov1jPHZyxCx9RyTm9rCb9CeE4oRdVbaTYC1M2l1wgVY2ZAeQltLpR3YGrEy8 U+U0YTJ05DlnKa0y5BGlMff3Qxcbw58jqJTUAFUMCqOJ03jMuEuW4G/HCKZhxRQ3EhzD EbbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=fenxytKArqtTHKIX0KFNGto9Rr37iOO0PVNFNChrRes=; b=085gNIR/qoIm/y213KhuxMYdrPDoGYSUhKsPhgLh3JOskDjijU3TaCaulsj0aj3sU+ y0UcpXMQm5vnWmZasqVj3x0umwSov97xO9a3WyOn7NfZRIP5/WIf8WCN9L89ZSeu4W4C BxJF5m67qosy2XGrxjvECfMdOI/vOPljEKr7DjInTG1SQU02vZXJNmGpNSydso2acPXN IgjNLbdheBixemfIb17rzCJuZlqceVxkKxQL4c1Azqpl5ACW+DpM/V7lKml4ubHMfo9N ybqtbL0bMQZ71UE0vGc6JFyVI4RE71ErMiA/cqxOgx5ExOYnM+GOf6+gwtayQzYYH86M i9/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=e3HpFZ9Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hq38si3899026ejc.21.2021.02.11.10.18.42; Thu, 11 Feb 2021 10:19:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=e3HpFZ9Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231516AbhBKSRZ (ORCPT + 99 others); Thu, 11 Feb 2021 13:17:25 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:30005 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230445AbhBKRxj (ORCPT ); Thu, 11 Feb 2021 12:53:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1613065928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=fenxytKArqtTHKIX0KFNGto9Rr37iOO0PVNFNChrRes=; b=e3HpFZ9Q8IbZWnpixonww1xygudzl0KQpXgNVrfUzfyil7lms97rmzMiyd31nz1xYbhVca odYp4C/7pFj4qk4gpYfK4how0Qt6lR8JjRgKk7TUoTGUeD4N9413pqgrTLrdNut0vwQRuC K54GoiNW86yJ91HN3mEAdRvmqhKBSqk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-278-0ivb-37aPGug7-ZVGVREEA-1; Thu, 11 Feb 2021 12:52:04 -0500 X-MC-Unique: 0ivb-37aPGug7-ZVGVREEA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 36A5A1020C25; Thu, 11 Feb 2021 17:52:02 +0000 (UTC) Received: from localhost (unknown [10.18.25.174]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 90E105D6B1; Thu, 11 Feb 2021 17:51:52 +0000 (UTC) Date: Thu, 11 Feb 2021 12:51:51 -0500 From: Mike Snitzer To: Sergei Shtepa Cc: Damien.LeMoal@wdc.com, hare@suse.de, ming.lei@redhat.com, agk@redhat.com, corbet@lwn.net, axboe@kernel.dk, jack@suse.cz, johannes.thumshirn@wdc.com, gregkh@linuxfoundation.org, koct9i@gmail.com, steve@sk2.org, dm-devel@redhat.com, linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, pavel.tide@veeam.com Subject: Re: [PATCH v5 5/6] dm: add 'noexcl' option for dm-linear Message-ID: <20210211175151.GA13839@redhat.com> References: <1612881028-7878-1-git-send-email-sergei.shtepa@veeam.com> <1612881028-7878-6-git-send-email-sergei.shtepa@veeam.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1612881028-7878-6-git-send-email-sergei.shtepa@veeam.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Feb 09 2021 at 9:30am -0500, Sergei Shtepa wrote: > The 'noexcl' option allow to open underlying block-device > without FMODE_EXCL. > > Signed-off-by: Sergei Shtepa > --- > drivers/md/dm-linear.c | 14 +++++++++++++- > drivers/md/dm-table.c | 14 ++++++++------ > drivers/md/dm.c | 26 +++++++++++++++++++------- > drivers/md/dm.h | 2 +- > include/linux/device-mapper.h | 7 +++++++ > 5 files changed, 48 insertions(+), 15 deletions(-) > > diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c > index 00774b5d7668..b16d89802b9d 100644 > --- a/drivers/md/dm-linear.c > +++ b/drivers/md/dm-linear.c > @@ -33,7 +33,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) > char dummy; > int ret; > > - if (argc != 2) { > + if ((argc < 2) || (argc > 3)) { > ti->error = "Invalid argument count"; > return -EINVAL; > } > @@ -51,6 +51,18 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) > } > lc->start = tmp; > > + ti->non_exclusive = false; > + if (argc > 2) { > + if (strcmp("noexcl", argv[2]) == 0) > + ti->non_exclusive = true; > + else if (strcmp("excl", argv[2]) == 0) > + ti->non_exclusive = false; > + else { > + ti->error = "Invalid exclusive option"; > + return -EINVAL; > + } > + } > + > ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev); > if (ret) { > ti->error = "Device lookup failed"; > diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c > index 4acf2342f7ad..f020459465bd 100644 > --- a/drivers/md/dm-table.c > +++ b/drivers/md/dm-table.c > @@ -322,7 +322,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, > * device and not to touch the existing bdev field in case > * it is accessed concurrently. > */ > -static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, > +static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, bool non_exclusive, > struct mapped_device *md) > { > int r; > @@ -330,8 +330,8 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, > > old_dev = dd->dm_dev; > > - r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, > - dd->dm_dev->mode | new_mode, &new_dev); > + r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, dd->dm_dev->mode | new_mode, > + non_exclusive, &new_dev); > if (r) > return r; > > @@ -387,7 +387,8 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, > if (!dd) > return -ENOMEM; > > - if ((r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev))) { > + r = dm_get_table_device(t->md, dev, mode, ti->non_exclusive, &dd->dm_dev); > + if (r) { > kfree(dd); > return r; > } > @@ -396,8 +397,9 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, > list_add(&dd->list, &t->devices); > goto out; > > - } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { > - r = upgrade_mode(dd, mode, t->md); > + } else if ((dd->dm_dev->mode != (mode | dd->dm_dev->mode)) && > + (dd->dm_dev->non_exclusive != ti->non_exclusive)) { > + r = upgrade_mode(dd, mode, ti->non_exclusive, t->md); > if (r) > return r; > } > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > index 00c41aa6d092..c25dcc2fdb89 100644 > --- a/drivers/md/dm.c > +++ b/drivers/md/dm.c > @@ -1117,33 +1117,44 @@ static void close_table_device(struct table_device *td, struct mapped_device *md > if (!td->dm_dev.bdev) > return; > > - bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); > - blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); > + if (td->dm_dev.non_exclusive) > + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode); > + else { > + bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); > + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); > + } > + > + > + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode); > + > put_dax(td->dm_dev.dax_dev); > td->dm_dev.bdev = NULL; > td->dm_dev.dax_dev = NULL; > + td->dm_dev.non_exclusive = false; > } > > static struct table_device *find_table_device(struct list_head *l, dev_t dev, > - fmode_t mode) > + fmode_t mode, bool non_exclusive) > { > struct table_device *td; > > list_for_each_entry(td, l, list) > - if (td->dm_dev.bdev->bd_dev == dev && td->dm_dev.mode == mode) > + if (td->dm_dev.bdev->bd_dev == dev && > + td->dm_dev.mode == mode && > + td->dm_dev.non_exclusive == non_exclusive) > return td; > > return NULL; > } > > -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, > +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, > struct dm_dev **result) > { > int r; > struct table_device *td; > > mutex_lock(&md->table_devices_lock); > - td = find_table_device(&md->table_devices, dev, mode); > + td = find_table_device(&md->table_devices, dev, mode, non_exclusive); > if (!td) { > td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id); > if (!td) { > @@ -1154,7 +1165,8 @@ int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, > td->dm_dev.mode = mode; > td->dm_dev.bdev = NULL; > > - if ((r = open_table_device(td, dev, md))) { > + r = open_table_device(td, dev, md, non_exclusive); > + if (r) { > mutex_unlock(&md->table_devices_lock); > kfree(td); > return r; > diff --git a/drivers/md/dm.h b/drivers/md/dm.h > index fffe1e289c53..7bf20fb2de74 100644 > --- a/drivers/md/dm.h > +++ b/drivers/md/dm.h > @@ -179,7 +179,7 @@ int dm_open_count(struct mapped_device *md); > int dm_lock_for_deletion(struct mapped_device *md, bool mark_deferred, bool only_deferred); > int dm_cancel_deferred_remove(struct mapped_device *md); > int dm_request_based(struct mapped_device *md); > -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, > +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, > struct dm_dev **result); > void dm_put_table_device(struct mapped_device *md, struct dm_dev *d); > > diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h > index 61a66fb8ebb3..70002363bfc0 100644 > --- a/include/linux/device-mapper.h > +++ b/include/linux/device-mapper.h > @@ -150,6 +150,7 @@ struct dm_dev { > struct block_device *bdev; > struct dax_device *dax_dev; > fmode_t mode; > + bool non_exclusive; > char name[16]; > }; > > @@ -325,6 +326,12 @@ struct dm_target { > * whether or not its underlying devices have support. > */ > bool discards_supported:1; > + > + /* > + * Set if this target needs to open device without FMODE_EXCL > + * mode. > + */ > + bool non_exclusive:1; > }; > > void *dm_per_bio_data(struct bio *bio, size_t data_size); > -- > 2.20.1 > I'm really not liking this tug-of-war about FMODE_EXCL vs not. Especially dislike the prospect of needing to change _every_ DM target that would be made to support blk_interposer. I've said this before, private or otherwise, but: Hannes' approach that fell back to opening without FMODE_EXCL if FMODE_EXCL open failed. Have you explored that kind of approach? You _should_ be able to infer that interposer is being used given the requirement to use an explicit remap ioctl to establish the use of interposer. Mike