* [PATCH] btrfs: harden identification of the stale device
@ 2021-12-08 14:05 Anand Jain
2021-12-08 14:29 ` Josef Bacik
2021-12-09 3:59 ` kernel test robot
0 siblings, 2 replies; 5+ messages in thread
From: Anand Jain @ 2021-12-08 14:05 UTC (permalink / raw)
To: linux-btrfs; +Cc: Josef Bacik
Identifying and removing the stale device from the fs_uuids list is done
by the function btrfs_free_stale_devices().
btrfs_free_stale_devices() in turn depends on the function
device_path_matched() to check if the device repeats in more than one
btrfs_device structure.
The matching of the device happens by its path, the device path. However,
when dm mapper is in use, the dm device paths are nothing but a link to
the actual block device, which leads to the device_path_matched() failing
to match.
Fix this by matching the dev_t as provided by lookup_bdev() instead of
plain strcmp() the device paths.
Reported-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
This patch should go to Stable-5.4.y and up but, there is a conflict.
I will send a separate patch for the stable.
fs/btrfs/volumes.c | 33 ++++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 553ee97078f6..cedadc81c851 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -535,15 +535,34 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
return ret;
}
-static bool device_path_matched(const char *path, struct btrfs_device *device)
+/*
+ * Check if the device in the 'path' matches with the device in the given
+ * struct btrfs_device '*device'.
+ * Returns:
+ * 0 If it is the same device.
+ * 1 If it is not the same device.
+ * -errno For error.
+ */
+static int device_matched(struct btrfs_device *device, const char *path)
{
- int found;
+ dev_t dev_old;
+ dev_t dev_new;
+ int error;
- rcu_read_lock();
- found = strcmp(rcu_str_deref(device->name), path);
- rcu_read_unlock();
+ lockdep_assert_held(&device->fs_devices->device_list_mutex);
+ /* rcu is not required as we are inside the device_list_mutex */
+ error = lookup_bdev(device->name->str, &dev_old);
+ if (error)
+ return error;
- return found == 0;
+ error = lookup_bdev(path, &dev_new);
+ if (error)
+ return error;
+
+ if (dev_old == dev_new)
+ return 0;
+
+ return 1;
}
/*
@@ -578,7 +597,7 @@ static int btrfs_free_stale_devices(const char *path,
continue;
if (path && !device->name)
continue;
- if (path && !device_path_matched(path, device))
+ if (path && device_matched(device, path) != 0)
continue;
if (fs_devices->opened) {
/* for an already deleted device return 0 */
--
2.33.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] btrfs: harden identification of the stale device
2021-12-08 14:05 [PATCH] btrfs: harden identification of the stale device Anand Jain
@ 2021-12-08 14:29 ` Josef Bacik
2021-12-10 12:54 ` Anand Jain
2021-12-09 3:59 ` kernel test robot
1 sibling, 1 reply; 5+ messages in thread
From: Josef Bacik @ 2021-12-08 14:29 UTC (permalink / raw)
To: Anand Jain; +Cc: linux-btrfs
On Wed, Dec 08, 2021 at 10:05:29PM +0800, Anand Jain wrote:
> Identifying and removing the stale device from the fs_uuids list is done
> by the function btrfs_free_stale_devices().
> btrfs_free_stale_devices() in turn depends on the function
> device_path_matched() to check if the device repeats in more than one
> btrfs_device structure.
>
> The matching of the device happens by its path, the device path. However,
> when dm mapper is in use, the dm device paths are nothing but a link to
> the actual block device, which leads to the device_path_matched() failing
> to match.
>
> Fix this by matching the dev_t as provided by lookup_bdev() instead of
> plain strcmp() the device paths.
>
> Reported-by: Josef Bacik <josef@toxicpanda.com>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
We already have the bdev for the device in most of the callers here, the only
exception is btrfs_forget_devices. Can we change this up to pass in the dev_t
of the device we're trying to remove, that way we don't have to do the lookup
over and over for the path of the device we're trying to forget? Thanks,
Josef
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] btrfs: harden identification of the stale device
2021-12-08 14:05 [PATCH] btrfs: harden identification of the stale device Anand Jain
2021-12-08 14:29 ` Josef Bacik
@ 2021-12-09 3:59 ` kernel test robot
2021-12-09 6:28 ` Anand Jain
1 sibling, 1 reply; 5+ messages in thread
From: kernel test robot @ 2021-12-09 3:59 UTC (permalink / raw)
To: Anand Jain, linux-btrfs; +Cc: kbuild-all, Josef Bacik
Hi Anand,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on kdave/for-next]
[also build test WARNING on v5.16-rc4 next-20211208]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Anand-Jain/btrfs-harden-identification-of-the-stale-device/20211208-220757
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: i386-randconfig-s001-20211207 (https://download.01.org/0day-ci/archive/20211209/202112091123.ETjD5KQj-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.4-dirty
# https://github.com/0day-ci/linux/commit/03b597640967afb3d37dc37f0a685fed95594b83
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Anand-Jain/btrfs-harden-identification-of-the-stale-device/20211208-220757
git checkout 03b597640967afb3d37dc37f0a685fed95594b83
# save the config file to linux build tree
mkdir build_dir
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=i386 SHELL=/bin/bash
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
fs/btrfs/volumes.c:402:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct rcu_string *str @@ got struct rcu_string [noderef] __rcu *name @@
fs/btrfs/volumes.c:402:31: sparse: expected struct rcu_string *str
fs/btrfs/volumes.c:402:31: sparse: got struct rcu_string [noderef] __rcu *name
>> fs/btrfs/volumes.c:549:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *pathname @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:549:35: sparse: expected char const *pathname
fs/btrfs/volumes.c:549:35: sparse: got char [noderef] __rcu *
fs/btrfs/volumes.c:643:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:643:43: sparse: expected char const *device_path
fs/btrfs/volumes.c:643:43: sparse: got char [noderef] __rcu *
fs/btrfs/volumes.c:904:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *cs @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:904:50: sparse: expected char const *cs
fs/btrfs/volumes.c:904:50: sparse: got char [noderef] __rcu *
fs/btrfs/volumes.c:984:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct rcu_string *str @@ got struct rcu_string [noderef] __rcu *name @@
fs/btrfs/volumes.c:984:39: sparse: expected struct rcu_string *str
fs/btrfs/volumes.c:984:39: sparse: got struct rcu_string [noderef] __rcu *name
fs/btrfs/volumes.c:1040:58: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *src @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:1040:58: sparse: expected char const *src
fs/btrfs/volumes.c:1040:58: sparse: got char [noderef] __rcu *
fs/btrfs/volumes.c:2235:49: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:2235:49: sparse: expected char const *device_path
fs/btrfs/volumes.c:2235:49: sparse: got char [noderef] __rcu *
fs/btrfs/volumes.c:2350:41: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
fs/btrfs/volumes.c:2350:41: sparse: expected char const *device_path
fs/btrfs/volumes.c:2350:41: sparse: got char [noderef] __rcu *
vim +549 fs/btrfs/volumes.c
532
533 /*
534 * Check if the device in the 'path' matches with the device in the given
535 * struct btrfs_device '*device'.
536 * Returns:
537 * 0 If it is the same device.
538 * 1 If it is not the same device.
539 * -errno For error.
540 */
541 static int device_matched(struct btrfs_device *device, const char *path)
542 {
543 dev_t dev_old;
544 dev_t dev_new;
545 int error;
546
547 lockdep_assert_held(&device->fs_devices->device_list_mutex);
548 /* rcu is not required as we are inside the device_list_mutex */
> 549 error = lookup_bdev(device->name->str, &dev_old);
550 if (error)
551 return error;
552
553 error = lookup_bdev(path, &dev_new);
554 if (error)
555 return error;
556
557 if (dev_old == dev_new)
558 return 0;
559
560 return 1;
561 }
562
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] btrfs: harden identification of the stale device
2021-12-09 3:59 ` kernel test robot
@ 2021-12-09 6:28 ` Anand Jain
0 siblings, 0 replies; 5+ messages in thread
From: Anand Jain @ 2021-12-09 6:28 UTC (permalink / raw)
To: kernel test robot, linux-btrfs; +Cc: kbuild-all, Josef Bacik
> sparse warnings: (new ones prefixed by >>)
The new Warning that this patch created is the same as the other 7 old
Warnings. It is all about how we have used the device:name.
I will fix the new Warning. Looks like we need to fix the older
Warning as well.
Thanks, Anand
> fs/btrfs/volumes.c:402:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct rcu_string *str @@ got struct rcu_string [noderef] __rcu *name @@
> fs/btrfs/volumes.c:402:31: sparse: expected struct rcu_string *str
> fs/btrfs/volumes.c:402:31: sparse: got struct rcu_string [noderef] __rcu *name
rcu_string_free(device->name);
>>> fs/btrfs/volumes.c:549:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *pathname @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:549:35: sparse: expected char const *pathname
> fs/btrfs/volumes.c:549:35: sparse: got char [noderef] __rcu *
error = lookup_bdev(device->name->str, &dev_old);
> fs/btrfs/volumes.c:643:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:643:43: sparse: expected char const *device_path
> fs/btrfs/volumes.c:643:43: sparse: got char [noderef] __rcu *
ret = btrfs_get_bdev_and_sb(device->name->str, flags, holder, 1,
&bdev, &disk_super);
> fs/btrfs/volumes.c:904:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *cs @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:904:50: sparse: expected char const *cs
> fs/btrfs/volumes.c:904:50: sparse: got char [noderef] __rcu *
} else if (!device->name || strcmp(device->name->str, path)) {
> fs/btrfs/volumes.c:984:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct rcu_string *str @@ got struct rcu_string [noderef] __rcu *name @@
> fs/btrfs/volumes.c:984:39: sparse: expected struct rcu_string *str
> fs/btrfs/volumes.c:984:39: sparse: got struct rcu_string [noderef] __rcu *name
rcu_string_free(device->name);
> fs/btrfs/volumes.c:1040:58: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char const *src @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:1040:58: sparse: expected char const *src
> fs/btrfs/volumes.c:1040:58: sparse: got char [noderef] __rcu *
name = rcu_string_strdup(orig_dev->name->str,
GFP_KERNEL);
> fs/btrfs/volumes.c:2235:49: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:2235:49: sparse: expected char const *device_path
> fs/btrfs/volumes.c:2235:49: sparse: got char [noderef] __rcu *
btrfs_scratch_superblocks(fs_info, device->bdev,
device->name->str);
> fs/btrfs/volumes.c:2350:41: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected char const *device_path @@ got char [noderef] __rcu * @@
> fs/btrfs/volumes.c:2350:41: sparse: expected char const *device_path
> fs/btrfs/volumes.c:2350:41: sparse: got char [noderef] __rcu *
btrfs_scratch_superblocks(tgtdev->fs_info, tgtdev->bdev,
tgtdev->name->str);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] btrfs: harden identification of the stale device
2021-12-08 14:29 ` Josef Bacik
@ 2021-12-10 12:54 ` Anand Jain
0 siblings, 0 replies; 5+ messages in thread
From: Anand Jain @ 2021-12-10 12:54 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs
On 08/12/2021 22:29, Josef Bacik wrote:
> On Wed, Dec 08, 2021 at 10:05:29PM +0800, Anand Jain wrote:
>> Identifying and removing the stale device from the fs_uuids list is done
>> by the function btrfs_free_stale_devices().
>> btrfs_free_stale_devices() in turn depends on the function
>> device_path_matched() to check if the device repeats in more than one
>> btrfs_device structure.
>>
>> The matching of the device happens by its path, the device path. However,
>> when dm mapper is in use, the dm device paths are nothing but a link to
>> the actual block device, which leads to the device_path_matched() failing
>> to match.
>>
>> Fix this by matching the dev_t as provided by lookup_bdev() instead of
>> plain strcmp() the device paths.
>>
>> Reported-by: Josef Bacik <josef@toxicpanda.com>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>
> We already have the bdev for the device in most of the callers here, the only
> exception is btrfs_forget_devices. Can we change this up to pass in the dev_t
> of the device we're trying to remove, that way we don't have to do the lookup
> over and over for the path of the device we're trying to forget? Thanks,
Right. I have made the related changes and, in v2, this change is on top
of this patch.
Thanks, Anand
>
> Josef
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-12-10 12:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-08 14:05 [PATCH] btrfs: harden identification of the stale device Anand Jain
2021-12-08 14:29 ` Josef Bacik
2021-12-10 12:54 ` Anand Jain
2021-12-09 3:59 ` kernel test robot
2021-12-09 6:28 ` Anand Jain
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).