@@ -853,6 +853,53 @@ mk_orphanage(
return(ino);
}
+/* Don't let metadata inode contents leak to lost+found. */
+static void
+trunc_metadata_inode(
+ struct xfs_inode *ip)
+{
+ struct xfs_trans *tp;
+ struct xfs_mount *mp = ip->i_mount;
+ int err;
+
+ err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
+ if (err)
+ do_error(
+ _("space reservation failed (%d), filesystem may be out of space\n"),
+ err);
+
+ libxfs_trans_ijoin(tp, ip, 0);
+ ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA;
+
+ switch (VFS_I(ip)->i_mode & S_IFMT) {
+ case S_IFIFO:
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFSOCK:
+ ip->i_df.if_format = XFS_DINODE_FMT_DEV;
+ break;
+ case S_IFREG:
+ switch (ip->i_df.if_format) {
+ case XFS_DINODE_FMT_EXTENTS:
+ case XFS_DINODE_FMT_BTREE:
+ break;
+ default:
+ ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
+ ip->i_df.if_nextents = 0;
+ break;
+ }
+ break;
+ }
+
+ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+ err = -libxfs_trans_commit(tp);
+ if (err)
+ do_error(
+ _("truncation of metadata inode 0x%llx failed, err=%d\n"),
+ (unsigned long long)ip->i_ino, err);
+}
+
/*
* Add a parent pointer back to the orphanage for any file we're moving into
* the orphanage, being careful not to trip over any existing parent pointer.
@@ -943,6 +990,9 @@ mv_orphanage(
if (err)
do_error(_("%d - couldn't iget disconnected inode\n"), err);
+ if (xfs_is_metadir_inode(ino_p))
+ trunc_metadata_inode(ino_p);
+
xname.type = libxfs_mode_to_ftype(VFS_I(ino_p)->i_mode);
if (isa_dir) {