Skip to content

Commit

Permalink
xfs: better xfs_trans_alloc interface
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Dave Chinner committed Apr 5, 2016
1 parent f55532a commit 253f491
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 347 deletions.
58 changes: 13 additions & 45 deletions fs/xfs/libxfs/xfs_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
/*
Expand Down
22 changes: 9 additions & 13 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 :
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions fs/xfs/libxfs/xfs_sb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions fs/xfs/libxfs/xfs_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
19 changes: 6 additions & 13 deletions fs/xfs/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
16 changes: 3 additions & 13 deletions fs/xfs/xfs_attr_inactive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
45 changes: 13 additions & 32 deletions fs/xfs/xfs_bmap_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
*/
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
7 changes: 3 additions & 4 deletions fs/xfs/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand Down
8 changes: 3 additions & 5 deletions fs/xfs/xfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 3 additions & 7 deletions fs/xfs/xfs_fsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 253f491

Please sign in to comment.