Hello,

The comment for the netfs_S_dir_mkfile function which calls
netfs_attempt_mkfile implies that after the call, the dir mutex should be
unlocked and the np mutex locked; however, this expectation is not reflected
in the comment explaining netfs_attempt_mkfile itself.  Examining the code
of netfs translators that implement this function (such as console-client)
reveals that they do indeed call pthread_mutex_lock (&(*np)->lock).
I believe we should document this in the comment.  Additionally,
netfs_S_dir_mkfile shows that the np variable is not accessed in the event
of an error, so setting it to NULL in that case serves no purpose; I think
we should remove the NULL assignment to avoid confusion.

Furthermore, in some netfs translators, the mutexes in netfs_attempt_mkfile
and netfs_attempt_create_file were not being unlocked.  This can cause
issues when attempting to create a file within such a translator (for
instance, when trying to create a file in the /proc directory). These
problems can be easily avoided by unlocking the dir mutex before exiting
these functions.

Thanks,

--
Mikhail Karpov
From 32edd69e556e7d3025b3cbf31a8b95b0dc83c2f0 Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Sun, 4 Oct 2026 11:32:50 +0700
Subject: [PATCH 2/3] Updated the comment for netfs_attempt_mkfile

---
 acpi/netfs_impl.c            | 3 ++-
 console-client/trans.c       | 4 ++--
 eth-multiplexer/netfs_impl.c | 3 ++-
 ftpfs/netfs.c                | 3 ++-
 hostmux/stubs.c              | 3 ++-
 libnetfs/netfs.h             | 3 ++-
 pci-arbiter/netfs_impl.c     | 3 ++-
 procfs/netfs.c               | 3 ++-
 usermux/stubs.c              | 3 ++-
 9 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/acpi/netfs_impl.c b/acpi/netfs_impl.c
index e37c7f6..248824b 100644
--- a/acpi/netfs_impl.c
+++ b/acpi/netfs_impl.c
@@ -468,7 +468,8 @@ netfs_attempt_link (struct iouser * user, struct node * dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t
 netfs_attempt_mkfile (struct iouser * user, struct node * dir,
                      mode_t mode, struct node ** node)
diff --git a/console-client/trans.c b/console-client/trans.c
index 24e22e6..599aab2 100644
--- a/console-client/trans.c
+++ b/console-client/trans.c
@@ -481,8 +481,8 @@ netfs_attempt_link (struct iouser *user, struct node *dir,
 
 
 /* Attempt to create an anonymous file related to DIR (which is
-   locked) for USER with MODE.  Set *NP to the returned file upon
-   success. No matter what, unlock DIR.  */
+   locked) for USER with MODE.  *NP should be locked on success;
+   no matter what, unlock DIR before returning.  */
 error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			     mode_t mode, struct node **np)
diff --git a/eth-multiplexer/netfs_impl.c b/eth-multiplexer/netfs_impl.c
index 2c8b18b..c3bd81e 100644
--- a/eth-multiplexer/netfs_impl.c
+++ b/eth-multiplexer/netfs_impl.c
@@ -479,7 +479,8 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **node)
 {
diff --git a/ftpfs/netfs.c b/ftpfs/netfs.c
index a6481c1..0d06fd0 100644
--- a/ftpfs/netfs.c
+++ b/ftpfs/netfs.c
@@ -404,7 +404,8 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **node)
 {
diff --git a/hostmux/stubs.c b/hostmux/stubs.c
index ae4daeb..37e1bc4 100644
--- a/hostmux/stubs.c
+++ b/hostmux/stubs.c
@@ -114,7 +114,8 @@ netfs_attempt_link (struct iouser *user, struct node *dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 		      mode_t mode, struct node **node)
diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h
index 1f1d5c2..b493c09 100644
--- a/libnetfs/netfs.h
+++ b/libnetfs/netfs.h
@@ -248,7 +248,8 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 
 /* The user must define this function.  Attempt to create an anonymous
    file related to DIR (which is locked) for USER with MODE.  Set *NP
-   to the returned file upon success. No matter what, unlock DIR.  */
+   to the returned file upon success.  *NP should be locked on success;
+   no matter what, unlock DIR before returning.  */
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **np);
 
diff --git a/pci-arbiter/netfs_impl.c b/pci-arbiter/netfs_impl.c
index 82e618a..7a6f1aa 100644
--- a/pci-arbiter/netfs_impl.c
+++ b/pci-arbiter/netfs_impl.c
@@ -474,7 +474,8 @@ netfs_attempt_link (struct iouser * user, struct node * dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t
 netfs_attempt_mkfile (struct iouser * user, struct node * dir,
 		      mode_t mode, struct node ** node)
diff --git a/procfs/netfs.c b/procfs/netfs.c
index 4ed5eab..a0f1b48 100644
--- a/procfs/netfs.c
+++ b/procfs/netfs.c
@@ -434,7 +434,8 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 
 /* The user must define this function.  Attempt to create an anonymous
    file related to DIR (which is locked) for USER with MODE.  Set *NP
-   to the returned file upon success. No matter what, unlock DIR.  */
+   to the returned file upon success.  *NP should be locked on success;
+   no matter what, unlock DIR before returning.  */
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **np)
 {
diff --git a/usermux/stubs.c b/usermux/stubs.c
index c3b9b96..b7166c2 100644
--- a/usermux/stubs.c
+++ b/usermux/stubs.c
@@ -114,7 +114,8 @@ netfs_attempt_link (struct iouser *user, struct node *dir,
 }
 
 /* Attempt to create an anonymous file related to DIR for USER with MODE.
-   Set *NODE to the returned file upon success.  No matter what, unlock DIR. */
+   Set *NODE to the returned file upon success.  *NP should be locked on
+   success; no matter what, unlock DIR before returning.  */
 error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 		      mode_t mode, struct node **node)
-- 
2.43.0

From 8b64d28f5eb4c8f7f56633ae4cc90b14b6fe72b8 Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Sun, 4 Oct 2026 12:45:24 +0700
Subject: [PATCH 3/3] Unlocking mutexes in libnetfs callbacks

---
 acpi/netfs_impl.c            | 1 +
 console-client/trans.c       | 8 ++------
 console/console.c            | 1 +
 eth-multiplexer/netfs_impl.c | 1 -
 ftpfs/netfs.c                | 1 -
 hostmux/stubs.c              | 1 -
 nfs/ops.c                    | 6 ++++--
 pci-arbiter/netfs_impl.c     | 1 +
 procfs/netfs.c               | 3 +++
 usermux/stubs.c              | 1 +
 10 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/acpi/netfs_impl.c b/acpi/netfs_impl.c
index 248824b..4ea5c60 100644
--- a/acpi/netfs_impl.c
+++ b/acpi/netfs_impl.c
@@ -474,6 +474,7 @@ error_t
 netfs_attempt_mkfile (struct iouser * user, struct node * dir,
                      mode_t mode, struct node ** node)
 {
+  pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
 
diff --git a/console-client/trans.c b/console-client/trans.c
index 599aab2..db41b11 100644
--- a/console-client/trans.c
+++ b/console-client/trans.c
@@ -491,13 +491,9 @@ netfs_attempt_mkfile (struct iouser *user, struct node *dir,
   struct netnode *nn;
 
   err = fshelp_access (&dir->nn_stat, S_IWRITE, user);
-  if (err)
-    {
-      *np = 0;
-      return err;
-    }
-
   pthread_mutex_unlock (&dir->lock);
+  if (err)
+    return err;
 
   nn = calloc (1, sizeof (*nn));
   if (!nn)
diff --git a/console/console.c b/console/console.c
index e7d7ed5..efc83da 100644
--- a/console/console.c
+++ b/console/console.c
@@ -1113,6 +1113,7 @@ error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 		      mode_t mode, struct node **np)
 {
+  pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
 
diff --git a/eth-multiplexer/netfs_impl.c b/eth-multiplexer/netfs_impl.c
index c3bd81e..bf620da 100644
--- a/eth-multiplexer/netfs_impl.c
+++ b/eth-multiplexer/netfs_impl.c
@@ -485,7 +485,6 @@ error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **node)
 {
   debug("");
-  *node = 0;
   pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
diff --git a/ftpfs/netfs.c b/ftpfs/netfs.c
index 0d06fd0..eb66534 100644
--- a/ftpfs/netfs.c
+++ b/ftpfs/netfs.c
@@ -409,7 +409,6 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **node)
 {
-  *node = 0;
   pthread_mutex_unlock (&dir->lock);
   return EROFS;
 }
diff --git a/hostmux/stubs.c b/hostmux/stubs.c
index 37e1bc4..f471fd2 100644
--- a/hostmux/stubs.c
+++ b/hostmux/stubs.c
@@ -120,7 +120,6 @@ error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 		      mode_t mode, struct node **node)
 {
-  *node = 0;
   pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
diff --git a/nfs/ops.c b/nfs/ops.c
index c87ec72..c95fb0d 100644
--- a/nfs/ops.c
+++ b/nfs/ops.c
@@ -1255,8 +1255,9 @@ netfs_attempt_mkfile (struct iouser *cred, struct node *dir,
   name = malloc (50);
   if (! name)
     {
+      err = errno;
       pthread_mutex_unlock (&dir->lock);
-      return ENOMEM;
+      return err;
     }
 
   do
@@ -1295,6 +1296,8 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np,
   error_t err;
   uid_t owner;
 
+  *newnp = 0;
+
   if (cred->uids->num)
     owner = cred->uids->ids[0];
   else
@@ -1342,7 +1345,6 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np,
     p = xdr_encode_create_state (p, mode, owner);
 
   err = conduct_rpc (&rpcbuf, &p);
-  *newnp = 0;
 
   pthread_mutex_unlock (&np->lock);
 
diff --git a/pci-arbiter/netfs_impl.c b/pci-arbiter/netfs_impl.c
index 7a6f1aa..a5ab0af 100644
--- a/pci-arbiter/netfs_impl.c
+++ b/pci-arbiter/netfs_impl.c
@@ -480,6 +480,7 @@ error_t
 netfs_attempt_mkfile (struct iouser * user, struct node * dir,
 		      mode_t mode, struct node ** node)
 {
+  pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
 
diff --git a/procfs/netfs.c b/procfs/netfs.c
index a0f1b48..f9b4302 100644
--- a/procfs/netfs.c
+++ b/procfs/netfs.c
@@ -439,6 +439,7 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir,
 error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 			      mode_t mode, struct node **np)
 {
+  pthread_mutex_unlock (&dir->lock);
   return EROFS;
 }
 
@@ -449,6 +450,8 @@ error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 error_t netfs_attempt_create_file (struct iouser *user, struct node *dir,
 				   const char *name, mode_t mode, struct node **np)
 {
+  *np = NULL;
+  pthread_mutex_unlock (&dir->lock);
   return EROFS;
 }
 
diff --git a/usermux/stubs.c b/usermux/stubs.c
index b7166c2..876347c 100644
--- a/usermux/stubs.c
+++ b/usermux/stubs.c
@@ -120,6 +120,7 @@ error_t
 netfs_attempt_mkfile (struct iouser *user, struct node *dir,
 		      mode_t mode, struct node **node)
 {
+  pthread_mutex_unlock (&dir->lock);
   return EOPNOTSUPP;
 }
 
-- 
2.43.0

Reply via email to