public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] btrfs-progs: mkfs: optimize file descriptor usage in mkfs.btrfs
@ 2024-01-31 15:49 Anand Jain
  2024-01-31 20:48 ` Josef Bacik
  0 siblings, 1 reply; 8+ messages in thread
From: Anand Jain @ 2024-01-31 15:49 UTC (permalink / raw)
  To: linux-btrfs

I've reproduced the missing udev events issue without device partitions
using the test case as below. The test waits for the creation of 'by-uuid'
and, waiting indefinitely means successful reproduction. as below:

--------------------------------------------------
#!/bin/bash
usage()
{
	echo
	echo "Usage: ./t1 sdb btrfs"
	exit 1
}

: ${1?"arg1 <dev> is missing"} || usage
dev=$1

: ${2?"arg2 <fstype> is missing"} || usage
fstype=$2

systemd=$(rpm -q --queryformat='%{NAME}-%{VERSION}-%{RELEASE}' systemd)

run_testcase()
{
	local cnt=$1
	local ret=0
	local sleepcnt=0

	local newuuid=""
	local logpid=""
	local log=""
	local logfile="./udev_log_${systemd}_${fstype}.out"

	>$logfile

	wipefs -a /dev/${dev}* &>/dev/null
	sync
	udevadm settle /dev/$dev

	udevadm monitor -k -u -p > $logfile &
	logpid=$!
	>strace.out
	run "strace -f -ttT -o strace.out mkfs.$fstype -q -f /dev/$dev"

	newuuid=$(blkid -p /dev/$dev | awk '{print $2}' | sed -e 's/UUID=//' -e 's/\"//g')

	kill $logpid
	sync $logfile

	ret=-1
	while [ $ret != 0 ]
	do
		run -s -q "ls -lt /dev/disk/by-uuid | grep $newuuid"
		ret=$?
		((sleepcnt++))
		sleep 1
	done

	#for systemd-239-78.0.3.el8
	log=$(cat $logfile|grep ID_FS_TYPE_NEW)
	#for systemd-252-18.0.1.el9.x86_64
	#log=$(grep --text "ID_FS_UUID=${newuuid}" $logfile)

	echo $cnt sleepcnt=$sleepcnt newuuid=$newuuid ret=$ret log=$log
}

echo Test case: t1: version 3.
echo

run -o cat /etc/system-release
run -o uname -a
run -o rpm -q systemd
if [ $fstype == "btrfs" ]; then
	run -o mkfs.btrfs --version
elif [ $fstype == "xfs" ]; then
	run -o mkfs.xfs -V
else
	echo unknown fstype $fstype
fi
echo

for ((cnt = 0; cnt < 13; cnt++)); do
	run_testcase $cnt
done
-----------------------------------------------------------------


It appears that the problem is due to the convoluted nested device open
and device close in mkfs.btrfs as shown below:

-------------
 prepare_ctx opens all devices <-- fd1
   zero the super-block
   writes temp-sb to the first device.

 open_ctree opens the first device again <-- fd2

 prepare_ctx writes temp-sb to all the remaining devs <-- fd1

 fs_info->finalize_on_close = 1;
 close_ctree_fs_info()<-- writes valid <--- fd2

 prepare_ctx is closed <--- fd1.
-------------

This cleanup patch reuses the main file descriptor (fd1) in open_ctree(),
and with this change both the test cases (with partition and without
partition) now runs fine.

I've done an initial tests only, not validated with the multi-device mkfs.
More cleanup is possible but pending feedback;  marking this patch as an RFC.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 kernel-shared/disk-io.c | 30 ++++++++++++++++++++++++++++++
 kernel-shared/disk-io.h |  1 +
 mkfs/main.c             |  2 +-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index c053319200cb..b4951d229647 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -1660,6 +1660,36 @@ out:
 	return NULL;
 }
 
+struct btrfs_fs_info *open_ctree_fs_info_mkfs(int fd, struct open_ctree_args *oca)
+{
+	int ret;
+	struct stat st;
+	//int oflags = O_RDWR;
+	struct btrfs_fs_info *fs_info;
+
+	ret = stat(oca->filename, &st);
+	if (ret < 0) {
+		error("cannot stat '%s': %m", oca->filename);
+		return NULL;
+	}
+
+	if (!(((st.st_mode & S_IFMT) == S_IFREG) || ((st.st_mode & S_IFMT) == S_IFBLK))) {
+		error("not a regular file or block device: %s", oca->filename);
+		return NULL;
+	}
+
+	/*
+	if (!(oca->flags & OPEN_CTREE_WRITES))
+		oflags = O_RDONLY;
+
+	if ((oflags & O_RDWR) && zoned_model(oca->filename) == ZONED_HOST_MANAGED)
+		oflags |= O_DIRECT;
+	*/
+
+	fs_info = __open_ctree_fd(fd, oca);
+	return fs_info;
+}
+
 struct btrfs_fs_info *open_ctree_fs_info(struct open_ctree_args *oca)
 {
 	int fp;
diff --git a/kernel-shared/disk-io.h b/kernel-shared/disk-io.h
index 68cdf5b08d52..0f2aa24a50a1 100644
--- a/kernel-shared/disk-io.h
+++ b/kernel-shared/disk-io.h
@@ -199,6 +199,7 @@ struct open_ctree_args {
 };
 
 struct btrfs_fs_info *open_ctree_fs_info(struct open_ctree_args *oca);
+struct btrfs_fs_info *open_ctree_fs_info_mkfs(int fd, struct open_ctree_args *oca);
 int close_ctree_fs_info(struct btrfs_fs_info *fs_info);
 static inline int close_ctree(struct btrfs_root *root)
 {
diff --git a/mkfs/main.c b/mkfs/main.c
index b50b78b5665a..2526fb2317e5 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1800,7 +1800,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
 
 	oca.filename = file;
 	oca.flags = OPEN_CTREE_WRITES | OPEN_CTREE_TEMPORARY_SUPER;
-	fs_info = open_ctree_fs_info(&oca);
+	fs_info = open_ctree_fs_info_mkfs(prepare_ctx[0].fd, &oca);
 	if (!fs_info) {
 		error("open ctree failed");
 		goto error;
-- 
2.39.3


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

end of thread, other threads:[~2024-02-02  1:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-31 15:49 [PATCH RFC] btrfs-progs: mkfs: optimize file descriptor usage in mkfs.btrfs Anand Jain
2024-01-31 20:48 ` Josef Bacik
2024-02-01  8:49   ` Qu Wenruo
2024-02-01 19:07     ` David Sterba
2024-02-01 20:50       ` Qu Wenruo
2024-02-01 19:18   ` David Sterba
2024-02-02  1:52     ` Anand Jain
2024-02-01 21:59   ` Qu Wenruo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox