xfs: Clean up xfs_trans_committed code after factoring
Now that the code has been factored, clean up all the remaining style cruft, simplify the code and re-order functions so that it doesn't need forward declarations. Also move the remaining functions that require forward declarations (xfs_trans_uncommit, xfs_trans_free) so that all the forward declarations can be removed from the file. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
8e646a55ac
commit
b1c1b5b610
@ -45,20 +45,12 @@
|
||||
#include "xfs_trans_space.h"
|
||||
#include "xfs_inode_item.h"
|
||||
|
||||
|
||||
STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *);
|
||||
STATIC void xfs_trans_uncommit(xfs_trans_t *, uint);
|
||||
STATIC void xfs_trans_committed(xfs_trans_t *, int);
|
||||
STATIC void xfs_trans_free(xfs_trans_t *);
|
||||
|
||||
kmem_zone_t *xfs_trans_zone;
|
||||
|
||||
|
||||
/*
|
||||
* Reservation functions here avoid a huge stack in xfs_trans_init
|
||||
* due to register overflow from temporaries in the calculations.
|
||||
*/
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_write_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
@ -257,6 +249,19 @@ _xfs_trans_alloc(
|
||||
return tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the transaction structure. If there is more clean up
|
||||
* to do when the structure is freed, add it here.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_free(
|
||||
xfs_trans_t *tp)
|
||||
{
|
||||
atomic_dec(&tp->t_mountp->m_active_trans);
|
||||
xfs_trans_free_dqinfo(tp);
|
||||
kmem_zone_free(xfs_trans_zone, tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called to create a new transaction which will share the
|
||||
* permanent log reservation of the given transaction. The remaining
|
||||
@ -769,7 +774,7 @@ xfs_trans_unreserve_and_mod_sb(
|
||||
*/
|
||||
static uint
|
||||
xfs_trans_count_vecs(
|
||||
xfs_trans_t *tp)
|
||||
struct xfs_trans *tp)
|
||||
{
|
||||
int nvecs;
|
||||
xfs_log_item_desc_t *lidp;
|
||||
@ -860,6 +865,158 @@ xfs_trans_fill_vecs(
|
||||
log_vector->i_type = XLOG_REG_TYPE_TRANSHDR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The committed item processing consists of calling the committed routine of
|
||||
* each logged item, updating the item's position in the AIL if necessary, and
|
||||
* unpinning each item. If the committed routine returns -1, then do nothing
|
||||
* further with the item because it may have been freed.
|
||||
*
|
||||
* Since items are unlocked when they are copied to the incore log, it is
|
||||
* possible for two transactions to be completing and manipulating the same
|
||||
* item simultaneously. The AIL lock will protect the lsn field of each item.
|
||||
* The value of this field can never go backwards.
|
||||
*
|
||||
* We unpin the items after repositioning them in the AIL, because otherwise
|
||||
* they could be immediately flushed and we'd have to race with the flusher
|
||||
* trying to pull the item from the AIL as we add it.
|
||||
*/
|
||||
static void
|
||||
xfs_trans_item_committed(
|
||||
struct xfs_log_item *lip,
|
||||
xfs_lsn_t commit_lsn,
|
||||
int aborted)
|
||||
{
|
||||
xfs_lsn_t item_lsn;
|
||||
struct xfs_ail *ailp;
|
||||
|
||||
if (aborted)
|
||||
lip->li_flags |= XFS_LI_ABORTED;
|
||||
item_lsn = IOP_COMMITTED(lip, commit_lsn);
|
||||
|
||||
/* If the committed routine returns -1, item has been freed. */
|
||||
if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the returned lsn is greater than what it contained before, update
|
||||
* the location of the item in the AIL. If it is not, then do nothing.
|
||||
* Items can never move backwards in the AIL.
|
||||
*
|
||||
* While the new lsn should usually be greater, it is possible that a
|
||||
* later transaction completing simultaneously with an earlier one
|
||||
* using the same item could complete first with a higher lsn. This
|
||||
* would cause the earlier transaction to fail the test below.
|
||||
*/
|
||||
ailp = lip->li_ailp;
|
||||
spin_lock(&ailp->xa_lock);
|
||||
if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) {
|
||||
/*
|
||||
* This will set the item's lsn to item_lsn and update the
|
||||
* position of the item in the AIL.
|
||||
*
|
||||
* xfs_trans_ail_update() drops the AIL lock.
|
||||
*/
|
||||
xfs_trans_ail_update(ailp, lip, item_lsn);
|
||||
} else {
|
||||
spin_unlock(&ailp->xa_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we've repositioned the item in the AIL, unpin it so it can
|
||||
* be flushed. Pass information about buffer stale state down from the
|
||||
* log item flags, if anyone else stales the buffer we do not want to
|
||||
* pay any attention to it.
|
||||
*/
|
||||
IOP_UNPIN(lip);
|
||||
}
|
||||
|
||||
/* Clear all the per-AG busy list items listed in this transaction */
|
||||
static void
|
||||
xfs_trans_clear_busy_extents(
|
||||
struct xfs_trans *tp)
|
||||
{
|
||||
xfs_log_busy_chunk_t *lbcp;
|
||||
xfs_log_busy_slot_t *lbsp;
|
||||
int i;
|
||||
|
||||
for (lbcp = &tp->t_busy; lbcp != NULL; lbcp = lbcp->lbc_next) {
|
||||
i = 0;
|
||||
for (lbsp = lbcp->lbc_busy; i < lbcp->lbc_unused; i++, lbsp++) {
|
||||
if (XFS_LBC_ISFREE(lbcp, i))
|
||||
continue;
|
||||
xfs_alloc_clear_busy(tp, lbsp->lbc_ag, lbsp->lbc_idx);
|
||||
}
|
||||
}
|
||||
xfs_trans_free_busy(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is typically called by the LM when a transaction has been fully
|
||||
* committed to disk. It needs to unpin the items which have
|
||||
* been logged by the transaction and update their positions
|
||||
* in the AIL if necessary.
|
||||
*
|
||||
* This also gets called when the transactions didn't get written out
|
||||
* because of an I/O error. Abortflag & XFS_LI_ABORTED is set then.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_committed(
|
||||
struct xfs_trans *tp,
|
||||
int abortflag)
|
||||
{
|
||||
xfs_log_item_desc_t *lidp;
|
||||
xfs_log_item_chunk_t *licp;
|
||||
xfs_log_item_chunk_t *next_licp;
|
||||
|
||||
/* Call the transaction's completion callback if there is one. */
|
||||
if (tp->t_callback != NULL)
|
||||
tp->t_callback(tp, tp->t_callarg);
|
||||
|
||||
for (lidp = xfs_trans_first_item(tp);
|
||||
lidp != NULL;
|
||||
lidp = xfs_trans_next_item(tp, lidp)) {
|
||||
xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag);
|
||||
}
|
||||
|
||||
/* free the item chunks, ignoring the embedded chunk */
|
||||
for (licp = tp->t_items.lic_next; licp != NULL; licp = next_licp) {
|
||||
next_licp = licp->lic_next;
|
||||
kmem_free(licp);
|
||||
}
|
||||
|
||||
xfs_trans_clear_busy_extents(tp);
|
||||
xfs_trans_free(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from the trans_commit code when we notice that
|
||||
* the filesystem is in the middle of a forced shutdown.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_uncommit(
|
||||
struct xfs_trans *tp,
|
||||
uint flags)
|
||||
{
|
||||
xfs_log_item_desc_t *lidp;
|
||||
|
||||
for (lidp = xfs_trans_first_item(tp);
|
||||
lidp != NULL;
|
||||
lidp = xfs_trans_next_item(tp, lidp)) {
|
||||
/*
|
||||
* Unpin all but those that aren't dirty.
|
||||
*/
|
||||
if (lidp->lid_flags & XFS_LID_DIRTY)
|
||||
IOP_UNPIN_REMOVE(lidp->lid_item, tp);
|
||||
}
|
||||
|
||||
xfs_trans_unreserve_and_mod_sb(tp);
|
||||
xfs_trans_unreserve_and_mod_dquots(tp);
|
||||
|
||||
xfs_trans_free_items(tp, flags);
|
||||
xfs_trans_free_busy(tp);
|
||||
xfs_trans_free(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Format the transaction direct to the iclog. This isolates the physical
|
||||
* transaction commit operation from the logical operation and hence allows
|
||||
@ -1110,35 +1267,6 @@ out_unreserve:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from the trans_commit code when we notice that
|
||||
* the filesystem is in the middle of a forced shutdown.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_uncommit(
|
||||
xfs_trans_t *tp,
|
||||
uint flags)
|
||||
{
|
||||
xfs_log_item_desc_t *lidp;
|
||||
|
||||
for (lidp = xfs_trans_first_item(tp);
|
||||
lidp != NULL;
|
||||
lidp = xfs_trans_next_item(tp, lidp)) {
|
||||
/*
|
||||
* Unpin all but those that aren't dirty.
|
||||
*/
|
||||
if (lidp->lid_flags & XFS_LID_DIRTY)
|
||||
IOP_UNPIN_REMOVE(lidp->lid_item, tp);
|
||||
}
|
||||
|
||||
xfs_trans_unreserve_and_mod_sb(tp);
|
||||
xfs_trans_unreserve_and_mod_dquots(tp);
|
||||
|
||||
xfs_trans_free_items(tp, flags);
|
||||
xfs_trans_free_busy(tp);
|
||||
xfs_trans_free(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock all of the transaction's items and free the transaction.
|
||||
* The transaction must not have modified any of its items, because
|
||||
@ -1215,20 +1343,6 @@ xfs_trans_cancel(
|
||||
xfs_trans_free(tp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free the transaction structure. If there is more clean up
|
||||
* to do when the structure is freed, add it here.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_free(
|
||||
xfs_trans_t *tp)
|
||||
{
|
||||
atomic_dec(&tp->t_mountp->m_active_trans);
|
||||
xfs_trans_free_dqinfo(tp);
|
||||
kmem_zone_free(xfs_trans_zone, tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Roll from one trans in the sequence of PERMANENT transactions to
|
||||
* the next: permanent transactions are only flushed out when
|
||||
@ -1298,141 +1412,3 @@ xfs_trans_roll(
|
||||
xfs_trans_ihold(trans, dp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The committed item processing consists of calling the committed routine of
|
||||
* each logged item, updating the item's position in the AIL if necessary, and
|
||||
* unpinning each item. If the committed routine returns -1, then do nothing
|
||||
* further with the item because it may have been freed.
|
||||
*
|
||||
* Since items are unlocked when they are copied to the incore log, it is
|
||||
* possible for two transactions to be completing and manipulating the same
|
||||
* item simultaneously. The AIL lock will protect the lsn field of each item.
|
||||
* The value of this field can never go backwards.
|
||||
*
|
||||
* We unpin the items after repositioning them in the AIL, because otherwise
|
||||
* they could be immediately flushed and we'd have to race with the flusher
|
||||
* trying to pull the item from the AIL as we add it.
|
||||
*/
|
||||
static void
|
||||
xfs_trans_item_committed(
|
||||
xfs_log_item_t *lip,
|
||||
xfs_lsn_t commit_lsn,
|
||||
int aborted)
|
||||
{
|
||||
xfs_lsn_t item_lsn;
|
||||
struct xfs_ail *ailp;
|
||||
|
||||
if (aborted)
|
||||
lip->li_flags |= XFS_LI_ABORTED;
|
||||
|
||||
/*
|
||||
* Send in the ABORTED flag to the COMMITTED routine so that it knows
|
||||
* whether the transaction was aborted or not.
|
||||
*/
|
||||
item_lsn = IOP_COMMITTED(lip, commit_lsn);
|
||||
|
||||
/*
|
||||
* If the committed routine returns -1, item has been freed.
|
||||
*/
|
||||
if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the returned lsn is greater than what it contained before, update
|
||||
* the location of the item in the AIL. If it is not, then do nothing.
|
||||
* Items can never move backwards in the AIL.
|
||||
*
|
||||
* While the new lsn should usually be greater, it is possible that a
|
||||
* later transaction completing simultaneously with an earlier one
|
||||
* using the same item could complete first with a higher lsn. This
|
||||
* would cause the earlier transaction to fail the test below.
|
||||
*/
|
||||
ailp = lip->li_ailp;
|
||||
spin_lock(&ailp->xa_lock);
|
||||
if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) {
|
||||
/*
|
||||
* This will set the item's lsn to item_lsn and update the
|
||||
* position of the item in the AIL.
|
||||
*
|
||||
* xfs_trans_ail_update() drops the AIL lock.
|
||||
*/
|
||||
xfs_trans_ail_update(ailp, lip, item_lsn);
|
||||
} else {
|
||||
spin_unlock(&ailp->xa_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we've repositioned the item in the AIL, unpin it so it can
|
||||
* be flushed. Pass information about buffer stale state down from the
|
||||
* log item flags, if anyone else stales the buffer we do not want to
|
||||
* pay any attention to it.
|
||||
*/
|
||||
IOP_UNPIN(lip);
|
||||
}
|
||||
|
||||
/* Clear all the per-AG busy list items listed in this transaction */
|
||||
static void
|
||||
xfs_trans_clear_busy_extents(
|
||||
struct xfs_trans *tp)
|
||||
{
|
||||
xfs_log_busy_chunk_t *lbcp;
|
||||
xfs_log_busy_slot_t *lbsp;
|
||||
int i;
|
||||
|
||||
lbcp = &tp->t_busy;
|
||||
while (lbcp != NULL) {
|
||||
for (i = 0, lbsp = lbcp->lbc_busy; i < lbcp->lbc_unused; i++, lbsp++) {
|
||||
if (!XFS_LBC_ISFREE(lbcp, i)) {
|
||||
xfs_alloc_clear_busy(tp, lbsp->lbc_ag,
|
||||
lbsp->lbc_idx);
|
||||
}
|
||||
}
|
||||
lbcp = lbcp->lbc_next;
|
||||
}
|
||||
xfs_trans_free_busy(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is typically called by the LM when a transaction has been fully
|
||||
* committed to disk. It needs to unpin the items which have
|
||||
* been logged by the transaction and update their positions
|
||||
* in the AIL if necessary.
|
||||
*
|
||||
* This also gets called when the transactions didn't get written out
|
||||
* because of an I/O error. Abortflag & XFS_LI_ABORTED is set then.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_trans_committed(
|
||||
xfs_trans_t *tp,
|
||||
int abortflag)
|
||||
{
|
||||
xfs_log_item_desc_t *lidp;
|
||||
xfs_log_item_chunk_t *licp;
|
||||
xfs_log_item_chunk_t *next_licp;
|
||||
|
||||
/*
|
||||
* Call the transaction's completion callback if there
|
||||
* is one.
|
||||
*/
|
||||
if (tp->t_callback != NULL) {
|
||||
tp->t_callback(tp, tp->t_callarg);
|
||||
}
|
||||
|
||||
for (lidp = xfs_trans_first_item(tp);
|
||||
lidp != NULL;
|
||||
lidp = xfs_trans_next_item(tp, lidp)) {
|
||||
xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag);
|
||||
}
|
||||
|
||||
/* free the item chunks, ignoring the embedded chunk */
|
||||
licp = tp->t_items.lic_next;
|
||||
while (licp != NULL) {
|
||||
next_licp = licp->lic_next;
|
||||
kmem_free(licp);
|
||||
licp = next_licp;
|
||||
}
|
||||
|
||||
xfs_trans_clear_busy_extents(tp);
|
||||
xfs_trans_free(tp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user