On Fri, Jul 02, 2021 at 08:02:33PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > 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@xxxxxxxxxx> 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@xxxxxxxxxxxxxxxxx> 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