mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/3] selftest: preparations for devfs changes
@ 2025-12-10 10:15 Sascha Hauer
  2025-12-10 10:15 ` [PATCH 1/3] fs: get path in path_init() Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sascha Hauer @ 2025-12-10 10:15 UTC (permalink / raw)
  To: BAREBOX

With the devfs series devfs as a filesystem will go away. The dirfd
selftest uses it though, so switch this test to use ramfs instead. This
revealed a bug in the fs layer which is fixed in this series.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Sascha Hauer (3):
      fs: get path in path_init()
      fs: warn when mount reference count becomes negative
      test: dirfs: use ramfs rather than devfs

 fs/fs.c           |  7 +++++++
 test/self/dirfd.c | 46 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 40 insertions(+), 13 deletions(-)
---
base-commit: 500df27eb054f86ce232c5bb30c3a7ea8f771e61
change-id: 20251210-devfs-prep-a8909ffc695d

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




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

* [PATCH 1/3] fs: get path in path_init()
  2025-12-10 10:15 [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
@ 2025-12-10 10:15 ` Sascha Hauer
  2025-12-10 10:16 ` [PATCH 2/3] fs: warn when mount reference count becomes negative Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2025-12-10 10:15 UTC (permalink / raw)
  To: BAREBOX

Call path_get() in path_init() when dirfd doesn't belong to the current
directory and is not the root directory. Without it path_put() will be
called later without a previous path_get().

Reproducer:

mkdir /ram
mount -t ramfs none /ram
stat -C ram .
umount /ram

Without this patch umount fails with -EBUSY.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/fs.c b/fs/fs.c
index d884726187dd526213f8b51a68a2e0db1bb50e58..f7859304a7b5f4158db83298b586c633668301d5 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -2251,6 +2251,7 @@ static const char *path_init(int dirfd, struct nameidata *nd, unsigned flags)
 
 		nd->path.mnt = &f->fsdev->vfsmount;
 		nd->path.dentry = f->f_path.dentry;
+		path_get(&nd->path);
 		follow_mount(&nd->path);
 
 		if (*s == '/')

-- 
2.47.3




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

* [PATCH 2/3] fs: warn when mount reference count becomes negative
  2025-12-10 10:15 [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
  2025-12-10 10:15 ` [PATCH 1/3] fs: get path in path_init() Sascha Hauer
@ 2025-12-10 10:16 ` Sascha Hauer
  2025-12-10 10:16 ` [PATCH 3/3] test: dirfs: use ramfs rather than devfs Sascha Hauer
  2025-12-15  9:30 ` [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2025-12-10 10:16 UTC (permalink / raw)
  To: BAREBOX

Warn when the reference count of a mount would become negative.
With this we warn when it happens. Previously, only unmounting
a mountpoint failed with -EBUSY which was misleading because
mnt->ref was only true because it was negative.

Do not actually allow it to become negative anymore.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/fs.c b/fs/fs.c
index f7859304a7b5f4158db83298b586c633668301d5..e063dc48d9d53a64932564c4b983d5ca1b026a1a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -260,6 +260,12 @@ static void mntput(struct vfsmount *mnt)
 	if (!mnt)
 		return;
 
+	if (!mnt->ref) {
+		WARN_ONCE(1, "refcount for mount \"%s\" becomes negative\n",
+			  mnt->mountpoint->name);
+		return;
+	}
+
 	mnt->ref--;
 }
 

-- 
2.47.3




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

* [PATCH 3/3] test: dirfs: use ramfs rather than devfs
  2025-12-10 10:15 [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
  2025-12-10 10:15 ` [PATCH 1/3] fs: get path in path_init() Sascha Hauer
  2025-12-10 10:16 ` [PATCH 2/3] fs: warn when mount reference count becomes negative Sascha Hauer
@ 2025-12-10 10:16 ` Sascha Hauer
  2025-12-15  9:30 ` [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2025-12-10 10:16 UTC (permalink / raw)
  To: BAREBOX

devfs as a filesystem is going away, so do not use it in the dirfd test.
Switch to ramfs, but this means we have to mount it ourselves. This
has the advantage though that it might reveal some bugs in the fs layer.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 test/self/dirfd.c | 46 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/test/self/dirfd.c b/test/self/dirfd.c
index 1f9b375e84ffa948a511b7ad94cd40fabeee4af3..04cbf6e285f3184f3e5b1680271aabffc272c8be 100644
--- a/test/self/dirfd.c
+++ b/test/self/dirfd.c
@@ -9,6 +9,7 @@
 #include <linux/bitfield.h>
 #include <unistd.h>
 #include <bselftest.h>
+#include <libfile.h>
 
 BSELFTEST_GLOBALS();
 
@@ -26,7 +27,7 @@ BSELFTEST_GLOBALS();
 
 static void check_statat(const char *at, int dirfd, const char *prefix, unsigned expected)
 {
-	static const char *paths[] = { ".", "..", "zero", "dev" };
+	static const char *paths[] = { ".", "..", "testfile", "dirfdtest" };
 	struct stat s;
 
 	for (int i = 0; i < ARRAY_SIZE(paths); i++) {
@@ -63,9 +64,9 @@ static void check_statat(const char *at, int dirfd, const char *prefix, unsigned
 			    fullpath, at, testpath))
 			goto next;
 
-		ret = strcmp_ptr(fsdev1->path, "/dev");
+		ret = strcmp_ptr(fsdev1->path, "/dirfdtest");
 		if (!expect(ret == 0, FIELD_GET(BIT(0), expected),
-			    "fsdev_of(%s)->path = %s != /dev", fullpath, fsdev1->path))
+			    "fsdev_of(%s)->path = %s != /dirfdtest", fullpath, fsdev1->path))
 			goto next;
 
 next:
@@ -84,9 +85,9 @@ static void do_test_dirfd(const char *at, int dirfd,
 
 	check_statat(at, dirfd, "",             expected1);
 	check_statat(at, dirfd, "./",           expected1);
-	check_statat(at, dirfd, "/dev/",        expected2);
-	check_statat(at, dirfd, "/dev/./",      expected2);
-	check_statat(at, dirfd, "/dev/../dev/", expected2);
+	check_statat(at, dirfd, "/dirfdtest/",        expected2);
+	check_statat(at, dirfd, "/dirfdtest/./",      expected2);
+	check_statat(at, dirfd, "/dirfdtest/../dirfdtest/", expected2);
 	check_statat(at, dirfd, "/",            expected3);
 	check_statat(at, dirfd, "../",          expected4);
 
@@ -97,19 +98,31 @@ static void do_test_dirfd(const char *at, int dirfd,
 
 static void test_dirfd(void)
 {
-	int fd;
+	int fd, ret;
 
 	fd = open("/", O_PATH | O_DIRECTORY);
-	if (expect(fd < 0, false, "open(/, O_PATH | O_DIRECTORY) = %d", fd))
+	if (!expect(fd < 0, false, "open(/, O_PATH | O_DIRECTORY) = %d", fd))
 		close(fd);
 
+	ret = make_directory("/dirfdtest");
+	if (!expect(ret == 0, true, "make_directory(\"/dirfdtest\") = %d", ret))
+		return;
+
+	ret = mount("none", "ramfs", "/dirfdtest", NULL);
+	if (!expect(ret == 0, true, "mount(\"none\", \"ramfs\", \"/dirfdtest\") = %d", ret))
+		goto out;
+
+	ret = write_file("/dirfdtest/testfile", __func__, strlen(__func__));
+	if (!expect(ret == 0, true, "write_file() = %d", ret))
+		goto out;
+
 #define B(dot, dotdot, zero, dev) 0b##dev##zero##dotdot##dot
 	/* We do fiften tests for every configuration
-	 * for dir in ./ /dev / ../ ; do
-	 *	for file in . .. zero dev ; do
+	 * for dir in ./ /dirfdtest / ../ ; do
+	 *	for file in . .. zero dirfdtest ; do
 	 *		test if file exists
 	 *		test if file can be canonicalized
-	 *		test if parent FS is mounted at /dev
+	 *		test if parent FS is mounted at /dirfdtest
 	 *	done
 	 * done
 	 *
@@ -119,11 +132,18 @@ static void test_dirfd(void)
 	do_test_dirfd("AT_FDCWD", AT_FDCWD,
 		      B(110,110,000,111), B(111,110,111,000),
 		      B(110,110,000,111), B(110,110,000,111));
-	do_test_dirfd("/dev", open("/dev", O_PATH | O_DIRECTORY),
+	do_test_dirfd("/dirfdtest", open("/dirfdtest", O_PATH | O_DIRECTORY),
 		      B(111,110,111,000), B(111,110,111,000),
 		      B(110,110,000,111), B(110,110,000,111));
-	do_test_dirfd("/dev O_CHROOT", open("/dev", O_PATH | O_CHROOT),
+	do_test_dirfd("/dirfdtest O_CHROOT", open("/dirfdtest", O_PATH | O_CHROOT),
 		      B(111,111,111,000), B(000,000,000,000),
 		      B(111,111,111,000), B(111,111,111,000));
+
+out:
+	ret = umount("/dirfdtest");
+	expect(ret == 0, true, "umount(\"/dirfdtest\") = %d", ret);
+
+	ret = rmdir("/dirfdtest");
+	expect(ret == 0, true, "rmdir(\"/dirfdtest\") = %d", ret);
 }
 bselftest(core, test_dirfd);

-- 
2.47.3




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

* Re: [PATCH 0/3] selftest: preparations for devfs changes
  2025-12-10 10:15 [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
                   ` (2 preceding siblings ...)
  2025-12-10 10:16 ` [PATCH 3/3] test: dirfs: use ramfs rather than devfs Sascha Hauer
@ 2025-12-15  9:30 ` Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2025-12-15  9:30 UTC (permalink / raw)
  To: BAREBOX, Sascha Hauer


On Wed, 10 Dec 2025 11:15:58 +0100, Sascha Hauer wrote:
> With the devfs series devfs as a filesystem will go away. The dirfd
> selftest uses it though, so switch this test to use ramfs instead. This
> revealed a bug in the fs layer which is fixed in this series.
> 
> 

Applied, thanks!

[1/3] fs: get path in path_init()
      https://git.pengutronix.de/cgit/barebox/commit/?id=dd496c007f8d (link may not be stable)
[2/3] fs: warn when mount reference count becomes negative
      https://git.pengutronix.de/cgit/barebox/commit/?id=aa4835448c79 (link may not be stable)
[3/3] test: dirfs: use ramfs rather than devfs
      https://git.pengutronix.de/cgit/barebox/commit/?id=a8ae0a3a6c3b (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




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

end of thread, other threads:[~2025-12-15  9:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-10 10:15 [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer
2025-12-10 10:15 ` [PATCH 1/3] fs: get path in path_init() Sascha Hauer
2025-12-10 10:16 ` [PATCH 2/3] fs: warn when mount reference count becomes negative Sascha Hauer
2025-12-10 10:16 ` [PATCH 3/3] test: dirfs: use ramfs rather than devfs Sascha Hauer
2025-12-15  9:30 ` [PATCH 0/3] selftest: preparations for devfs changes Sascha Hauer

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