xfs: better xfs_trans_alloc interface

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>
This commit is contained in:
Christoph Hellwig 2016-04-06 09:19:55 +10:00 committed by Dave Chinner
parent f55532a0c0
commit 253f4911f2
22 changed files with 191 additions and 347 deletions

View File

@ -242,37 +242,21 @@ xfs_attr_set(
return error; return error;
} }
/* tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
* Start our first transaction of the day. M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
* tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
* All future transactions during this code must be "chained" off tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
* 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);
/* /*
* Root fork attributes can use reserved data blocks for this * Root fork attributes can use reserved data blocks for this
* operation if necessary * operation if necessary
*/ */
error = xfs_trans_alloc(mp, &tres, args.total, 0,
if (rsvd) rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
args.trans->t_flags |= XFS_TRANS_RESERVE; if (error)
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);
return 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, error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
XFS_QMOPT_RES_REGBLKS); XFS_QMOPT_RES_REGBLKS);
@ -428,32 +412,16 @@ xfs_attr_remove(
if (error) if (error)
return 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 * Root fork attributes can use reserved data blocks for this
* operation if necessary * operation if necessary
*/ */
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm,
if (flags & ATTR_ROOT) XFS_ATTRRM_SPACE_RES(mp), 0,
args.trans->t_flags |= XFS_TRANS_RESERVE; (flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0,
&args.trans);
error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm, if (error)
XFS_ATTRRM_SPACE_RES(mp), 0);
if (error) {
xfs_trans_cancel(args.trans);
return error; return error;
}
xfs_ilock(dp, XFS_ILOCK_EXCL); xfs_ilock(dp, XFS_ILOCK_EXCL);
/* /*

View File

@ -1121,15 +1121,14 @@ xfs_bmap_add_attrfork(
mp = ip->i_mount; mp = ip->i_mount;
ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
blks = XFS_ADDAFORK_SPACE_RES(mp); blks = XFS_ADDAFORK_SPACE_RES(mp);
if (rsvd)
tp->t_flags |= XFS_TRANS_RESERVE; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_addafork, blks, 0,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0); rsvd ? XFS_TRANS_RESERVE : 0, &tp);
if (error) { if (error)
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
@ -6026,13 +6025,10 @@ xfs_bmap_split_extent(
xfs_fsblock_t firstfsb; xfs_fsblock_t firstfsb;
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
XFS_DIOSTRAT_SPACE_RES(mp, 0), 0); if (error)
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);

View File

@ -838,12 +838,10 @@ xfs_sync_sb(
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); XFS_TRANS_NO_WRITECOUNT, &tp);
if (error) { if (error)
xfs_trans_cancel(tp);
return error; return error;
}
xfs_log_sb(tp); xfs_log_sb(tp);
if (wait) if (wait)

View 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_SYNC 0x08 /* make commit synchronous */
#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ #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_RESERVE 0x20 /* OK to use reserved data blocks */
#define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer #define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */
count in superblock */ #define XFS_TRANS_NOFS 0x80 /* pass KM_NOFS to kmem_alloc */
/* /*
* Field values for xfs_trans_mod_sb. * Field values for xfs_trans_mod_sb.
*/ */

View File

@ -120,13 +120,9 @@ xfs_setfilesize_trans_alloc(
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
if (error)
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
ioend->io_append_trans = tp; ioend->io_append_trans = tp;
@ -1391,13 +1387,10 @@ xfs_end_io_direct_write(
trace_xfs_end_io_direct_write_append(ip, offset, size); trace_xfs_end_io_direct_write_append(ip, offset, size);
tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0); &tp);
if (error) { if (!error)
xfs_trans_cancel(tp); error = xfs_setfilesize(ip, tp, offset, size);
return error;
}
error = xfs_setfilesize(ip, tp, offset, size);
} }
return error; return error;

View File

@ -405,21 +405,11 @@ xfs_attr_inactive(
goto out_destroy_fork; goto out_destroy_fork;
xfs_iunlock(dp, lock_mode); 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; 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) if (error)
goto out_cancel; goto out_destroy_fork;
lock_mode = XFS_ILOCK_EXCL; lock_mode = XFS_ILOCK_EXCL;
xfs_ilock(dp, lock_mode); xfs_ilock(dp, lock_mode);

View File

@ -900,19 +900,15 @@ xfs_free_eofblocks(
* Free them up now by truncating the file to * Free them up now by truncating the file to
* its current size. * its current size.
*/ */
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
if (need_iolock) { if (need_iolock) {
if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL))
xfs_trans_cancel(tp);
return -EAGAIN; 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) { if (error) {
ASSERT(XFS_FORCED_SHUTDOWN(mp)); ASSERT(XFS_FORCED_SHUTDOWN(mp));
xfs_trans_cancel(tp);
if (need_iolock) if (need_iolock)
xfs_iunlock(ip, XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error; return error;
@ -1037,9 +1033,9 @@ xfs_alloc_file_space(
/* /*
* Allocate and setup the transaction. * Allocate and setup the transaction.
*/ */
tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resrtextents, 0, &tp);
resblks, resrtextents);
/* /*
* Check for running out of space * Check for running out of space
*/ */
@ -1048,7 +1044,6 @@ xfs_alloc_file_space(
* Free the transaction structure. * Free the transaction structure.
*/ */
ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
xfs_trans_cancel(tp);
break; break;
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
@ -1311,18 +1306,10 @@ xfs_free_file_space(
* transaction to dip into the reserve blocks to ensure * transaction to dip into the reserve blocks to ensure
* the freeing of the space succeeds at ENOSPC. * the freeing of the space succeeds at ENOSPC.
*/ */
tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); &tp);
/*
* check for running out of space
*/
if (error) { if (error) {
/*
* Free the transaction structure.
*/
ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
xfs_trans_cancel(tp);
break; break;
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
@ -1482,19 +1469,16 @@ xfs_shift_file_space(
} }
while (!error && !done) { while (!error && !done) {
tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
/* /*
* We would need to reserve permanent block for transaction. * We would need to reserve permanent block for transaction.
* This will come into picture when after shifting extent into * This will come into picture when after shifting extent into
* hole we found that adjacent extents can be merged which * hole we found that adjacent extents can be merged which
* may lead to freeing of a block during record update. * may lead to freeing of a block during record update.
*/ */
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
XFS_DIOSTRAT_SPACE_RES(mp, 0), 0); XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
if (error) { if (error)
xfs_trans_cancel(tp);
break; break;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot, error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot,
@ -1747,12 +1731,9 @@ xfs_swap_extents(
if (error) if (error)
goto out_unlock; goto out_unlock;
tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
goto out_unlock; goto out_unlock;
}
/* /*
* Lock and join the inodes to the tansaction so that transaction commit * Lock and join the inodes to the tansaction so that transaction commit

View File

@ -614,11 +614,10 @@ xfs_qm_dqread(
trace_xfs_dqread(dqp); trace_xfs_dqread(dqp);
if (flags & XFS_QMOPT_DQALLOC) { if (flags & XFS_QMOPT_DQALLOC) {
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_dqalloc, XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp);
XFS_QM_DQALLOC_SPACE_RES(mp), 0);
if (error) if (error)
goto error1; goto error0;
} }
/* /*

View File

@ -145,12 +145,10 @@ xfs_update_prealloc_flags(
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID); error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_writeid,
error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0); 0, 0, 0, &tp);
if (error) { if (error)
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);

View File

@ -198,14 +198,10 @@ xfs_growfs_data_private(
return error; return error;
} }
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata,
tp->t_flags |= XFS_TRANS_RESERVE; XFS_GROWFS_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growdata, if (error)
XFS_GROWFS_SPACE_RES(mp), 0);
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
/* /*
* Write new AG headers to disk. Non-transactional, but written * Write new AG headers to disk. Non-transactional, but written

View File

@ -1161,11 +1161,9 @@ xfs_create(
rdev = 0; rdev = 0;
resblks = XFS_MKDIR_SPACE_RES(mp, name->len); resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
tres = &M_RES(mp)->tr_mkdir; tres = &M_RES(mp)->tr_mkdir;
tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
} else { } else {
resblks = XFS_CREATE_SPACE_RES(mp, name->len); resblks = XFS_CREATE_SPACE_RES(mp, name->len);
tres = &M_RES(mp)->tr_create; 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 * the case we'll drop the one we have and get a more
* appropriate transaction later. * appropriate transaction later.
*/ */
error = xfs_trans_reserve(tp, tres, resblks, 0); error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
if (error == -ENOSPC) { if (error == -ENOSPC) {
/* flush outstanding delalloc blocks and retry */ /* flush outstanding delalloc blocks and retry */
xfs_flush_inodes(mp); 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) { if (error == -ENOSPC) {
/* No space at all so try a "no-allocation" reservation */ /* No space at all so try a "no-allocation" reservation */
resblks = 0; resblks = 0;
error = xfs_trans_reserve(tp, tres, 0, 0); error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
} }
if (error) if (error)
goto out_trans_cancel; goto out_release_inode;
xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL | xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT); XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
@ -1337,17 +1334,16 @@ xfs_create_tmpfile(
return error; return error;
resblks = XFS_IALLOC_SPACE_RES(mp); resblks = XFS_IALLOC_SPACE_RES(mp);
tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
tres = &M_RES(mp)->tr_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) { if (error == -ENOSPC) {
/* No space at all so try a "no-allocation" reservation */ /* No space at all so try a "no-allocation" reservation */
resblks = 0; resblks = 0;
error = xfs_trans_reserve(tp, tres, 0, 0); error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
} }
if (error) if (error)
goto out_trans_cancel; goto out_release_inode;
error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
pdqp, resblks, 1, 0); pdqp, resblks, 1, 0);
@ -1432,15 +1428,14 @@ xfs_link(
if (error) if (error)
goto std_return; goto std_return;
tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
resblks = XFS_LINK_SPACE_RES(mp, target_name->len); 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) { if (error == -ENOSPC) {
resblks = 0; 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) if (error)
goto error_return; goto std_return;
xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT); xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
@ -1710,11 +1705,9 @@ xfs_inactive_truncate(
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
if (error) { if (error) {
ASSERT(XFS_FORCED_SHUTDOWN(mp)); ASSERT(XFS_FORCED_SHUTDOWN(mp));
xfs_trans_cancel(tp);
return error; return error;
} }
@ -1764,8 +1757,6 @@ xfs_inactive_ifree(
struct xfs_trans *tp; struct xfs_trans *tp;
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
/* /*
* The ifree transaction might need to allocate blocks for record * The ifree transaction might need to allocate blocks for record
* insertion to the finobt. We don't want to fail here at ENOSPC, so * 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 * now remains allocated and sits on the unlinked list until the fs is
* repaired. * repaired.
*/ */
tp->t_flags |= XFS_TRANS_RESERVE; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ifree,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree, XFS_IFREE_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
XFS_IFREE_SPACE_RES(mp), 0);
if (error) { if (error) {
if (error == -ENOSPC) { if (error == -ENOSPC) {
xfs_warn_ratelimited(mp, xfs_warn_ratelimited(mp,
@ -1792,7 +1782,6 @@ xfs_inactive_ifree(
} else { } else {
ASSERT(XFS_FORCED_SHUTDOWN(mp)); ASSERT(XFS_FORCED_SHUTDOWN(mp));
} }
xfs_trans_cancel(tp);
return error; return error;
} }
@ -2525,11 +2514,6 @@ xfs_remove(
if (error) if (error)
goto std_return; 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, * We try to get the real space reservation first,
* allowing for directory btree deletion(s) implying * allowing for directory btree deletion(s) implying
@ -2540,14 +2524,15 @@ xfs_remove(
* block from the directory. * block from the directory.
*/ */
resblks = XFS_REMOVE_SPACE_RES(mp); 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) { if (error == -ENOSPC) {
resblks = 0; 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) { if (error) {
ASSERT(error != -ENOSPC); ASSERT(error != -ENOSPC);
goto out_trans_cancel; goto std_return;
} }
xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT); 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, xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, wip,
inodes, &num_inodes); inodes, &num_inodes);
tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len); 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) { if (error == -ENOSPC) {
spaceres = 0; 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) if (error)
goto out_trans_cancel; goto out_release_wip;
/* /*
* Attach the dquots to the inodes * Attach the dquots to the inodes
@ -3155,6 +3140,7 @@ out_bmap_cancel:
xfs_bmap_cancel(&free_list); xfs_bmap_cancel(&free_list);
out_trans_cancel: out_trans_cancel:
xfs_trans_cancel(tp); xfs_trans_cancel(tp);
out_release_wip:
if (wip) if (wip)
IRELE(wip); IRELE(wip);
return error; return error;

View File

@ -334,12 +334,10 @@ xfs_set_dmattrs(
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return -EIO; return -EIO;
tp = xfs_trans_alloc(mp, XFS_TRANS_SET_DMATTRS); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, 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)) if (XFS_FORCED_SHUTDOWN(mp))
goto out_unlock; goto out_unlock;
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
if (error) if (error)
goto out_cancel; return ERR_PTR(error);
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | join_flags); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | join_flags);

View File

@ -132,6 +132,7 @@ xfs_iomap_write_direct(
int error; int error;
int lockmode; int lockmode;
int bmapi_flags = XFS_BMAPI_PREALLOC; int bmapi_flags = XFS_BMAPI_PREALLOC;
uint tflags = 0;
rt = XFS_IS_REALTIME_INODE(ip); rt = XFS_IS_REALTIME_INODE(ip);
extsz = xfs_get_extsz_hint(ip); extsz = xfs_get_extsz_hint(ip);
@ -191,11 +192,6 @@ xfs_iomap_write_direct(
if (error) if (error)
return 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 * 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 * 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 * the reserve block pool for bmbt block allocation if there is no space
* left but we need to do unwritten extent conversion. * left but we need to do unwritten extent conversion.
*/ */
if (IS_DAX(VFS_I(ip))) { if (IS_DAX(VFS_I(ip))) {
bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO;
if (ISUNWRITTEN(imap)) { if (ISUNWRITTEN(imap)) {
tp->t_flags |= XFS_TRANS_RESERVE; tflags |= XFS_TRANS_RESERVE;
resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
} }
} }
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, resrtextents,
resblks, resrtextents); tflags, &tp);
/* if (error)
* Check for running out of space, note: need lock to return
*/
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
lockmode = XFS_ILOCK_EXCL; lockmode = XFS_ILOCK_EXCL;
xfs_ilock(ip, lockmode); xfs_ilock(ip, lockmode);
@ -726,15 +716,13 @@ xfs_iomap_write_allocate(
nimaps = 0; nimaps = 0;
while (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); nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
nres, 0); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, nres,
if (error) { 0, XFS_TRANS_RESERVE, &tp);
xfs_trans_cancel(tp); if (error)
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0); xfs_trans_ijoin(tp, ip, 0);
@ -878,25 +866,18 @@ xfs_iomap_write_unwritten(
do { 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 * from unwritten to real. Do allocations in a loop until
* we have covered the range passed in. * we have covered the range passed in.
* *
* Note that we open code the transaction allocation here * Note that we can't risk to recursing back into the filesystem
* to pass KM_NOFS--we can't risk to recursing back into * here as we might be asked to write out the same inode that we
* the filesystem here as we might be asked to write out * complete here and might deadlock on the iolock.
* the same inode that we complete here and might deadlock
* on the iolock.
*/ */
sb_start_intwrite(mp->m_super); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS); XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
tp->t_flags |= XFS_TRANS_RESERVE | XFS_TRANS_FREEZE_PROT; if (error)
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
resblks, 0);
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0); xfs_trans_ijoin(tp, ip, 0);

View File

@ -599,12 +599,12 @@ xfs_setattr_nonsize(
return error; return error;
} }
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
if (error) if (error)
goto out_trans_cancel; goto out_dqrele;
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
/* /*
* Change file ownership. Must be the owner or privileged. * Change file ownership. Must be the owner or privileged.
@ -633,12 +633,10 @@ xfs_setattr_nonsize(
NULL, capable(CAP_FOWNER) ? NULL, capable(CAP_FOWNER) ?
XFS_QMOPT_FORCE_RES : 0); XFS_QMOPT_FORCE_RES : 0);
if (error) /* out of quota */ 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. * Change file ownership. Must be the owner or privileged.
*/ */
@ -722,10 +720,9 @@ xfs_setattr_nonsize(
return 0; return 0;
out_unlock: out_cancel:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
out_trans_cancel:
xfs_trans_cancel(tp); xfs_trans_cancel(tp);
out_dqrele:
xfs_qm_dqrele(udqp); xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp); xfs_qm_dqrele(gdqp);
return error; return error;
@ -834,7 +831,7 @@ xfs_setattr_size(
* We have to do all the page cache truncate work outside the * We have to do all the page cache truncate work outside the
* transaction context as the "lock" order is page lock->log space * transaction context as the "lock" order is page lock->log space
* reservation as defined by extent allocation in the writeback path. * 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 * 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 * user visible changes). There's not much we can do about this, except
* to hope that the caller sees ENOMEM and retries the truncate * to hope that the caller sees ENOMEM and retries the truncate
@ -849,10 +846,9 @@ xfs_setattr_size(
return error; return error;
truncate_setsize(inode, newsize); truncate_setsize(inode, newsize);
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
if (error) if (error)
goto out_trans_cancel; return error;
lock_flags |= XFS_ILOCK_EXCL; lock_flags |= XFS_ILOCK_EXCL;
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
@ -971,12 +967,9 @@ xfs_vn_update_time(
trace_xfs_update_time(ip); trace_xfs_update_time(ip);
tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
if (flags & S_CTIME) if (flags & S_CTIME)

View File

@ -4205,10 +4205,9 @@ xlog_recover_process_efi(
} }
} }
tp = xfs_trans_alloc(mp, 0); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
if (error) if (error)
goto abort_error; return error;
efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
for (i = 0; i < efip->efi_format.efi_nextents; i++) { for (i = 0; i < efip->efi_format.efi_nextents; i++) {
@ -4355,10 +4354,9 @@ xlog_recover_clear_agi_bucket(
int offset; int offset;
int error; int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_clearagi, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_clearagi, 0, 0);
if (error) if (error)
goto out_abort; goto out_error;
error = xfs_read_agi(mp, tp, agno, &agibp); error = xfs_read_agi(mp, tp, agno, &agibp);
if (error) if (error)

View File

@ -308,12 +308,9 @@ xfs_fs_commit_blocks(
goto out_drop_iolock; goto out_drop_iolock;
} }
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
goto out_drop_iolock; goto out_drop_iolock;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);

View File

@ -783,13 +783,10 @@ xfs_qm_qino_alloc(
} }
} }
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_create,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_create, XFS_QM_QINOCREATE_SPACE_RES(mp), 0, 0, &tp);
XFS_QM_QINOCREATE_SPACE_RES(mp), 0); if (error)
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
if (need_alloc) { if (need_alloc) {
error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip, error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip,

View File

@ -236,10 +236,8 @@ xfs_qm_scall_trunc_qfile(
xfs_ilock(ip, XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL);
tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
if (error) { if (error) {
xfs_trans_cancel(tp);
xfs_iunlock(ip, XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL);
goto out_put; goto out_put;
} }
@ -436,12 +434,9 @@ xfs_qm_scall_setqlim(
defq = xfs_get_defquota(dqp, q); defq = xfs_get_defquota(dqp, q);
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_setqlim, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
goto out_rele; goto out_rele;
}
xfs_dqlock(dqp); xfs_dqlock(dqp);
xfs_trans_dqjoin(tp, dqp); xfs_trans_dqjoin(tp, dqp);
@ -569,13 +564,9 @@ xfs_qm_log_quotaoff_end(
int error; int error;
xfs_qoff_logitem_t *qoffi; xfs_qoff_logitem_t *qoffi;
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp);
if (error)
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_equotaoff, 0, 0);
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
qoffi = xfs_trans_get_qoff_item(tp, startqoff, qoffi = xfs_trans_get_qoff_item(tp, startqoff,
flags & XFS_ALL_QUOTA_ACCT); flags & XFS_ALL_QUOTA_ACCT);
@ -603,12 +594,9 @@ xfs_qm_log_quotaoff(
*qoffstartp = NULL; *qoffstartp = NULL;
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
goto out; goto out;
}
qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
xfs_trans_log_quotaoff_item(tp, qoffi); xfs_trans_log_quotaoff_item(tp, qoffi);

View File

@ -780,15 +780,14 @@ xfs_growfs_rt_alloc(
* Allocate space to the file, as necessary. * Allocate space to the file, as necessary.
*/ */
while (oblocks < nblocks) { while (oblocks < nblocks) {
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ALLOC);
resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks); resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
/* /*
* Reserve space & log for one extent added to the file. * Reserve space & log for one extent added to the file.
*/ */
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtalloc, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks,
resblks, 0); 0, 0, &tp);
if (error) if (error)
goto out_trans_cancel; return error;
/* /*
* Lock the inode. * Lock the inode.
*/ */
@ -823,14 +822,13 @@ xfs_growfs_rt_alloc(
for (bno = map.br_startoff, fsbno = map.br_startblock; for (bno = map.br_startoff, fsbno = map.br_startblock;
bno < map.br_startoff + map.br_blockcount; bno < map.br_startoff + map.br_blockcount;
bno++, fsbno++) { bno++, fsbno++) {
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ZERO);
/* /*
* Reserve log for one block zeroing. * Reserve log for one block zeroing.
*/ */
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtzero, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero,
0, 0); 0, 0, 0, &tp);
if (error) if (error)
goto out_trans_cancel; return error;
/* /*
* Lock the bitmap inode. * Lock the bitmap inode.
*/ */
@ -994,11 +992,10 @@ xfs_growfs_rt(
/* /*
* Start a transaction, get the log reservation. * Start a transaction, get the log reservation.
*/ */
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_FREE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0,
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtfree, &tp);
0, 0);
if (error) if (error)
goto error_cancel; break;
/* /*
* Lock out other callers by grabbing the bitmap inode lock. * Lock out other callers by grabbing the bitmap inode lock.
*/ */

View File

@ -221,7 +221,6 @@ xfs_symlink(
if (error) if (error)
return error; return error;
tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK);
/* /*
* The symlink will fit into the inode data fork? * The symlink will fit into the inode data fork?
* There can't be any attributes so we get the whole variable part. * There can't be any attributes so we get the whole variable part.
@ -231,13 +230,15 @@ xfs_symlink(
else else
fs_blocks = xfs_symlink_blocks(mp, pathlen); fs_blocks = xfs_symlink_blocks(mp, pathlen);
resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); 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) { if (error == -ENOSPC && fs_blocks == 0) {
resblks = 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) if (error)
goto out_trans_cancel; goto out_release_inode;
xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL | xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT); 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); ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2);
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); if (error)
if (error) {
xfs_trans_cancel(tp);
return error; return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0); xfs_trans_ijoin(tp, ip, 0);

View File

@ -46,47 +46,6 @@ xfs_trans_init(
xfs_trans_resv_calc(mp, M_RES(mp)); 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 * Free the transaction structure. If there is more clean up
* to do when the structure is freed, add it here. * 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); xfs_extent_busy_clear(tp->t_mountp, &tp->t_busy, false);
atomic_dec(&tp->t_mountp->m_active_trans); 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); sb_end_intwrite(tp->t_mountp->m_super);
xfs_trans_free_dqinfo(tp); xfs_trans_free_dqinfo(tp);
kmem_zone_free(xfs_trans_zone, tp); kmem_zone_free(xfs_trans_zone, tp);
@ -125,7 +84,6 @@ xfs_trans_dup(
* Initialize the new transaction structure. * Initialize the new transaction structure.
*/ */
ntp->t_magic = XFS_TRANS_HEADER_MAGIC; ntp->t_magic = XFS_TRANS_HEADER_MAGIC;
ntp->t_type = tp->t_type;
ntp->t_mountp = tp->t_mountp; ntp->t_mountp = tp->t_mountp;
INIT_LIST_HEAD(&ntp->t_items); INIT_LIST_HEAD(&ntp->t_items);
INIT_LIST_HEAD(&ntp->t_busy); INIT_LIST_HEAD(&ntp->t_busy);
@ -135,9 +93,9 @@ xfs_trans_dup(
ntp->t_flags = XFS_TRANS_PERM_LOG_RES | ntp->t_flags = XFS_TRANS_PERM_LOG_RES |
(tp->t_flags & XFS_TRANS_RESERVE) | (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 */ /* 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_ticket = xfs_log_ticket_get(tp->t_ticket);
ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used; ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
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 * This does not do quota reservations. That typically is done by the
* caller afterwards. * caller afterwards.
*/ */
int static int
xfs_trans_reserve( xfs_trans_reserve(
struct xfs_trans *tp, struct xfs_trans *tp,
struct xfs_trans_res *resp, struct xfs_trans_res *resp,
@ -219,7 +177,7 @@ xfs_trans_reserve(
resp->tr_logres, resp->tr_logres,
resp->tr_logcount, resp->tr_logcount,
&tp->t_ticket, XFS_TRANSACTION, &tp->t_ticket, XFS_TRANSACTION,
permanent, tp->t_type); permanent, 0);
} }
if (error) if (error)
@ -268,6 +226,42 @@ undo_blocks:
return error; 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 * Record the indicated change to the given field for application
* to the file system's superblock when the transaction commits. * to the file system's superblock when the transaction commits.

View File

@ -90,7 +90,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
*/ */
typedef struct xfs_trans { typedef struct xfs_trans {
unsigned int t_magic; /* magic number */ 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_res; /* amt of log space resvd */
unsigned int t_log_count; /* count for perm log res */ unsigned int t_log_count; /* count for perm log res */
unsigned int t_blk_res; /* # of blocks resvd */ unsigned int t_blk_res; /* # of blocks resvd */
@ -148,10 +147,9 @@ typedef struct xfs_trans {
/* /*
* XFS transaction mechanism exported interfaces. * XFS transaction mechanism exported interfaces.
*/ */
xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); int xfs_trans_alloc(struct xfs_mount *mp, struct xfs_trans_res *resp,
xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t); uint blocks, uint rtextents, uint flags,
int xfs_trans_reserve(struct xfs_trans *, struct xfs_trans_res *, struct xfs_trans **tpp);
uint, uint);
void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp,