@@ -140,6 +140,9 @@
#define xfs_log_get_max_trans_res libxfs_log_get_max_trans_res
#define xfs_log_sb libxfs_log_sb
#define xfs_mode_to_ftype libxfs_mode_to_ftype
+#define xfs_parent_defer_add libxfs_parent_defer_add
+#define xfs_parent_finish libxfs_parent_finish
+#define xfs_parent_start libxfs_parent_start
#define xfs_perag_get libxfs_perag_get
#define xfs_perag_put libxfs_perag_put
#define xfs_prealloc_blocks libxfs_prealloc_blocks
@@ -8,7 +8,6 @@
#include <sys/stat.h>
#include "libfrog/convert.h"
#include "proto.h"
-#include "xfs_parent.h"
/*
* Prototypes for internal functions.
@@ -349,6 +348,20 @@ newdirectory(
fail(_("directory create error"), error);
}
+static struct xfs_parent_defer *
+newpptr(
+ struct xfs_mount *mp)
+{
+ struct xfs_parent_defer *ret;
+ int error;
+
+ error = -libxfs_parent_start(mp, &ret);
+ if (error)
+ fail(_("initializing parent pointer"), error);
+
+ return ret;
+}
+
static void
parseproto(
xfs_mount_t *mp,
@@ -384,6 +397,7 @@ parseproto(
char *value;
struct xfs_name xname;
xfs_dir2_dataptr_t offset;
+ struct xfs_parent_defer *parent = NULL;
memset(&creds, 0, sizeof(creds));
mstr = getstr(pp);
@@ -458,6 +472,7 @@ parseproto(
case IF_REGULAR:
buf = newregfile(pp, &len);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
+ parent = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -481,7 +496,7 @@ parseproto(
exit(1);
}
tp = getres(mp, XFS_B_TO_FSB(mp, llen));
-
+ parent = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -492,15 +507,24 @@ parseproto(
xname.type = XFS_DIR3_FT_REG_FILE;
newdirent(mp, tp, pip, &xname, ip->i_ino, &offset);
libxfs_trans_log_inode(tp, ip, flags);
+ if (parent) {
+ error = -libxfs_parent_defer_add(tp, parent, pip,
+ &xname, offset, ip);
+ if (error)
+ fail(_("committing parent pointers failed."),
+ error);
+ }
error = -libxfs_trans_commit(tp);
if (error)
fail(_("Space preallocation failed."), error);
+ libxfs_parent_finish(mp, parent);
rsvfile(mp, ip, llen);
libxfs_irele(ip);
return;
case IF_BLOCK:
tp = getres(mp, 0);
+ parent = newpptr(mp);
majdev = getnum(getstr(pp), 0, 0, false);
mindev = getnum(getstr(pp), 0, 0, false);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFBLK, 1,
@@ -516,6 +540,7 @@ parseproto(
case IF_CHAR:
tp = getres(mp, 0);
+ parent = newpptr(mp);
majdev = getnum(getstr(pp), 0, 0, false);
mindev = getnum(getstr(pp), 0, 0, false);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFCHR, 1,
@@ -530,6 +555,7 @@ parseproto(
case IF_FIFO:
tp = getres(mp, 0);
+ parent = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFIFO, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -542,6 +568,7 @@ parseproto(
buf = getstr(pp);
len = (int)strlen(buf);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
+ parent = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFLNK, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -564,6 +591,7 @@ parseproto(
libxfs_log_sb(tp);
isroot = 1;
} else {
+ parent = newpptr(mp);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_DIR;
newdirent(mp, tp, pip, &xname, ip->i_ino, &offset);
@@ -572,9 +600,19 @@ parseproto(
}
newdirectory(mp, tp, ip, pip);
libxfs_trans_log_inode(tp, ip, flags);
+ if (parent) {
+ error = -libxfs_parent_defer_add(tp, parent, pip,
+ &xname, offset, ip);
+ if (error)
+ fail(_("committing parent pointers failed."),
+ error);
+ }
error = -libxfs_trans_commit(tp);
if (error)
fail(_("Directory inode allocation failed."), error);
+
+ libxfs_parent_finish(mp, parent);
+
/*
* RT initialization. Do this here to ensure that
* the RT inodes get placed after the root inode.
@@ -597,28 +635,19 @@ parseproto(
fail(_("Unknown format"), EINVAL);
}
libxfs_trans_log_inode(tp, ip, flags);
+ if (parent) {
+ error = -libxfs_parent_defer_add(tp, parent, pip, &xname,
+ offset, ip);
+ if (error)
+ fail(_("committing parent pointers failed."), error);
+ }
error = -libxfs_trans_commit(tp);
if (error) {
fail(_("Error encountered creating file from prototype file"),
error);
}
- if (xfs_has_parent(mp)) {
- struct xfs_parent_name_rec rec;
- struct xfs_da_args args = {
- .dp = ip,
- .name = (const unsigned char *)&rec,
- .namelen = sizeof(rec),
- .attr_filter = XFS_ATTR_PARENT,
- .value = (void *)xname.name,
- .valuelen = xname.len,
- };
- libxfs_init_parent_name_rec(&rec, pip, offset);
- error = -libxfs_attr_set(&args);
- if (error)
- fail(_("Error creating parent pointer"), error);
- }
-
+ libxfs_parent_finish(mp, parent);
libxfs_irele(ip);
}