Hello,

Milos Nikic, le jeu. 12 févr. 2026 06:30:45 -0800, a ecrit:
> We don't always undo the link increases in error cases.
> Added logic the undo the changes to link count if an
> error occurred in those cases.
> ---
>  libdiskfs/dir-rename.c  | 12 ++++++++++--
>  libdiskfs/dir-renamed.c | 29 +++++++++++++++++++++++++++--
>  2 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/libdiskfs/dir-rename.c b/libdiskfs/dir-rename.c
> index c8bb0dad..7953132b 100644
> --- a/libdiskfs/dir-rename.c
> +++ b/libdiskfs/dir-rename.c
> @@ -188,12 +188,20 @@ diskfs_S_dir_rename (struct protid *fromcred,
>      diskfs_node_update (tdp, 1);
>  
>    pthread_mutex_unlock (&tdp->lock);
> -  pthread_mutex_unlock (&fnp->lock);
>    if (err)
>      {
> -      diskfs_nrele (fnp);
> +      if (fnp->dn_stat.st_nlink > 0)

Do we really need to check these? We have increased it just above, and
haven't released the mutex. We're actually the owner of that reference,
it'd rather be an assert.

> +     {
> +       fnp->dn_stat.st_nlink--;
> +       fnp->dn_set_ctime = 1;
> +       if (diskfs_synchronous)
> +         diskfs_node_update (fnp, 1);
> +     }
> +      diskfs_drop_dirstat (tdp, ds);
> +      diskfs_nput (fnp);
>        return err;
>      }
> +  pthread_mutex_unlock (&fnp->lock);
>  
>    /* We now hold no locks */
>  
> diff --git a/libdiskfs/dir-renamed.c b/libdiskfs/dir-renamed.c
> index 1f3f3de4..532ff998 100644
> --- a/libdiskfs/dir-renamed.c
> +++ b/libdiskfs/dir-renamed.c
> @@ -159,6 +159,13 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
> const char *fromname,
>        assert_backtrace (err != ENOENT);
>        if (err)
>       {
> +       if (tdp->dn_stat.st_nlink > 0)
> +         {
> +           tdp->dn_stat.st_nlink--;
> +           tdp->dn_set_ctime = 1;
> +           if (diskfs_synchronous)
> +             diskfs_node_update (tdp, 1);
> +         }
>         diskfs_drop_dirstat (fnp, tmpds);
>         goto out;
>       }
> @@ -168,7 +175,16 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
> const char *fromname,
>        if (diskfs_synchronous)
>       diskfs_file_update (fnp, 1);
>        if (err)
> -     goto out;
> +     {
> +       if (tdp->dn_stat.st_nlink > 0)
> +         {
> +           tdp->dn_stat.st_nlink--;
> +           tdp->dn_set_ctime = 1;
> +           if (diskfs_synchronous)
> +             diskfs_node_update (tdp, 1);
> +         }
> +       goto out;
> +     }
>  
>        fdp->dn_stat.st_nlink--;
>        fdp->dn_set_ctime = 1;
> @@ -213,7 +229,16 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
> const char *fromname,
>      }
>  
>    if (err)
> -    goto out;
> +    {
> +      if (fnp->dn_stat.st_nlink > 0)
> +     {
> +       fnp->dn_stat.st_nlink--;
> +       fnp->dn_set_ctime = 1;
> +       if (diskfs_synchronous)
> +         diskfs_node_update (fnp, 1);
> +     }
> +      goto out;
> +    }
>  
>    /* 4: Remove the entry in fdp. */
>    ds = buf;
> -- 
> 2.52.0
> 

-- 
Samuel
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and
the Ugly)."
(By Matt Welsh)

Reply via email to