xfs: better xfs_trans_alloc interface
authorChristoph Hellwig <hch@lst.de>
Tue, 5 Apr 2016 23:19:55 +0000 (09:19 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 5 Apr 2016 23:19:55 +0000 (09:19 +1000)
Merge xfs_trans_reserve and xfs_trans_alloc into a single function call
that returns a transaction with all the required log and block reservations,
and which allows passing transaction flags directly to avoid the cumbersome
_xfs_trans_alloc interface.

While we're at it we also get rid of the transaction type argument that has
been superflous since we stopped supporting the non-CIL logging mode.  The
guts of it will be removed in another patch.

[dchinner: fixed transaction leak in error path in xfs_setattr_nonsize]

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
22 files changed:
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_shared.h
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr_inactive.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_file.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_pnfs.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm_syscalls.c
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_symlink.c
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans.h

index fa3b948ef9c2561e8b34aae282ca8c0f02a22abc..4e126f41a0aa97d1f73773ea8efb89ef7a52746c 100644 (file)
@@ -242,37 +242,21 @@ xfs_attr_set(
                        return error;
        }
 
-       /*
-        * Start our first transaction of the day.
-        *
-        * All future transactions during this code must be "chained" off
-        * this one via the trans_dup() call.  All transactions will contain
-        * the inode, and the inode will always be marked with trans_ihold().
-        * Since the inode will be locked in all transactions, we must log
-        * the inode in every transaction to let it float upward through
-        * the log.
-        */
-       args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);
+       tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
+                        M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
+       tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
+       tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
 
        /*
         * Root fork attributes can use reserved data blocks for this
         * operation if necessary
         */
-
-       if (rsvd)
-               args.trans->t_flags |= XFS_TRANS_RESERVE;
-
-       tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
-                        M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
-       tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
-       tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-       error = xfs_trans_reserve(args.trans, &tres, args.total, 0);
-       if (error) {
-               xfs_trans_cancel(args.trans);
+       error = xfs_trans_alloc(mp, &tres, args.total, 0,
+                       rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
+       if (error)
                return error;
-       }
-       xfs_ilock(dp, XFS_ILOCK_EXCL);
 
+       xfs_ilock(dp, XFS_ILOCK_EXCL);
        error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
                                rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
                                       XFS_QMOPT_RES_REGBLKS);
@@ -428,32 +412,16 @@ xfs_attr_remove(
        if (error)
                return error;
 
-       /*
-        * Start our first transaction of the day.
-        *
-        * All future transactions during this code must be "chained" off
-        * this one via the trans_dup() call.  All transactions will contain
-        * the inode, and the inode will always be marked with trans_ihold().
-        * Since the inode will be locked in all transactions, we must log
-        * the inode in every transaction to let it float upward through
-        * the log.
-        */
-       args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);
-
        /*
         * Root fork attributes can use reserved data blocks for this
         * operation if necessary
         */
-
-       if (flags & ATTR_ROOT)
-               args.trans->t_flags |= XFS_TRANS_RESERVE;
-
-       error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm,
-                                 XFS_ATTRRM_SPACE_RES(mp), 0);
-       if (error) {
-               xfs_trans_cancel(args.trans);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm,
+                       XFS_ATTRRM_SPACE_RES(mp), 0,
+                       (flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0,
+                       &args.trans);
+       if (error)
                return error;
-       }
 
        xfs_ilock(dp, XFS_ILOCK_EXCL);
        /*
index 041b6948aeccd928f6f88d95ed9985052d915390..e7ec8ccd3d641e411a2283ed10027e5f8c5759dc 100644 (file)
@@ -1121,15 +1121,14 @@ xfs_bmap_add_attrfork(
 
        mp = ip->i_mount;
        ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
-       tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
+
        blks = XFS_ADDAFORK_SPACE_RES(mp);
-       if (rsvd)
-               tp->t_flags |= XFS_TRANS_RESERVE;
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_addafork, blks, 0,
+                       rsvd ? XFS_TRANS_RESERVE : 0, &tp);
+       if (error)
                return error;
-       }
+
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
                        XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
@@ -6026,13 +6025,10 @@ xfs_bmap_split_extent(
        xfs_fsblock_t           firstfsb;
        int                     error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                       XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
+                       XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
index 8a53eaa349f44884354139fcde0a9c17b35e741a..12ca86778e023e4261998660f39b482927a16c02 100644 (file)
@@ -838,12 +838,10 @@ xfs_sync_sb(
        struct xfs_trans        *tp;
        int                     error;
 
-       tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0,
+                       XFS_TRANS_NO_WRITECOUNT, &tp);
+       if (error)
                return error;
-       }
 
        xfs_log_sb(tp);
        if (wait)
index 81ac870834da9e63515553e3fa291318acd1e73a..7d4ab6439081bdb0eef14d8f085ca3521ad50d97 100644 (file)
@@ -181,8 +181,9 @@ int xfs_log_calc_minimum_size(struct xfs_mount *);
 #define        XFS_TRANS_SYNC          0x08    /* make commit synchronous */
 #define XFS_TRANS_DQ_DIRTY     0x10    /* at least one dquot in trx dirty */
 #define XFS_TRANS_RESERVE      0x20    /* OK to use reserved data blocks */
-#define XFS_TRANS_FREEZE_PROT  0x40    /* Transaction has elevated writer
-                                          count in superblock */
+#define XFS_TRANS_NO_WRITECOUNT 0x40   /* do not elevate SB writecount */
+#define XFS_TRANS_NOFS         0x80    /* pass KM_NOFS to kmem_alloc */
+
 /*
  * Field values for xfs_trans_mod_sb.
  */
index d445a64b979e963dccbef0a721989c112351a97e..3311db6ecbbdd9cb2c61160e802a4c593ac4211f 100644 (file)
@@ -120,13 +120,9 @@ xfs_setfilesize_trans_alloc(
        struct xfs_trans        *tp;
        int                     error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
-
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        ioend->io_append_trans = tp;
 
@@ -1391,13 +1387,10 @@ xfs_end_io_direct_write(
 
                trace_xfs_end_io_direct_write_append(ip, offset, size);
 
-               tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
-               if (error) {
-                       xfs_trans_cancel(tp);
-                       return error;
-               }
-               error = xfs_setfilesize(ip, tp, offset, size);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0,
+                               &tp);
+               if (!error)
+                       error = xfs_setfilesize(ip, tp, offset, size);
        }
 
        return error;
index 2bb959ada45bb5444830373a102fc4d7aced7273..55d214981ed27e6bb85490767939d25058815201 100644 (file)
@@ -405,21 +405,11 @@ xfs_attr_inactive(
                goto out_destroy_fork;
        xfs_iunlock(dp, lock_mode);
 
-       /*
-        * Start our first transaction of the day.
-        *
-        * All future transactions during this code must be "chained" off
-        * this one via the trans_dup() call.  All transactions will contain
-        * the inode, and the inode will always be marked with trans_ihold().
-        * Since the inode will be locked in all transactions, we must log
-        * the inode in every transaction to let it float upward through
-        * the log.
-        */
        lock_mode = 0;
-       trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
-       error = xfs_trans_reserve(trans, &M_RES(mp)->tr_attrinval, 0, 0);
+
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans);
        if (error)
-               goto out_cancel;
+               goto out_destroy_fork;
 
        lock_mode = XFS_ILOCK_EXCL;
        xfs_ilock(dp, lock_mode);
index a32c1dcae2ff37b3ee1542fd3fbc5dd74a1e0a86..3246ebc7cbd0db6650064199f873505527e188b3 100644 (file)
@@ -900,19 +900,15 @@ xfs_free_eofblocks(
                 * Free them up now by truncating the file to
                 * its current size.
                 */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
-
                if (need_iolock) {
-                       if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
-                               xfs_trans_cancel(tp);
+                       if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL))
                                return -EAGAIN;
-                       }
                }
 
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
+                               &tp);
                if (error) {
                        ASSERT(XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp);
                        if (need_iolock)
                                xfs_iunlock(ip, XFS_IOLOCK_EXCL);
                        return error;
@@ -1037,9 +1033,9 @@ xfs_alloc_file_space(
                /*
                 * Allocate and setup the transaction.
                 */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                                         resblks, resrtextents);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks,
+                               resrtextents, 0, &tp);
+
                /*
                 * Check for running out of space
                 */
@@ -1048,7 +1044,6 @@ xfs_alloc_file_space(
                         * Free the transaction structure.
                         */
                        ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp);
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1311,18 +1306,10 @@ xfs_free_file_space(
                 * transaction to dip into the reserve blocks to ensure
                 * the freeing of the space succeeds at ENOSPC.
                 */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0);
-
-               /*
-                * check for running out of space
-                */
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0,
+                               &tp);
                if (error) {
-                       /*
-                        * Free the transaction structure.
-                        */
                        ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
-                       xfs_trans_cancel(tp);
                        break;
                }
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1482,19 +1469,16 @@ xfs_shift_file_space(
        }
 
        while (!error && !done) {
-               tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
                /*
                 * We would need to reserve permanent block for transaction.
                 * This will come into picture when after shifting extent into
                 * hole we found that adjacent extents can be merged which
                 * may lead to freeing of a block during record update.
                 */
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                               XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
-               if (error) {
-                       xfs_trans_cancel(tp);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
+                               XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
+               if (error)
                        break;
-               }
 
                xfs_ilock(ip, XFS_ILOCK_EXCL);
                error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot,
@@ -1747,12 +1731,9 @@ xfs_swap_extents(
        if (error)
                goto out_unlock;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
+       if (error)
                goto out_unlock;
-       }
 
        /*
         * Lock and join the inodes to the tansaction so that transaction commit
index 316b2a1bdba5f6da82f1bad0dcbc0708151a59d2..23e24329b132135806f4f1571e5d0abc9cf37fa8 100644 (file)
@@ -614,11 +614,10 @@ xfs_qm_dqread(
        trace_xfs_dqread(dqp);
 
        if (flags & XFS_QMOPT_DQALLOC) {
-               tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_dqalloc,
-                                         XFS_QM_DQALLOC_SPACE_RES(mp), 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc,
+                               XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp);
                if (error)
-                       goto error1;
+                       goto error0;
        }
 
        /*
index ac0fd32de31e4e5455e43da208cdef4861710a21..98bbd8f84c76188cd56079526635371437b80d88 100644 (file)
@@ -145,12 +145,10 @@ xfs_update_prealloc_flags(
        struct xfs_trans        *tp;
        int                     error;
 
-       tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
-       error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_writeid,
+                       0, 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
index ee3aaa0a53179f761ffffe6257a58b637a6b7dc8..9c563d480b3c1535f0f5535cd4932d4b287aad58 100644 (file)
@@ -198,14 +198,10 @@ xfs_growfs_data_private(
                        return error;
        }
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
-       tp->t_flags |= XFS_TRANS_RESERVE;
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growdata,
-                                 XFS_GROWFS_SPACE_RES(mp), 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata,
+                       XFS_GROWFS_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
+       if (error)
                return error;
-       }
 
        /*
         * Write new AG headers to disk. Non-transactional, but written
index 96f606deee313aed506b7e7ee229fc801ba5de80..b82c729634f6ee30a0f1b19082394ea188f91b9c 100644 (file)
@@ -1161,11 +1161,9 @@ xfs_create(
                rdev = 0;
                resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
                tres = &M_RES(mp)->tr_mkdir;
-               tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
        } else {
                resblks = XFS_CREATE_SPACE_RES(mp, name->len);
                tres = &M_RES(mp)->tr_create;
-               tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
        }
 
        /*
@@ -1174,20 +1172,19 @@ xfs_create(
         * the case we'll drop the one we have and get a more
         * appropriate transaction later.
         */
-       error = xfs_trans_reserve(tp, tres, resblks, 0);
+       error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
        if (error == -ENOSPC) {
                /* flush outstanding delalloc blocks and retry */
                xfs_flush_inodes(mp);
-               error = xfs_trans_reserve(tp, tres, resblks, 0);
+               error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
        }
        if (error == -ENOSPC) {
                /* No space at all so try a "no-allocation" reservation */
                resblks = 0;
-               error = xfs_trans_reserve(tp, tres, 0, 0);
+               error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
        }
        if (error)
-               goto out_trans_cancel;
-
+               goto out_release_inode;
 
        xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
                      XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
@@ -1337,17 +1334,16 @@ xfs_create_tmpfile(
                return error;
 
        resblks = XFS_IALLOC_SPACE_RES(mp);
-       tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
-
        tres = &M_RES(mp)->tr_create_tmpfile;
-       error = xfs_trans_reserve(tp, tres, resblks, 0);
+
+       error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
        if (error == -ENOSPC) {
                /* No space at all so try a "no-allocation" reservation */
                resblks = 0;
-               error = xfs_trans_reserve(tp, tres, 0, 0);
+               error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
        }
        if (error)
-               goto out_trans_cancel;
+               goto out_release_inode;
 
        error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
                                                pdqp, resblks, 1, 0);
@@ -1432,15 +1428,14 @@ xfs_link(
        if (error)
                goto std_return;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
        resblks = XFS_LINK_SPACE_RES(mp, target_name->len);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_link, resblks, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, resblks, 0, 0, &tp);
        if (error == -ENOSPC) {
                resblks = 0;
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_link, 0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, 0, 0, 0, &tp);
        }
        if (error)
-               goto error_return;
+               goto std_return;
 
        xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
        xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
@@ -1710,11 +1705,9 @@ xfs_inactive_truncate(
        struct xfs_trans        *tp;
        int                     error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
        if (error) {
                ASSERT(XFS_FORCED_SHUTDOWN(mp));
-               xfs_trans_cancel(tp);
                return error;
        }
 
@@ -1764,8 +1757,6 @@ xfs_inactive_ifree(
        struct xfs_trans        *tp;
        int                     error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
-
        /*
         * The ifree transaction might need to allocate blocks for record
         * insertion to the finobt. We don't want to fail here at ENOSPC, so
@@ -1781,9 +1772,8 @@ xfs_inactive_ifree(
         * now remains allocated and sits on the unlinked list until the fs is
         * repaired.
         */
-       tp->t_flags |= XFS_TRANS_RESERVE;
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree,
-                                 XFS_IFREE_SPACE_RES(mp), 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ifree,
+                       XFS_IFREE_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
        if (error) {
                if (error == -ENOSPC) {
                        xfs_warn_ratelimited(mp,
@@ -1792,7 +1782,6 @@ xfs_inactive_ifree(
                } else {
                        ASSERT(XFS_FORCED_SHUTDOWN(mp));
                }
-               xfs_trans_cancel(tp);
                return error;
        }
 
@@ -2525,11 +2514,6 @@ xfs_remove(
        if (error)
                goto std_return;
 
-       if (is_dir)
-               tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
-       else
-               tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
-
        /*
         * We try to get the real space reservation first,
         * allowing for directory btree deletion(s) implying
@@ -2540,14 +2524,15 @@ xfs_remove(
         * block from the directory.
         */
        resblks = XFS_REMOVE_SPACE_RES(mp);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_remove, resblks, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_remove, resblks, 0, 0, &tp);
        if (error == -ENOSPC) {
                resblks = 0;
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_remove, 0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_remove, 0, 0, 0,
+                               &tp);
        }
        if (error) {
                ASSERT(error != -ENOSPC);
-               goto out_trans_cancel;
+               goto std_return;
        }
 
        xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
@@ -2910,15 +2895,15 @@ xfs_rename(
        xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, wip,
                                inodes, &num_inodes);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
        spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_rename, spaceres, 0, 0, &tp);
        if (error == -ENOSPC) {
                spaceres = 0;
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_rename, 0, 0, 0,
+                               &tp);
        }
        if (error)
-               goto out_trans_cancel;
+               goto out_release_wip;
 
        /*
         * Attach the dquots to the inodes
@@ -3155,6 +3140,7 @@ out_bmap_cancel:
        xfs_bmap_cancel(&free_list);
 out_trans_cancel:
        xfs_trans_cancel(tp);
+out_release_wip:
        if (wip)
                IRELE(wip);
        return error;
index bcb6c19ce3ea4fea69c536343c07ea222de3155d..6f82187ee297b28dd19024dae0a58fa0ef1ce7b3 100644 (file)
@@ -334,12 +334,10 @@ xfs_set_dmattrs(
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SET_DMATTRS);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
+       if (error)
                return error;
-       }
+
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 
@@ -1141,10 +1139,9 @@ xfs_ioctl_setattr_get_trans(
        if (XFS_FORCED_SHUTDOWN(mp))
                goto out_unlock;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
        if (error)
-               goto out_cancel;
+               return ERR_PTR(error);
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | join_flags);
index d81bdc080370e474f52b7fbd68c327cf576e74ea..58391355a44df71b7973ae132bb4b5adc2f77a9b 100644 (file)
@@ -132,6 +132,7 @@ xfs_iomap_write_direct(
        int             error;
        int             lockmode;
        int             bmapi_flags = XFS_BMAPI_PREALLOC;
+       uint            tflags = 0;
 
        rt = XFS_IS_REALTIME_INODE(ip);
        extsz = xfs_get_extsz_hint(ip);
@@ -191,11 +192,6 @@ xfs_iomap_write_direct(
        if (error)
                return error;
 
-       /*
-        * Allocate and setup the transaction
-        */
-       tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-
        /*
         * For DAX, we do not allocate unwritten extents, but instead we zero
         * the block before we commit the transaction.  Ideally we'd like to do
@@ -209,23 +205,17 @@ xfs_iomap_write_direct(
         * the reserve block pool for bmbt block allocation if there is no space
         * left but we need to do unwritten extent conversion.
         */
-
        if (IS_DAX(VFS_I(ip))) {
                bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO;
                if (ISUNWRITTEN(imap)) {
-                       tp->t_flags |= XFS_TRANS_RESERVE;
+                       tflags |= XFS_TRANS_RESERVE;
                        resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
                }
        }
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                                 resblks, resrtextents);
-       /*
-        * Check for running out of space, note: need lock to return
-        */
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, resrtextents,
+                       tflags, &tp);
+       if (error)
                return error;
-       }
 
        lockmode = XFS_ILOCK_EXCL;
        xfs_ilock(ip, lockmode);
@@ -726,15 +716,13 @@ xfs_iomap_write_allocate(
 
                nimaps = 0;
                while (nimaps == 0) {
-                       tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
-                       tp->t_flags |= XFS_TRANS_RESERVE;
                        nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
-                       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                                                 nres, 0);
-                       if (error) {
-                               xfs_trans_cancel(tp);
+
+                       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, nres,
+                                       0, XFS_TRANS_RESERVE, &tp);
+                       if (error)
                                return error;
-                       }
+
                        xfs_ilock(ip, XFS_ILOCK_EXCL);
                        xfs_trans_ijoin(tp, ip, 0);
 
@@ -878,25 +866,18 @@ xfs_iomap_write_unwritten(
 
        do {
                /*
-                * set up a transaction to convert the range of extents
+                * Set up a transaction to convert the range of extents
                 * from unwritten to real. Do allocations in a loop until
                 * we have covered the range passed in.
                 *
-                * Note that we open code the transaction allocation here
-                * to pass KM_NOFS--we can't risk to recursing back into
-                * the filesystem here as we might be asked to write out
-                * the same inode that we complete here and might deadlock
-                * on the iolock.
+                * Note that we can't risk to recursing back into the filesystem
+                * here as we might be asked to write out the same inode that we
+                * complete here and might deadlock on the iolock.
                 */
-               sb_start_intwrite(mp->m_super);
-               tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS);
-               tp->t_flags |= XFS_TRANS_RESERVE | XFS_TRANS_FREEZE_PROT;
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
-                                         resblks, 0);
-               if (error) {
-                       xfs_trans_cancel(tp);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
+                               XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
+               if (error)
                        return error;
-               }
 
                xfs_ilock(ip, XFS_ILOCK_EXCL);
                xfs_trans_ijoin(tp, ip, 0);
index fb7dc61f4a29d7cee3d4683c675c4551e7669e52..fc7766164dc960a217d00fa0ea960f5ba56d8d73 100644 (file)
@@ -599,12 +599,12 @@ xfs_setattr_nonsize(
                        return error;
        }
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
        if (error)
-               goto out_trans_cancel;
+               goto out_dqrele;
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
+       xfs_trans_ijoin(tp, ip, 0);
 
        /*
         * Change file ownership.  Must be the owner or privileged.
@@ -633,12 +633,10 @@ xfs_setattr_nonsize(
                                                NULL, capable(CAP_FOWNER) ?
                                                XFS_QMOPT_FORCE_RES : 0);
                        if (error)      /* out of quota */
-                               goto out_unlock;
+                               goto out_cancel;
                }
        }
 
-       xfs_trans_ijoin(tp, ip, 0);
-
        /*
         * Change file ownership.  Must be the owner or privileged.
         */
@@ -722,10 +720,9 @@ xfs_setattr_nonsize(
 
        return 0;
 
-out_unlock:
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-out_trans_cancel:
+out_cancel:
        xfs_trans_cancel(tp);
+out_dqrele:
        xfs_qm_dqrele(udqp);
        xfs_qm_dqrele(gdqp);
        return error;
@@ -834,7 +831,7 @@ xfs_setattr_size(
         * We have to do all the page cache truncate work outside the
         * transaction context as the "lock" order is page lock->log space
         * reservation as defined by extent allocation in the writeback path.
-        * Hence a truncate can fail with ENOMEM from xfs_trans_reserve(), but
+        * Hence a truncate can fail with ENOMEM from xfs_trans_alloc(), but
         * having already truncated the in-memory version of the file (i.e. made
         * user visible changes). There's not much we can do about this, except
         * to hope that the caller sees ENOMEM and retries the truncate
@@ -849,10 +846,9 @@ xfs_setattr_size(
                return error;
        truncate_setsize(inode, newsize);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
        if (error)
-               goto out_trans_cancel;
+               return error;
 
        lock_flags |= XFS_ILOCK_EXCL;
        xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -971,12 +967,9 @@ xfs_vn_update_time(
 
        trace_xfs_update_time(ip);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        if (flags & S_CTIME)
index 396565f4324764058b979cf5e4c5bd96744f8ef8..558f3d1d91ada0c356c37ee31718e0f0e3af059a 100644 (file)
@@ -4205,10 +4205,9 @@ xlog_recover_process_efi(
                }
        }
 
-       tp = xfs_trans_alloc(mp, 0);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
        if (error)
-               goto abort_error;
+               return error;
        efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
 
        for (i = 0; i < efip->efi_format.efi_nextents; i++) {
@@ -4355,10 +4354,9 @@ xlog_recover_clear_agi_bucket(
        int             offset;
        int             error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_clearagi, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_clearagi, 0, 0, 0, &tp);
        if (error)
-               goto out_abort;
+               goto out_error;
 
        error = xfs_read_agi(mp, tp, agno, &agibp);
        if (error)
index ade236e90bb3612d429a8b6b0909b3937302096c..3332baeac5824b1adcbef6969e217f70e7ad79a8 100644 (file)
@@ -308,12 +308,9 @@ xfs_fs_commit_blocks(
                        goto out_drop_iolock;
        }
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
+       if (error)
                goto out_drop_iolock;
-       }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
index be125e1758c1a5e4df36cfb8ec6e3e3643adc534..a60d9e2739d14a2ebcff8ee7dcedae7f5177bf3c 100644 (file)
@@ -783,13 +783,10 @@ xfs_qm_qino_alloc(
                }
        }
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_create,
-                                 XFS_QM_QINOCREATE_SPACE_RES(mp), 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_create,
+                       XFS_QM_QINOCREATE_SPACE_RES(mp), 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        if (need_alloc) {
                error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip,
index f4d0e0a8f517c65913b8d45f383450384576b39e..475a3882a81fef1cedaabf33383d04c1ee8d3e4b 100644 (file)
@@ -236,10 +236,8 @@ xfs_qm_scall_trunc_qfile(
 
        xfs_ilock(ip, XFS_IOLOCK_EXCL);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
        if (error) {
-               xfs_trans_cancel(tp);
                xfs_iunlock(ip, XFS_IOLOCK_EXCL);
                goto out_put;
        }
@@ -436,12 +434,9 @@ xfs_qm_scall_setqlim(
        defq = xfs_get_defquota(dqp, q);
        xfs_dqunlock(dqp);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_setqlim, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp);
+       if (error)
                goto out_rele;
-       }
 
        xfs_dqlock(dqp);
        xfs_trans_dqjoin(tp, dqp);
@@ -569,13 +564,9 @@ xfs_qm_log_quotaoff_end(
        int                     error;
        xfs_qoff_logitem_t      *qoffi;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
-
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_equotaoff, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        qoffi = xfs_trans_get_qoff_item(tp, startqoff,
                                        flags & XFS_ALL_QUOTA_ACCT);
@@ -603,12 +594,9 @@ xfs_qm_log_quotaoff(
 
        *qoffstartp = NULL;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp);
+       if (error)
                goto out;
-       }
 
        qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
        xfs_trans_log_quotaoff_item(tp, qoffi);
index abf44435d04a3f4b898e21a00e45ee8ae607738a..3938b37d1043bb6fd98879fa4783b6bbec8cfef6 100644 (file)
@@ -780,15 +780,14 @@ xfs_growfs_rt_alloc(
         * Allocate space to the file, as necessary.
         */
        while (oblocks < nblocks) {
-               tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ALLOC);
                resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
                /*
                 * Reserve space & log for one extent added to the file.
                 */
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtalloc,
-                                         resblks, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks,
+                               0, 0, &tp);
                if (error)
-                       goto out_trans_cancel;
+                       return error;
                /*
                 * Lock the inode.
                 */
@@ -823,14 +822,13 @@ xfs_growfs_rt_alloc(
                for (bno = map.br_startoff, fsbno = map.br_startblock;
                     bno < map.br_startoff + map.br_blockcount;
                     bno++, fsbno++) {
-                       tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ZERO);
                        /*
                         * Reserve log for one block zeroing.
                         */
-                       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtzero,
-                                                 0, 0);
+                       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero,
+                                       0, 0, 0, &tp);
                        if (error)
-                               goto out_trans_cancel;
+                               return error;
                        /*
                         * Lock the bitmap inode.
                         */
@@ -994,11 +992,10 @@ xfs_growfs_rt(
                /*
                 * Start a transaction, get the log reservation.
                 */
-               tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_FREE);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtfree,
-                                         0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0,
+                               &tp);
                if (error)
-                       goto error_cancel;
+                       break;
                /*
                 * Lock out other callers by grabbing the bitmap inode lock.
                 */
index b44284c1adda15c647ddcc2feebf0a24302bdcbc..c3aeaa884478b40584fbb0207a123826ad0cd513 100644 (file)
@@ -221,7 +221,6 @@ xfs_symlink(
        if (error)
                return error;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK);
        /*
         * The symlink will fit into the inode data fork?
         * There can't be any attributes so we get the whole variable part.
@@ -231,13 +230,15 @@ xfs_symlink(
        else
                fs_blocks = xfs_symlink_blocks(mp, pathlen);
        resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_symlink, resblks, 0);
+
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, resblks, 0, 0, &tp);
        if (error == -ENOSPC && fs_blocks == 0) {
                resblks = 0;
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_symlink, 0, 0);
+               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, 0, 0, 0,
+                               &tp);
        }
        if (error)
-               goto out_trans_cancel;
+               goto out_release_inode;
 
        xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
                      XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
@@ -455,12 +456,9 @@ xfs_inactive_symlink_rmt(
         */
        ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2);
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
-       error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
-       if (error) {
-               xfs_trans_cancel(tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
+       if (error)
                return error;
-       }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, 0);
index 20c53666cb4b3272400bc7111d285f104e555d75..b3669efb2a0a05519b83573a5679c2b5d78af377 100644 (file)
@@ -46,47 +46,6 @@ xfs_trans_init(
        xfs_trans_resv_calc(mp, M_RES(mp));
 }
 
-/*
- * This routine is called to allocate a transaction structure.
- * The type parameter indicates the type of the transaction.  These
- * are enumerated in xfs_trans.h.
- *
- * Dynamically allocate the transaction structure from the transaction
- * zone, initialize it, and return it to the caller.
- */
-xfs_trans_t *
-xfs_trans_alloc(
-       xfs_mount_t     *mp,
-       uint            type)
-{
-       xfs_trans_t     *tp;
-
-       sb_start_intwrite(mp->m_super);
-       tp = _xfs_trans_alloc(mp, type, KM_SLEEP);
-       tp->t_flags |= XFS_TRANS_FREEZE_PROT;
-       return tp;
-}
-
-xfs_trans_t *
-_xfs_trans_alloc(
-       xfs_mount_t     *mp,
-       uint            type,
-       xfs_km_flags_t  memflags)
-{
-       xfs_trans_t     *tp;
-
-       WARN_ON(mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE);
-       atomic_inc(&mp->m_active_trans);
-
-       tp = kmem_zone_zalloc(xfs_trans_zone, memflags);
-       tp->t_magic = XFS_TRANS_HEADER_MAGIC;
-       tp->t_type = type;
-       tp->t_mountp = mp;
-       INIT_LIST_HEAD(&tp->t_items);
-       INIT_LIST_HEAD(&tp->t_busy);
-       return tp;
-}
-
 /*
  * Free the transaction structure.  If there is more clean up
  * to do when the structure is freed, add it here.
@@ -99,7 +58,7 @@ xfs_trans_free(
        xfs_extent_busy_clear(tp->t_mountp, &tp->t_busy, false);
 
        atomic_dec(&tp->t_mountp->m_active_trans);
-       if (tp->t_flags & XFS_TRANS_FREEZE_PROT)
+       if (!(tp->t_flags & XFS_TRANS_NO_WRITECOUNT))
                sb_end_intwrite(tp->t_mountp->m_super);
        xfs_trans_free_dqinfo(tp);
        kmem_zone_free(xfs_trans_zone, tp);
@@ -125,7 +84,6 @@ xfs_trans_dup(
         * Initialize the new transaction structure.
         */
        ntp->t_magic = XFS_TRANS_HEADER_MAGIC;
-       ntp->t_type = tp->t_type;
        ntp->t_mountp = tp->t_mountp;
        INIT_LIST_HEAD(&ntp->t_items);
        INIT_LIST_HEAD(&ntp->t_busy);
@@ -135,9 +93,9 @@ xfs_trans_dup(
 
        ntp->t_flags = XFS_TRANS_PERM_LOG_RES |
                       (tp->t_flags & XFS_TRANS_RESERVE) |
-                      (tp->t_flags & XFS_TRANS_FREEZE_PROT);
+                      (tp->t_flags & XFS_TRANS_NO_WRITECOUNT);
        /* We gave our writer reference to the new transaction */
-       tp->t_flags &= ~XFS_TRANS_FREEZE_PROT;
+       tp->t_flags |= XFS_TRANS_NO_WRITECOUNT;
        ntp->t_ticket = xfs_log_ticket_get(tp->t_ticket);
        ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
        tp->t_blk_res = tp->t_blk_res_used;
@@ -165,7 +123,7 @@ xfs_trans_dup(
  * This does not do quota reservations. That typically is done by the
  * caller afterwards.
  */
-int
+static int
 xfs_trans_reserve(
        struct xfs_trans        *tp,
        struct xfs_trans_res    *resp,
@@ -219,7 +177,7 @@ xfs_trans_reserve(
                                                resp->tr_logres,
                                                resp->tr_logcount,
                                                &tp->t_ticket, XFS_TRANSACTION,
-                                               permanent, tp->t_type);
+                                               permanent, 0);
                }
 
                if (error)
@@ -268,6 +226,42 @@ undo_blocks:
        return error;
 }
 
+int
+xfs_trans_alloc(
+       struct xfs_mount        *mp,
+       struct xfs_trans_res    *resp,
+       uint                    blocks,
+       uint                    rtextents,
+       uint                    flags,
+       struct xfs_trans        **tpp)
+{
+       struct xfs_trans        *tp;
+       int                     error;
+
+       if (!(flags & XFS_TRANS_NO_WRITECOUNT))
+               sb_start_intwrite(mp->m_super);
+
+       WARN_ON(mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE);
+       atomic_inc(&mp->m_active_trans);
+
+       tp = kmem_zone_zalloc(xfs_trans_zone,
+               (flags & XFS_TRANS_NOFS) ? KM_NOFS : KM_SLEEP);
+       tp->t_magic = XFS_TRANS_HEADER_MAGIC;
+       tp->t_flags = flags;
+       tp->t_mountp = mp;
+       INIT_LIST_HEAD(&tp->t_items);
+       INIT_LIST_HEAD(&tp->t_busy);
+
+       error = xfs_trans_reserve(tp, resp, blocks, rtextents);
+       if (error) {
+               xfs_trans_cancel(tp);
+               return error;
+       }
+
+       *tpp = tp;
+       return 0;
+}
+
 /*
  * Record the indicated change to the given field for application
  * to the file system's superblock when the transaction commits.
index e7c49cf43fbc85c183e1728966d4f4506b94eaf6..9a462e892e4f33f9f50508b6ba8f33bfb348a420 100644 (file)
@@ -90,7 +90,6 @@ void  xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
  */
 typedef struct xfs_trans {
        unsigned int            t_magic;        /* magic number */
-       unsigned int            t_type;         /* transaction type */
        unsigned int            t_log_res;      /* amt of log space resvd */
        unsigned int            t_log_count;    /* count for perm log res */
        unsigned int            t_blk_res;      /* # of blocks resvd */
@@ -148,10 +147,9 @@ typedef struct xfs_trans {
 /*
  * XFS transaction mechanism exported interfaces.
  */
-xfs_trans_t    *xfs_trans_alloc(struct xfs_mount *, uint);
-xfs_trans_t    *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t);
-int            xfs_trans_reserve(struct xfs_trans *, struct xfs_trans_res *,
-                                 uint, uint);
+int            xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp,
+                       uint blocks, uint rtextents, uint flags,
+                       struct xfs_trans **tpp);
 void           xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
 
 struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp,