]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - mkfs/proto.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / mkfs / proto.c
index 9ada4abc0caa81ee5245d16bad1438faa6651ed0..3bba49171983a0bc3475152083c71f4331a6cdd8 100644 (file)
@@ -1,53 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * 
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  */
 
-#include <xfs/libxfs.h>
+#include "libxfs.h"
 #include <sys/stat.h>
-#include "xfs_mkfs.h"
+#include "xfs_multidisk.h"
 
 /*
  * Prototypes for internal functions.
  */
-extern long long cvtnum(int blocksize, int sectorsize, char *s);
-extern void parseproto(xfs_mount_t *mp, xfs_inode_t *pip, char **pp,
-       char *name); 
-static long getnum(char **pp);
 static char *getstr(char **pp);
 static void fail(char *msg, int i);
-static void getres(xfs_trans_t *tp, uint blocks);
+static struct xfs_trans * getres(struct xfs_mount *mp, uint blocks);
 static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len);
-static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, xfs_bmap_free_t *flist,
-       xfs_fsblock_t *first, int dolocal, int logit, char *buf, int len);
-static char *newregfile(char **pp, int *len); 
+static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, int symlink, int logit,
+                       char *buf, int len);
+static char *newregfile(char **pp, int *len);
 static void rtinit(xfs_mount_t *mp);
 static long filesize(int fd);
 
@@ -56,17 +26,37 @@ static long filesize(int fd);
  * (basically no fragmentation).
  */
 #define        MKFS_BLOCKRES_INODE     \
-       ((uint)(XFS_IALLOC_BLOCKS(mp) + (XFS_IN_MAXLEVELS(mp) - 1)))
+       ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
 #define        MKFS_BLOCKRES(rb)       \
        ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
        (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
 
+static long long
+getnum(
+       const char      *str,
+       unsigned int    blksize,
+       unsigned int    sectsize,
+       bool            convert)
+{
+       long long       i;
+       char            *sp;
+
+       if (convert)
+               return cvtnum(blksize, sectsize, str);
+
+       i = strtoll(str, &sp, 0);
+       if (i == 0 && sp == str)
+               return -1LL;
+       if (*sp != '\0')
+               return -1LL; /* trailing garbage */
+       return i;
+}
 
 char *
 setup_proto(
        char    *fname)
 {
-       char            *buf;
+       char            *buf = NULL;
        static char     dflt[] = "d--755 0 0 $";
        int             fd;
        long            size;
@@ -76,37 +66,35 @@ setup_proto(
        if ((fd = open(fname, O_RDONLY)) < 0 || (size = filesize(fd)) < 0) {
                fprintf(stderr, _("%s: failed to open %s: %s\n"),
                        progname, fname, strerror(errno));
-               exit(1);
+               goto out_fail;
        }
+
        buf = malloc(size + 1);
        if (read(fd, buf, size) < size) {
                fprintf(stderr, _("%s: read failed on %s: %s\n"),
                        progname, fname, strerror(errno));
-               exit(1);
+               goto out_fail;
        }
        if (buf[size - 1] != '\n') {
                fprintf(stderr, _("%s: proto file %s premature EOF\n"),
                        progname, fname);
-               exit(1);
+               goto out_fail;
        }
        buf[size] = '\0';
        /*
         * Skip past the stuff there for compatibility, a string and 2 numbers.
         */
        (void)getstr(&buf);     /* boot image name */
-       (void)getnum(&buf);     /* block count */
-       (void)getnum(&buf);     /* inode count */
+       (void)getnum(getstr(&buf), 0, 0, false);        /* block count */
+       (void)getnum(getstr(&buf), 0, 0, false);        /* inode count */
+       close(fd);
        return buf;
-}
 
-static long
-getnum(
-       char    **pp)
-{
-       char    *s;
-
-       s = getstr(pp);
-       return atol(s);
+out_fail:
+       if (fd >= 0)
+               close(fd);
+       free(buf);
+       exit(1);
 }
 
 static void
@@ -125,23 +113,23 @@ res_failed(
        fail(_("cannot reserve space"), i);
 }
 
-static void
+static struct xfs_trans *
 getres(
-       xfs_trans_t     *tp,
+       struct xfs_mount *mp,
        uint            blocks)
 {
+       struct xfs_trans *tp;
        int             i;
-       xfs_mount_t     *mp;
        uint            r;
 
-       mp = tp->t_mountp;
        for (i = 0, r = MKFS_BLOCKRES(blocks); r >= blocks; r--) {
-               i = libxfs_trans_reserve(tp, r, 0, 0, 0, 0);
+               i = -libxfs_trans_alloc_rollable(mp, r, &tp);
                if (i == 0)
-                       return;
+                       return tp;
        }
        res_failed(i);
        /* NOTREACHED */
+       return NULL;
 }
 
 static char *
@@ -191,7 +179,7 @@ rsvfile(
        int             error;
        xfs_trans_t     *tp;
 
-       error = libxfs_alloc_file_space(ip, 0, llen, 1, 0);
+       error = -libxfs_alloc_file_space(ip, 0, llen, 1, 0);
 
        if (error) {
                fail(_("error reserving space for a file"), error);
@@ -201,38 +189,38 @@ rsvfile(
        /*
         * update the inode timestamp, mode, and prealloc flag bits
         */
-       tp = libxfs_trans_alloc(mp, 0);
-
+       error = -libxfs_trans_alloc_rollable(mp, 0, &tp);
+       if (error)
+               fail(_("allocating transaction for a file"), error);
        libxfs_trans_ijoin(tp, ip, 0);
-       libxfs_trans_ihold(tp, ip);
 
-       ip->i_d.di_mode &= ~ISUID;
+       VFS_I(ip)->i_mode &= ~S_ISUID;
 
        /*
         * Note that we don't have to worry about mandatory
         * file locking being disabled here because we only
-        * clear the ISGID bit if the Group execute bit is
+        * clear the S_ISGID bit if the Group execute bit is
         * on, but if it was on then mandatory locking wouldn't
         * have been enabled.
         */
-       if (ip->i_d.di_mode & (IEXEC >> 3))
-               ip->i_d.di_mode &= ~ISGID;
+       if (VFS_I(ip)->i_mode & S_IXGRP)
+               VFS_I(ip)->i_mode &= ~S_ISGID;
 
-       libxfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
+       libxfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
 
        ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
 
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-       libxfs_trans_commit(tp, 0, NULL);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               fail(_("committing space for a file failed"), error);
 }
 
 static int
 newfile(
        xfs_trans_t     *tp,
        xfs_inode_t     *ip,
-       xfs_bmap_free_t *flist,
-       xfs_fsblock_t   *first,
-       int             dolocal,
+       int             symlink,
        int             logit,
        char            *buf,
        int             len)
@@ -248,20 +236,14 @@ newfile(
 
        flags = 0;
        mp = ip->i_mount;
-       if (dolocal && len <= XFS_IFORK_DSIZE(ip)) {
-               libxfs_idata_realloc(ip, len, XFS_DATA_FORK);
-               if (buf)
-                       bcopy(buf, ip->i_df.if_u1.if_data, len);
-               ip->i_d.di_size = len;
-               ip->i_df.if_flags &= ~XFS_IFEXTENTS;
-               ip->i_df.if_flags |= XFS_IFINLINE;
+       if (symlink && len <= XFS_IFORK_DSIZE(ip)) {
+               libxfs_init_local_fork(ip, XFS_DATA_FORK, buf, len);
                ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
                flags = XFS_ILOG_DDATA;
        } else if (len > 0) {
                nb = XFS_B_TO_FSB(mp, len);
                nmap = 1;
-               error = libxfs_bmapi(tp, ip, 0, nb, XFS_BMAPI_WRITE, first, nb,
-                               &map, &nmap, flist);
+               error = -libxfs_bmapi_write(tp, ip, 0, nb, 0, nb, &map, &nmap);
                if (error) {
                        fail(_("error allocating space for a file"), error);
                }
@@ -272,13 +254,13 @@ newfile(
                        exit(1);
                }
                d = XFS_FSB_TO_DADDR(mp, map.br_startblock);
-               bp = libxfs_trans_get_buf(logit ? tp : 0, mp->m_dev, d,
+               bp = libxfs_trans_get_buf(logit ? tp : NULL, mp->m_dev, d,
                        nb << mp->m_blkbb_log, 0);
-               bcopy(buf, XFS_BUF_PTR(bp), len);
-               if (len < XFS_BUF_COUNT(bp))
-                       bzero(XFS_BUF_PTR(bp) + len, XFS_BUF_COUNT(bp) - len);
+               memmove(bp->b_addr, buf, len);
+               if (len < bp->b_bcount)
+                       memset((char *)bp->b_addr + len, 0, bp->b_bcount - len);
                if (logit)
-                       libxfs_trans_log_buf(tp, bp, 0, XFS_BUF_COUNT(bp) - 1);
+                       libxfs_trans_log_buf(tp, bp, 0, bp->b_bcount - 1);
                else
                        libxfs_writebuf(bp, LIBXFS_EXIT_ON_FAILURE);
        }
@@ -310,7 +292,7 @@ newregfile(
                        exit(1);
                }
        } else
-               buf = 0;
+               buf = NULL;
        close(fd);
        return buf;
 }
@@ -320,21 +302,15 @@ newdirent(
        xfs_mount_t     *mp,
        xfs_trans_t     *tp,
        xfs_inode_t     *pip,
-       char            *name,
-       int             namelen,
-       xfs_ino_t       inum,
-       xfs_fsblock_t   *first,
-       xfs_bmap_free_t *flist,
-       xfs_extlen_t    total)
+       struct xfs_name *name,
+       xfs_ino_t       inum)
 {
        int     error;
+       int     rsv;
 
-       if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb))
-               error = libxfs_dir2_createname(tp, pip, name, namelen,
-                                               inum, first, flist, total);
-       else
-               error = libxfs_dir_createname(tp, pip, name, namelen,
-                                               inum, first, flist, total);
+       rsv = XFS_DIRENTER_SPACE_RES(mp, name->len);
+
+       error = -libxfs_dir_createname(tp, pip, name, inum, rsv);
        if (error)
                fail(_("directory createname error"), error);
 }
@@ -348,18 +324,16 @@ newdirectory(
 {
        int     error;
 
-       if (XFS_SB_VERSION_HASDIRV2(&mp->m_sb))
-               error = libxfs_dir2_init(tp, dp, pdp);
-       else
-               error = libxfs_dir_init(tp, dp, pdp);
+       error = -libxfs_dir_init(tp, dp, pdp);
        if (error)
                fail(_("directory create error"), error);
 }
 
-void
+static void
 parseproto(
        xfs_mount_t     *mp,
        xfs_inode_t     *pip,
+       struct fsxattr  *fsxp,
        char            **pp,
        char            *name)
 {
@@ -372,11 +346,8 @@ parseproto(
 #define        IF_FIFO         6
 
        char            *buf;
-       int             committed;
        int             error;
-       xfs_fsblock_t   first;
        int             flags;
-       xfs_bmap_free_t flist;
        int             fmt;
        int             i;
        xfs_inode_t     *ip;
@@ -391,8 +362,9 @@ parseproto(
        int             isroot = 0;
        cred_t          creds;
        char            *value;
+       struct xfs_name xname;
 
-       bzero(&creds, sizeof(creds));
+       memset(&creds, 0, sizeof(creds));
        mstr = getstr(pp);
        switch (mstr[0]) {
        case '-':
@@ -426,7 +398,7 @@ parseproto(
        case '-':
                break;
        case 'u':
-               mode |= ISUID;
+               mode |= S_ISUID;
                break;
        default:
                fprintf(stderr, _("%s: bad format string %s\n"),
@@ -437,7 +409,7 @@ parseproto(
        case '-':
                break;
        case 'g':
-               mode |= ISGID;
+               mode |= S_ISGID;
                break;
        default:
                fprintf(stderr, _("%s: bad format string %s\n"),
@@ -454,137 +426,133 @@ parseproto(
                val = val * 8 + mstr[i] - '0';
        }
        mode |= val;
-       creds.cr_uid = (int)getnum(pp);
-       creds.cr_gid = (int)getnum(pp);
-       tp = libxfs_trans_alloc(mp, 0);
+       creds.cr_uid = (int)getnum(getstr(pp), 0, 0, false);
+       creds.cr_gid = (int)getnum(getstr(pp), 0, 0, false);
+       xname.name = (unsigned char *)name;
+       xname.len = name ? strlen(name) : 0;
+       xname.type = 0;
        flags = XFS_ILOG_CORE;
-       XFS_BMAP_INIT(&flist, &first);
        switch (fmt) {
        case IF_REGULAR:
                buf = newregfile(pp, &len);
-               getres(tp, XFS_B_TO_FSB(mp, len));
-               error = libxfs_inode_alloc(&tp, pip, mode|IFREG, 1,
-                                       mp->m_dev, &creds, &ip);
+               tp = getres(mp, XFS_B_TO_FSB(mp, len));
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
+                                          &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode allocation failed"), error);
-               flags |= newfile(tp, ip, &flist, &first, 0, 0, buf, len);
+               flags |= newfile(tp, ip, 0, 0, buf, len);
                if (buf)
                        free(buf);
                libxfs_trans_ijoin(tp, pip, 0);
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_REG_FILE;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                break;
 
        case IF_RESERVED:                       /* pre-allocated space only */
                value = getstr(pp);
-               llen = cvtnum(mp->m_sb.sb_blocksize, mp->m_sb.sb_sectsize, value);
-               getres(tp, XFS_B_TO_FSB(mp, llen));
+               llen = getnum(value, mp->m_sb.sb_blocksize,
+                             mp->m_sb.sb_sectsize, true);
+               if (llen < 0) {
+                       fprintf(stderr,
+                               _("%s: Bad value %s for proto file %s\n"),
+                               progname, value, name);
+                       exit(1);
+               }
+               tp = getres(mp, XFS_B_TO_FSB(mp, llen));
 
-               error = libxfs_inode_alloc(&tp, pip, mode|IFREG, 1,
-                                               mp->m_dev, &creds, &ip);
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
+                                         &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode pre-allocation failed"), error);
 
                libxfs_trans_ijoin(tp, pip, 0);
 
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_REG_FILE;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                libxfs_trans_log_inode(tp, ip, flags);
-
-               error = libxfs_bmap_finish(&tp, &flist, first, &committed);
+               error = -libxfs_trans_commit(tp);
                if (error)
-                       fail(_("Pre-allocated file creation failed"), error);
-               libxfs_trans_commit(tp, 0, NULL);
+                       fail(_("Space preallocation failed."), error);
                rsvfile(mp, ip, llen);
+               libxfs_irele(ip);
                return;
 
        case IF_BLOCK:
-               getres(tp, 0);
-               majdev = (int)getnum(pp);
-               mindev = (int)getnum(pp);
-               error = libxfs_inode_alloc(&tp, pip, mode|IFBLK, 1,
-                               makedev(majdev, mindev), &creds, &ip);
+               tp = getres(mp, 0);
+               majdev = getnum(getstr(pp), 0, 0, false);
+               mindev = getnum(getstr(pp), 0, 0, false);
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1,
+                               IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
                if (error) {
                        fail(_("Inode allocation failed"), error);
                }
                libxfs_trans_ijoin(tp, pip, 0);
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_BLKDEV;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                flags |= XFS_ILOG_DEV;
                break;
 
        case IF_CHAR:
-               getres(tp, 0);
-               majdev = (int)getnum(pp);
-               mindev = (int)getnum(pp);
-               error = libxfs_inode_alloc(&tp, pip, mode|IFCHR, 1,
-                               makedev(majdev, mindev), &creds, &ip);
+               tp = getres(mp, 0);
+               majdev = getnum(getstr(pp), 0, 0, false);
+               mindev = getnum(getstr(pp), 0, 0, false);
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1,
+                               IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode allocation failed"), error);
                libxfs_trans_ijoin(tp, pip, 0);
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_CHRDEV;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                flags |= XFS_ILOG_DEV;
                break;
 
        case IF_FIFO:
-               getres(tp, 0);
-               error = libxfs_inode_alloc(&tp, pip, mode|IFIFO, 1,
-                               mp->m_dev, &creds, &ip);
+               tp = getres(mp, 0);
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0,
+                               &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode allocation failed"), error);
                libxfs_trans_ijoin(tp, pip, 0);
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_FIFO;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                break;
        case IF_SYMLINK:
                buf = getstr(pp);
                len = (int)strlen(buf);
-               getres(tp, XFS_B_TO_FSB(mp, len));
-               error = libxfs_inode_alloc(&tp, pip, mode|IFLNK, 1,
-                               mp->m_dev, &creds, &ip);
+               tp = getres(mp, XFS_B_TO_FSB(mp, len));
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0,
+                               &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode allocation failed"), error);
-               flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len);
+               flags |= newfile(tp, ip, 1, 1, buf, len);
                libxfs_trans_ijoin(tp, pip, 0);
-               i = strlen(name);
-               newdirent(mp, tp, pip, name, i, ip->i_ino, &first, &flist, 1);
-               libxfs_trans_ihold(tp, pip);
+               xname.type = XFS_DIR3_FT_SYMLINK;
+               newdirent(mp, tp, pip, &xname, ip->i_ino);
                break;
        case IF_DIRECTORY:
-               getres(tp, 0);
-               error = libxfs_inode_alloc(&tp, pip, mode|IFDIR, 1,
-                               mp->m_dev, &creds, &ip);
+               tp = getres(mp, 0);
+               error = -libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0,
+                               &creds, fsxp, &ip);
                if (error)
                        fail(_("Inode allocation failed"), error);
-               ip->i_d.di_nlink++;             /* account for . */
+               inc_nlink(VFS_I(ip));           /* account for . */
                if (!pip) {
                        pip = ip;
                        mp->m_sb.sb_rootino = ip->i_ino;
-                       libxfs_mod_sb(tp, XFS_SB_ROOTINO);
-                       mp->m_rootip = ip;
+                       libxfs_log_sb(tp);
                        isroot = 1;
                } else {
                        libxfs_trans_ijoin(tp, pip, 0);
-                       i = strlen(name);
-                       newdirent(mp, tp, pip, name, i, ip->i_ino,
-                                 &first, &flist, 1);
-                       pip->i_d.di_nlink++;
-                       libxfs_trans_ihold(tp, pip);
+                       xname.type = XFS_DIR3_FT_DIR;
+                       newdirent(mp, tp, pip, &xname, ip->i_ino);
+                       inc_nlink(VFS_I(pip));
                        libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
                }
                newdirectory(mp, tp, ip, pip);
                libxfs_trans_log_inode(tp, ip, flags);
-               error = libxfs_bmap_finish(&tp, &flist, first, &committed);
+               error = -libxfs_trans_commit(tp);
                if (error)
-                       fail(_("Directory creation failed"), error);
-               libxfs_trans_ihold(tp, ip);
-               libxfs_trans_commit(tp, 0, NULL);
+                       fail(_("Directory inode allocation failed."), error);
                /*
                 * RT initialization.  Do this here to ensure that
                 * the RT inodes get placed after the root inode.
@@ -598,18 +566,30 @@ parseproto(
                                break;
                        if (strcmp(name, "$") == 0)
                                break;
-                       parseproto(mp, ip, pp, name);
+                       parseproto(mp, ip, fsxp, pp, name);
                }
-               libxfs_iput(ip, 0);
+               libxfs_irele(ip);
                return;
+       default:
+               ASSERT(0);
+               fail(_("Unknown format"), EINVAL);
        }
        libxfs_trans_log_inode(tp, ip, flags);
-       error = libxfs_bmap_finish(&tp, &flist, first, &committed);
+       error = -libxfs_trans_commit(tp);
        if (error) {
                fail(_("Error encountered creating file from prototype file"),
                        error);
        }
-       libxfs_trans_commit(tp, 0, NULL);
+       libxfs_irele(ip);
+}
+
+void
+parse_proto(
+       xfs_mount_t     *mp,
+       struct fsxattr  *fsx,
+       char            **pp)
+{
+       parseproto(mp, NULL, fsx, pp, NULL);
 }
 
 /*
@@ -619,31 +599,32 @@ static void
 rtinit(
        xfs_mount_t     *mp)
 {
-       xfs_dfiloff_t   bno;
-       int             committed;
-       xfs_dfiloff_t   ebno;
+       xfs_fileoff_t   bno;
+       xfs_fileoff_t   ebno;
        xfs_bmbt_irec_t *ep;
        int             error;
-       xfs_fsblock_t   first;
-       xfs_bmap_free_t flist;
        int             i;
        xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
        xfs_extlen_t    nsumblocks;
+       uint            blocks;
        int             nmap;
        xfs_inode_t     *rbmip;
        xfs_inode_t     *rsumip;
        xfs_trans_t     *tp;
-       cred_t          creds;
+       struct cred     creds;
+       struct fsxattr  fsxattrs;
 
        /*
         * First, allocate the inodes.
         */
-       tp = libxfs_trans_alloc(mp, 0);
-       if ((i = libxfs_trans_reserve(tp, MKFS_BLOCKRES_INODE, 0, 0, 0, 0)))
+       i = -libxfs_trans_alloc_rollable(mp, MKFS_BLOCKRES_INODE, &tp);
+       if (i)
                res_failed(i);
-       bzero(&creds, sizeof(creds));
-       error = libxfs_inode_alloc(&tp, mp->m_rootip, IFREG, 1,
-                               mp->m_dev, &creds, &rbmip);
+
+       memset(&creds, 0, sizeof(creds));
+       memset(&fsxattrs, 0, sizeof(fsxattrs));
+       error = -libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
+                                       &creds, &fsxattrs, &rbmip);
        if (error) {
                fail(_("Realtime bitmap inode allocation failed"), error);
        }
@@ -655,113 +636,109 @@ rtinit(
        mp->m_sb.sb_rbmino = rbmip->i_ino;
        rbmip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
        rbmip->i_d.di_flags = XFS_DIFLAG_NEWRTBM;
-       *(__uint64_t *)&rbmip->i_d.di_atime = 0;
+       *(uint64_t *)&VFS_I(rbmip)->i_atime = 0;
        libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
-       libxfs_mod_sb(tp, XFS_SB_RBMINO);
-       libxfs_trans_ihold(tp, rbmip);
+       libxfs_log_sb(tp);
        mp->m_rbmip = rbmip;
-       error = libxfs_inode_alloc(&tp, mp->m_rootip, IFREG, 1,
-                               mp->m_dev, &creds, &rsumip);
+       error = -libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
+                                       &creds, &fsxattrs, &rsumip);
        if (error) {
                fail(_("Realtime summary inode allocation failed"), error);
        }
        mp->m_sb.sb_rsumino = rsumip->i_ino;
        rsumip->i_d.di_size = mp->m_rsumsize;
        libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE);
-       libxfs_mod_sb(tp, XFS_SB_RSUMINO);
-       libxfs_trans_ihold(tp, rsumip);
-       libxfs_trans_commit(tp, 0, NULL);
+       libxfs_log_sb(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               fail(_("Completion of the realtime summary inode failed"),
+                               error);
        mp->m_rsumip = rsumip;
        /*
         * Next, give the bitmap file some zero-filled blocks.
         */
-       tp = libxfs_trans_alloc(mp, 0);
-       if ((i = libxfs_trans_reserve(tp, mp->m_sb.sb_rbmblocks +
-                       (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0, 0, 0, 0)))
+       blocks = mp->m_sb.sb_rbmblocks +
+                       XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
+       i = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
+       if (i)
                res_failed(i);
+
        libxfs_trans_ijoin(tp, rbmip, 0);
        bno = 0;
-       XFS_BMAP_INIT(&flist, &first);
        while (bno < mp->m_sb.sb_rbmblocks) {
                nmap = XFS_BMAP_MAX_NMAP;
-               error = libxfs_bmapi(tp, rbmip, bno,
+               error = -libxfs_bmapi_write(tp, rbmip, bno,
                                (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno),
-                               XFS_BMAPI_WRITE, &first, mp->m_sb.sb_rbmblocks,
-                               map, &nmap, &flist);
+                               0, mp->m_sb.sb_rbmblocks, map, &nmap);
                if (error) {
                        fail(_("Allocation of the realtime bitmap failed"),
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targp,
                                XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
                }
        }
 
-       error = libxfs_bmap_finish(&tp, &flist, first, &committed);
-       if (error) {
-               fail(_("Completion of the realtime bitmap failed"), error);
-       }
-       libxfs_trans_commit(tp, 0, NULL);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               fail(_("Block allocation of the realtime bitmap inode failed"),
+                               error);
 
        /*
         * Give the summary file some zero-filled blocks.
         */
-       tp = libxfs_trans_alloc(mp, 0);
        nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
-       if ((i = libxfs_trans_reserve(tp,
-                       nsumblocks + (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1),
-                       0, 0, 0, 0)))
+       blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
+       i = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
+       if (i)
                res_failed(i);
        libxfs_trans_ijoin(tp, rsumip, 0);
        bno = 0;
-       XFS_BMAP_INIT(&flist, &first);
        while (bno < nsumblocks) {
                nmap = XFS_BMAP_MAX_NMAP;
-               error = libxfs_bmapi(tp, rsumip, bno,
+               error = -libxfs_bmapi_write(tp, rsumip, bno,
                                (xfs_extlen_t)(nsumblocks - bno),
-                               XFS_BMAPI_WRITE, &first, nsumblocks,
-                               map, &nmap, &flist);
+                               0, nsumblocks, map, &nmap);
                if (error) {
                        fail(_("Allocation of the realtime summary failed"),
                                error);
                }
                for (i = 0, ep = map; i < nmap; i++, ep++) {
-                       libxfs_device_zero(mp->m_dev,
+                       libxfs_device_zero(mp->m_ddev_targp,
                                XFS_FSB_TO_DADDR(mp, ep->br_startblock),
                                XFS_FSB_TO_BB(mp, ep->br_blockcount));
                        bno += ep->br_blockcount;
                }
        }
-       error = libxfs_bmap_finish(&tp, &flist, first, &committed);
-       if (error) {
-               fail(_("Completion of the realtime summary failed"), error);
-       }
-       libxfs_trans_commit(tp, 0, NULL);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               fail(_("Block allocation of the realtime summary inode failed"),
+                               error);
 
        /*
         * Free the whole area using transactions.
         * Do one transaction per bitmap block.
         */
        for (bno = 0; bno < mp->m_sb.sb_rextents; bno = ebno) {
-               tp = libxfs_trans_alloc(mp, 0);
-               if ((i = libxfs_trans_reserve(tp, 0, 0, 0, 0, 0)))
+               i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
+                               0, 0, 0, &tp);
+               if (i)
                        res_failed(i);
-               XFS_BMAP_INIT(&flist, &first);
+               libxfs_trans_ijoin(tp, rbmip, 0);
                ebno = XFS_RTMIN(mp->m_sb.sb_rextents,
                        bno + NBBY * mp->m_sb.sb_blocksize);
-               error = libxfs_rtfree_extent(tp, bno, (xfs_extlen_t)(ebno-bno));
+               error = -libxfs_rtfree_extent(tp, bno, (xfs_extlen_t)(ebno-bno));
                if (error) {
                        fail(_("Error initializing the realtime space"),
                                error);
                }
-               error = libxfs_bmap_finish(&tp, &flist, first, &committed);
-               if (error) {
-                       fail(_("Error completing the realtime space"), error);
-               }
-               libxfs_trans_commit(tp, 0, NULL);
+               error = -libxfs_trans_commit(tp);
+               if (error)
+                       fail(_("Initialization of the realtime space failed"),
+                                       error);
        }
 }
 
@@ -769,9 +746,9 @@ static long
 filesize(
        int             fd)
 {
-       struct stat64   stb;
+       struct stat     stb;
 
-       if (fstat64(fd, &stb) < 0)
+       if (fstat(fd, &stb) < 0)
                return -1;
        return (long)stb.st_size;
 }