All of lore.kernel.org
 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 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.