git: a2f08d0ddc29 - main - pseudofs: return errors from pfs_create_*()

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Thu, 04 Sep 2025 02:09:52 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=a2f08d0ddc29e4da15f614bdb6a5072b3fd6332c

commit a2f08d0ddc29e4da15f614bdb6a5072b3fd6332c
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-09-04 02:08:52 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-09-04 02:08:52 +0000

    pseudofs: return errors from pfs_create_*()
    
    In D52038, we kind of guess at the reason that pfs_create_dir() failed,
    which isn't great: it could be EEXISTS, or it could even be ENOMEM.
    
    Change the pfs_create_*() interfaces to return an error and use a double
    pointer to return the new node as requested.  Outside of the changes
    in sys/fs/pseudofs, this diff is the result of running the added
    coccinelle script against in-tree pseudofs and fixing all of the
    style(9) violations that spatch added.
    
    We set *opn to NULL in the failure cases to avoid breaking callers that
    did actually error-check their results, since the cocci patch does not
    attempt to handle that in any way.
    
    Reviewed by:    des (previous version), kib
    Differential Revision:  https://reviews.freebsd.org/D52157
---
 sys/compat/lindebugfs/lindebugfs.c     |   8 +-
 sys/compat/linprocfs/linprocfs.c       | 256 ++++++++++++++++-----------------
 sys/compat/linsysfs/linsysfs.c         | 119 +++++++--------
 sys/compat/linsysfs/linsysfs_net.c     |  24 ++--
 sys/fs/procfs/procfs.c                 |  68 ++++-----
 sys/fs/pseudofs/pseudofs.c             |  66 ++++++---
 sys/fs/pseudofs/pseudofs.h             |  19 +--
 tools/coccinelle/pseudofs-create.cocci |  35 +++++
 8 files changed, 327 insertions(+), 268 deletions(-)

diff --git a/sys/compat/lindebugfs/lindebugfs.c b/sys/compat/lindebugfs/lindebugfs.c
index 50f9377ffec3..8cddc6f390bc 100644
--- a/sys/compat/lindebugfs/lindebugfs.c
+++ b/sys/compat/lindebugfs/lindebugfs.c
@@ -206,7 +206,7 @@ debugfs_create_file(const char *name, umode_t mode,
 		pnode = debugfs_root;
 
 	flags = fops->write ? PFS_RDWR : PFS_RD;
-	dnode->d_pfs_node = pfs_create_file(pnode, name, debugfs_fill,
+	pfs_create_file(pnode, &dnode->d_pfs_node, name, debugfs_fill,
 	    debugfs_attr, NULL, debugfs_destroy, flags | PFS_NOWAIT);
 	if (dnode->d_pfs_node == NULL) {
 		free(dm, M_DFSINT);
@@ -283,7 +283,8 @@ debugfs_create_dir(const char *name, struct dentry *parent)
 	else
 		pnode = debugfs_root;
 
-	dnode->d_pfs_node = pfs_create_dir(pnode, name, debugfs_attr, NULL, debugfs_destroy, PFS_RD | PFS_NOWAIT);
+	pfs_create_dir(pnode, &dnode->d_pfs_node, name, debugfs_attr, NULL,
+	    debugfs_destroy, PFS_RD | PFS_NOWAIT);
 	if (dnode->d_pfs_node == NULL) {
 		free(dm, M_DFSINT);
 		return (NULL);
@@ -316,7 +317,8 @@ debugfs_create_symlink(const char *name, struct dentry *parent,
 	else
 		pnode = debugfs_root;
 
-	dnode->d_pfs_node = pfs_create_link(pnode, name, &debugfs_fill_data, NULL, NULL, NULL, PFS_NOWAIT);
+	pfs_create_link(pnode, &dnode->d_pfs_node, name, &debugfs_fill_data,
+	    NULL, NULL, NULL, PFS_NOWAIT);
 	if (dnode->d_pfs_node == NULL)
 		goto fail;
 	dnode->d_pfs_node->pn_data = dm;
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 1c6d64d6b8bc..95b212be1306 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -2320,165 +2320,165 @@ linprocfs_init(PFS_INIT_ARGS)
 	root = pi->pi_root;
 
 	/* /proc/... */
-	pfs_create_file(root, "cmdline", &linprocfs_docmdline,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "cpuinfo", &linprocfs_docpuinfo,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "devices", &linprocfs_dodevices,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "filesystems", &linprocfs_dofilesystems,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "loadavg", &linprocfs_doloadavg,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "meminfo", &linprocfs_domeminfo,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "modules", &linprocfs_domodules,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "mounts", &linprocfs_domtab,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "mtab", &linprocfs_domtab,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "partitions", &linprocfs_dopartitions,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_link(root, "self", &procfs_docurproc,
-	    NULL, NULL, NULL, 0);
-	pfs_create_file(root, "stat", &linprocfs_dostat,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "swaps", &linprocfs_doswaps,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "uptime", &linprocfs_douptime,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(root, "version", &linprocfs_doversion,
+	pfs_create_file(root, NULL, "cmdline", &linprocfs_docmdline, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "cpuinfo", &linprocfs_docpuinfo, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "devices", &linprocfs_dodevices, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "filesystems", &linprocfs_dofilesystems,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(root, NULL, "loadavg", &linprocfs_doloadavg, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "meminfo", &linprocfs_domeminfo, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "modules", &linprocfs_domodules, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "mounts", &linprocfs_domtab, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "mtab", &linprocfs_domtab, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(root, NULL, "partitions", &linprocfs_dopartitions, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_link(root, NULL, "self", &procfs_docurproc, NULL, NULL, NULL,
+	    0);
+	pfs_create_file(root, NULL, "stat", &linprocfs_dostat, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(root, NULL, "swaps", &linprocfs_doswaps, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "uptime", &linprocfs_douptime, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(root, NULL, "version", &linprocfs_doversion, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/bus/... */
-	dir = pfs_create_dir(root, "bus", NULL, NULL, NULL, 0);
-	dir = pfs_create_dir(dir, "pci", NULL, NULL, NULL, 0);
-	dir = pfs_create_dir(dir, "devices", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &dir, "bus", NULL, NULL, NULL, 0);
+	pfs_create_dir(dir, &dir, "pci", NULL, NULL, NULL, 0);
+	pfs_create_dir(dir, &dir, "devices", NULL, NULL, NULL, 0);
 
 	/* /proc/net/... */
-	dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "dev", &linprocfs_donetdev,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "route", &linprocfs_donetroute,
-	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_dir(root, &dir, "net", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "dev", &linprocfs_donetdev, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(dir, NULL, "route", &linprocfs_donetroute, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/<pid>/... */
-	dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP);
-	pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_link(dir, "cwd", &linprocfs_doproccwd,
-	    NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "environ", &linprocfs_doprocenviron,
-	    NULL, &procfs_candebug, NULL, PFS_RD);
-	pfs_create_link(dir, "exe", &procfs_doprocfile,
-	    NULL, &procfs_notsystem, NULL, 0);
-	pfs_create_file(dir, "maps", &linprocfs_doprocmaps,
-	    NULL, NULL, NULL, PFS_RD | PFS_AUTODRAIN);
-	pfs_create_file(dir, "mem", &linprocfs_doprocmem,
-	    procfs_attr_rw, &procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
-	pfs_create_file(dir, "mountinfo", &linprocfs_doprocmountinfo,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "mounts", &linprocfs_domtab,
+	pfs_create_dir(root, &dir, "pid", NULL, NULL, NULL, PFS_PROCDEP);
+	pfs_create_file(dir, NULL, "cmdline", &linprocfs_doproccmdline, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_link(dir, NULL, "cwd", &linprocfs_doproccwd, NULL, NULL,
+	    NULL, 0);
+	pfs_create_file(dir, NULL, "environ", &linprocfs_doprocenviron, NULL,
+	    &procfs_candebug, NULL, PFS_RD);
+	pfs_create_link(dir, NULL, "exe", &procfs_doprocfile, NULL,
+	    &procfs_notsystem, NULL, 0);
+	pfs_create_file(dir, NULL, "maps", &linprocfs_doprocmaps, NULL, NULL,
+	    NULL, PFS_RD | PFS_AUTODRAIN);
+	pfs_create_file(dir, NULL, "mem", &linprocfs_doprocmem, procfs_attr_rw,
+	    &procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
+	pfs_create_file(dir, NULL, "mountinfo", &linprocfs_doprocmountinfo,
 	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_link(dir, "root", &linprocfs_doprocroot,
-	    NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "stat", &linprocfs_doprocstat,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "statm", &linprocfs_doprocstatm,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "status", &linprocfs_doprocstatus,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_link(dir, "fd", &linprocfs_dofdescfs,
-	    NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "auxv", &linprocfs_doauxv,
-	    NULL, &procfs_candebug, NULL, PFS_RD|PFS_RAWRD);
-	pfs_create_file(dir, "limits", &linprocfs_doproclimits,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "oom_score_adj", &linprocfs_do_oom_score_adj,
+	pfs_create_file(dir, NULL, "mounts", &linprocfs_domtab, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_link(dir, NULL, "root", &linprocfs_doprocroot, NULL, NULL,
+	    NULL, 0);
+	pfs_create_file(dir, NULL, "stat", &linprocfs_doprocstat, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "statm", &linprocfs_doprocstatm, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "status", &linprocfs_doprocstatus, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_link(dir, NULL, "fd", &linprocfs_dofdescfs, NULL, NULL, NULL,
+	    0);
+	pfs_create_file(dir, NULL, "auxv", &linprocfs_doauxv, NULL,
+	    &procfs_candebug, NULL, PFS_RD | PFS_RAWRD);
+	pfs_create_file(dir, NULL, "limits", &linprocfs_doproclimits, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "oom_score_adj", &linprocfs_do_oom_score_adj,
 	    procfs_attr_rw, &procfs_candebug, NULL, PFS_RDWR);
 
 	/* /proc/<pid>/task/... */
-	dir = pfs_create_dir(dir, "task", linprocfs_dotaskattr, NULL, NULL, 0);
-	pfs_create_file(dir, ".dummy", &linprocfs_dotaskdummy,
-	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_dir(dir, &dir, "task", linprocfs_dotaskattr, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, ".dummy", &linprocfs_dotaskdummy, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/scsi/... */
-	dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "device_info", &linprocfs_doscsidevinfo,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "scsi", &linprocfs_doscsiscsi,
+	pfs_create_dir(root, &dir, "scsi", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "device_info", &linprocfs_doscsidevinfo,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "scsi", &linprocfs_doscsiscsi, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/sys/... */
-	sys = pfs_create_dir(root, "sys", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &sys, "sys", NULL, NULL, NULL, 0);
 
 	/* /proc/sys/kernel/... */
-	dir = pfs_create_dir(sys, "kernel", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "osrelease", &linprocfs_doosrelease,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "ostype", &linprocfs_doostype,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "version", &linprocfs_doosbuild,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msgmax", &linprocfs_domsgmax,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msgmni", &linprocfs_domsgmni,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msgmnb", &linprocfs_domsgmnb,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "ngroups_max", &linprocfs_dongroups_max,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "pid_max", &linprocfs_dopid_max,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "sem", &linprocfs_dosem,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "shmall", &linprocfs_doshmall,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "shmmax", &linprocfs_doshmmax,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "shmmni", &linprocfs_doshmmni,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "tainted", &linprocfs_dotainted,
+	pfs_create_dir(sys, &dir, "kernel", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "osrelease", &linprocfs_doosrelease, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "ostype", &linprocfs_doostype, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "version", &linprocfs_doosbuild, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msgmax", &linprocfs_domsgmax, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msgmni", &linprocfs_domsgmni, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msgmnb", &linprocfs_domsgmnb, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "ngroups_max", &linprocfs_dongroups_max,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "pid_max", &linprocfs_dopid_max, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "sem", &linprocfs_dosem, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(dir, NULL, "shmall", &linprocfs_doshmall, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "shmmax", &linprocfs_doshmmax, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "shmmni", &linprocfs_doshmmni, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "tainted", &linprocfs_dotainted, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/sys/kernel/random/... */
-	dir = pfs_create_dir(dir, "random", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "uuid", &linprocfs_douuid,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "boot_id", &linprocfs_doboot_id,
-	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_dir(dir, &dir, "random", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "uuid", &linprocfs_douuid, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(dir, NULL, "boot_id", &linprocfs_doboot_id, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/sys/vm/.... */
-	dir = pfs_create_dir(sys, "vm", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "min_free_kbytes", &linprocfs_dominfree,
+	pfs_create_dir(sys, &dir, "vm", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "min_free_kbytes", &linprocfs_dominfree,
 	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "max_map_count", &linprocfs_domax_map_cnt,
+	pfs_create_file(dir, NULL, "max_map_count", &linprocfs_domax_map_cnt,
 	    NULL, NULL, NULL, PFS_RD);
 
 	/* /proc/sysvipc/... */
-	dir = pfs_create_dir(root, "sysvipc", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "msg", &linprocfs_dosysvipc_msg,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "sem", &linprocfs_dosysvipc_sem,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "shm", &linprocfs_dosysvipc_shm,
-	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_dir(root, &dir, "sysvipc", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "msg", &linprocfs_dosysvipc_msg, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "sem", &linprocfs_dosysvipc_sem, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "shm", &linprocfs_dosysvipc_shm, NULL, NULL,
+	    NULL, PFS_RD);
 
 	/* /proc/sys/fs/... */
-	dir = pfs_create_dir(sys, "fs", NULL, NULL, NULL, 0);
+	pfs_create_dir(sys, &dir, "fs", NULL, NULL, NULL, 0);
 
 	/* /proc/sys/fs/mqueue/... */
-	dir = pfs_create_dir(dir, "mqueue", NULL, NULL, NULL, 0);
-	pfs_create_file(dir, "msg_default", &linprocfs_domqueue_msg_default,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msgsize_default", &linprocfs_domqueue_msgsize_default,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msg_max", &linprocfs_domqueue_msg_max,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "msgsize_max", &linprocfs_domqueue_msgsize_max,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "queues_max", &linprocfs_domqueue_queues_max,
+	pfs_create_dir(dir, &dir, "mqueue", NULL, NULL, NULL, 0);
+	pfs_create_file(dir, NULL, "msg_default",
+	    &linprocfs_domqueue_msg_default, NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msgsize_default",
+	    &linprocfs_domqueue_msgsize_default, NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msg_max", &linprocfs_domqueue_msg_max, NULL,
+	    NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "msgsize_max",
+	    &linprocfs_domqueue_msgsize_max, NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "queues_max", &linprocfs_domqueue_queues_max,
 	    NULL, NULL, NULL, PFS_RD);
 
 	return (0);
diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c
index b70cb43d0f9a..5a41c5193415 100644
--- a/sys/compat/linsysfs/linsysfs.c
+++ b/sys/compat/linsysfs/linsysfs.c
@@ -294,43 +294,43 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi,
 				    dinfo->cfg.func);
 				strcat(new_path, "/");
 				strcat(new_path, device);
-				dir = pfs_create_dir(dir, device,
+				error = pfs_create_dir(dir, &dir, device,
 				    NULL, NULL, NULL, 0);
-				if (dir == NULL) {
-					error = EEXIST;
+				if (error != 0)
 					goto out;
-				}
-				cur_file = pfs_create_file(dir, "vendor",
+				pfs_create_dir(dir, &dir, device, NULL, NULL,
+				    NULL, 0);
+				pfs_create_file(dir, &cur_file, "vendor",
 				    &linsysfs_fill_vendor, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir, "device",
+				pfs_create_file(dir, &cur_file, "device",
 				    &linsysfs_fill_device, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir,
+				pfs_create_file(dir, &cur_file,
 				    "subsystem_vendor",
 				    &linsysfs_fill_subvendor, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir,
+				pfs_create_file(dir, &cur_file,
 				    "subsystem_device",
 				    &linsysfs_fill_subdevice, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir, "revision",
+				pfs_create_file(dir, &cur_file, "revision",
 				    &linsysfs_fill_revid, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir, "config",
+				pfs_create_file(dir, &cur_file, "config",
 				    &linsysfs_fill_config, NULL, NULL, NULL,
 				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_file(dir, "uevent",
-				    &linsysfs_fill_uevent_pci, NULL, NULL,
-				    NULL, PFS_RD);
+				pfs_create_file(dir, &cur_file, "uevent",
+				    &linsysfs_fill_uevent_pci, NULL, NULL, NULL,
+				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
-				cur_file = pfs_create_link(dir, "subsystem",
+				pfs_create_link(dir, &cur_file, "subsystem",
 				    &linsysfs_fill_data, NULL, NULL, NULL, 0);
 				/* libdrm just checks that the link ends in "/pci" */
 				cur_file->pn_data = "/sys/bus/pci";
@@ -340,8 +340,8 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi,
 					sprintf(host, "host%d", host_number++);
 					strcat(new_path, "/");
 					strcat(new_path, host);
-					pfs_create_dir(dir, host,
-					    NULL, NULL, NULL, 0);
+					pfs_create_dir(dir, NULL, host, NULL,
+					    NULL, NULL, 0);
 					scsi_host = malloc(sizeof(
 					    struct scsi_host_queue),
 					    M_DEVBUF, M_WAITOK);
@@ -353,13 +353,13 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi,
 					    strlen(new_path) + 1);
 					scsi_host->name = "unknown";
 
-					sub_dir = pfs_create_dir(scsi, host,
-					    NULL, NULL, NULL, 0);
-					pfs_create_link(sub_dir, "device",
-					    &linsysfs_link_scsi_host,
+					pfs_create_dir(scsi, &sub_dir, host,
 					    NULL, NULL, NULL, 0);
-					pfs_create_file(sub_dir, "proc_name",
-					    &linsysfs_scsiname,
+					pfs_create_link(sub_dir, NULL, "device",
+					    &linsysfs_link_scsi_host, NULL,
+					    NULL, NULL, 0);
+					pfs_create_file(sub_dir, NULL,
+					    "proc_name", &linsysfs_scsiname,
 					    NULL, NULL, NULL, PFS_RD);
 					scsi_host->name
 					    = linux_driver_get_name_dev(dev);
@@ -378,26 +378,27 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi,
 		    device_get_unit(dev) >= 0) {
 			dinfo = device_get_ivars(parent);
 			if (dinfo != NULL && dinfo->cfg.baseclass == PCIC_DISPLAY) {
-				pfs_create_dir(dir, "drm", NULL, NULL, NULL, 0);
+				pfs_create_dir(dir, NULL, "drm", NULL, NULL,
+				    NULL, 0);
 				sprintf(devname, "226:%d",
 				    device_get_unit(dev));
-				sub_dir = pfs_create_dir(chardev,
-				    devname, NULL, NULL, NULL, 0);
-				cur_file = pfs_create_link(sub_dir,
-				    "device", &linsysfs_fill_vgapci, NULL,
-				    NULL, NULL, PFS_RD);
+				pfs_create_dir(chardev, &sub_dir, devname, NULL,
+				    NULL, NULL, 0);
+				pfs_create_link(sub_dir, &cur_file, "device",
+				    &linsysfs_fill_vgapci, NULL, NULL, NULL,
+				    PFS_RD);
 				cur_file->pn_data = (void*)dir;
-				cur_file = pfs_create_file(sub_dir,
-				    "uevent", &linsysfs_fill_uevent_drm, NULL,
-				    NULL, NULL, PFS_RD);
+				pfs_create_file(sub_dir, &cur_file, "uevent",
+				    &linsysfs_fill_uevent_drm, NULL, NULL, NULL,
+				    PFS_RD);
 				cur_file->pn_data = (void*)dev;
 				sprintf(devname, "card%d",
 				    device_get_unit(dev));
-				sub_dir = pfs_create_dir(drm,
-				    devname, NULL, NULL, NULL, 0);
-				cur_file = pfs_create_link(sub_dir,
-				    "device", &linsysfs_fill_vgapci, NULL,
-				    NULL, NULL, PFS_RD);
+				pfs_create_dir(drm, &sub_dir, devname, NULL,
+				    NULL, NULL, 0);
+				pfs_create_link(sub_dir, &cur_file, "device",
+				    &linsysfs_fill_vgapci, NULL, NULL, NULL,
+				    PFS_RD);
 				cur_file->pn_data = (void*)dir;
 			}
 		}
@@ -479,10 +480,10 @@ linsysfs_listcpus(struct pfs_node *dir)
 	for (i = 0; i < mp_ncpus; ++i) {
 		/* /sys/devices/system/cpu/cpuX */
 		sprintf(name, "cpu%d", i);
-		cpu = pfs_create_dir(dir, name, NULL, NULL, NULL, 0);
+		pfs_create_dir(dir, &cpu, name, NULL, NULL, NULL, 0);
 
-		pfs_create_file(cpu, "online", &linsysfs_cpuxonline,
-		    NULL, NULL, NULL, PFS_RD);
+		pfs_create_file(cpu, NULL, "online", &linsysfs_cpuxonline, NULL,
+		    NULL, NULL, PFS_RD);
 	}
 	free(name, M_TEMP);
 }
@@ -509,24 +510,24 @@ linsysfs_init(PFS_INIT_ARGS)
 	root = pi->pi_root;
 
 	/* /sys/bus/... */
-	dir = pfs_create_dir(root, "bus", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &dir, "bus", NULL, NULL, NULL, 0);
 
 	/* /sys/class/... */
-	class = pfs_create_dir(root, "class", NULL, NULL, NULL, 0);
-	scsi = pfs_create_dir(class, "scsi_host", NULL, NULL, NULL, 0);
-	drm = pfs_create_dir(class, "drm", NULL, NULL, NULL, 0);
-	pfs_create_dir(class, "power_supply", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &class, "class", NULL, NULL, NULL, 0);
+	pfs_create_dir(class, &scsi, "scsi_host", NULL, NULL, NULL, 0);
+	pfs_create_dir(class, &drm, "drm", NULL, NULL, NULL, 0);
+	pfs_create_dir(class, NULL, "power_supply", NULL, NULL, NULL, 0);
 
 	/* /sys/class/net/.. */
-	net = pfs_create_dir(class, "net", NULL, NULL, NULL, 0);
+	pfs_create_dir(class, &net, "net", NULL, NULL, NULL, 0);
 
 	/* /sys/dev/... */
-	devdir = pfs_create_dir(root, "dev", NULL, NULL, NULL, 0);
-	chardev = pfs_create_dir(devdir, "char", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &devdir, "dev", NULL, NULL, NULL, 0);
+	pfs_create_dir(devdir, &chardev, "char", NULL, NULL, NULL, 0);
 
 	/* /sys/devices/... */
-	dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0);
-	pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &dir, "devices", NULL, NULL, NULL, 0);
+	pfs_create_dir(dir, &pci, "pci0000:00", NULL, NULL, NULL, 0);
 
 	devclass = devclass_find("root");
 	if (devclass == NULL) {
@@ -541,24 +542,24 @@ linsysfs_init(PFS_INIT_ARGS)
 	linsysfs_run_bus(dev, pci, scsi, chardev, drm, "/pci0000:00", "0000");
 
 	/* /sys/devices/system */
-	sys = pfs_create_dir(dir, "system", NULL, NULL, NULL, 0);
+	pfs_create_dir(dir, &sys, "system", NULL, NULL, NULL, 0);
 
 	/* /sys/devices/system/cpu */
-	cpu = pfs_create_dir(sys, "cpu", NULL, NULL, NULL, 0);
+	pfs_create_dir(sys, &cpu, "cpu", NULL, NULL, NULL, 0);
 
-	pfs_create_file(cpu, "online", &linsysfs_cpuonline,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(cpu, "possible", &linsysfs_cpuonline,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(cpu, "present", &linsysfs_cpuonline,
-	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(cpu, NULL, "online", &linsysfs_cpuonline, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(cpu, NULL, "possible", &linsysfs_cpuonline, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(cpu, NULL, "present", &linsysfs_cpuonline, NULL, NULL,
+	    NULL, PFS_RD);
 
 	linsysfs_listcpus(cpu);
 
 	/* /sys/kernel */
-	kernel = pfs_create_dir(root, "kernel", NULL, NULL, NULL, 0);
+	pfs_create_dir(root, &kernel, "kernel", NULL, NULL, NULL, 0);
 	/* /sys/kernel/debug, mountpoint for lindebugfs. */
-	pfs_create_dir(kernel, "debug", NULL, NULL, NULL, 0);
+	pfs_create_dir(kernel, NULL, "debug", NULL, NULL, NULL, 0);
 
 	linsysfs_net_init();
 
diff --git a/sys/compat/linsysfs/linsysfs_net.c b/sys/compat/linsysfs/linsysfs_net.c
index 73602b0132a4..751dbb5b3713 100644
--- a/sys/compat/linsysfs/linsysfs_net.c
+++ b/sys/compat/linsysfs/linsysfs_net.c
@@ -237,22 +237,22 @@ linsysfs_net_addif(if_t ifp, void *arg)
 
 	nic = pfs_find_node(dir, ifname);
 	if (nic == NULL) {
-		nic = pfs_create_dir(dir, ifname, NULL, linsysfs_if_visible,
+		pfs_create_dir(dir, &nic, ifname, NULL, linsysfs_if_visible,
 		    NULL, 0);
-		pfs_create_file(nic, "address", &linsysfs_if_addr,
+		pfs_create_file(nic, NULL, "address", &linsysfs_if_addr, NULL,
+		    NULL, NULL, PFS_RD);
+		pfs_create_file(nic, NULL, "addr_len", &linsysfs_if_addrlen,
 		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "addr_len", &linsysfs_if_addrlen,
+		pfs_create_file(nic, NULL, "flags", &linsysfs_if_flags, NULL,
+		    NULL, NULL, PFS_RD);
+		pfs_create_file(nic, NULL, "ifindex", &linsysfs_if_ifindex,
 		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "flags", &linsysfs_if_flags,
+		pfs_create_file(nic, NULL, "mtu", &linsysfs_if_mtu, NULL, NULL,
+		    NULL, PFS_RD);
+		pfs_create_file(nic, NULL, "tx_queue_len", &linsysfs_if_txq_len,
 		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "ifindex", &linsysfs_if_ifindex,
-		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "mtu", &linsysfs_if_mtu,
-		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "tx_queue_len", &linsysfs_if_txq_len,
-		    NULL, NULL, NULL, PFS_RD);
-		pfs_create_file(nic, "type", &linsysfs_if_type,
-		NULL, NULL, NULL, PFS_RD);
+		pfs_create_file(nic, NULL, "type", &linsysfs_if_type, NULL,
+		    NULL, NULL, PFS_RD);
 	}
 	/*
 	 * There is a small window between registering the if_arrival
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
index ab60ba47f322..cd66dd6f8b3b 100644
--- a/sys/fs/procfs/procfs.c
+++ b/sys/fs/procfs/procfs.c
@@ -156,42 +156,42 @@ procfs_init(PFS_INIT_ARGS)
 
 	root = pi->pi_root;
 
-	pfs_create_link(root, "curproc", procfs_docurproc,
-	    NULL, NULL, NULL, 0);
-	pfs_create_link(root, "self", procfs_docurproc,
-	    NULL, NULL, NULL, 0);
-
-	dir = pfs_create_dir(root, "pid",
-	    procfs_attr_all_rx, NULL, NULL, PFS_PROCDEP);
-	pfs_create_file(dir, "cmdline", procfs_doproccmdline,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "dbregs", procfs_doprocdbregs,
+	pfs_create_link(root, NULL, "curproc", procfs_docurproc, NULL, NULL,
+	    NULL, 0);
+	pfs_create_link(root, NULL, "self", procfs_docurproc, NULL, NULL, NULL,
+	    0);
+
+	pfs_create_dir(root, &dir, "pid", procfs_attr_all_rx, NULL, NULL,
+	    PFS_PROCDEP);
+	pfs_create_file(dir, NULL, "cmdline", procfs_doproccmdline, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "dbregs", procfs_doprocdbregs,
 	    procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
-	pfs_create_file(dir, "etype", procfs_doproctype,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "fpregs", procfs_doprocfpregs,
+	pfs_create_file(dir, NULL, "etype", procfs_doproctype, NULL, NULL, NULL,
+	    PFS_RD);
+	pfs_create_file(dir, NULL, "fpregs", procfs_doprocfpregs,
 	    procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
-	pfs_create_file(dir, "map", procfs_doprocmap,
-	    NULL, procfs_notsystem, NULL, PFS_RD);
-	pfs_create_file(dir, "mem", procfs_doprocmem,
-	    procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
-	pfs_create_file(dir, "note", procfs_doprocnote,
-	    procfs_attr_w, procfs_candebug, NULL, PFS_WR);
-	pfs_create_file(dir, "notepg", procfs_doprocnote,
-	    procfs_attr_w, procfs_candebug, NULL, PFS_WR);
-	pfs_create_file(dir, "regs", procfs_doprocregs,
-	    procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
-	pfs_create_file(dir, "rlimit", procfs_doprocrlimit,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "status", procfs_doprocstatus,
-	    NULL, NULL, NULL, PFS_RD);
-	pfs_create_file(dir, "osrel", procfs_doosrel,
-	    procfs_attr_rw, procfs_candebug, NULL, PFS_RDWR);
-
-	pfs_create_link(dir, "file", procfs_doprocfile,
-	    NULL, procfs_notsystem, NULL, 0);
-	pfs_create_link(dir, "exe", procfs_doprocfile,
-	    NULL, procfs_notsystem, NULL, 0);
+	pfs_create_file(dir, NULL, "map", procfs_doprocmap, NULL,
+	    procfs_notsystem, NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "mem", procfs_doprocmem, procfs_attr_rw,
+	    procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
+	pfs_create_file(dir, NULL, "note", procfs_doprocnote, procfs_attr_w,
+	    procfs_candebug, NULL, PFS_WR);
+	pfs_create_file(dir, NULL, "notepg", procfs_doprocnote, procfs_attr_w,
+	    procfs_candebug, NULL, PFS_WR);
+	pfs_create_file(dir, NULL, "regs", procfs_doprocregs, procfs_attr_rw,
+	    procfs_candebug, NULL, PFS_RDWR | PFS_RAW);
+	pfs_create_file(dir, NULL, "rlimit", procfs_doprocrlimit, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "status", procfs_doprocstatus, NULL, NULL,
+	    NULL, PFS_RD);
+	pfs_create_file(dir, NULL, "osrel", procfs_doosrel, procfs_attr_rw,
+	    procfs_candebug, NULL, PFS_RDWR);
+
+	pfs_create_link(dir, NULL, "file", procfs_doprocfile, NULL,
+	    procfs_notsystem, NULL, 0);
+	pfs_create_link(dir, NULL, "exe", procfs_doprocfile, NULL,
+	    procfs_notsystem, NULL, 0);
 
 	return (0);
 }
diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c
index 20cb87c6c6d5..26a1dcd4ad39 100644
--- a/sys/fs/pseudofs/pseudofs.c
+++ b/sys/fs/pseudofs/pseudofs.c
@@ -239,81 +239,101 @@ pfs_fixup_dir(struct pfs_node *parent)
 /*
  * Create a directory
  */
-struct pfs_node	*
-pfs_create_dir(struct pfs_node *parent, const char *name,
-	       pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy,
-	       int flags)
+int
+pfs_create_dir(struct pfs_node *parent, struct pfs_node **opn,
+	       const char *name, pfs_attr_t attr, pfs_vis_t vis,
+	       pfs_destroy_t destroy, int flags)
 {
-	struct pfs_node *pn;
+	struct pfs_node *pdir, *pn;
 	int rc;
 
-	pn = pfs_alloc_node_flags(parent->pn_info, name,
+	/* Preserve in case the caller is reusing the one pointer for both. */
+	pdir = parent;
+	if (opn != NULL)
+		*opn = NULL;
+	pn = pfs_alloc_node_flags(pdir->pn_info, name,
 			 (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir, flags);
 	if (pn == NULL)
-		return (NULL);
+		return (ENOMEM);
 	pn->pn_attr = attr;
 	pn->pn_vis = vis;
 	pn->pn_destroy = destroy;
 	pn->pn_flags = flags;
-	rc = pfs_add_node(parent, pn);
+	rc = pfs_add_node(pdir, pn);
 	if (rc == 0)
 		rc = pfs_fixup_dir_flags(pn, flags);
 	if (rc != 0) {
 		pfs_destroy(pn);
 		pn = NULL;
+	} else if (opn != NULL) {
+		*opn = pn;
 	}
-	return (pn);
+
+	return (rc);
 }
 
 /*
  * Create a file
  */
-struct pfs_node	*
-pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill,
-		pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy,
-		int flags)
+int
+pfs_create_file(struct pfs_node *parent, struct pfs_node **opn,
+		const char *name, pfs_fill_t fill, pfs_attr_t attr,
+		pfs_vis_t vis, pfs_destroy_t destroy, int flags)
 {
 	struct pfs_node *pn;
+	int rc;
 
+	if (opn != NULL)
+		*opn = NULL;
 	pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_file, flags);
 	if (pn == NULL)
-		return (NULL);
+		return (ENOMEM);
+
 	pn->pn_fill = fill;
 	pn->pn_attr = attr;
 	pn->pn_vis = vis;
 	pn->pn_destroy = destroy;
 	pn->pn_flags = flags;
-	if (pfs_add_node(parent, pn) != 0) {
+	if ((rc = pfs_add_node(parent, pn)) != 0) {
 		pfs_destroy(pn);
 		pn = NULL;
+	} else if (opn != NULL) {
+		*opn = pn;
 	}
-	return (pn);
+
+	return (rc);
 }
 
 /*
  * Create a symlink
  */
-struct pfs_node	*
-pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill,
-		pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy,
-		int flags)
+int
+pfs_create_link(struct pfs_node *parent, struct pfs_node **opn,
+		const char *name, pfs_fill_t fill, pfs_attr_t attr,
+		pfs_vis_t vis, pfs_destroy_t destroy, int flags)
 {
 	struct pfs_node *pn;
+	int rc;
 
+	if (opn != NULL)
+		*opn = NULL;
 	pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_symlink, flags);
 	if (pn == NULL)
-		return (NULL);
+		return (ENOMEM);
+
 	pn->pn_fill = fill;
 	pn->pn_attr = attr;
 	pn->pn_vis = vis;
 	pn->pn_destroy = destroy;
 	pn->pn_flags = flags;
-	if (pfs_add_node(parent, pn) != 0) {
+	if ((rc = pfs_add_node(parent, pn)) != 0) {
 		pfs_destroy(pn);
 		pn = NULL;
+	} else if (opn != NULL) {
+		*opn = pn;
 	}
 
-	return (pn);
+	return (rc);
 }
 
 /*
diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h
index 461a1d2402e4..e060f89b580f 100644
--- a/sys/fs/pseudofs/pseudofs.h
+++ b/sys/fs/pseudofs/pseudofs.h
@@ -260,17 +260,18 @@ int		 pfs_vfsuninit	(struct pfs_info *pi, struct vfsconf *vfc);
 /*
  * Directory structure construction and manipulation
  */
-struct pfs_node	*pfs_create_dir	(struct pfs_node *parent, const char *name,
-				 pfs_attr_t attr, pfs_vis_t vis,
-				 pfs_destroy_t destroy, int flags);
-struct pfs_node	*pfs_create_file(struct pfs_node *parent, const char *name,
-				 pfs_fill_t fill, pfs_attr_t attr,
-				 pfs_vis_t vis, pfs_destroy_t destroy,
-				 int flags);
-struct pfs_node	*pfs_create_link(struct pfs_node *parent, const char *name,
-				 pfs_fill_t fill, pfs_attr_t attr,
+int pfs_create_dir		(struct pfs_node *parent, struct pfs_node **opn,
+				 const char *name, pfs_attr_t attr,
 				 pfs_vis_t vis, pfs_destroy_t destroy,
 				 int flags);
+int pfs_create_file		(struct pfs_node *parent, struct pfs_node **opn,
+				 const char *name, pfs_fill_t fill,
+				 pfs_attr_t attr, pfs_vis_t vis,
+				 pfs_destroy_t destroy, int flags);
+int pfs_create_link		(struct pfs_node *parent, struct pfs_node **opn,
+				 const char *name, pfs_fill_t fill,
+				 pfs_attr_t attr, pfs_vis_t vis,
+				 pfs_destroy_t destroy, int flags);
 struct pfs_node	*pfs_find_node	(struct pfs_node *parent, const char *name);
 void		 pfs_purge	(struct pfs_node *pn);
 int		 pfs_destroy	(struct pfs_node *pn);
diff --git a/tools/coccinelle/pseudofs-create.cocci b/tools/coccinelle/pseudofs-create.cocci
new file mode 100644
index 000000000000..ba5870f38732
--- /dev/null
+++ b/tools/coccinelle/pseudofs-create.cocci
@@ -0,0 +1,35 @@
+@ pfs_create_dir_ret_ident @
+ expression _pfn, E1, E2, E3, E4, E5, E6;
+@@
+-_pfn = pfs_create_dir(E1, E2, E3, E4, E5, E6);
++pfs_create_dir(E1, &_pfn, E2, E3, E4, E5, E6);
+
+@ pfs_create_file_ret @
+ expression _pfn, E1, E2, E3, E4, E5, E6, E7;
+@@
+-_pfn = pfs_create_file(E1, E2, E3, E4, E5, E6, E7);
++pfs_create_file(E1, &_pfn, E2, E3, E4, E5, E6, E7);
+
+@ pfs_create_link_ret @
+ expression _pfn, E1, E2, E3, E4, E5, E6, E7;
+@@
+-_pfn = pfs_create_link(E1, E2, E3, E4, E5, E6, E7);
++pfs_create_link(E1, &_pfn, E2, E3, E4, E5, E6, E7);
+
+@ pfs_create_dir_noret @
+ expression E1, E2, E3, E4, E5, E6;
+@@
+-pfs_create_dir(E1, E2, E3, E4, E5, E6);
++pfs_create_dir(E1, NULL, E2, E3, E4, E5, E6);
+
+@ pfs_create_file_noret @
+ expression E1, E2, E3, E4, E5, E6, E7;
+@@
+-pfs_create_file(E1, E2, E3, E4, E5, E6, E7);
++pfs_create_file(E1, NULL, E2, E3, E4, E5, E6, E7);
+
+@ pfs_create_link_noret @
+ expression E1, E2, E3, E4, E5, E6, E7;
+@@
+-pfs_create_link(E1, E2, E3, E4, E5, E6, E7);
++pfs_create_link(E1, NULL, E2, E3, E4, E5, E6, E7);