]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
mkfs: Add parent pointers during protofile creation
authorAllison Henderson <allison.henderson@oracle.com>
Tue, 9 Jan 2024 17:39:26 +0000 (09:39 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 10 Apr 2024 00:21:31 +0000 (17:21 -0700)
Inodes created from protofile parsing will also need to add the
appropriate parent pointers.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: use xfs_parent_add from libxfs instead of open-coding xfs_attr_set]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
mkfs/proto.c

index a9a9b704a3ca96e104eb48bb52bc9fb53dd73e70..8e16eb1506f1efffc035d49d0ccd4dcca8fa9242 100644 (file)
@@ -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);
 }