All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/3] btrfs: cleanup prepare_sprout
@ 2021-09-21  4:33 Anand Jain
  2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Anand Jain @ 2021-09-21  4:33 UTC (permalink / raw)
  To: linux-btrfs, dsterba

Patch 3/3 was part of the patchset [1] before.
 [1] btrfs: device_list_mutex fix lockdep warn and cleanup
As the patch 1/2 in [1] is already merged, so the patch 2/2
in [1] along with the other cleanup has formed a new set here.

Patch 1/3 and 2/3 are a minor cleanup in btrfs_prepare_sprout().
Patch 3/3 cleans btrfs_prepare_sprout() so that a part of it
can be within the device_list_mutex in the parent function 
btrfs_init_new_device().

v6:
Patch 1/3 and 2/3 are new.
Removed RFC from 3/3. Take memory allocation out of device_list_mutex.

Anand Jain (3):
  btrfs: declare seeding_dev in init_new_device as bool
  btrfs: remove unused device_list_mutex for seed fs_devices
  btrfs: consolidate device_list_mutex in prepare_sprout to its parent

 fs/btrfs/volumes.c | 51 ++++++++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 18 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool
  2021-09-21  4:33 [PATCH v6 0/3] btrfs: cleanup prepare_sprout Anand Jain
@ 2021-09-21  4:33 ` Anand Jain
  2021-09-21 11:01   ` Nikolay Borisov
  2021-10-13  8:00   ` Anand Jain
  2021-09-21  4:33 ` [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices Anand Jain
  2021-09-21  4:33 ` [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent Anand Jain
  2 siblings, 2 replies; 14+ messages in thread
From: Anand Jain @ 2021-09-21  4:33 UTC (permalink / raw)
  To: linux-btrfs, dsterba

This patch declares int seeding_dev as a bool. Also, move its declaration
a line below to adjust packing.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v6: new
 fs/btrfs/volumes.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 5117c5816922..c4bc49e58b69 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2532,8 +2532,8 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
 	u64 orig_super_total_bytes;
 	u64 orig_super_num_devices;
-	int seeding_dev = 0;
 	int ret = 0;
+	bool seeding_dev = false;
 	bool locked = false;
 
 	if (sb_rdonly(sb) && !fs_devices->seeding)
@@ -2550,7 +2550,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 	}
 
 	if (fs_devices->seeding) {
-		seeding_dev = 1;
+		seeding_dev = true;
 		down_write(&sb->s_umount);
 		mutex_lock(&uuid_mutex);
 		locked = true;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices
  2021-09-21  4:33 [PATCH v6 0/3] btrfs: cleanup prepare_sprout Anand Jain
  2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
@ 2021-09-21  4:33 ` Anand Jain
  2021-09-21  6:44   ` Nikolay Borisov
  2021-09-21  4:33 ` [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent Anand Jain
  2 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2021-09-21  4:33 UTC (permalink / raw)
  To: linux-btrfs, dsterba

The btrfs_fs_devices::seed_list is of type btrfs_fs_devices as well and,
it is a pointer to the seed btrfs_fs_device in a btrfs created from a
seed devices.
In this struct, when it points to seed, the device_list_mutex is not
used. So drop its initialize.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v6: new
 fs/btrfs/volumes.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c4bc49e58b69..e4079e25db70 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2418,7 +2418,6 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
 	seed_devices->opened = 1;
 	INIT_LIST_HEAD(&seed_devices->devices);
 	INIT_LIST_HEAD(&seed_devices->alloc_list);
-	mutex_init(&seed_devices->device_list_mutex);
 
 	mutex_lock(&fs_devices->device_list_mutex);
 	list_splice_init_rcu(&fs_devices->devices, &seed_devices->devices,
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent
  2021-09-21  4:33 [PATCH v6 0/3] btrfs: cleanup prepare_sprout Anand Jain
  2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
  2021-09-21  4:33 ` [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices Anand Jain
@ 2021-09-21  4:33 ` Anand Jain
  2021-09-21 11:01   ` Nikolay Borisov
  2 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2021-09-21  4:33 UTC (permalink / raw)
  To: linux-btrfs, dsterba

btrfs_prepare_sprout() splices seed devices into its own struct fs_devices,
so that its parent function btrfs_init_new_device() can add the new sprout
device to fs_info->fs_devices.

Both btrfs_prepare_sprout() and btrfs_init_new_device() needs
device_list_mutex. But they are holding it sequentially, thus creates a
small window to an opportunity to race. Close this opportunity and hold
device_list_mutex common to both btrfs_init_new_device() and
btrfs_prepare_sprout().

This patch splits btrfs_prepare_sprout() into btrfs_alloc_sprout() and
btrfs_splice_sprout(). This split is essential because device_list_mutex
shouldn't be held for btrfs_alloc_sprout() but must be held for
btrfs_splice_sprout(). So now a common device_list_mutex can be used
between btrfs_init_new_device() and btrfs_splice_sprout().

This patch also moves the lockdep_assert_held(&uuid_mutex) from the
starting of the function to just above the line where we need this lock.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v6:
 Remove RFC.
 Split btrfs_prepare_sprout so that the allocation part can be outside
 of the device_list_mutex in the parent function btrfs_init_new_device().

 fs/btrfs/volumes.c | 46 +++++++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e4079e25db70..b21eac32ec98 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2376,19 +2376,13 @@ struct btrfs_device *btrfs_find_device_by_devspec(
 	return btrfs_find_device_by_path(fs_info, device_path);
 }
 
-/*
- * does all the dirty work required for changing file system's UUID.
- */
-static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
+static int btrfs_alloc_sprout(struct btrfs_fs_info *fs_info,
+			      struct btrfs_fs_devices **seed_devices_ret)
 {
 	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
 	struct btrfs_fs_devices *old_devices;
 	struct btrfs_fs_devices *seed_devices;
-	struct btrfs_super_block *disk_super = fs_info->super_copy;
-	struct btrfs_device *device;
-	u64 super_flags;
 
-	lockdep_assert_held(&uuid_mutex);
 	if (!fs_devices->seeding)
 		return -EINVAL;
 
@@ -2412,6 +2406,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
 		return PTR_ERR(old_devices);
 	}
 
+	lockdep_assert_held(&uuid_mutex);
 	list_add(&old_devices->fs_list, &fs_uuids);
 
 	memcpy(seed_devices, fs_devices, sizeof(*seed_devices));
@@ -2419,7 +2414,23 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
 	INIT_LIST_HEAD(&seed_devices->devices);
 	INIT_LIST_HEAD(&seed_devices->alloc_list);
 
-	mutex_lock(&fs_devices->device_list_mutex);
+	*seed_devices_ret = seed_devices;
+
+	return 0;
+}
+
+/*
+ * Splice seed devices into the sprout fs_devices.
+ * Generate a new fsid for the sprouted readwrite btrfs.
+ */
+static void btrfs_splice_sprout(struct btrfs_fs_info *fs_info,
+				struct btrfs_fs_devices *seed_devices)
+{
+	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+	struct btrfs_super_block *disk_super = fs_info->super_copy;
+	struct btrfs_device *device;
+	u64 super_flags;
+
 	list_splice_init_rcu(&fs_devices->devices, &seed_devices->devices,
 			      synchronize_rcu);
 	list_for_each_entry(device, &seed_devices->devices, dev_list)
@@ -2435,13 +2446,10 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
 	generate_random_uuid(fs_devices->fsid);
 	memcpy(fs_devices->metadata_uuid, fs_devices->fsid, BTRFS_FSID_SIZE);
 	memcpy(disk_super->fsid, fs_devices->fsid, BTRFS_FSID_SIZE);
-	mutex_unlock(&fs_devices->device_list_mutex);
 
 	super_flags = btrfs_super_flags(disk_super) &
 		      ~BTRFS_SUPER_FLAG_SEEDING;
 	btrfs_set_super_flags(disk_super, super_flags);
-
-	return 0;
 }
 
 /*
@@ -2529,6 +2537,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 	struct super_block *sb = fs_info->sb;
 	struct rcu_string *name;
 	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+	struct btrfs_fs_devices *seed_devices;
 	u64 orig_super_total_bytes;
 	u64 orig_super_num_devices;
 	int ret = 0;
@@ -2612,18 +2621,25 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 
 	if (seeding_dev) {
 		btrfs_clear_sb_rdonly(sb);
-		ret = btrfs_prepare_sprout(fs_info);
+
+		/* GFP_KERNEL alloc should not be under device_list_mutex */
+		ret = btrfs_alloc_sprout(fs_info, &seed_devices);
 		if (ret) {
 			btrfs_abort_transaction(trans, ret);
 			goto error_trans;
 		}
+	}
+
+	mutex_lock(&fs_devices->device_list_mutex);
+	if (seeding_dev) {
+		btrfs_splice_sprout(fs_info, seed_devices);
+
 		btrfs_assign_next_active_device(fs_info->fs_devices->latest_dev,
 						device);
 	}
 
 	device->fs_devices = fs_devices;
 
-	mutex_lock(&fs_devices->device_list_mutex);
 	mutex_lock(&fs_info->chunk_mutex);
 	list_add_rcu(&device->dev_list, &fs_devices->devices);
 	list_add(&device->dev_alloc_list, &fs_devices->alloc_list);
@@ -2685,7 +2701,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 
 		/*
 		 * fs_devices now represents the newly sprouted filesystem and
-		 * its fsid has been changed by btrfs_prepare_sprout
+		 * its fsid has been changed by btrfs_sprout_splice().
 		 */
 		btrfs_sysfs_update_sprout_fsid(fs_devices);
 	}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices
  2021-09-21  4:33 ` [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices Anand Jain
@ 2021-09-21  6:44   ` Nikolay Borisov
  2021-09-22 11:29     ` Anand Jain
  0 siblings, 1 reply; 14+ messages in thread
From: Nikolay Borisov @ 2021-09-21  6:44 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs, dsterba



On 21.09.21 г. 7:33, Anand Jain wrote:
> The btrfs_fs_devices::seed_list is of type btrfs_fs_devices as well and,

seed_list is in fact a list_head which points to btrfs_fs_devices, so
that sentence is somewhat misleading.

> it is a pointer to the seed btrfs_fs_device in a btrfs created from a
> seed devices.
> In this struct, when it points to seed, the device_list_mutex is not
> used. So drop its initialize.

Even if the device_list_mutex is not used in the seed_devices it will
have whatever is the state from the original fs_devices so
re-initializing it to a sane state is the right thing to do.

We don't need this.

> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> v6: new
>  fs/btrfs/volumes.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index c4bc49e58b69..e4079e25db70 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -2418,7 +2418,6 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>  	seed_devices->opened = 1;
>  	INIT_LIST_HEAD(&seed_devices->devices);
>  	INIT_LIST_HEAD(&seed_devices->alloc_list);
> -	mutex_init(&seed_devices->device_list_mutex);
>  
>  	mutex_lock(&fs_devices->device_list_mutex);
>  	list_splice_init_rcu(&fs_devices->devices, &seed_devices->devices,
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent
  2021-09-21  4:33 ` [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent Anand Jain
@ 2021-09-21 11:01   ` Nikolay Borisov
  2021-09-22 11:41     ` Anand Jain
  0 siblings, 1 reply; 14+ messages in thread
From: Nikolay Borisov @ 2021-09-21 11:01 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs, dsterba



On 21.09.21 г. 7:33, Anand Jain wrote:
> btrfs_prepare_sprout() splices seed devices into its own struct fs_devices,
> so that its parent function btrfs_init_new_device() can add the new sprout
> device to fs_info->fs_devices.
> 
> Both btrfs_prepare_sprout() and btrfs_init_new_device() needs
> device_list_mutex. But they are holding it sequentially, thus creates a
> small window to an opportunity to race. Close this opportunity and hold
> device_list_mutex common to both btrfs_init_new_device() and
> btrfs_prepare_sprout().
> 
> This patch splits btrfs_prepare_sprout() into btrfs_alloc_sprout() and
> btrfs_splice_sprout(). This split is essential because device_list_mutex
> shouldn't be held for btrfs_alloc_sprout() but must be held for
> btrfs_splice_sprout(). So now a common device_list_mutex can be used
> between btrfs_init_new_device() and btrfs_splice_sprout().
> 
> This patch also moves the lockdep_assert_held(&uuid_mutex) from the
> starting of the function to just above the line where we need this lock.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> v6:
>  Remove RFC.
>  Split btrfs_prepare_sprout so that the allocation part can be outside
>  of the device_list_mutex in the parent function btrfs_init_new_device().
> 
>  fs/btrfs/volumes.c | 46 +++++++++++++++++++++++++++++++---------------
>  1 file changed, 31 insertions(+), 15 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index e4079e25db70..b21eac32ec98 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -2376,19 +2376,13 @@ struct btrfs_device *btrfs_find_device_by_devspec(
>  	return btrfs_find_device_by_path(fs_info, device_path);
>  }
>  
> -/*
> - * does all the dirty work required for changing file system's UUID.
> - */
> -static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
> +static int btrfs_alloc_sprout(struct btrfs_fs_info *fs_info,
> +			      struct btrfs_fs_devices **seed_devices_ret)

Nope, make the function return a struct btrfs_fs_devices *.

>  {
>  	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
>  	struct btrfs_fs_devices *old_devices;
>  	struct btrfs_fs_devices *seed_devices;
> -	struct btrfs_super_block *disk_super = fs_info->super_copy;
> -	struct btrfs_device *device;
> -	u64 super_flags;
>  
> -	lockdep_assert_held(&uuid_mutex);
>  	if (!fs_devices->seeding)
>  		return -EINVAL;
>  
> @@ -2412,6 +2406,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>  		return PTR_ERR(old_devices);
>  	}
>  
> +	lockdep_assert_held(&uuid_mutex);
>  	list_add(&old_devices->fs_list, &fs_uuids);
>  
>  	memcpy(seed_devices, fs_devices, sizeof(*seed_devices));
> @@ -2419,7 +2414,23 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>  	INIT_LIST_HEAD(&seed_devices->devices);
>  	INIT_LIST_HEAD(&seed_devices->alloc_list);
>  
> -	mutex_lock(&fs_devices->device_list_mutex);
> +	*seed_devices_ret = seed_devices;
> +
> +	return 0;
> +}
> +
> +/*
> + * Splice seed devices into the sprout fs_devices.
> + * Generate a new fsid for the sprouted readwrite btrfs.
> + */
> +static void btrfs_splice_sprout(struct btrfs_fs_info *fs_info,
> +				struct btrfs_fs_devices *seed_devices)
> +{

This function is missing a lockdep_assert_held annotation and it depends
on the device_list_mutex being held.

However looking at the resulting code it doesn't look good, because
btrfs_splice_sporut suggests you simply add the seed device to a bunch
of places, yet looking at the function's body it's evident it actually
finishes some parts of the initialization, changes the uuid of the
fs_devices. I'm not convinced it really makes the code better or at the
very least the 'splice_sprout' needs to be changed, because splicing is
a minot part of what this function really does.


<snip>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool
  2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
@ 2021-09-21 11:01   ` Nikolay Borisov
  2021-10-13  8:00   ` Anand Jain
  1 sibling, 0 replies; 14+ messages in thread
From: Nikolay Borisov @ 2021-09-21 11:01 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs, dsterba



On 21.09.21 г. 7:33, Anand Jain wrote:
> This patch declares int seeding_dev as a bool. Also, move its declaration
> a line below to adjust packing.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>

Reviewed-by: Nikolay Borisov <nborisov@suse.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices
  2021-09-21  6:44   ` Nikolay Borisov
@ 2021-09-22 11:29     ` Anand Jain
  0 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2021-09-22 11:29 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: linux-btrfs, dsterba

On 21/09/2021 14:44, Nikolay Borisov wrote:
> 
> 
> On 21.09.21 г. 7:33, Anand Jain wrote:
>> The btrfs_fs_devices::seed_list is of type btrfs_fs_devices as well and,
> 
> seed_list is in fact a list_head which points to btrfs_fs_devices, so
> that sentence is somewhat misleading.
> 
>> it is a pointer to the seed btrfs_fs_device in a btrfs created from a
>> seed devices.
>> In this struct, when it points to seed, the device_list_mutex is not
>> used. So drop its initialize.
> 
> Even if the device_list_mutex is not used in the seed_devices it will
> have whatever is the state from the original fs_devices so
> re-initializing it to a sane state is the right thing to do.
> 
> We don't need this.

  I agree. Maybe at some point, we should have a separate new struct for 
the seed's fs_devices, as few members in it aren't in use.

  We can drop this patch.

Thanks, Anand

> 
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>> v6: new
>>   fs/btrfs/volumes.c | 1 -
>>   1 file changed, 1 deletion(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index c4bc49e58b69..e4079e25db70 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -2418,7 +2418,6 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>>   	seed_devices->opened = 1;
>>   	INIT_LIST_HEAD(&seed_devices->devices);
>>   	INIT_LIST_HEAD(&seed_devices->alloc_list);
>> -	mutex_init(&seed_devices->device_list_mutex);
>>   
>>   	mutex_lock(&fs_devices->device_list_mutex);
>>   	list_splice_init_rcu(&fs_devices->devices, &seed_devices->devices,
>>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent
  2021-09-21 11:01   ` Nikolay Borisov
@ 2021-09-22 11:41     ` Anand Jain
  2021-09-23  6:52       ` Nikolay Borisov
  0 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2021-09-22 11:41 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: linux-btrfs, dsterba

On 21/09/2021 19:01, Nikolay Borisov wrote:
> 
> 
> On 21.09.21 г. 7:33, Anand Jain wrote:
>> btrfs_prepare_sprout() splices seed devices into its own struct fs_devices,
>> so that its parent function btrfs_init_new_device() can add the new sprout
>> device to fs_info->fs_devices.
>>
>> Both btrfs_prepare_sprout() and btrfs_init_new_device() needs
>> device_list_mutex. But they are holding it sequentially, thus creates a
>> small window to an opportunity to race. Close this opportunity and hold
>> device_list_mutex common to both btrfs_init_new_device() and
>> btrfs_prepare_sprout().
>>
>> This patch splits btrfs_prepare_sprout() into btrfs_alloc_sprout() and
>> btrfs_splice_sprout(). This split is essential because device_list_mutex
>> shouldn't be held for btrfs_alloc_sprout() but must be held for
>> btrfs_splice_sprout(). So now a common device_list_mutex can be used
>> between btrfs_init_new_device() and btrfs_splice_sprout().
>>
>> This patch also moves the lockdep_assert_held(&uuid_mutex) from the
>> starting of the function to just above the line where we need this lock.
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>> v6:
>>   Remove RFC.
>>   Split btrfs_prepare_sprout so that the allocation part can be outside
>>   of the device_list_mutex in the parent function btrfs_init_new_device().
>>
>>   fs/btrfs/volumes.c | 46 +++++++++++++++++++++++++++++++---------------
>>   1 file changed, 31 insertions(+), 15 deletions(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index e4079e25db70..b21eac32ec98 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -2376,19 +2376,13 @@ struct btrfs_device *btrfs_find_device_by_devspec(
>>   	return btrfs_find_device_by_path(fs_info, device_path);
>>   }
>>   
>> -/*
>> - * does all the dirty work required for changing file system's UUID.
>> - */
>> -static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>> +static int btrfs_alloc_sprout(struct btrfs_fs_info *fs_info,
>> +			      struct btrfs_fs_devices **seed_devices_ret)
> 
> Nope, make the function return a struct btrfs_fs_devices *.
> 

  Ok.

>>   {
>>   	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
>>   	struct btrfs_fs_devices *old_devices;
>>   	struct btrfs_fs_devices *seed_devices;
>> -	struct btrfs_super_block *disk_super = fs_info->super_copy;
>> -	struct btrfs_device *device;
>> -	u64 super_flags;
>>   
>> -	lockdep_assert_held(&uuid_mutex);
>>   	if (!fs_devices->seeding)
>>   		return -EINVAL;
>>   
>> @@ -2412,6 +2406,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>>   		return PTR_ERR(old_devices);
>>   	}
>>   
>> +	lockdep_assert_held(&uuid_mutex);
>>   	list_add(&old_devices->fs_list, &fs_uuids);
>>   
>>   	memcpy(seed_devices, fs_devices, sizeof(*seed_devices));
>> @@ -2419,7 +2414,23 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
>>   	INIT_LIST_HEAD(&seed_devices->devices);
>>   	INIT_LIST_HEAD(&seed_devices->alloc_list);
>>   
>> -	mutex_lock(&fs_devices->device_list_mutex);
>> +	*seed_devices_ret = seed_devices;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Splice seed devices into the sprout fs_devices.
>> + * Generate a new fsid for the sprouted readwrite btrfs.
>> + */
>> +static void btrfs_splice_sprout(struct btrfs_fs_info *fs_info,
>> +				struct btrfs_fs_devices *seed_devices)
>> +{
> 
> This function is missing a lockdep_assert_held annotation and it depends
> on the device_list_mutex being held.

  You mean
     lockdep_assert_held(&device_list_mutex);
  and not
     lockdep_assert_held(&uuid_mutex);
  right?

> However looking at the resulting code it doesn't look good, because
> btrfs_splice_sporut suggests you simply add the seed device to a bunch
> of places, yet looking at the function's body it's evident it actually
> finishes some parts of the initialization, changes the uuid of the
> fs_devices. I'm not convinced it really makes the code better or at the
> very least the 'splice_sprout' needs to be changed, because splicing is
> a minot part of what this function really does.

The purpose of the split of btrfs_prepare_sprout() was to use a common 
device_list_mutex. So I tend to avoid any other changes, but I think I 
will do it now based on the comments.

Thanks, Anand
> 
> 
> <snip>
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent
  2021-09-22 11:41     ` Anand Jain
@ 2021-09-23  6:52       ` Nikolay Borisov
  2021-09-23 11:55         ` Anand Jain
  0 siblings, 1 reply; 14+ messages in thread
From: Nikolay Borisov @ 2021-09-23  6:52 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba



On 22.09.21 г. 14:41, Anand Jain wrote:

<snip>

>>> @@ -2419,7 +2414,23 @@ static int btrfs_prepare_sprout(struct
>>> btrfs_fs_info *fs_info)
>>>       INIT_LIST_HEAD(&seed_devices->devices);
>>>       INIT_LIST_HEAD(&seed_devices->alloc_list);
>>>   -    mutex_lock(&fs_devices->device_list_mutex);
>>> +    *seed_devices_ret = seed_devices;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +/*
>>> + * Splice seed devices into the sprout fs_devices.
>>> + * Generate a new fsid for the sprouted readwrite btrfs.
>>> + */
>>> +static void btrfs_splice_sprout(struct btrfs_fs_info *fs_info,
>>> +                struct btrfs_fs_devices *seed_devices)
>>> +{
>>
>> This function is missing a lockdep_assert_held annotation and it depends
>> on the device_list_mutex being held.
> 
>  You mean
>     lockdep_assert_held(&device_list_mutex);
>  and not
>     lockdep_assert_held(&uuid_mutex);
>  right?

I meant that the new function - btrfs_splice_sprout doesn't have any
lockdep annotation, and based on the old code it depends on
device_list_mutex being locked. This is based on the following hunk in
btrfs_init_new_device:

+	mutex_lock(&fs_devices->device_list_mutex);
+	if (seeding_dev) {
+		btrfs_splice_sprout(fs_info, seed_devices);

The way I understand this is btrfs_splice_sprout indeed requires
device_list_mutex being locked, no?

> 
>> However looking at the resulting code it doesn't look good, because
>> btrfs_splice_sporut suggests you simply add the seed device to a bunch
>> of places, yet looking at the function's body it's evident it actually
>> finishes some parts of the initialization, changes the uuid of the
>> fs_devices. I'm not convinced it really makes the code better or at the
>> very least the 'splice_sprout' needs to be changed, because splicing is
>> a minot part of what this function really does.
> 
> The purpose of the split of btrfs_prepare_sprout() was to use a common
> device_list_mutex. So I tend to avoid any other changes, but I think I
> will do it now based on the comments.
> 
> Thanks, Anand
>>
>>
>> <snip>
>>
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent
  2021-09-23  6:52       ` Nikolay Borisov
@ 2021-09-23 11:55         ` Anand Jain
  0 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2021-09-23 11:55 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: linux-btrfs, dsterba



On 23/09/2021 14:52, Nikolay Borisov wrote:
> 
> 
> On 22.09.21 г. 14:41, Anand Jain wrote:
> 
> <snip>
> 
>>>> @@ -2419,7 +2414,23 @@ static int btrfs_prepare_sprout(struct
>>>> btrfs_fs_info *fs_info)
>>>>        INIT_LIST_HEAD(&seed_devices->devices);
>>>>        INIT_LIST_HEAD(&seed_devices->alloc_list);
>>>>    -    mutex_lock(&fs_devices->device_list_mutex);
>>>> +    *seed_devices_ret = seed_devices;
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +/*
>>>> + * Splice seed devices into the sprout fs_devices.
>>>> + * Generate a new fsid for the sprouted readwrite btrfs.
>>>> + */
>>>> +static void btrfs_splice_sprout(struct btrfs_fs_info *fs_info,
>>>> +                struct btrfs_fs_devices *seed_devices)
>>>> +{
>>>
>>> This function is missing a lockdep_assert_held annotation and it depends
>>> on the device_list_mutex being held.
>>
>>   You mean
>>      lockdep_assert_held(&device_list_mutex);
>>   and not
>>      lockdep_assert_held(&uuid_mutex);
>>   right?
> 
> I meant that the new function - btrfs_splice_sprout doesn't have any
> lockdep annotation, and based on the old code it depends on
> device_list_mutex being locked. This is based on the following hunk in
> btrfs_init_new_device:
> 
> +	mutex_lock(&fs_devices->device_list_mutex);
> +	if (seeding_dev) {
> +		btrfs_splice_sprout(fs_info, seed_devices);
> 
> The way I understand this is btrfs_splice_sprout indeed requires
> device_list_mutex being locked, no?

  Yes it requires both uuid_mutex and device_list_mutex. I will add.
  With comments.

Thx.


>>> However looking at the resulting code it doesn't look good, because
>>> btrfs_splice_sporut suggests you simply add the seed device to a bunch
>>> of places, yet looking at the function's body it's evident it actually
>>> finishes some parts of the initialization, changes the uuid of the
>>> fs_devices. I'm not convinced it really makes the code better or at the
>>> very least the 'splice_sprout' needs to be changed, because splicing is
>>> a minot part of what this function really does.
>>
>> The purpose of the split of btrfs_prepare_sprout() was to use a common
>> device_list_mutex. So I tend to avoid any other changes, but I think I
>> will do it now based on the comments.
>>
>> Thanks, Anand
>>>
>>>
>>> <snip>
>>>
>>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool
  2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
  2021-09-21 11:01   ` Nikolay Borisov
@ 2021-10-13  8:00   ` Anand Jain
  2021-10-28  4:39     ` Anand Jain
  1 sibling, 1 reply; 14+ messages in thread
From: Anand Jain @ 2021-10-13  8:00 UTC (permalink / raw)
  To: dsterba; +Cc: linux-btrfs


Ping?


On 21/09/2021 12:33, Anand Jain wrote:
> This patch declares int seeding_dev as a bool. Also, move its declaration
> a line below to adjust packing.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> v6: new
>   fs/btrfs/volumes.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 5117c5816922..c4bc49e58b69 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -2532,8 +2532,8 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
>   	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
>   	u64 orig_super_total_bytes;
>   	u64 orig_super_num_devices;
> -	int seeding_dev = 0;
>   	int ret = 0;
> +	bool seeding_dev = false;
>   	bool locked = false;
>   
>   	if (sb_rdonly(sb) && !fs_devices->seeding)
> @@ -2550,7 +2550,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
>   	}
>   
>   	if (fs_devices->seeding) {
> -		seeding_dev = 1;
> +		seeding_dev = true;
>   		down_write(&sb->s_umount);
>   		mutex_lock(&uuid_mutex);
>   		locked = true;
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool
  2021-10-13  8:00   ` Anand Jain
@ 2021-10-28  4:39     ` Anand Jain
  2021-11-08 20:06       ` David Sterba
  0 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2021-10-28  4:39 UTC (permalink / raw)
  To: dsterba; +Cc: linux-btrfs


  2nd try. Ping?

  (Pls note, patch 2/3  dropped based on Nik's comments.  patch 3/3 
separated from this set, as it went thru revisions and not related)

Thanks, Anand


On 13/10/2021 16:00, Anand Jain wrote:
> 
> Ping?
> 
> 
> On 21/09/2021 12:33, Anand Jain wrote:
>> This patch declares int seeding_dev as a bool. Also, move its declaration
>> a line below to adjust packing.
>>
>> Signed-off-by: Anand Jain <anand.jain@oracle.com>
>> ---
>> v6: new
>>   fs/btrfs/volumes.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index 5117c5816922..c4bc49e58b69 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -2532,8 +2532,8 @@ int btrfs_init_new_device(struct btrfs_fs_info 
>> *fs_info, const char *device_path
>>       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
>>       u64 orig_super_total_bytes;
>>       u64 orig_super_num_devices;
>> -    int seeding_dev = 0;
>>       int ret = 0;
>> +    bool seeding_dev = false;
>>       bool locked = false;
>>       if (sb_rdonly(sb) && !fs_devices->seeding)
>> @@ -2550,7 +2550,7 @@ int btrfs_init_new_device(struct btrfs_fs_info 
>> *fs_info, const char *device_path
>>       }
>>       if (fs_devices->seeding) {
>> -        seeding_dev = 1;
>> +        seeding_dev = true;
>>           down_write(&sb->s_umount);
>>           mutex_lock(&uuid_mutex);
>>           locked = true;
>>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool
  2021-10-28  4:39     ` Anand Jain
@ 2021-11-08 20:06       ` David Sterba
  0 siblings, 0 replies; 14+ messages in thread
From: David Sterba @ 2021-11-08 20:06 UTC (permalink / raw)
  To: Anand Jain; +Cc: dsterba, linux-btrfs

On Thu, Oct 28, 2021 at 12:39:54PM +0800, Anand Jain wrote:
> 
>   2nd try. Ping?
> 
>   (Pls note, patch 2/3  dropped based on Nik's comments.  patch 3/3 
> separated from this set, as it went thru revisions and not related)

Patch 1 added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-11-08 20:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-21  4:33 [PATCH v6 0/3] btrfs: cleanup prepare_sprout Anand Jain
2021-09-21  4:33 ` [PATCH v6 1/3] btrfs: declare seeding_dev in init_new_device as bool Anand Jain
2021-09-21 11:01   ` Nikolay Borisov
2021-10-13  8:00   ` Anand Jain
2021-10-28  4:39     ` Anand Jain
2021-11-08 20:06       ` David Sterba
2021-09-21  4:33 ` [PATCH v6 2/3] btrfs: remove unused device_list_mutex for seed fs_devices Anand Jain
2021-09-21  6:44   ` Nikolay Borisov
2021-09-22 11:29     ` Anand Jain
2021-09-21  4:33 ` [PATCH v6 3/3] btrfs: consolidate device_list_mutex in prepare_sprout to its parent Anand Jain
2021-09-21 11:01   ` Nikolay Borisov
2021-09-22 11:41     ` Anand Jain
2021-09-23  6:52       ` Nikolay Borisov
2021-09-23 11:55         ` Anand Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.