git: 675ea9d1d6a5 - stable/14 - vfs: handle vfs_init() failures
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 12 Apr 2026 13:44:14 UTC
The branch stable/14 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=675ea9d1d6a5ca8d224f5fdb2d01ef3fee8e6325
commit 675ea9d1d6a5ca8d224f5fdb2d01ef3fee8e6325
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-09-04 02:08:51 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-04-12 13:43:39 +0000
vfs: handle vfs_init() failures
Most vfs_init implementations will not fail, with the notable current
exception that tmpfs_subr_init() can fail to allocate a new swap pager
type, in which case we probably do not want to proceed and keep it
registered. linsysfs was a potential consumer, but we opted to go a
different direction and move pseudofs init/deinit over to first mount
and last mount instead.
Reviewed by: fuz, kib
(cherry picked from commit 6d33507ff9b877f52516df00b012715b55d4e14f)
---
sys/kern/vfs_init.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index e516d929d9d0..880a8780c367 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -404,7 +404,7 @@ vfs_register(struct vfsconf *vfc)
static int once;
struct vfsconf *tvfc;
uint32_t hashval;
- int secondpass;
+ int error, prevmaxconf, secondpass;
if (!once) {
vattr_null(&va_null);
@@ -422,6 +422,7 @@ vfs_register(struct vfsconf *vfc)
return (EEXIST);
}
+ prevmaxconf = maxvfsconf;
if (vfs_typenumhash != 0) {
/*
* Calculate a hash on vfc_name to use for vfc_typenum. Unless
@@ -514,16 +515,24 @@ vfs_register(struct vfsconf *vfc)
vfc->vfc_vfsops = &vfsops_sigdefer;
}
- if (vfc->vfc_flags & VFCF_JAIL)
- prison_add_vfs(vfc);
-
/*
* Call init function for this VFS...
*/
if ((vfc->vfc_flags & VFCF_SBDRY) != 0)
- vfc->vfc_vfsops_sd->vfs_init(vfc);
+ error = vfc->vfc_vfsops_sd->vfs_init(vfc);
else
- vfc->vfc_vfsops->vfs_init(vfc);
+ error = vfc->vfc_vfsops->vfs_init(vfc);
+
+ if (error != 0) {
+ maxvfsconf = prevmaxconf;
+ TAILQ_REMOVE(&vfsconf, vfc, vfc_list);
+ vfsconf_unlock();
+ return (error);
+ }
+
+ if ((vfc->vfc_flags & VFCF_JAIL) != 0)
+ prison_add_vfs(vfc);
+
vfsconf_unlock();
/*