linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).