@@ -185,6 +185,8 @@
#define xfs_parent_add libxfs_parent_add
#define xfs_parent_finish libxfs_parent_finish
#define xfs_parent_irec_from_disk libxfs_parent_irec_from_disk
+#define xfs_parent_irec_hashname libxfs_parent_irec_hashname
+#define xfs_parent_lookup libxfs_parent_lookup
#define xfs_parent_start libxfs_parent_start
#define xfs_parent_hashcheck libxfs_parent_hashcheck
#define xfs_parent_namecheck libxfs_parent_namecheck
@@ -902,6 +902,12 @@ mk_orphanage(xfs_mount_t *mp)
const int mode = 0755;
int nres;
struct xfs_name xname;
+ struct xfs_parent_args *ppargs;
+
+ i = -libxfs_parent_start(mp, &ppargs);
+ if (i)
+ do_error(_("%d - couldn't allocate parent pointer for %s\n"),
+ i, ORPHANAGE);
/*
* check for an existing lost+found first, if it exists, return
@@ -991,6 +997,12 @@ mk_orphanage(xfs_mount_t *mp)
_("can't make %s, createname error %d\n"),
ORPHANAGE, error);
+ error = -libxfs_parent_add(tp, ppargs, pip, &xname, ip);
+ if (error)
+ do_error(
+ _("committing %s parent pointer failed, error %d.\n"),
+ ORPHANAGE, error);
+
/*
* bump up the link count in the root directory to account
* for .. in the new directory, and update the irec copy of the
@@ -1012,10 +1024,51 @@ mk_orphanage(xfs_mount_t *mp)
}
libxfs_irele(ip);
libxfs_irele(pip);
+ libxfs_parent_finish(mp, ppargs);
return(ino);
}
+/*
+ * 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.
+ * You never know when the orphanage might get corrupted.
+ */
+static void
+add_orphan_pptr(
+ struct xfs_trans *tp,
+ struct xfs_inode *orphanage_ip,
+ const struct xfs_name *xname,
+ struct xfs_inode *ip,
+ struct xfs_parent_args *ppargs)
+{
+ struct xfs_parent_name_irec pptr = {
+ .p_ino = orphanage_ip->i_ino,
+ .p_gen = VFS_I(orphanage_ip)->i_generation,
+ .p_namelen = xname->len,
+ };
+ struct xfs_parent_scratch scr = { };
+ struct xfs_mount *mp = tp->t_mountp;
+ int error;
+
+ memcpy(pptr.p_name, xname->name, xname->len);
+ libxfs_parent_irec_hashname(mp, &pptr);
+
+ error = -libxfs_parent_lookup(tp, ip, &pptr, &scr);
+ if (!error)
+ return;
+ if (error != ENOATTR)
+ do_log(
+ _("cannot look up parent pointer for '%.*s', err %d\n"),
+ xname->len, xname->name, error);
+
+ error = -libxfs_parent_add(tp, ppargs, orphanage_ip, xname, ip);
+ if (error)
+ do_error(
+ _("adding '%.*s' parent pointer failed, error %d.\n"),
+ xname->len, xname->name, error);
+}
+
/*
* move a file to the orphange.
*/
@@ -1036,6 +1089,13 @@ mv_orphanage(
ino_tree_node_t *irec;
int ino_offset = 0;
struct xfs_name xname;
+ struct xfs_parent_args *ppargs;
+
+ err = -libxfs_parent_start(mp, &ppargs);
+ if (err)
+ do_error(
+ _("%d - couldn't allocate parent pointer for lost inode\n"),
+ err);
xname.name = fname;
xname.len = snprintf((char *)fname, sizeof(fname), "%llu",
@@ -1087,6 +1147,10 @@ mv_orphanage(
do_error(
_("name create failed in %s (%d)\n"), ORPHANAGE, err);
+ if (ppargs)
+ add_orphan_pptr(tp, orphanage_ip, &xname,
+ ino_p, ppargs);
+
if (irec)
add_inode_ref(irec, ino_offset);
else
@@ -1121,6 +1185,10 @@ mv_orphanage(
do_error(
_("name create failed in %s (%d)\n"), ORPHANAGE, err);
+ if (ppargs)
+ add_orphan_pptr(tp, orphanage_ip, &xname,
+ ino_p, ppargs);
+
if (irec)
add_inode_ref(irec, ino_offset);
else
@@ -1169,6 +1237,10 @@ mv_orphanage(
_("name create failed in %s (%d)\n"), ORPHANAGE, err);
ASSERT(err == 0);
+ if (ppargs)
+ add_orphan_pptr(tp, orphanage_ip, &xname, ino_p,
+ ppargs);
+
set_nlink(VFS_I(ino_p), 1);
libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
err = -libxfs_trans_commit(tp);
@@ -1178,6 +1250,7 @@ mv_orphanage(
}
libxfs_irele(ino_p);
libxfs_irele(orphanage_ip);
+ libxfs_parent_finish(mp, ppargs);
}
static int