Milos Nikic, le jeu. 29 oct. 2026 21:26:41 -0700, a ecrit:
> A lookup of ".." with SPEC_DOTDOT and LOOKUP releases the directory
> only when it succeeds; its callers, checkpath and ancestors in
> diskfs_rename_dir, release it themselves otherwise.
This should probably be specified in the comment of the prototype of
diskfs_lookup_hard in libdiskfs/diskfs.h
> diskfs_lookup_hard
> released it before diskfs_cached_lookup of the parent, so when that
> failed the directory was unlocked and dereferenced twice.
>
> Hold a reference across the lookup, and give the directory back locked
> when it fails.
> ---
> ext2fs/dir.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/ext2fs/dir.c b/ext2fs/dir.c
> index 09f5a7225..583232f36 100644
> --- a/ext2fs/dir.c
> +++ b/ext2fs/dir.c
> @@ -316,10 +316,17 @@ diskfs_lookup_hard (struct node *dp, const char *name,
> lookup_flags_t l_flags,
>
> else if (type == LOOKUP)
> {
> + /* Hold DP until the lookup succeeds: on failure the caller
> + still has it, locked. */
> + diskfs_nref (dp);
> diskfs_nput (dp);
? This is taking a hard ref, only to release it immediately after.
Better just unlock dp?
Samuel
> err = diskfs_cached_lookup (inum, &np);
> if (err)
> - goto out;
> + {
> + pthread_mutex_lock (&dp->lock);
> + goto out;
> + }
> + diskfs_nrele (dp);
> }
> else
> assert_backtrace (0);
> --
> 2.56.0
>