Thread (10 messages) 10 messages, 5 authors, 2021-10-27

Re: [PATCH] btrfs: sysfs: set / query btrfs stripe size

From: Damien Le Moal <hidden>
Date: 2021-10-27 06:51:44

On 2021/10/27 15:28, Johannes Thumshirn wrote:
On 26/10/2021 18:59, Stefan Roesch wrote:

[...]
quoted
+/*
+ * Compute stripe size depending on block type.
+ */
+static u64 compute_stripe_size(struct btrfs_fs_info *info, u64 flags)
+{
+	if (flags & BTRFS_BLOCK_GROUP_DATA) {
+		return SZ_1G;
+	} else if (flags & BTRFS_BLOCK_GROUP_METADATA) {
+		/* For larger filesystems, use larger metadata chunks */
+		return info->fs_devices->total_rw_bytes > 50ULL * SZ_1G
+			? 5ULL * SZ_1G
+			: SZ_256M;
+	} else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
+		return SZ_32M;
+	}
+
+	BUG();
+}
+
+/*
+ * Compute chunk size depending on block type and stripe size.
+ */
+static u64 compute_chunk_size(u64 flags, u64 max_stripe_size)
+{
+	if (flags & BTRFS_BLOCK_GROUP_DATA)
+		return BTRFS_MAX_DATA_CHUNK_SIZE;
+	else if (flags & BTRFS_BLOCK_GROUP_METADATA)
+		return max_stripe_size;
+	else if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
+		return 2 * max_stripe_size;
+
+	BUG();
+}
+
+/*
+ * Update maximum stripe size and chunk size.
+ *
+ */
+void btrfs_update_space_info_max_alloc_sizes(struct btrfs_space_info *space_info,
+					     u64 flags, u64 max_stripe_size)
+{
+	spin_lock(&space_info->lock);
+	space_info->max_stripe_size = max_stripe_size;
+	space_info->max_chunk_size = compute_chunk_size(flags,
+						space_info->max_stripe_size);
+	spin_unlock(&space_info->lock);
+}
+
 static int create_space_info(struct btrfs_fs_info *info, u64 flags)
 {
 
@@ -203,6 +251,10 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags)
 	INIT_LIST_HEAD(&space_info->priority_tickets);
 	space_info->clamp = 1;
 
+	space_info->max_stripe_size = compute_stripe_size(info, flags);
+	space_info->max_chunk_size = compute_chunk_size(flags,
+						space_info->max_stripe_size);
+
 	ret = btrfs_sysfs_add_space_info_type(info, space_info);
 	if (ret)
 		return ret;
[...]

  
quoted
+/*
+ * Return space info stripe size.
+ */
+static ssize_t btrfs_stripe_size_show(struct kobject *kobj,
+				      struct kobj_attribute *a, char *buf)
+{
+	struct btrfs_space_info *sinfo = to_space_info(kobj);
+
+	return btrfs_show_u64(&sinfo->max_stripe_size, &sinfo->lock, buf);
+}

This will return the wrong values for a fs on a zoned device.
What you could do is:

static ssize_t btrfs_stripe_size_show(struct kobject *kobj,
				struct kobj_attribute *a, char *buf)

{
	struct btrfs_space_info *sinfo = to_space_info(kobj);
	struct btrfs_fs_info *fs_info = to_fs_info(get_btrfs_kobj(kobj));
	u64 max_stripe_size;

	spin_lock(&sinfo->lock);
	if (btrfs_is_zoned(fs_info))
		max_stripe_size = fs_info->zone_size;
	else
		max_stripe_size = sinfo->max_stripe_size;
	spin_unlock(&sinfo->lock);
This will not work once we have stripped zoned volume though, won't it ?
Why is not max_stripe_size set to zone size for a simple zoned btrfs volume ?
	return btrfs_show_u64(&max_stripe_size, NULL, buf);
}

[...]
quoted
+	if (fs_info->fs_devices->chunk_alloc_policy == BTRFS_CHUNK_ALLOC_ZONED)
+		return -EINVAL;
Nit: As we can't mix zoned and non-zoned devices 'if (btrfs_is_zoned(fs_info))'
should do the trick here as well and is way more readable. 

-- 
Damien Le Moal
Western Digital Research
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help