linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property
@ 2022-01-06 17:49 Goffredo Baroncelli
  2022-01-06 17:49 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2022-01-06 17:49 UTC (permalink / raw)
  To: linux-btrfs
  Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
	Paul Jones, Boris Burkov, Goffredo Baroncelli

From: Goffredo Baroncelli <kreijack@inwind.it>

This patches set is the userspace portion of the serie
"[PATCH V10] btrfs: allocation_hint mode".

Look this patches set for further information.

G.Baroncelli

Goffredo Baroncelli (2):
  btrfs-progs: new "allocation_hint" property.
  Update man page for allocator_hint property.

 Documentation/btrfs-property.asciidoc |  17 +++
 cmds/property.c                       | 202 ++++++++++++++++++++++++++
 kernel-shared/ctree.h                 |  13 ++
 3 files changed, 232 insertions(+)

-- 
2.34.1


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

* [PATCH 1/2] btrfs-progs: new "allocation_hint" property.
  2022-01-06 17:49 [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
@ 2022-01-06 17:49 ` Goffredo Baroncelli
  2022-01-06 17:49 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
  2022-01-06 17:52 ` [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2022-01-06 17:49 UTC (permalink / raw)
  To: linux-btrfs
  Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
	Paul Jones, Boris Burkov, Goffredo Baroncelli

From: Goffredo Baroncelli <kreijack@inwind.it>

Handle the property allocation_hint of a btrfs device. Below
an example of use:

$ # set a new value
$ sudo btrfs property set /dev/vde allocation_hint DATA_ONLY

$ # get the current value
$ sudo btrfs property get /dev/vde allocation_hint
devid=4, path=/dev/vde: allocation_hint=DATA_ONLY

The following values are availables:
- DATA_ONLY
- DATA_PREFERRED (default)
- METADATA_PREFERRED
- METADATA_ONLY

Root privileges are required.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 cmds/property.c       | 202 ++++++++++++++++++++++++++++++++++++++++++
 kernel-shared/ctree.h |  13 +++
 2 files changed, 215 insertions(+)

diff --git a/cmds/property.c b/cmds/property.c
index 59ef997c..1ac4266a 100644
--- a/cmds/property.c
+++ b/cmds/property.c
@@ -22,6 +22,7 @@
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/xattr.h>
+#include <sys/sysmacros.h>
 #include <uuid/uuid.h>
 #include <btrfsutil.h>
 #include "cmds/commands.h"
@@ -30,6 +31,7 @@
 #include "common/open-utils.h"
 #include "common/utils.h"
 #include "common/help.h"
+#include "common/path-utils.h"
 
 #define XATTR_BTRFS_PREFIX     "btrfs."
 #define XATTR_BTRFS_PREFIX_LEN (sizeof(XATTR_BTRFS_PREFIX) - 1)
@@ -232,6 +234,200 @@ out:
 	return ret;
 }
 
+static int btrfs_find_devid_and_mnt(const char *devpath, int *devid,
+				    char *path, int maxpath)
+{
+	int ret, i, fd;
+	DIR *dir;
+	struct stat stdevpath;
+	struct btrfs_ioctl_fs_info_args fi_args;
+	struct btrfs_ioctl_dev_info_args dev_info;
+
+	ret = get_btrfs_mount(devpath, path, maxpath);
+	if (ret)
+		return ret;
+
+	fd = btrfs_open_dir(path, &dir, 1);
+	if (fd < 0)
+		return fd;
+
+	ret = stat(devpath, &stdevpath);
+	if (ret) {
+		error("cannot stat '%s'", devpath);
+		goto out;
+	}
+
+	ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
+	if (ret < 0) {
+		if (errno == EPERM)
+			return -errno;
+		error("cannot get filesystem info: %m");
+		ret = -10;
+		goto out;
+	}
+
+	for (i = 0 ; i <= fi_args.max_id ; i++) {
+		struct stat st;
+
+		memset(&dev_info, 0, sizeof(dev_info));
+		ret = get_device_info(fd, i, &dev_info);
+		if (ret == -ENODEV)
+			continue;
+		if (ret) {
+			error("cannot get info about device devid=%d", i);
+			goto out;
+		}
+
+		if (!dev_info.path)
+			/* missing devices */
+			continue;
+
+		ret = stat((char *)dev_info.path, &st);
+		if (ret) {
+			error("cannot stat '%s'", devpath);
+			goto out;
+		}
+
+		if (major(st.st_rdev) == major(stdevpath.st_rdev) &&
+		    minor(st.st_rdev) == minor(stdevpath.st_rdev)) {
+			*devid = dev_info.devid;
+			ret = 0;
+			goto out;
+		}
+	}
+
+	ret = -12;
+
+out:
+	close_file_or_dir(fd, dir);
+	return ret;
+}
+
+static struct ull_charp_pair_t {
+	u64		value;
+	const char	*descr;
+} allocation_hint_description[] = {
+	{BTRFS_DEV_ALLOCATION_HINT_METADATA_PREFERRED, "METADATA_PREFERRED"},
+	{BTRFS_DEV_ALLOCATION_HINT_METADATA_ONLY, "METADATA_ONLY"},
+	{BTRFS_DEV_ALLOCATION_HINT_DATA_PREFERRED, "DATA_PREFERRED"},
+	{BTRFS_DEV_ALLOCATION_HINT_DATA_ONLY, "DATA_ONLY"},
+	{0, NULL}
+};
+
+static int prop_allocation_hint(enum prop_object_type type,
+				const char *object,
+				const char *name,
+				const char *val,
+				bool force)
+{
+	int ret, devid, fd, fd2 = -1;
+	char path[PATH_MAX];
+	DIR *dir;
+	u8 fsid[BTRFS_UUID_SIZE];
+	char fsid_str[BTRFS_UUID_UNPARSED_SIZE];
+	char sysfs_file[PATH_MAX];
+	char filename[PATH_MAX];
+	int i;
+	u64 v;
+	char buf[1024];
+
+	ret = btrfs_find_devid_and_mnt(object, &devid, path, sizeof(path));
+	if (ret)
+		return -5;
+
+	fd = btrfs_open_dir(path, &dir, 1);
+	if (fd < 0)
+		return fd;
+
+	ret = get_fsid_fd(fd, fsid);
+	if (ret < 0)
+		goto out;
+
+	uuid_unparse(fsid, fsid_str);
+	sprintf(filename, "devinfo/%d/allocation_hint", devid);
+
+	/* build /sys/fs/btrfs/<UUID>/devinfo/<DEVID>/type */
+	ret = path_cat3_out(sysfs_file, "/sys/fs/btrfs", fsid_str, filename);
+	if (ret < 0)
+		goto out;
+
+	if (!val) {
+		/* READ */
+		fd2 = open(sysfs_file, O_RDONLY);
+		if (fd2 < 0) {
+			error("'allocation_hint' property not available or accessible.");
+			ret = -errno;
+			goto out;
+		}
+
+		ret = read(fd2, buf, sizeof(buf) - 1);
+		if (ret < 0) {
+			error("Unable to read the 'allocation_hint' property.");
+			ret = -errno;
+			goto out;
+		}
+
+		buf[sizeof(buf) - 1] = 0;
+		v = strtoull(buf, NULL, 0);
+
+		for (i = 0 ; allocation_hint_description[i].descr ; i++)
+			if (v == allocation_hint_description[i].value)
+				break;
+
+		if (allocation_hint_description[i].descr)
+			printf("devid=%d, path=%s: allocation_hint=%s\n",
+				devid, object,
+				allocation_hint_description[i].descr);
+		else
+			printf("devid=%d, path=%s: allocation_hint=unknown:%llu\n",
+				devid, object, v);
+		ret = 0;
+	} else {
+		/* WRITE */
+		for (i = 0 ; allocation_hint_description[i].descr ; i++)
+			if (!strcmp(val, allocation_hint_description[i].descr))
+				break;
+
+		if (allocation_hint_description[i].descr) {
+			v = allocation_hint_description[i].value;
+		} else if (sscanf(val, "%llu", &v) != 1) {
+			error("Invalid value '%s'\n", val);
+			ret = -3;
+			goto out;
+		}
+		if (v & ~BTRFS_DEV_ALLOCATION_HINT_MASK) {
+			error("Invalid value '%s'\n", val);
+			ret = -3;
+			goto out;
+		}
+
+		fd2 = open(sysfs_file, O_RDWR);
+		if (fd2 < 0) {
+			error("'allocation_hint' property not available or accessible for updating.");
+			ret = -errno;
+			goto out;
+		}
+
+		sprintf(buf, "%llu", v);
+
+		ret = write(fd2, buf, strlen(buf));
+
+		if (ret != strlen(buf)) {
+			error("Unable to update 'allocation_hint' property.");
+			ret = -errno;
+			goto out;
+		}
+
+	}
+
+	ret = 0;
+out:
+	if (fd2 >= 0)
+		close(fd2);
+	close_file_or_dir(fd, dir);
+	return ret;
+}
+
 const struct prop_handler prop_handlers[] = {
 	{
 		.name ="ro",
@@ -254,6 +450,12 @@ const struct prop_handler prop_handlers[] = {
 		.types = prop_object_inode,
 		.handler = prop_compression
 	},
+	{
+		.name = "allocation_hint",
+		.desc = "hint to store the data/metadata chunks",
+		.types = prop_object_dev,
+		.handler = prop_allocation_hint
+	},
 	{NULL, NULL, 0, 0, NULL}
 };
 
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 6ca49c09..597ad1af 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -216,6 +216,19 @@ struct btrfs_mapping_tree {
 	struct cache_tree cache_tree;
 };
 
+/* btrfs chunk allocation hints */
+#define BTRFS_DEV_ALLOCATION_HINT_BIT_COUNT    2
+#define BTRFS_DEV_ALLOCATION_HINT_MASK ((1ULL << \
+	       BTRFS_DEV_ALLOCATION_HINT_BIT_COUNT) - 1)
+/* preferred metadata chunk, but data chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_METADATA_PREFERRED        (1ULL)
+/* only metadata chunk are allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_METADATA_ONLY     (2ULL)
+/* only data chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_DATA_ONLY         (3ULL)
+/* preferred data chunk, but metadata chunk allowed */
+#define BTRFS_DEV_ALLOCATION_HINT_DATA_PREFERRED    (0ULL)
+
 #define BTRFS_UUID_SIZE 16
 struct btrfs_dev_item {
 	/* the internal btrfs device id */
-- 
2.34.1


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

* [PATCH 2/2] Update man page for allocator_hint property.
  2022-01-06 17:49 [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
  2022-01-06 17:49 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
@ 2022-01-06 17:49 ` Goffredo Baroncelli
  2022-01-06 17:52 ` [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2022-01-06 17:49 UTC (permalink / raw)
  To: linux-btrfs
  Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
	Paul Jones, Boris Burkov, Goffredo Baroncelli

From: Goffredo Baroncelli <kreijack@inwind.it>

Update the man page of the btrfs property subcommand to show the use
of the device property "allocation_hint".

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 Documentation/btrfs-property.asciidoc | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/btrfs-property.asciidoc b/Documentation/btrfs-property.asciidoc
index b32d000e..70b01f68 100644
--- a/Documentation/btrfs-property.asciidoc
+++ b/Documentation/btrfs-property.asciidoc
@@ -49,6 +49,23 @@ device as object. For a mounted filesystem, specify a mount point.
 compression::::
 compression algorithm set for an inode, possible values: 'lzo', 'zlib', 'zstd'.
 To disable compression use "" (empty string), 'no' or 'none'.
+allocation_hint::::
+a device property that instructs how and when the allocator should use a
+block device.
+Possible values are:
+- 'METADATA_PREFERRED': the device has an higher priority when a new metadata
+chunk is allocated. Data chunk is allowed only if there is no other possibility.
+- 'METADATA_ONLY': the device is used only for metadata chunk.
+Data chunk is never allowed.
+- 'DATA_PREFERRED' (default): the device has an higher priority when a new data
+chunk is allocated. Metadata chunk is allowed only if there is no other
+possibility.
+- 'DATA_ONLY': the device is used only for data chunk.
+Metadata chunk is never allowed.
+ ::::
+The default is 'DATA_PREFERRED'; if all the disks have this setting the
+allocator uses all of them with the same priority.
+
 
 *list* [-t <type>] <object>::
 Lists available properties with their descriptions for the given object.
-- 
2.34.1


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

* Re: [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property
  2022-01-06 17:49 [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
  2022-01-06 17:49 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
  2022-01-06 17:49 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
@ 2022-01-06 17:52 ` Goffredo Baroncelli
  2 siblings, 0 replies; 4+ messages in thread
From: Goffredo Baroncelli @ 2022-01-06 17:52 UTC (permalink / raw)
  To: Goffredo Baroncelli, linux-btrfs
  Cc: Zygo Blaxell, Josef Bacik, David Sterba, Sinnamohideen Shafeeq,
	Paul Jones, Boris Burkov

Below the script that I use to test this patch

----
#!/bin/bash

#size of disk, smaller -> faster
MAXSIZE=$((1*1024*1024*1024))
MNT=mnt
BTRFS=./btrfs-hint
UUID=292afefb-6e8c-4fb3-9d12-8c4ecb1f237c

cleanup_all() {
	while losetup | egrep loop; do
		umount $MNT
		losetup -D
		sleep 1s
	done
}

raise() {
	echo 1>&2 "$@"
	exit 100
}

xmount() {
	mount -o allocation_hint=1 "$1" "$2"
	#mount  "$1" "$2"
}

create_loops() {
	[ -n "$1" ] || {
		raise "Create_loops, missing an argument"
	}

	cleanup_all
	
	size=$MAXSIZE
	[ -n "$2" ] && size=$2
	ret=""
	for i in $(seq "$1"); do
		disk=disk-$i.img
		rm -rf $disk
		truncate -s $size $disk
		losetup /dev/loop$i $disk
		ret="$ret /dev/loop$i"
	done

	echo "$ret"
}


fill_1_file() {
	fn=$MNT/giant-file-$1
	if [ -n "$2" ]; then
		size=count=$(($2 / 16 / 1024 / 1024 ))
	else
		size=
	fi
	dd if=/dev/zero of=$fn bs=16M oflag=direct $size
	ls -l $fn | awk '{ print $5 }'
}

dump_bg_data() {
	$BTRFS fi us -b $MNT | awk '
		/^$/    { flag=0 }
		        { if(flag) print $0 }
		/^Data/ { flag=1 }
	'
}

dump_bg_metadata() {
	$BTRFS fi us -b $MNT | awk '
		/^$/        { flag=0 }
		            { if(flag) print $0 }
		/^Metadata/ { flag=1 }
	'
}

# check if a disk conrain data and/or metadata
check_data_bg() {
	res=$(dump_bg_data)
	while [ -n "$1" ]; do
		if ! echo $res | egrep -q $1 ; then
			btrfs fil us $MNT
			raise "Data BG should contains $1"
		fi
		shift
	done
}

check_data_not_bg() {
	res=$(dump_bg_data)
	while [ -n "$1" ]; do
		if echo $res | egrep -q $1 ; then
			btrfs fil us $MNT
			raise "Data BG should not contains $1"
		fi
		shift
	done
}

check_metadata_bg() {
	res=$(dump_bg_metadata)
	while [ -n "$1" ]; do
		if ! echo $res | egrep -q $1 ; then
			btrfs fil us $MNT
			raise "Metadata BG should contains $1"
		fi
		shift
	done
}

check_metadata_not_bg() {
	res=$(dump_bg_metadata)
	while [ -n "$1" ]; do
		if echo $res | egrep -q $1 ; then
			btrfs fil us $MNT
			raise "Metadata BG should not contains $1"
		fi
		shift
	done
}


test_default_raid1() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT
	
	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	check_data_bg $loop0 $loop1 $loop2 $loop3
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 || raise "Data BG should contains $loop0"
	#echo $res | egrep $loop1 || raise "Data BG should contains $loop1"
	#echo $res | egrep $loop2 || raise "Data BG should contains $loop2"
	#echo $res | egrep $loop3 || raise "Data BG should contains $loop3"

	size1=$(fill_1_file y )

	size=$(($size + $size1))

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] || raise "File too small: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 * 3 / 2 )) ] || raise "File too big: check mnt/"

	cleanup_all
}

test_default_single() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT
	
	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	check_data_bg $loop0 $loop1
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 || raise "Data BG should contains $loop0"
	#echo $res | egrep $loop1 || raise "Data BG should contains $loop1"

	size1=$(fill_1_file y )

	size=$(($size + $size1))

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] || raise "File too small: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 * 3 / 2 )) ] || raise "File too big: check mnt/"

	cleanup_all
}

test_single_preferred_data() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop1 allocation_hint DATA_PREFERRED
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	check_data_bg $loop1
	check_data_not_bg $loop0
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_single_preferred_metadata_slow() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop1 allocation_hint DATA_PREFERRED
	
	$BTRFS balance start --full-balance $MNT

	fnsize=2048
	for i in $(seq $(( $MAXSIZE / $fnsize * 700 / 1000))); do
		dd if=/dev/zero of=$MNT/fn-$i bs=$fnsize count=1
	done

	#BTRFS fi us $MNT

	check_metadata_bg  $loop0
	check_metadata_not_bg  $loop1
	#res=$(dump_bg_metadata)
	#echo $res | egrep $loop0 &>/dev/null || raise "Metadata BG should contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null && raise "Metadata BG should not contains $loop3"

	cleanup_all
}



test_raid1_preferred_data() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop1 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop2 allocation_hint DATA_PREFERRED
	$BTRFS prop set $loop3 allocation_hint DATA_PREFERRED
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	check_data_bg  $loop2 $loop3
	check_data_not_bg $loop0 $loop1
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	#echo $res | egrep $loop2 &>/dev/null || raise "Data BG should contains $loop2"
	#echo $res | egrep $loop3 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_raid1_preferred_metadata_slow() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop1 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop2 allocation_hint DATA_PREFERRED
	$BTRFS prop set $loop3 allocation_hint DATA_PREFERRED
	
	$BTRFS balance start --full-balance $MNT

	fnsize=2048
	for i in $(seq $(( $MAXSIZE / $fnsize * 700 / 1000))); do
		dd if=/dev/zero of=$MNT/fn-$i bs=$fnsize count=1
	done

	#BTRFS fi us $MNT

	check_metadata_bg $loop0 $loop1
	check_metadata_not_bg $loop2 $loop3
	#res=$(dump_bg_metadata)
	#echo $res | egrep $loop0 &>/dev/null || raise "Metadata BG should contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null || raise "Metadata BG should contains $loop1"
	#echo $res | egrep $loop2 &>/dev/null && raise "Metadata BG should not contains $loop2"
	#echo $res | egrep $loop3 &>/dev/null && raise "Metadata BG should not contains $loop3"

	cleanup_all
}

test_raid1_data_only() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop2 allocation_hint DATA_ONLY
	$BTRFS prop set $loop3 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  )

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 / 3 )) ] && raise "File too small: check mnt/"

	check_data_bg $loop2 $loop3
	check_data_not_bg $loop0 $loop1
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	#echo $res | egrep $loop2 &>/dev/null || raise "Data BG should contains $loop2"
	#echo $res | egrep $loop3 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_single_data_only() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  )

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 / 3 )) ] && raise "File too small: check mnt/"

	check_data_bg $loop1
	check_data_not_bg $loop0
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}


test_single_data_bouncing() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  $(($MAXSIZE * 2 / 4 )))

	[ $size -gt $(($MAXSIZE * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 1 / 3 )) ] && raise "File too small: check mnt/"

	check_data_bg $loop1
	check_data_not_bg $loop0
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop1"

	$BTRFS balance start --full-balance $MNT

	check_data_bg $loop1
	check_data_not_bg $loop0
	#res=$(dump_bg_data)
	#echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	#echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop1"


	$BTRFS prop set $loop1 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop0 allocation_hint DATA_ONLY

	$BTRFS balance start --full-balance $MNT

	check_data_bg $loop0
	check_data_not_bg $loop1
	#res=$(dump_bg_data)
	#echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	#echo $res | egrep $loop0 &>/dev/null || raise "Data BG should contains $loop0"
	cleanup_all
}

test_single_progressive_fill_data() {

	xsize=$MAXSIZE

	loops=$(create_loops 4 $xsize)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop2 allocation_hint DATA_PREFERRED
	$BTRFS prop set $loop3 allocation_hint DATA_ONLY
	$BTRFS balance start --full-balance $MNT	
	
	# fill $loop3
	
	size=$(fill_1_file x  $(( $xsize / 3 )))

	for i in 1 2 3; do
		check_data_bg $loop3
		check_data_not_bg $loop1 $loop2 $loop0
		$BTRFS balance start --full-balance $MNT
	done
		
	# fill $loop3 then $loop2

     	size=$(fill_1_file y  $(( $xsize )))

	for i in 1 2 3; do
		check_data_bg $loop3 $loop2
		check_data_not_bg $loop1 $loop0
		$BTRFS balance start --full-balance $MNT
	done
		
	# fill $loop3 then $loop2, then $loop1

     	size=$(fill_1_file z  $(( $xsize )))

	for i in 1 2 3; do
		check_data_bg $loop3 $loop2 $loop1
		check_data_not_bg $loop0
		$BTRFS balance start --full-balance $MNT
	done

	# fill the disk

     	size=$(fill_1_file w  )

	# when the disk is filled not balance is possible
	check_data_bg $loop3 $loop2 $loop1
	check_data_not_bg $loop0

	cleanup_all
}

test_raid1_progressive_fill_data() {

	xsize=$MAXSIZE

	loops=$(create_loops 5 $xsize)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	loop4=$(echo $loops | awk '{ print $5 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dRAID1 -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint METADATA_PREFERRED
	$BTRFS prop set $loop2 allocation_hint DATA_PREFERRED
	$BTRFS prop set $loop3 allocation_hint DATA_ONLY
	$BTRFS prop set $loop4 allocation_hint DATA_ONLY
	$BTRFS balance start --full-balance $MNT	
	
	# fill $loop3 $loop4
	
	size=$(fill_1_file x  $(( $xsize / 6 )))

	for i in 1 2 3; do
		check_data_bg $loop3 $loop4
		check_data_not_bg $loop1 $loop0 $loop2
		$BTRFS balance start --full-balance $MNT
	done
		
	# fill $loop3, $loop4 then $loop2, $loop1

     	size=$(fill_1_file y  $(( $xsize )))

	for i in 1 2 3; do
		check_data_bg $loop3 $loop2 $loop1 $loop4
		check_data_not_bg  $loop0
		$BTRFS balance start --full-balance $MNT
	done
		
	cleanup_all
}



SETV=""
SETX=""

while true; do
	if [ "$1" = "-x" ]; then
		SETX="set -x"
		shift
	elif [ "$1" = "-v" ]; then
		SETV="-v"
		shift
	elif [ "$1" = "--list" ]; then
		declare -F | awk '{ print $3 }' | egrep ^test_ | sort
		exit
     elif [ "$1" = "cleanup" ]; then
	    cleanup_all

	    exit
     elif [ "$1" = "makeraid1" ]; then
	    loops=$(create_loops 4)
	    loop0=$(echo $loops | awk '{ print $1 }')
	    mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	    xmount $loop0 $MNT

	    exit
	else
		break
	fi
done

cleanup_all &>/dev/null
cleanup_all &>/dev/null

ARG="$1"

$SETX

[ -z "$ARG" ] && ARG="."
declare -F | awk '{ print $3 }' | egrep ^test_ | sort |
	egrep $SETV "$ARG" | while read func; do

	echo -n "TEST '$func' "
	(
		$SETX
		$func >.out.log 2>.err.log
	)|| raise "Error !!!; read .out.log, .err.log"
	echo "OK"
done

----
-- 
gpg @keyserver.linux.it: Goffredo Baroncelli <kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5

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

end of thread, other threads:[~2022-01-06 17:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-06 17:49 [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli
2022-01-06 17:49 ` [PATCH 1/2] btrfs-progs: new "allocation_hint" property Goffredo Baroncelli
2022-01-06 17:49 ` [PATCH 2/2] Update man page for allocator_hint property Goffredo Baroncelli
2022-01-06 17:52 ` [PATCH 0/2][V10] btrfs-progs: allocation_hint disk property Goffredo Baroncelli

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).