@@ -348,11 +348,12 @@ newregfile(
static void
newdirent(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_inode_t *pip,
- struct xfs_name *name,
- xfs_ino_t inum)
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_inode *pip,
+ struct xfs_name *name,
+ struct xfs_inode *ip,
+ struct xfs_parent_args *ppargs)
{
int error;
int rsv;
@@ -365,9 +366,15 @@ newdirent(
rsv = XFS_DIRENTER_SPACE_RES(mp, name->len);
- error = -libxfs_dir_createname(tp, pip, name, inum, rsv);
+ error = -libxfs_dir_createname(tp, pip, name, ip->i_ino, rsv);
if (error)
fail(_("directory createname error"), error);
+
+ if (ppargs) {
+ error = -libxfs_parent_addname(tp, ppargs, pip, name, ip);
+ if (error)
+ fail(_("parent addname error"), error);
+ }
}
static void
@@ -384,6 +391,20 @@ newdirectory(
fail(_("directory create error"), error);
}
+static struct xfs_parent_args *
+newpptr(
+ struct xfs_mount *mp)
+{
+ struct xfs_parent_args *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,
@@ -418,6 +439,7 @@ parseproto(
struct cred creds;
char *value;
struct xfs_name xname;
+ struct xfs_parent_args *ppargs = NULL;
memset(&creds, 0, sizeof(creds));
mstr = getstr(pp);
@@ -492,6 +514,7 @@ parseproto(
case IF_REGULAR:
buf = newregfile(pp, &len);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
+ ppargs = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -501,7 +524,7 @@ parseproto(
free(buf);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_REG_FILE;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
break;
case IF_RESERVED: /* pre-allocated space only */
@@ -515,7 +538,7 @@ parseproto(
exit(1);
}
tp = getres(mp, XFS_B_TO_FSB(mp, llen));
-
+ ppargs = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -524,17 +547,19 @@ parseproto(
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_REG_FILE;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
libxfs_trans_log_inode(tp, ip, flags);
error = -libxfs_trans_commit(tp);
if (error)
fail(_("Space preallocation failed."), error);
+ libxfs_parent_finish(mp, ppargs);
rsvfile(mp, ip, llen);
libxfs_irele(ip);
return;
case IF_BLOCK:
tp = getres(mp, 0);
+ ppargs = 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,
@@ -544,12 +569,13 @@ parseproto(
}
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_BLKDEV;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
flags |= XFS_ILOG_DEV;
break;
case IF_CHAR:
tp = getres(mp, 0);
+ ppargs = 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,
@@ -558,24 +584,26 @@ parseproto(
fail(_("Inode allocation failed"), error);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_CHRDEV;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
flags |= XFS_ILOG_DEV;
break;
case IF_FIFO:
tp = getres(mp, 0);
+ ppargs = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFIFO, 1, 0,
&creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_FIFO;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
break;
case IF_SYMLINK:
buf = getstr(pp);
len = (int)strlen(buf);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
+ ppargs = newpptr(mp);
error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFLNK, 1, 0,
&creds, fsxp, &ip);
if (error)
@@ -583,7 +611,7 @@ parseproto(
writesymlink(tp, ip, buf, len);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_SYMLINK;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
break;
case IF_DIRECTORY:
tp = getres(mp, 0);
@@ -598,9 +626,10 @@ parseproto(
libxfs_log_sb(tp);
isroot = 1;
} else {
+ ppargs = newpptr(mp);
libxfs_trans_ijoin(tp, pip, 0);
xname.type = XFS_DIR3_FT_DIR;
- newdirent(mp, tp, pip, &xname, ip->i_ino);
+ newdirent(mp, tp, pip, &xname, ip, ppargs);
libxfs_bumplink(tp, pip);
libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
}
@@ -609,6 +638,9 @@ parseproto(
error = -libxfs_trans_commit(tp);
if (error)
fail(_("Directory inode allocation failed."), error);
+
+ libxfs_parent_finish(mp, ppargs);
+
/*
* RT initialization. Do this here to ensure that
* the RT inodes get placed after the root inode.
@@ -636,6 +668,8 @@ parseproto(
fail(_("Error encountered creating file from prototype file"),
error);
}
+
+ libxfs_parent_finish(mp, ppargs);
libxfs_irele(ip);
}