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
