From: Filipe Manana <fdmanana@kernel.org>
To: Qu Wenruo <quwenruo.btrfs@gmx.com>
Cc: Qu Wenruo <wqu@suse.com>,
linux-btrfs@vger.kernel.org, Filipe Manana <fdmanana@suse.com>,
Fabian Vogt <fvogt@suse.com>
Subject: Re: [PATCH v2 1/2] btrfs: avoid unnecessary device path update for the same device
Date: Wed, 2 Oct 2024 22:20:51 +0100 [thread overview]
Message-ID: <CAL3q7H66XxddXSiOZ3AC1=fbpyJb+Q5TQrw9ZR=ac4e-wR72Nw@mail.gmail.com> (raw)
In-Reply-To: <421d016b-672e-4eb7-bd0c-3269eb675f66@gmx.com>
On Wed, Oct 2, 2024 at 10:09 PM Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
>
>
>
> 在 2024/10/2 23:44, Filipe Manana 写道:
> > On Wed, Sep 25, 2024 at 1:14 AM Qu Wenruo <wqu@suse.com> wrote:
> >>
> >> [PROBLEM]
> >> It is very common for udev to trigger device scan, and every time a
> >> mounted btrfs device got re-scan from different soft links, we will get
> >> some of unnecessary device path updates, this is especially common
> >> for LVM based storage:
> >>
> >> # lvs
> >> scratch1 test -wi-ao---- 10.00g
> >> scratch2 test -wi-a----- 10.00g
> >> scratch3 test -wi-a----- 10.00g
> >> scratch4 test -wi-a----- 10.00g
> >> scratch5 test -wi-a----- 10.00g
> >> test test -wi-a----- 10.00g
> >>
> >> # mkfs.btrfs -f /dev/test/scratch1
> >> # mount /dev/test/scratch1 /mnt/btrfs
> >> # dmesg -c
> >> [ 205.705234] BTRFS: device fsid 7be2602f-9e35-4ecf-a6ff-9e91d2c182c9 devid 1 transid 6 /dev/mapper/test-scratch1 (253:4) scanned by mount (1154)
> >> [ 205.710864] BTRFS info (device dm-4): first mount of filesystem 7be2602f-9e35-4ecf-a6ff-9e91d2c182c9
> >> [ 205.711923] BTRFS info (device dm-4): using crc32c (crc32c-intel) checksum algorithm
> >> [ 205.713856] BTRFS info (device dm-4): using free-space-tree
> >> [ 205.722324] BTRFS info (device dm-4): checking UUID tree
> >>
> >> So far so good, but even if we just touched any soft link of
> >> "dm-4", we will get quite some unnecessary device path updates.
> >>
> >> # touch /dev/mapper/test-scratch1
> >> # dmesg -c
> >> [ 469.295796] BTRFS info: devid 1 device path /dev/mapper/test-scratch1 changed to /dev/dm-4 scanned by (udev-worker) (1221)
> >> [ 469.300494] BTRFS info: devid 1 device path /dev/dm-4 changed to /dev/mapper/test-scratch1 scanned by (udev-worker) (1221)
> >>
> >> Such device path rename is unnecessary and can lead to random path
> >> change due to the udev race.
> >>
> >> [CAUSE]
> >> Inside device_list_add(), we are using a very primitive way checking if
> >> the device has changed, strcmp().
> >>
> >> Which can never handle links well, no matter if it's hard or soft links.
> >>
> >> So every different link of the same device will be treated as a different
> >> device, causing the unnecessary device path update.
> >>
> >> [FIX]
> >> Introduce a helper, is_same_device(), and use path_equal() to properly
> >> detect the same block device.
> >> So that the different soft links won't trigger the rename race.
> >>
> >> Reviewed-by: Filipe Manana <fdmanana@suse.com>
> >> Link: https://bugzilla.suse.com/show_bug.cgi?id=1230641
> >> Reported-by: Fabian Vogt <fvogt@suse.com>
> >> Signed-off-by: Qu Wenruo <wqu@suse.com>
> >> ---
> >> fs/btrfs/volumes.c | 28 +++++++++++++++++++++++++++-
> >> 1 file changed, 27 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> >> index 995b0647f538..b713e4ebb362 100644
> >> --- a/fs/btrfs/volumes.c
> >> +++ b/fs/btrfs/volumes.c
> >> @@ -732,6 +732,32 @@ const u8 *btrfs_sb_fsid_ptr(const struct btrfs_super_block *sb)
> >> return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
> >> }
> >>
> >> +static bool is_same_device(struct btrfs_device *device, const char *new_path)
> >> +{
> >> + struct path old = { .mnt = NULL, .dentry = NULL };
> >> + struct path new = { .mnt = NULL, .dentry = NULL };
> >> + char *old_path;
> >> + bool is_same = false;
> >> + int ret;
> >> +
> >> + if (!device->name)
> >> + goto out;
> >> +
> >> + old_path = rcu_str_deref(device->name);
> >
> > There's a missing rcu_read_lock / unlock btw. It's triggering warnings
> > in the test vms.
>
> Thanks a lot, I was also wondering if it's the case, but the zoned code
> gave me a bad example of not calling rcu_read_lock().
It doesn't call rcu_read_lock() explicitly because it uses the
btrfs_*_in_rcu() log functions, which do the locking.
Except for one place for which I've sent a patch earlier today.
>
> Shouldn't all btrfs_dev_name() and the usages inside zoned code also be
> fixed?
Except for that single case, there's no other case anywhere else,
zoned code or non-zoned code.
>
> Thanks,
> Qu
> >
> > Thanks.
> >
> >> + ret = kern_path(old_path, LOOKUP_FOLLOW, &old);
> >> + if (ret)
> >> + goto out;
> >> + ret = kern_path(new_path, LOOKUP_FOLLOW, &new);
> >> + if (ret)
> >> + goto out;
> >> + if (path_equal(&old, &new))
> >> + is_same = true;
> >> +out:
> >> + path_put(&old);
> >> + path_put(&new);
> >> + return is_same;
> >> +}
> >> +
> >> /*
> >> * Add new device to list of registered devices
> >> *
> >> @@ -852,7 +878,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
> >> MAJOR(path_devt), MINOR(path_devt),
> >> current->comm, task_pid_nr(current));
> >>
> >> - } else if (!device->name || strcmp(device->name->str, path)) {
> >> + } else if (!device->name || !is_same_device(device, path)) {
> >> /*
> >> * When FS is already mounted.
> >> * 1. If you are here and if the device->name is NULL that
> >> --
> >> 2.46.1
> >>
> >>
> >
>
next prev parent reply other threads:[~2024-10-02 21:21 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-25 0:05 [PATCH v2 0/2] btrfs: enhance btrfs device path rename Qu Wenruo
2024-09-25 0:05 ` [PATCH v2 1/2] btrfs: avoid unnecessary device path update for the same device Qu Wenruo
2024-10-02 14:14 ` Filipe Manana
2024-10-02 21:09 ` Qu Wenruo
2024-10-02 21:20 ` Filipe Manana [this message]
2024-09-25 0:06 ` [PATCH v2 2/2] btrfs: canonicalize the device path before adding it Qu Wenruo
2024-09-25 11:04 ` Filipe Manana
2024-09-30 5:26 ` Anand Jain
2024-09-30 5:31 ` Qu Wenruo
2024-09-30 12:40 ` Anand Jain
2024-09-30 21:42 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAL3q7H66XxddXSiOZ3AC1=fbpyJb+Q5TQrw9ZR=ac4e-wR72Nw@mail.gmail.com' \
--to=fdmanana@kernel.org \
--cc=fdmanana@suse.com \
--cc=fvogt@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=quwenruo.btrfs@gmx.com \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).