xfs: simplify inode to transaction joining

Currently we need to either call IHOLD or xfs_trans_ihold on an inode when
joining it to a transaction via xfs_trans_ijoin.

This patches instead makes xfs_trans_ijoin usable on it's own by doing
an implicity xfs_trans_ihold, which also allows us to drop the third
argument.  For the case where we want to hold a reference on the inode
a xfs_trans_ijoin_ref wrapper is added which does the IHOLD and marks
the inode for needing an xfs_iput.  In addition to the cleaner interface
to the caller this also simplifies the implementation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Christoph Hellwig 2010-06-24 11:36:58 +10:00 committed by Alex Elder
parent 4d16e9246f
commit 898621d5a7
19 changed files with 103 additions and 247 deletions

View File

@ -158,8 +158,7 @@ xfs_file_fsync(
* transaction. So we play it safe and fire off the * transaction. So we play it safe and fire off the
* transaction anyway. * transaction anyway.
*/ */
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
error = _xfs_trans_commit(tp, 0, &log_flushed); error = _xfs_trans_commit(tp, 0, &log_flushed);

View File

@ -1034,8 +1034,7 @@ xfs_ioctl_setattr(
} }
} }
xfs_trans_ijoin(tp, ip, lock_flags); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* Change file ownership. Must be the owner or privileged. * Change file ownership. Must be the owner or privileged.

View File

@ -1023,8 +1023,7 @@ xfs_log_inode(
* an inode in another recent transaction. So we play it safe and * an inode in another recent transaction. So we play it safe and
* fire off the transaction anyway. * fire off the transaction anyway.
*/ */
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0); error = xfs_trans_commit(tp, 0);

View File

@ -362,8 +362,7 @@ xfs_commit_dummy_trans(
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_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = xfs_trans_commit(tp, 0); error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);

View File

@ -378,14 +378,7 @@ xfs_qm_dqalloc(
return (ESRCH); return (ESRCH);
} }
/* xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL);
* xfs_trans_commit normally decrements the vnode ref count
* when it unlocks the inode. Since we want to keep the quota
* inode around, we bump the vnode ref count now.
*/
IHOLD(quotip);
xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
nmaps = 1; nmaps = 1;
if ((error = xfs_bmapi(tp, quotip, if ((error = xfs_bmapi(tp, quotip,
offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB, offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB,

View File

@ -319,8 +319,7 @@ xfs_attr_set_int(
return (error); return (error);
} }
xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args.trans, dp);
xfs_trans_ihold(args.trans, dp);
/* /*
* If the attribute list is non-existent or a shortform list, * If the attribute list is non-existent or a shortform list,
@ -390,10 +389,8 @@ xfs_attr_set_int(
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args.trans, dp);
xfs_trans_ihold(args.trans, dp);
}
/* /*
* Commit the leaf transformation. We'll need another (linked) * Commit the leaf transformation. We'll need another (linked)
@ -538,8 +535,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
* No need to make quota reservations here. We expect to release some * No need to make quota reservations here. We expect to release some
* blocks not allocate in the common case. * blocks not allocate in the common case.
*/ */
xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args.trans, dp);
xfs_trans_ihold(args.trans, dp);
/* /*
* Decide on what work routines to call based on the inode size. * Decide on what work routines to call based on the inode size.
@ -815,8 +811,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
* No need to make quota reservations here. We expect to release some * No need to make quota reservations here. We expect to release some
* blocks, not allocate, in the common case. * blocks, not allocate, in the common case.
*/ */
xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(trans, dp);
xfs_trans_ihold(trans, dp);
/* /*
* Decide on what work routines to call based on the inode size. * Decide on what work routines to call based on the inode size.
@ -975,10 +970,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
/* /*
* Commit the current trans (including the inode) and start * Commit the current trans (including the inode) and start
@ -1079,10 +1072,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
* and started a new one. We need the inode to be * and started a new one. We need the inode to be
* in all transactions. * in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
} else } else
xfs_da_buf_done(bp); xfs_da_buf_done(bp);
@ -1155,10 +1146,8 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
} else } else
xfs_da_buf_done(bp); xfs_da_buf_done(bp);
return(0); return(0);
@ -1311,10 +1300,8 @@ xfs_attr_node_addname(xfs_da_args_t *args)
* and started a new one. We need the inode to be * and started a new one. We need the inode to be
* in all transactions. * in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
/* /*
* Commit the node conversion and start the next * Commit the node conversion and start the next
@ -1350,10 +1337,8 @@ xfs_attr_node_addname(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
} else { } else {
/* /*
* Addition succeeded, update Btree hashvals. * Addition succeeded, update Btree hashvals.
@ -1464,10 +1449,8 @@ xfs_attr_node_addname(xfs_da_args_t *args)
* and started a new one. We need the inode to be * and started a new one. We need the inode to be
* in all transactions. * in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
} }
/* /*
@ -1598,10 +1581,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
/* /*
* Commit the Btree join operation and start a new trans. * Commit the Btree join operation and start a new trans.
@ -1652,10 +1633,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
* and started a new one. We need the inode to be * and started a new one. We need the inode to be
* in all transactions. * in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
} else } else
xfs_da_brelse(args->trans, bp); xfs_da_brelse(args->trans, bp);
} }
@ -2093,10 +2072,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, dp);
xfs_trans_ihold(args->trans, dp);
}
ASSERT(nmap == 1); ASSERT(nmap == 1);
ASSERT((map.br_startblock != DELAYSTARTBLOCK) && ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
@ -2249,10 +2226,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started * bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions. * a new one. We need the inode to be in all transactions.
*/ */
if (committed) { if (committed)
xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(args->trans, args->dp);
xfs_trans_ihold(args->trans, args->dp);
}
/* /*
* Close out trans and start the next one in the chain. * Close out trans and start the next one in the chain.

View File

@ -3751,9 +3751,10 @@ xfs_bmap_add_attrfork(
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
} }
ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_d.di_anextents == 0);
IHOLD(ip);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
switch (ip->i_d.di_format) { switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_DEV: case XFS_DINODE_FMT_DEV:
ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;

View File

@ -416,11 +416,8 @@ xfs_swap_extents(
} }
IHOLD(ip); xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin_ref(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
IHOLD(tip);
xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_log_inode(tp, ip, ilf_fields); xfs_trans_log_inode(tp, ip, ilf_fields);
xfs_trans_log_inode(tp, tip, tilf_fields); xfs_trans_log_inode(tp, tip, tilf_fields);

View File

@ -622,8 +622,7 @@ xfs_fs_log_dummy(
ip = mp->m_rootip; ip = mp->m_rootip;
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_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0); error = xfs_trans_commit(tp, 0);

View File

@ -1456,7 +1456,7 @@ xfs_itruncate_finish(
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
ASSERT(ip->i_transp == *tp); ASSERT(ip->i_transp == *tp);
ASSERT(ip->i_itemp != NULL); ASSERT(ip->i_itemp != NULL);
ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD); ASSERT(ip->i_itemp->ili_lock_flags == 0);
ntp = *tp; ntp = *tp;
@ -1608,12 +1608,8 @@ xfs_itruncate_finish(
*/ */
error = xfs_bmap_finish(tp, &free_list, &committed); error = xfs_bmap_finish(tp, &free_list, &committed);
ntp = *tp; ntp = *tp;
if (committed) { if (committed)
/* link the inode into the next xact in the chain */ xfs_trans_ijoin(ntp, ip);
xfs_trans_ijoin(ntp, ip,
XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ihold(ntp, ip);
}
if (error) { if (error) {
/* /*
@ -1642,9 +1638,7 @@ xfs_itruncate_finish(
error = xfs_trans_commit(*tp, 0); error = xfs_trans_commit(*tp, 0);
*tp = ntp; *tp = ntp;
/* link the inode into the next transaction in the chain */ xfs_trans_ijoin(ntp, ip);
xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ihold(ntp, ip);
if (error) if (error)
return error; return error;

View File

@ -628,19 +628,10 @@ xfs_inode_item_unlock(
{ {
struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode_log_item *iip = INODE_ITEM(lip);
struct xfs_inode *ip = iip->ili_inode; struct xfs_inode *ip = iip->ili_inode;
uint hold; unsigned short lock_flags;
uint iolocked;
uint lock_flags;
ASSERT(iip != NULL);
ASSERT(iip->ili_inode->i_itemp != NULL); ASSERT(iip->ili_inode->i_itemp != NULL);
ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL));
ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
XFS_ILI_IOLOCKED_EXCL)) ||
xfs_isilocked(iip->ili_inode, XFS_IOLOCK_EXCL));
ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
XFS_ILI_IOLOCKED_SHARED)) ||
xfs_isilocked(iip->ili_inode, XFS_IOLOCK_SHARED));
/* /*
* Clear the transaction pointer in the inode. * Clear the transaction pointer in the inode.
@ -668,36 +659,11 @@ xfs_inode_item_unlock(
iip->ili_aextents_buf = NULL; iip->ili_aextents_buf = NULL;
} }
/* lock_flags = iip->ili_lock_flags;
* Figure out if we should unlock the inode or not. iip->ili_lock_flags = 0;
*/ if (lock_flags)
hold = iip->ili_flags & XFS_ILI_HOLD;
/*
* Before clearing out the flags, remember whether we
* are holding the inode's IO lock.
*/
iolocked = iip->ili_flags & XFS_ILI_IOLOCKED_ANY;
/*
* Clear out the fields of the inode log item particular
* to the current transaction.
*/
iip->ili_flags = 0;
/*
* Unlock the inode if XFS_ILI_HOLD was not set.
*/
if (!hold) {
lock_flags = XFS_ILOCK_EXCL;
if (iolocked & XFS_ILI_IOLOCKED_EXCL) {
lock_flags |= XFS_IOLOCK_EXCL;
} else if (iolocked & XFS_ILI_IOLOCKED_SHARED) {
lock_flags |= XFS_IOLOCK_SHARED;
}
xfs_iput(iip->ili_inode, lock_flags); xfs_iput(iip->ili_inode, lock_flags);
} }
}
/* /*
* This is called to find out where the oldest active copy of the * This is called to find out where the oldest active copy of the

View File

@ -103,12 +103,6 @@ typedef struct xfs_inode_log_format_64 {
XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
XFS_ILOG_ABROOT) XFS_ILOG_ABROOT)
#define XFS_ILI_HOLD 0x1
#define XFS_ILI_IOLOCKED_EXCL 0x2
#define XFS_ILI_IOLOCKED_SHARED 0x4
#define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED)
static inline int xfs_ilog_fbroot(int w) static inline int xfs_ilog_fbroot(int w)
{ {
return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
@ -137,7 +131,7 @@ typedef struct xfs_inode_log_item {
struct xfs_inode *ili_inode; /* inode ptr */ struct xfs_inode *ili_inode; /* inode ptr */
xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ xfs_lsn_t ili_flush_lsn; /* lsn at last flush */
xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ xfs_lsn_t ili_last_lsn; /* lsn at last transaction */
unsigned short ili_flags; /* misc flags */ unsigned short ili_lock_flags; /* lock flags */
unsigned short ili_logged; /* flushed logged data */ unsigned short ili_logged; /* flushed logged data */
unsigned int ili_last_fields; /* fields when flushed */ unsigned int ili_last_fields; /* fields when flushed */
struct xfs_bmbt_rec *ili_extents_buf; /* array of logged struct xfs_bmbt_rec *ili_extents_buf; /* array of logged

View File

@ -329,8 +329,7 @@ xfs_iomap_write_direct(
if (error) if (error)
goto error1; goto error1;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
bmapi_flag = XFS_BMAPI_WRITE; bmapi_flag = XFS_BMAPI_WRITE;
if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz)) if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
@ -597,8 +596,7 @@ xfs_iomap_write_allocate(
return XFS_ERROR(error); return XFS_ERROR(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_trans_ihold(tp, ip);
xfs_bmap_init(&free_list, &first_block); xfs_bmap_init(&free_list, &first_block);
@ -761,8 +759,7 @@ xfs_iomap_write_unwritten(
} }
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_trans_ihold(tp, ip);
/* /*
* Modify the unwritten extent state of the buffer. * Modify the unwritten extent state of the buffer.

View File

@ -169,26 +169,14 @@ xfs_rename(
/* /*
* Join all the inodes to the transaction. From this point on, * Join all the inodes to the transaction. From this point on,
* we can rely on either trans_commit or trans_cancel to unlock * we can rely on either trans_commit or trans_cancel to unlock
* them. Note that we need to add a vnode reference to the * them.
* directories since trans_commit & trans_cancel will decrement
* them when they unlock the inodes. Also, we need to be careful
* not to add an inode to the transaction more than once.
*/ */
IHOLD(src_dp); xfs_trans_ijoin_ref(tp, src_dp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); if (new_parent)
xfs_trans_ijoin_ref(tp, target_dp, XFS_ILOCK_EXCL);
if (new_parent) { xfs_trans_ijoin_ref(tp, src_ip, XFS_ILOCK_EXCL);
IHOLD(target_dp); if (target_ip)
xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); xfs_trans_ijoin_ref(tp, target_ip, XFS_ILOCK_EXCL);
}
IHOLD(src_ip);
xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
if (target_ip) {
IHOLD(target_ip);
xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
}
/* /*
* If we are using project inheritance, we only allow renames * If we are using project inheritance, we only allow renames

View File

@ -1892,7 +1892,6 @@ xfs_trans_roll(
if (error) if (error)
return error; return error;
xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); xfs_trans_ijoin(trans, dp);
xfs_trans_ihold(trans, dp);
return 0; return 0;
} }

View File

@ -475,8 +475,8 @@ void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *, int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
xfs_ino_t , uint, uint, struct xfs_inode **); xfs_ino_t , uint, uint, struct xfs_inode **);
void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint); void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint);
void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *); void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *);
void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);

View File

@ -33,6 +33,7 @@
#include "xfs_btree.h" #include "xfs_btree.h"
#include "xfs_trans_priv.h" #include "xfs_trans_priv.h"
#include "xfs_inode_item.h" #include "xfs_inode_item.h"
#include "xfs_trace.h"
#ifdef XFS_TRANS_DEBUG #ifdef XFS_TRANS_DEBUG
STATIC void STATIC void
@ -42,7 +43,6 @@ xfs_trans_inode_broot_debug(
#define xfs_trans_inode_broot_debug(ip) #define xfs_trans_inode_broot_debug(ip)
#endif #endif
/* /*
* Get an inode and join it to the transaction. * Get an inode and join it to the transaction.
*/ */
@ -58,32 +58,31 @@ xfs_trans_iget(
int error; int error;
error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp); error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp);
if (!error && tp) if (!error && tp) {
xfs_trans_ijoin(tp, *ipp, lock_flags); xfs_trans_ijoin(tp, *ipp);
(*ipp)->i_itemp->ili_lock_flags = lock_flags;
}
return error; return error;
} }
/* /*
* Add the locked inode to the transaction. * Add a locked inode to the transaction.
* The inode must be locked, and it cannot be associated with any *
* transaction. The caller must specify the locks already held * The inode must be locked, and it cannot be associated with any transaction.
* on the inode.
*/ */
void void
xfs_trans_ijoin( xfs_trans_ijoin(
xfs_trans_t *tp, struct xfs_trans *tp,
xfs_inode_t *ip, struct xfs_inode *ip)
uint lock_flags)
{ {
xfs_inode_log_item_t *iip; xfs_inode_log_item_t *iip;
ASSERT(ip->i_transp == NULL); ASSERT(ip->i_transp == NULL);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
ASSERT(lock_flags & XFS_ILOCK_EXCL);
if (ip->i_itemp == NULL) if (ip->i_itemp == NULL)
xfs_inode_item_init(ip, ip->i_mount); xfs_inode_item_init(ip, ip->i_mount);
iip = ip->i_itemp; iip = ip->i_itemp;
ASSERT(iip->ili_flags == 0); ASSERT(iip->ili_lock_flags == 0);
/* /*
* Get a log_item_desc to point at the new item. * Get a log_item_desc to point at the new item.
@ -92,15 +91,6 @@ xfs_trans_ijoin(
xfs_trans_inode_broot_debug(ip); xfs_trans_inode_broot_debug(ip);
/*
* If the IO lock is already held, mark that in the inode log item.
*/
if (lock_flags & XFS_IOLOCK_EXCL) {
iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL;
} else if (lock_flags & XFS_IOLOCK_SHARED) {
iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED;
}
/* /*
* Initialize i_transp so we can find it with xfs_inode_incore() * Initialize i_transp so we can find it with xfs_inode_incore()
* in xfs_trans_iget() above. * in xfs_trans_iget() above.
@ -108,27 +98,25 @@ xfs_trans_ijoin(
ip->i_transp = tp; ip->i_transp = tp;
} }
/* /*
* Mark the inode as not needing to be unlocked when the inode item's * Add a locked inode to the transaction.
* IOP_UNLOCK() routine is called. The inode must already be locked *
* and associated with the given transaction. *
* Grabs a reference to the inode which will be dropped when the transaction
* is commited. The inode will also be unlocked at that point. The inode
* must be locked, and it cannot be associated with any transaction.
*/ */
/*ARGSUSED*/
void void
xfs_trans_ihold( xfs_trans_ijoin_ref(
xfs_trans_t *tp, struct xfs_trans *tp,
xfs_inode_t *ip) struct xfs_inode *ip,
uint lock_flags)
{ {
ASSERT(ip->i_transp == tp); xfs_trans_ijoin(tp, ip);
ASSERT(ip->i_itemp != NULL); IHOLD(ip);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ip->i_itemp->ili_lock_flags = lock_flags;
ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
} }
/* /*
* This is called to mark the fields indicated in fieldmask as needing * This is called to mark the fields indicated in fieldmask as needing
* to be logged when the transaction is committed. The inode must * to be logged when the transaction is committed. The inode must

View File

@ -374,8 +374,8 @@ xfs_truncate_file(
* of references will stay constant. * of references will stay constant.
*/ */
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* Signal a sync xaction. The only case where that isn't * Signal a sync xaction. The only case where that isn't
* the case is if we're truncating an already unlinked file * the case is if we're truncating an already unlinked file

View File

@ -268,8 +268,7 @@ xfs_setattr(
commit_flags = XFS_TRANS_RELEASE_LOG_RES; commit_flags = XFS_TRANS_RELEASE_LOG_RES;
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, lock_flags); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* Only change the c/mtime if we are changing the size * Only change the c/mtime if we are changing the size
@ -319,8 +318,7 @@ xfs_setattr(
xfs_iflags_set(ip, XFS_ITRUNCATED); xfs_iflags_set(ip, XFS_ITRUNCATED);
} }
} else if (tp) { } else if (tp) {
xfs_trans_ijoin(tp, ip, lock_flags); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
} }
/* /*
@ -653,10 +651,7 @@ xfs_free_eofblocks(
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, xfs_trans_ijoin(tp, ip);
XFS_IOLOCK_EXCL |
XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
error = xfs_itruncate_finish(&tp, ip, error = xfs_itruncate_finish(&tp, ip,
ip->i_size, ip->i_size,
@ -728,8 +723,7 @@ xfs_inactive_symlink_rmt(
xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
size = (int)ip->i_d.di_size; size = (int)ip->i_d.di_size;
ip->i_d.di_size = 0; ip->i_d.di_size = 0;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
/* /*
* Find the block(s) so we can inval and unmap them. * Find the block(s) so we can inval and unmap them.
@ -773,8 +767,7 @@ xfs_inactive_symlink_rmt(
* Mark it dirty so it will be logged and moved forward in the log as * Mark it dirty so it will be logged and moved forward in the log as
* part of every commit. * part of every commit.
*/ */
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
/* /*
* Get a new, empty transaction to return to our caller. * Get a new, empty transaction to return to our caller.
@ -907,8 +900,7 @@ xfs_inactive_attrs(
goto error_cancel; goto error_cancel;
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
xfs_idestroy_fork(ip, XFS_ATTR_FORK); xfs_idestroy_fork(ip, XFS_ATTR_FORK);
ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_d.di_anextents == 0);
@ -1095,8 +1087,7 @@ xfs_inactive(
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* normally, we have to run xfs_itruncate_finish sync. * normally, we have to run xfs_itruncate_finish sync.
@ -1129,8 +1120,7 @@ xfs_inactive(
return VN_INACTIVE_CACHE; return VN_INACTIVE_CACHE;
} }
xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
} else { } else {
error = xfs_trans_reserve(tp, 0, error = xfs_trans_reserve(tp, 0,
XFS_IFREE_LOG_RES(mp), XFS_IFREE_LOG_RES(mp),
@ -1143,8 +1133,7 @@ xfs_inactive(
} }
xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
} }
/* /*
@ -1392,8 +1381,7 @@ xfs_create(
* the transaction cancel unlocking dp so don't do it explicitly in the * the transaction cancel unlocking dp so don't do it explicitly in the
* error path. * error path.
*/ */
IHOLD(dp); xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = B_FALSE; unlock_dp_on_error = B_FALSE;
error = xfs_dir_createname(tp, dp, name, ip->i_ino, error = xfs_dir_createname(tp, dp, name, ip->i_ino,
@ -1730,15 +1718,8 @@ xfs_remove(
xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
/* xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
* At this point, we've gotten both the directory and the entry xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
* inodes locked.
*/
IHOLD(ip);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
IHOLD(dp);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
/* /*
* If we're removing a directory perform some additional validation. * If we're removing a directory perform some additional validation.
@ -1884,15 +1865,8 @@ xfs_link(
xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
/* xfs_trans_ijoin_ref(tp, sip, XFS_ILOCK_EXCL);
* Increment vnode ref counts since xfs_trans_commit & xfs_trans_ijoin_ref(tp, tdp, XFS_ILOCK_EXCL);
* xfs_trans_cancel will both unlock the inodes and
* decrement the associated ref counts.
*/
IHOLD(sip);
IHOLD(tdp);
xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
/* /*
* If the source has too many links, we can't make any more to it. * If the source has too many links, we can't make any more to it.
@ -2087,8 +2061,7 @@ xfs_symlink(
* transaction cancel unlocking dp so don't do it explicitly in the * transaction cancel unlocking dp so don't do it explicitly in the
* error path. * error path.
*/ */
IHOLD(dp); xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = B_FALSE; unlock_dp_on_error = B_FALSE;
/* /*
@ -2227,13 +2200,12 @@ xfs_set_dmattrs(
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_ref(tp, ip, XFS_ILOCK_EXCL);
ip->i_d.di_dmevmask = evmask; ip->i_d.di_dmevmask = evmask;
ip->i_d.di_dmstate = state; ip->i_d.di_dmstate = state;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
IHOLD(ip);
error = xfs_trans_commit(tp, 0); error = xfs_trans_commit(tp, 0);
return error; return error;
@ -2366,8 +2338,7 @@ xfs_alloc_file_space(
if (error) if (error)
goto error1; goto error1;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* Issue the xfs_bmapi() call to allocate the blocks * Issue the xfs_bmapi() call to allocate the blocks
@ -2668,8 +2639,7 @@ xfs_free_file_space(
if (error) if (error)
goto error1; goto error1;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip);
xfs_trans_ihold(tp, ip);
/* /*
* issue the bunmapi() call to free the blocks * issue the bunmapi() call to free the blocks
@ -2839,8 +2809,7 @@ xfs_change_file_space(
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_trans_ihold(tp, ip);
if ((attr_flags & XFS_ATTR_DMI) == 0) { if ((attr_flags & XFS_ATTR_DMI) == 0) {
ip->i_d.di_mode &= ~S_ISUID; ip->i_d.di_mode &= ~S_ISUID;