@@ -52,6 +52,7 @@
#define xfs_attr_shortform_verify libxfs_attr_shortform_verify
#define __xfs_bmap_add_free __libxfs_bmap_add_free
+#define xfs_bmap_add_attrfork libxfs_bmap_add_attrfork
#define xfs_bmap_validate_extent libxfs_bmap_validate_extent
#define xfs_bmapi_read libxfs_bmapi_read
#define xfs_bmapi_remap libxfs_bmapi_remap
@@ -205,6 +206,7 @@
#define xfs_parent_addname libxfs_parent_addname
#define xfs_parent_finish libxfs_parent_finish
#define xfs_parent_hashval libxfs_parent_hashval
+#define xfs_parent_lookup libxfs_parent_lookup
#define xfs_parent_removename libxfs_parent_removename
#define xfs_parent_start libxfs_parent_start
#define xfs_parent_from_attr libxfs_parent_from_attr
@@ -903,6 +903,12 @@ mk_orphanage(xfs_mount_t *mp)
const int mode = 0755;
int nres;
struct xfs_name xname;
+ struct xfs_parent_args *ppargs = NULL;
+
+ 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
@@ -994,6 +1000,14 @@ mk_orphanage(xfs_mount_t *mp)
_("can't make %s, createname error %d\n"),
ORPHANAGE, error);
+ if (ppargs) {
+ error = -libxfs_parent_addname(tp, ppargs, pip, &xname, ip);
+ if (error)
+ do_error(
+ _("can't make %s, parent addname 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
@@ -1016,10 +1030,52 @@ mk_orphanage(xfs_mount_t *mp)
libxfs_irele(ip);
out_pip:
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_rec pptr = { };
+ struct xfs_da_args scratch;
+ int error;
+
+ xfs_inode_to_parent_rec(&pptr, orphanage_ip);
+ error = -libxfs_parent_lookup(tp, ip, xname, &pptr, &scratch);
+ if (!error)
+ return;
+ if (error != ENOATTR)
+ do_log(
+ _("cannot look up parent pointer for '%.*s', err %d\n"),
+ xname->len, xname->name, error);
+
+ if (!xfs_inode_has_attr_fork(ip)) {
+ error = -libxfs_bmap_add_attrfork(tp, ip,
+ sizeof(struct xfs_attr_sf_hdr), true);
+ if (error)
+ do_error(_("can't add attr fork to inode 0x%llx\n"),
+ (unsigned long long)ip->i_ino);
+ }
+
+ error = -libxfs_parent_addname(tp, ppargs, orphanage_ip, xname, ip);
+ if (error)
+ do_error(
+ _("can't add parent pointer for '%.*s', error %d\n"),
+ xname->len, xname->name, error);
+}
+
/*
* move a file to the orphange.
*/
@@ -1040,6 +1096,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",
@@ -1091,6 +1154,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
@@ -1125,6 +1192,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
@@ -1173,6 +1244,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);
@@ -1182,6 +1257,7 @@ mv_orphanage(
}
libxfs_irele(ino_p);
libxfs_irele(orphanage_ip);
+ libxfs_parent_finish(mp, ppargs);
}
static int