try_lookup unlocks the directory before fshelp_fetch_root, which locks
only the translated node again. Every outcome but ENOENT then goes to
OUT, which unlocks the directory a second time with diskfs_nput. A
thread holding the directory, such as another lookup in it, loses its
lock, as with any lookup through a translator, e.g. under /dev or
/servers.
Release only the directory's reference on those exits.
---
libdiskfs/dir-lookup.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index fd444be21..eef922eaf 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -277,6 +277,12 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (err != ENOENT)
{
+ /* DNP is still unlocked: only its reference goes. */
+ if (np != dnp)
+ {
+ diskfs_nrele (dnp);
+ dnp = 0;
+ }
*retry_port_type = MACH_MSG_TYPE_MOVE_SEND;
if (!err)
{
--
2.56.0