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)