* [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