I figured it out. The basic Fullfs now works
(writes fail with ENOSPC). Could someone
review my code?

-- IC
diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi
index fe14a819cd9f..e70342028a72 100644
--- a/distrib/sets/lists/base/mi
+++ b/distrib/sets/lists/base/mi
@@ -414,6 +414,7 @@
 ./sbin/mount_fdesc				base-miscfs-root
 ./sbin/mount_ffs				base-sysutil-root
 ./sbin/mount_filecore				base-filecorefs-root
+./sbin/mount_full				base-miscfs-root
 ./sbin/mount_hfs				base-hfs-root
 ./sbin/mount_hfsp				base-obsolete		obsolete
 ./sbin/mount_kernfs				base-sysutil-root
@@ -1114,6 +1115,7 @@
 ./usr/include/miscfs				base-c-usr
 ./usr/include/miscfs/fdesc			base-c-usr
 ./usr/include/miscfs/fifofs			base-c-usr
+./usr/include/miscfs/fullfs			base-c-usr
 ./usr/include/miscfs/genfs			base-c-usr
 ./usr/include/miscfs/kernfs			base-c-usr
 ./usr/include/miscfs/nullfs			base-c-usr
diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi
index b8952f060b89..530e97226710 100644
--- a/distrib/sets/lists/comp/mi
+++ b/distrib/sets/lists/comp/mi
@@ -2670,6 +2670,7 @@
 ./usr/include/milter/mfdef.h			comp-obsolete		obsolete
 ./usr/include/miscfs/fdesc/fdesc.h		comp-c-include
 ./usr/include/miscfs/fifofs/fifo.h		comp-c-include
+./usr/include/miscfs/fullfs/full.h		comp-c-include
 ./usr/include/miscfs/genfs/genfs.h		comp-c-include
 ./usr/include/miscfs/genfs/genfs_node.h		comp-c-include
 ./usr/include/miscfs/genfs/layer.h		comp-c-include
diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi
index ec52c3c82aed..b08803cc8911 100644
--- a/distrib/sets/lists/man/mi
+++ b/distrib/sets/lists/man/mi
@@ -6210,6 +6210,7 @@
 ./usr/share/man/html8/mount_fdesc.html		man-miscfs-htmlman	html
 ./usr/share/man/html8/mount_ffs.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/mount_filecore.html	man-filecorefs-htmlman	html
+./usr/share/man/html8/mount_full.html		man-miscfs-htmlman	html
 ./usr/share/man/html8/mount_hfs.html		man-hfs-htmlman		html
 ./usr/share/man/html8/mount_kernfs.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/mount_lfs.html		man-sysutil-htmlman	html
@@ -9599,6 +9600,7 @@
 ./usr/share/man/man8/mount_fdesc.8		man-miscfs-man		.man
 ./usr/share/man/man8/mount_ffs.8		man-sysutil-man		.man
 ./usr/share/man/man8/mount_filecore.8		man-filecorefs-man	.man
+./usr/share/man/man8/mount_full.8		man-miscfs-man		.man
 ./usr/share/man/man8/mount_hfs.8		man-hfs-man		.man
 ./usr/share/man/man8/mount_hfsp.8		man-obsolete		obsolete
 ./usr/share/man/man8/mount_kernfs.8		man-sysutil-man		.man
diff --git a/sbin/Makefile b/sbin/Makefile
index 8cc5125b95c9..2f3036fcfd8a 100644
--- a/sbin/Makefile
+++ b/sbin/Makefile
@@ -33,6 +33,7 @@ SUBDIR+= mount_ext2fs
 SUBDIR+= mount_fdesc
 SUBDIR+= mount_filecore
 SUBDIR+= mount_ffs
+SUBDIR+= mount_full
 SUBDIR+= mount_hfs
 SUBDIR+= mount_kernfs
 SUBDIR+= mount_lfs
diff --git a/sbin/mount_full/Makefile b/sbin/mount_full/Makefile
new file mode 100644
index 000000000000..7c3790d28c0f
--- /dev/null
+++ b/sbin/mount_full/Makefile
@@ -0,0 +1,17 @@
+#	$NetBSD: Makefile,v 1.13 2020/07/26 08:20:22 mlelstv Exp $
+#	@(#)Makefile	8.3 (Berkeley) 3/27/94
+
+.include <bsd.own.mk>
+
+PROG=	mount_full
+SRCS=	mount_full.c pathadj.c
+MAN=	mount_full.8
+
+MOUNT=  ${NETBSDSRCDIR}/sbin/mount
+CPPFLAGS+= -I${NETBSDSRCDIR}/sys -I${MOUNT}
+.PATH:  ${MOUNT}
+
+DPADD+=${LIBUTIL}
+LDADD+=-lutil
+
+.include <bsd.prog.mk>
diff --git a/sbin/mount_full/mount_full.8 b/sbin/mount_full/mount_full.8
new file mode 100644
index 000000000000..d59d41deda9b
--- /dev/null
+++ b/sbin/mount_full/mount_full.8
@@ -0,0 +1,12 @@
+.Dd March 28, 2024
+.Dt MOUNT_FULL 8
+.Os
+.Sh NAME
+.Nm mount_full
+.Nd a filesystem where writes fail with disk
+full
+.Sh SYNOPSIS
+.Nm
+.Op Fl o Ar options
+.Ar target
+.Ar mount-point
diff --git a/sbin/mount_full/mount_full.c b/sbin/mount_full/mount_full.c
new file mode 100644
index 000000000000..507a1c2a2f94
--- /dev/null
+++ b/sbin/mount_full/mount_full.c
@@ -0,0 +1,127 @@
+/*	$NetBSD: mount_null.c,v 1.21 2020/07/26 08:20:22 mlelstv Exp $	*/
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)mount_null.c	8.6 (Berkeley) 4/26/95";
+#else
+__RCSID("$NetBSD: mount_null.c,v 1.21 2020/07/26 08:20:22 mlelstv Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <miscfs/fullfs/full.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mntopts.h>
+
+#include "mountprog.h"
+
+static const struct mntopt mopts[] = {
+	MOPT_STDOPTS,
+	MOPT_GETARGS,
+	MOPT_NULL,
+};
+
+int	mount_full(int argc, char **argv);
+__dead static void	usage(void);
+
+#ifndef MOUNT_NOMAIN
+int
+main(int argc, char **argv)
+{
+	return mount_full(argc, argv);
+}
+#endif
+
+int
+mount_full(int argc, char *argv[])
+{
+	struct full_args args;
+	int ch, mntflags;
+	char target[MAXPATHLEN], canon_dir[MAXPATHLEN];
+	mntoptparse_t mp;
+
+	mntflags = 0;
+	while ((ch = getopt(argc, argv, "o:")) != -1)
+		switch(ch) {
+		case 'o':
+			mp = getmntopts(optarg, mopts, &mntflags, 0);
+			if (mp == NULL)
+				err(1, "getmntopts");
+			freemntopts(mp);
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 2)
+		usage();
+
+	pathadj(argv[0], target);
+	pathadj(argv[1], canon_dir);
+
+	if (strcmp(target, canon_dir) == 0)
+		errx(1, "%s (%s) and %s (%s) are identical paths",
+		    argv[0], target, argv[1], canon_dir);
+
+	args.la.target = target;
+
+	if (mount(MOUNT_FULL, canon_dir, mntflags, &args, sizeof args) == -1)
+		err(1, "%s on %s", target, canon_dir);
+	exit(0);
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr,
+		"usage: mount_full [-o options] target_fs mount_point\n");
+	exit(1);
+}
diff --git a/sys/compat/linux/common/linux_misc.c b/sys/compat/linux/common/linux_misc.c
index 25c02fc07014..5c5de3df9660 100644
--- a/sys/compat/linux/common/linux_misc.c
+++ b/sys/compat/linux/common/linux_misc.c
@@ -149,6 +149,7 @@ const struct linux_mnttypes linux_fstypes[] = {
 	{ MOUNT_MSDOS,		LINUX_MSDOS_SUPER_MAGIC		},
 	{ MOUNT_LFS,		LINUX_DEFAULT_SUPER_MAGIC	},
 	{ MOUNT_FDESC,		LINUX_DEFAULT_SUPER_MAGIC	},
+	{ MOUNT_FULL,		LINUX_DEFAULT_SUPER_MAGIC	},
 	{ MOUNT_NULL,		LINUX_DEFAULT_SUPER_MAGIC	},
 	{ MOUNT_OVERLAY,	LINUX_DEFAULT_SUPER_MAGIC	},
 	{ MOUNT_UMAP,		LINUX_DEFAULT_SUPER_MAGIC	},
diff --git a/sys/conf/files b/sys/conf/files
index e6a86dcce628..0871cb89bf87 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1567,6 +1567,7 @@ include "fs/union/files.union"
 include "fs/v7fs/files.v7fs"
 include "fs/autofs/files.autofs"
 include "miscfs/fdesc/files.fdesc"
+include "miscfs/fullfs/files.fullfs"
 include "miscfs/kernfs/files.kernfs"
 include "miscfs/nullfs/files.nullfs"
 include "miscfs/overlay/files.overlay"
diff --git a/sys/conf/filesystems.config b/sys/conf/filesystems.config
index aea8bb6110bd..d2ce57d9b761 100644
--- a/sys/conf/filesystems.config
+++ b/sys/conf/filesystems.config
@@ -12,6 +12,7 @@ file-system	EXT2FS		# second extended file system (linux)
 file-system	FDESC		# /dev/fd
 file-system 	FFS		# UFS
 #file-system	FILECORE	# Acorn filecore file system
+file-system	FULLFS		# fullfs file system
 #file-system	HFS		# experimental - Apple HFS+ (read-only)
 file-system	KERNFS		# /kern
 file-system	LFS		# log-structured file system
diff --git a/sys/miscfs/Makefile b/sys/miscfs/Makefile
index 9ba12575c96c..61f6c9ff3f08 100644
--- a/sys/miscfs/Makefile
+++ b/sys/miscfs/Makefile
@@ -1,6 +1,6 @@
 #	$NetBSD: Makefile,v 1.10 2015/05/06 15:57:08 hannken Exp $
 
-SUBDIR=	fdesc fifofs genfs kernfs nullfs overlay procfs specfs umapfs
+SUBDIR=	fdesc fifofs fullfs genfs kernfs nullfs overlay procfs specfs umapfs
 
 INCSDIR= /usr/include/miscfs
 
diff --git a/sys/miscfs/fullfs/Makefile b/sys/miscfs/fullfs/Makefile
new file mode 100644
index 000000000000..7a162414933f
--- /dev/null
+++ b/sys/miscfs/fullfs/Makefile
@@ -0,0 +1,7 @@
+#	$NetBSD: Makefile,v 1.1 1998/06/12 23:23:02 cgd Exp $
+
+INCSDIR= /usr/include/miscfs/fullfs
+
+INCS=	full.h
+
+.include <bsd.kinc.mk>
diff --git a/sys/miscfs/fullfs/files.fullfs b/sys/miscfs/fullfs/files.fullfs
new file mode 100644
index 000000000000..c4e9350cc632
--- /dev/null
+++ b/sys/miscfs/fullfs/files.fullfs
@@ -0,0 +1,7 @@
+#	$NetBSD: files.fullfs,v 1.5 2014/10/12 03:52:30 uebayasi Exp $
+
+deffs	FULLFS
+
+define	fullfs: vfs, layerfs
+file	miscfs/fullfs/full_vfsops.c	fullfs
+file	miscfs/fullfs/full_vnops.c	fullfs
diff --git a/sys/miscfs/fullfs/full.h b/sys/miscfs/fullfs/full.h
new file mode 100644
index 000000000000..5b45e7de57a3
--- /dev/null
+++ b/sys/miscfs/fullfs/full.h
@@ -0,0 +1,117 @@
+/*	$NetBSD: full.h,v 1.20 2017/04/11 07:51:37 hannken Exp $	*/
+
+/*
+ * Copyright (c) 1999 National Aeronautics & Space Administration
+ * All rights reserved.
+ *
+ * This software was written by William Studenmund of the
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the National Aeronautics & Space Administration
+ *    nor the names of its contributors may be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB-
+ * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: Id: lofs.h,v 1.8 1992/05/30 10:05:43 jsp Exp
+ *	@(#)full.h	8.2 (Berkeley) 1/21/94
+ */
+
+#ifndef _MISCFS_FULLFS_H_
+#define _MISCFS_FULLFS_H_
+
+#include <miscfs/genfs/layer.h>
+
+struct full_args {
+	struct	layer_args	la;	/* generic layerfs args */
+};
+#define	fulla_target	la.target
+#define	fulla_export	la.export
+
+#ifdef _KERNEL
+struct full_mount {
+	struct	layer_mount	lm;	/* generic layerfs mount stuff */
+};
+#define	fullm_rootvp		lm.layerm_rootvp
+#define	fullm_export		lm.layerm_export
+#define	fullm_flags		lm.layerm_flags
+#define	fullm_size		lm.layerm_size
+#define	fullm_tag		lm.layerm_tag
+#define	fullm_bypass		lm.layerm_bypass
+#define	fullm_alloc		lm.layerm_alloc
+#define	fullm_vnodeop_p		lm.layerm_vnodeop_p
+#define	fullm_node_hashtbl	lm.layerm_node_hashtbl
+#define	fullm_node_hash		lm.layerm_node_hash
+#define	fullm_hashlock		lm.layerm_hashlock
+
+/*
+ * A cache of vnode references
+ */
+struct full_node {
+	struct	layer_node	ln;
+};
+#define	full_hash	ln.layer_hash
+#define	full_lowervp	ln.layer_lowervp
+#define	full_vnode	ln.layer_vnode
+#define	full_flags	ln.layer_flags
+
+#define	MOUNTTOFULLMOUNT(mp) ((struct full_mount *)((mp)->mnt_data))
+
+extern int (**full_vnodeop_p)(void *);
+extern struct vfsops fullfs_vfsops;
+
+void fullfs_init(void);
+
+#endif /* _KERNEL */
+#endif /* _MISCFS_FULLFS_H_ */
diff --git a/sys/miscfs/fullfs/full_vfsops.c b/sys/miscfs/fullfs/full_vfsops.c
new file mode 100644
index 000000000000..14873cbe03e6
--- /dev/null
+++ b/sys/miscfs/fullfs/full_vfsops.c
@@ -0,0 +1,282 @@
+/*	$NetBSD: full_vfsops.c,v 1.101 2023/02/06 10:32:58 hannken Exp $	*/
+
+/*
+ * Copyright (c) 1999 National Aeronautics & Space Administration
+ * All rights reserved.
+ *
+ * This software was written by William Studenmund of the
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the National Aeronautics & Space Administration
+ *    nor the names of its contributors may be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB-
+ * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1992, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: Id: lofs_vfsops.c,v 1.9 1992/05/30 10:26:24 jsp Exp
+ *	from: @(#)lofs_vfsops.c	1.2 (Berkeley) 6/18/92
+ *	@(#)null_vfsops.c	8.7 (Berkeley) 5/14/95
+ */
+
+/*
+ * Null file-system: VFS operations.
+ *
+ * See full_vnops.c for a description.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: full_vfsops.c,v 1.101 2023/02/06 10:32:58 hannken Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/namei.h>
+#include <sys/module.h>
+
+#include <miscfs/fullfs/full.h>
+#include <miscfs/genfs/layer_extern.h>
+
+MODULE(MODULE_CLASS_VFS, full, "layerfs");
+
+VFS_PROTOS(fullfs);
+
+int
+fullfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
+{
+	struct vnode *lowerrootvp, *vp;
+	struct full_args *args = data;
+	struct full_mount *nmp;
+	struct layer_mount *lmp;
+	struct pathbuf *pb;
+	struct nameidata nd;
+	int error;
+
+	if (args == NULL)
+		return EINVAL;
+	if (*data_len < sizeof(*args))
+		return EINVAL;
+
+	if (mp->mnt_flag & MNT_GETARGS) {
+		lmp = MOUNTTOLAYERMOUNT(mp);
+		if (lmp == NULL)
+			return EIO;
+		args->la.target = NULL;
+		*data_len = sizeof(*args);
+		return 0;
+	}
+
+	/* Update is not supported. */
+	if (mp->mnt_flag & MNT_UPDATE)
+		return EOPNOTSUPP;
+
+	/* Find the lower vnode and lock it. */
+	error = pathbuf_copyin(args->la.target, &pb);
+	if (error) {
+		return error;
+	}
+	NDINIT(&nd, LOOKUP, FOLLOW|LOCKLEAF, pb);
+	if ((error = namei(&nd)) != 0) {
+		pathbuf_destroy(pb);
+		return error;
+	}
+	lowerrootvp = nd.ni_vp;
+	pathbuf_destroy(pb);
+
+	/* Create the mount point. */
+	nmp = kmem_zalloc(sizeof(struct full_mount), KM_SLEEP);
+	mp->mnt_data = nmp;
+	mp->mnt_iflag |= lowerrootvp->v_mount->mnt_iflag & IMNT_MPSAFE;
+	mp->mnt_iflag |= lowerrootvp->v_mount->mnt_iflag & IMNT_SHRLOOKUP;
+
+	/*
+	 * Make sure that the mount point is sufficiently initialized
+	 * that the node create call will work.
+	 */
+	vfs_getnewfsid(mp);
+	error = vfs_set_lowermount(mp, lowerrootvp->v_mount);
+	if (error) {
+		vput(lowerrootvp);
+		kmem_free(nmp, sizeof(struct full_mount));
+		return error;
+	}
+
+	nmp->fullm_size = sizeof(struct full_node);
+	nmp->fullm_tag = VT_FULL;
+	nmp->fullm_bypass = layer_bypass;
+	nmp->fullm_vnodeop_p = full_vnodeop_p;
+
+	/* Setup a full node for root vnode. */
+	VOP_UNLOCK(lowerrootvp);
+	error = layer_node_create(mp, lowerrootvp, &vp);
+	if (error) {
+		vrele(lowerrootvp);
+		kmem_free(nmp, sizeof(struct full_mount));
+		return error;
+	}
+	/*
+	 * Keep a held reference to the root vnode.  It will be released on
+	 * umount.  Note: fullfs is MP-safe.
+	 */
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+	vp->v_vflag |= VV_ROOT;
+	nmp->fullm_rootvp = vp;
+	VOP_UNLOCK(vp);
+
+	error = set_statvfs_info(path, UIO_USERSPACE, args->la.target,
+	    UIO_USERSPACE, mp->mnt_op->vfs_name, mp, curlwp);
+	if (error)
+		return error;
+
+	if (mp->mnt_lower->mnt_flag & MNT_LOCAL)
+		mp->mnt_flag |= MNT_LOCAL;
+	return 0;
+}
+
+int
+fullfs_unmount(struct mount *mp, int mntflags)
+{
+	struct full_mount *nmp = MOUNTTOFULLMOUNT(mp);
+	struct vnode *full_rootvp = nmp->fullm_rootvp;
+	int error, flags = 0;
+
+	if (mntflags & MNT_FORCE)
+		flags |= FORCECLOSE;
+
+	if (vrefcnt(full_rootvp) > 1 && (mntflags & MNT_FORCE) == 0)
+		return EBUSY;
+
+	if ((error = vflush(mp, full_rootvp, flags)) != 0)
+		return error;
+
+	/* Eliminate all activity and release the vnode. */
+	vgone(full_rootvp);
+
+	/* Finally, destroy the mount point structures. */
+	kmem_free(mp->mnt_data, sizeof(struct full_mount));
+	mp->mnt_data = NULL;
+	return 0;
+}
+
+extern const struct vnodeopv_desc full_vnodeop_opv_desc;
+
+const struct vnodeopv_desc * const fullfs_vnodeopv_descs[] = {
+	&full_vnodeop_opv_desc,
+	NULL,
+};
+
+struct vfsops fullfs_vfsops = {
+	.vfs_name = MOUNT_FULL,
+	.vfs_min_mount_data = sizeof (struct full_args),
+	.vfs_mount = fullfs_mount,
+	.vfs_start = layerfs_start,
+	.vfs_unmount = fullfs_unmount,
+	.vfs_root = layerfs_root,
+	.vfs_quotactl = layerfs_quotactl,
+	.vfs_statvfs = layerfs_statvfs,
+	.vfs_sync = layerfs_sync,
+	.vfs_loadvnode = layerfs_loadvnode,
+	.vfs_vget = layerfs_vget,
+	.vfs_fhtovp = layerfs_fhtovp,
+	.vfs_vptofh = layerfs_vptofh,
+	.vfs_init = layerfs_init,
+	.vfs_done = layerfs_done,
+	.vfs_snapshot = layerfs_snapshot,
+	.vfs_extattrctl = vfs_stdextattrctl,
+	.vfs_suspendctl = layerfs_suspendctl,
+	.vfs_renamelock_enter = layerfs_renamelock_enter,
+	.vfs_renamelock_exit = layerfs_renamelock_exit,
+	.vfs_fsync = (void *)eopnotsupp,
+	.vfs_opv_descs = fullfs_vnodeopv_descs
+};
+
+SYSCTL_SETUP(fullfs_sysctl_setup, "fullfs sysctl")
+{
+
+	sysctl_createv(clog, 0, NULL, NULL,
+	    CTLFLAG_PERMANENT,
+	    CTLTYPE_NODE, "full",
+	    SYSCTL_DESCR("Fullfs file system"),
+	    NULL, 0, NULL, 0,
+	    CTL_VFS, 9, CTL_EOL);
+	/*
+	 * XXX the "9" above could be dynamic, thereby eliminating
+	 * one more instance of the "number to vfs" mapping problem,
+	 * but "9" is the order as taken from sys/mount.h
+	 */
+}
+
+static int
+full_modcmd(modcmd_t cmd, void *arg)
+{
+	int error;
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = vfs_attach(&fullfs_vfsops);
+		if (error != 0)
+			break;
+		break;
+	case MODULE_CMD_FINI:
+		error = vfs_detach(&fullfs_vfsops);
+		if (error != 0)
+			break;
+		break;
+	default:
+		error = ENOTTY;
+		break;
+	}
+	return error;
+}
diff --git a/sys/miscfs/fullfs/full_vnops.c b/sys/miscfs/fullfs/full_vnops.c
new file mode 100644
index 000000000000..e55cafc85aa4
--- /dev/null
+++ b/sys/miscfs/fullfs/full_vnops.c
@@ -0,0 +1,139 @@
+/*	$NetBSD: full_vnops.c,v 1.43 2020/05/16 18:31:51 christos Exp $	*/
+
+/*
+ * Copyright (c) 1999 National Aeronautics & Space Administration
+ * All rights reserved.
+ *
+ * This software was written by William Studenmund of the
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the National Aeronautics & Space Administration
+ *    nor the names of its contributors may be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB-
+ * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * John Heidemann of the UCLA Ficus project.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)null_vnops.c	8.6 (Berkeley) 5/27/95
+ *
+ * Ancestors:
+ *	@(#)lofs_vnops.c	1.2 (Berkeley) 6/18/92
+ *      Id: lofs_vnops.c,v 1.11 1992/05/30 10:05:43 jsp Exp jsp
+ *	...and...
+ *	@(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
+ */
+
+/*
+ * Null file-system.
+ *
+ * Implemented using layerfs, see layer_vnops.c for a description.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: full_vnops.c,v 1.43 2020/05/16 18:31:51 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/vnode.h>
+
+#include <miscfs/genfs/genfs.h>
+#include <miscfs/genfs/layer_extern.h>
+#include <miscfs/fullfs/full.h>
+
+int full_create(void *);
+
+/*
+ * Global VFS data structures.
+ */
+
+int (**full_vnodeop_p)(void *);
+
+const struct vnodeopv_entry_desc full_vnodeop_entries[] = {
+	{ &vop_default_desc,	layer_bypass },
+
+	{ &vop_lookup_desc,	layer_lookup },
+	{ &vop_setattr_desc,	layer_setattr },
+	{ &vop_getattr_desc,	layer_getattr },
+	{ &vop_access_desc,	layer_access },
+	{ &vop_accessx_desc,	genfs_accessx },
+	{ &vop_fsync_desc,	layer_fsync },
+	{ &vop_inactive_desc,	layer_inactive },
+	{ &vop_reclaim_desc,	layer_reclaim },
+	{ &vop_print_desc,	layer_print },
+	{ &vop_remove_desc,	layer_remove },
+	{ &vop_rename_desc,	layer_rename },
+	{ &vop_revoke_desc,	layer_revoke },
+	{ &vop_rmdir_desc,	layer_rmdir },
+
+	{ &vop_open_desc,	layer_open },	/* mount option handling */
+	{ &vop_close_desc,	layer_close },
+
+	{ &vop_bmap_desc,	layer_bmap },
+	{ &vop_getpages_desc,	layer_getpages },
+	{ &vop_putpages_desc,	layer_putpages },
+
+	{ &vop_create_desc,	full_create },
+
+	{ NULL, NULL }
+};
+
+const struct vnodeopv_desc full_vnodeop_opv_desc = {
+	&full_vnodeop_p, full_vnodeop_entries
+};
+
+/* Reject all writes */
+int
+full_create(void *v)
+{
+	return ENOSPC;
+}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 1903fcd3c697..55ac71f161a4 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -72,6 +72,7 @@
 #define	MOUNT_MSDOS	"msdos"		/* MSDOS Filesystem */
 #define	MOUNT_LFS	"lfs"		/* Log-based Filesystem */
 #define	MOUNT_FDESC	"fdesc"		/* File Descriptor Filesystem */
+#define	MOUNT_FULL	"full"		/* FS where writes fail with disk full */
 #define	MOUNT_NULL	"null"		/* Minimal Filesystem Layer */
 #define	MOUNT_OVERLAY	"overlay"	/* Minimal Overlay Filesystem Layer */
 #define	MOUNT_UMAP	"umap"	/* User/Group Identifier Remapping Filesystem */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index e0796d2cf6d0..1b046ce53d06 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -103,7 +103,7 @@ enum vtagtype	{
 	VT_AFS, VT_ISOFS, VT_UNION, VT_ADOSFS, VT_EXT2FS, VT_CODA,
 	VT_FILECORE, VT_NTFS, VT_VFS, VT_OVERLAY, VT_SMBFS, VT_PTYFS,
 	VT_TMPFS, VT_UDF, VT_SYSVBFS, VT_PUFFS, VT_HFS, VT_EFS, VT_ZFS,
-	VT_RUMP, VT_NILFS, VT_V7FS, VT_CHFS, VT_AUTOFS
+	VT_RUMP, VT_NILFS, VT_V7FS, VT_CHFS, VT_AUTOFS, VT_FULL
 };
 
 #define	VNODE_TAGS \
@@ -112,7 +112,7 @@ enum vtagtype	{
     "VT_AFS", "VT_ISOFS", "VT_UNION", "VT_ADOSFS", "VT_EXT2FS", "VT_CODA", \
     "VT_FILECORE", "VT_NTFS", "VT_VFS", "VT_OVERLAY", "VT_SMBFS", "VT_PTYFS", \
     "VT_TMPFS", "VT_UDF", "VT_SYSVBFS", "VT_PUFFS", "VT_HFS", "VT_EFS", \
-    "VT_ZFS", "VT_RUMP", "VT_NILFS", "VT_V7FS", "VT_CHFS", "VT_AUTOFS"
+    "VT_ZFS", "VT_RUMP", "VT_NILFS", "VT_V7FS", "VT_CHFS", "VT_AUTOFS", "VT_FULL"
 
 #if defined(_KERNEL) || defined(_KMEMUSER)
 struct vnode;

Reply via email to