Re: [PATCH] xfs: reset child dir '..' entry when unlinking child

Gao Xiang
2021-07-05T08:21:05Z

On Fri, Jul 02, 2021 at 08:02:33PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> While running xfs/168, I noticed a second source of post-shrink
> corruption errors causing shutdowns.
>
> Let's say that directory B has a low inode number and is a child of
> directory A, which has a high number. If B is empty but open, and
> unlinked from A, B's dotdot link continues to point to A. If A is then
> unlinked and the filesystem shrunk so that A is no longer a valid inode,
> a subsequent AIL push of B will trip the inode verifiers because the
> dotdot entry points outside of the filesystem.
>
> To avoid this problem, reset B's dotdot entry to the root directory when
> unlinking directories, since the root directory cannot be removed.
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>

I think it is reasonable to clean dotdot for all deaddir
cases (compared with skipping validating such dotdot dirent which
sounds a bit hacky though since dotdot was actually outdated...)

Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>

Thanks,
Gao Xiang

> ---
> fs/xfs/xfs_inode.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index 52be5c6d0b3b..03e25246e936 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -2817,6 +2817,19 @@ xfs_remove(
> error = xfs_droplink(tp, ip);
> if (error)
> goto out_trans_cancel;
> +
> + /*
> + * Point the unlinked child directory's ".." entry to the root
> + * directory to eliminate back-references to inodes that may
> + * get freed before the child directory is closed. If the fs
> + * gets shrunk, this can lead to dirent inode validation errors.
> + */
> + if (dp->i_ino != tp->t_mountp->m_sb.sb_rootino) {
> + error = xfs_dir_replace(tp, ip, &xfs_name_dotdot,
> + tp->t_mountp->m_sb.sb_rootino, 0);
> + if (error)
> + return error;
> + }
> } else {
> /*
> * When removing a non-directory we need to log the parent