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
> 

Reply via email to