From: Allison Henderson <allison.henderson@xxxxxxxxxx> Inodes created from protofile parsing will also need to add the appropriate parent pointers. Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> [djwong: use xfs_parent_add from libxfs instead of open-coding xfs_attr_set] Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- mkfs/proto.c | 62 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/mkfs/proto.c b/mkfs/proto.c index a9a9b704a3ca..8e16eb1506f1 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -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); }