diff options
Diffstat (limited to 'fs/xfs/xfs_trans_buf.c')
| -rw-r--r-- | fs/xfs/xfs_trans_buf.c | 233 | 
1 files changed, 70 insertions, 163 deletions
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index fb586360d1c9..63d81a22f4fd 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -40,11 +40,51 @@  #include "xfs_rw.h"  #include "xfs_trace.h" +/* + * Check to see if a buffer matching the given parameters is already + * a part of the given transaction. + */ +STATIC struct xfs_buf * +xfs_trans_buf_item_match( +	struct xfs_trans	*tp, +	struct xfs_buftarg	*target, +	xfs_daddr_t		blkno, +	int			len) +{ +	xfs_log_item_chunk_t	*licp; +	xfs_log_item_desc_t	*lidp; +	xfs_buf_log_item_t	*blip; +	int			i; + +	len = BBTOB(len); +	for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { +		if (xfs_lic_are_all_free(licp)) { +			ASSERT(licp == &tp->t_items); +			ASSERT(licp->lic_next == NULL); +			return NULL; +		} + +		for (i = 0; i < licp->lic_unused; i++) { +			/* +			 * Skip unoccupied slots. +			 */ +			if (xfs_lic_isfree(licp, i)) +				continue; + +			lidp = xfs_lic_slot(licp, i); +			blip = (xfs_buf_log_item_t *)lidp->lid_item; +			if (blip->bli_item.li_type != XFS_LI_BUF) +				continue; + +			if (XFS_BUF_TARGET(blip->bli_buf) == target && +			    XFS_BUF_ADDR(blip->bli_buf) == blkno && +			    XFS_BUF_COUNT(blip->bli_buf) == len) +				return blip->bli_buf; +		} +	} -STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *, -		xfs_daddr_t, int); -STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *, -		xfs_daddr_t, int); +	return NULL; +}  /*   * Add the locked buffer to the transaction. @@ -74,7 +114,7 @@ _xfs_trans_bjoin(  	xfs_buf_item_init(bp, tp->t_mountp);  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); -	ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL)); +	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));  	ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));  	if (reset_recur)  		bip->bli_recur = 0; @@ -112,14 +152,6 @@ xfs_trans_bjoin(   * within the transaction, just increment its lock recursion count   * and return a pointer to it.   * - * Use the fast path function xfs_trans_buf_item_match() or the buffer - * cache routine incore_match() to find the buffer - * if it is already owned by this transaction. - * - * If we don't already own the buffer, use get_buf() to get it. - * If it doesn't yet have an associated xfs_buf_log_item structure, - * then allocate one and add the item to this transaction. - *   * If the transaction pointer is NULL, make this just a normal   * get_buf() call.   */ @@ -149,11 +181,7 @@ xfs_trans_get_buf(xfs_trans_t	*tp,  	 * have it locked.  In this case we just increment the lock  	 * recursion count and return the buffer to the caller.  	 */ -	if (tp->t_items.lic_next == NULL) { -		bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); -	} else { -		bp  = xfs_trans_buf_item_match_all(tp, target_dev, blkno, len); -	} +	bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);  	if (bp != NULL) {  		ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);  		if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) @@ -259,14 +287,6 @@ int	xfs_error_mod = 33;   * within the transaction and already read in, just increment its   * lock recursion count and return a pointer to it.   * - * Use the fast path function xfs_trans_buf_item_match() or the buffer - * cache routine incore_match() to find the buffer - * if it is already owned by this transaction. - * - * If we don't already own the buffer, use read_buf() to get it. - * If it doesn't yet have an associated xfs_buf_log_item structure, - * then allocate one and add the item to this transaction. - *   * If the transaction pointer is NULL, make this just a normal   * read_buf() call.   */ @@ -328,11 +348,7 @@ xfs_trans_read_buf(  	 * If the buffer is not yet read in, then we read it in, increment  	 * the lock recursion count, and return it to the caller.  	 */ -	if (tp->t_items.lic_next == NULL) { -		bp = xfs_trans_buf_item_match(tp, target, blkno, len); -	} else { -		bp = xfs_trans_buf_item_match_all(tp, target, blkno, len); -	} +	bp = xfs_trans_buf_item_match(tp, target, blkno, len);  	if (bp != NULL) {  		ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);  		ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); @@ -495,7 +511,7 @@ xfs_trans_brelse(xfs_trans_t	*tp,  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(bip->bli_item.li_type == XFS_LI_BUF);  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); -	ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL)); +	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));  	ASSERT(atomic_read(&bip->bli_refcount) > 0);  	/* @@ -603,7 +619,7 @@ xfs_trans_bhold(xfs_trans_t	*tp,  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); -	ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL)); +	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));  	ASSERT(atomic_read(&bip->bli_refcount) > 0);  	bip->bli_flags |= XFS_BLI_HOLD;  	trace_xfs_trans_bhold(bip); @@ -625,7 +641,7 @@ xfs_trans_bhold_release(xfs_trans_t	*tp,  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); -	ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL)); +	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));  	ASSERT(atomic_read(&bip->bli_refcount) > 0);  	ASSERT(bip->bli_flags & XFS_BLI_HOLD);  	bip->bli_flags &= ~XFS_BLI_HOLD; @@ -688,7 +704,7 @@ xfs_trans_log_buf(xfs_trans_t	*tp,  		bip->bli_flags &= ~XFS_BLI_STALE;  		ASSERT(XFS_BUF_ISSTALE(bp));  		XFS_BUF_UNSTALE(bp); -		bip->bli_format.blf_flags &= ~XFS_BLI_CANCEL; +		bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL;  	}  	lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip); @@ -696,7 +712,6 @@ xfs_trans_log_buf(xfs_trans_t	*tp,  	tp->t_flags |= XFS_TRANS_DIRTY;  	lidp->lid_flags |= XFS_LID_DIRTY; -	lidp->lid_flags &= ~XFS_LID_BUF_STALE;  	bip->bli_flags |= XFS_BLI_LOGGED;  	xfs_buf_item_log(bip, first, last);  } @@ -747,8 +762,8 @@ xfs_trans_binval(  		ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));  		ASSERT(XFS_BUF_ISSTALE(bp));  		ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY))); -		ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_INODE_BUF)); -		ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); +		ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF)); +		ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);  		ASSERT(lidp->lid_flags & XFS_LID_DIRTY);  		ASSERT(tp->t_flags & XFS_TRANS_DIRTY);  		return; @@ -759,7 +774,7 @@ xfs_trans_binval(  	 * in the buf log item.  The STALE flag will be used in  	 * xfs_buf_item_unpin() to determine if it should clean up  	 * when the last reference to the buf item is given up. -	 * We set the XFS_BLI_CANCEL flag in the buf log format structure +	 * We set the XFS_BLF_CANCEL flag in the buf log format structure  	 * and log the buf item.  This will be used at recovery time  	 * to determine that copies of the buffer in the log before  	 * this should not be replayed. @@ -777,26 +792,26 @@ xfs_trans_binval(  	XFS_BUF_UNDELAYWRITE(bp);  	XFS_BUF_STALE(bp);  	bip->bli_flags |= XFS_BLI_STALE; -	bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_DIRTY); -	bip->bli_format.blf_flags &= ~XFS_BLI_INODE_BUF; -	bip->bli_format.blf_flags |= XFS_BLI_CANCEL; +	bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY); +	bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF; +	bip->bli_format.blf_flags |= XFS_BLF_CANCEL;  	memset((char *)(bip->bli_format.blf_data_map), 0,  	      (bip->bli_format.blf_map_size * sizeof(uint))); -	lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE; +	lidp->lid_flags |= XFS_LID_DIRTY;  	tp->t_flags |= XFS_TRANS_DIRTY;  }  /* - * This call is used to indicate that the buffer contains on-disk - * inodes which must be handled specially during recovery.  They - * require special handling because only the di_next_unlinked from - * the inodes in the buffer should be recovered.  The rest of the - * data in the buffer is logged via the inodes themselves. + * This call is used to indicate that the buffer contains on-disk inodes which + * must be handled specially during recovery.  They require special handling + * because only the di_next_unlinked from the inodes in the buffer should be + * recovered.  The rest of the data in the buffer is logged via the inodes + * themselves.   * - * All we do is set the XFS_BLI_INODE_BUF flag in the buffer's log - * format structure so that we'll know what to do at recovery time. + * All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be + * transferred to the buffer's log format structure so that we'll know what to + * do at recovery time.   */ -/* ARGSUSED */  void  xfs_trans_inode_buf(  	xfs_trans_t	*tp, @@ -811,7 +826,7 @@ xfs_trans_inode_buf(  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(atomic_read(&bip->bli_refcount) > 0); -	bip->bli_format.blf_flags |= XFS_BLI_INODE_BUF; +	bip->bli_flags |= XFS_BLI_INODE_BUF;  }  /* @@ -893,120 +908,12 @@ xfs_trans_dquot_buf(  	ASSERT(XFS_BUF_ISBUSY(bp));  	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);  	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); -	ASSERT(type == XFS_BLI_UDQUOT_BUF || -	       type == XFS_BLI_PDQUOT_BUF || -	       type == XFS_BLI_GDQUOT_BUF); +	ASSERT(type == XFS_BLF_UDQUOT_BUF || +	       type == XFS_BLF_PDQUOT_BUF || +	       type == XFS_BLF_GDQUOT_BUF);  	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);  	ASSERT(atomic_read(&bip->bli_refcount) > 0);  	bip->bli_format.blf_flags |= type;  } - -/* - * Check to see if a buffer matching the given parameters is already - * a part of the given transaction.  Only check the first, embedded - * chunk, since we don't want to spend all day scanning large transactions. - */ -STATIC xfs_buf_t * -xfs_trans_buf_item_match( -	xfs_trans_t	*tp, -	xfs_buftarg_t	*target, -	xfs_daddr_t	blkno, -	int		len) -{ -	xfs_log_item_chunk_t	*licp; -	xfs_log_item_desc_t	*lidp; -	xfs_buf_log_item_t	*blip; -	xfs_buf_t		*bp; -	int			i; - -	bp = NULL; -	len = BBTOB(len); -	licp = &tp->t_items; -	if (!xfs_lic_are_all_free(licp)) { -		for (i = 0; i < licp->lic_unused; i++) { -			/* -			 * Skip unoccupied slots. -			 */ -			if (xfs_lic_isfree(licp, i)) { -				continue; -			} - -			lidp = xfs_lic_slot(licp, i); -			blip = (xfs_buf_log_item_t *)lidp->lid_item; -			if (blip->bli_item.li_type != XFS_LI_BUF) { -				continue; -			} - -			bp = blip->bli_buf; -			if ((XFS_BUF_TARGET(bp) == target) && -			    (XFS_BUF_ADDR(bp) == blkno) && -			    (XFS_BUF_COUNT(bp) == len)) { -				/* -				 * We found it.  Break out and -				 * return the pointer to the buffer. -				 */ -				break; -			} else { -				bp = NULL; -			} -		} -	} -	return bp; -} - -/* - * Check to see if a buffer matching the given parameters is already - * a part of the given transaction.  Check all the chunks, we - * want to be thorough. - */ -STATIC xfs_buf_t * -xfs_trans_buf_item_match_all( -	xfs_trans_t	*tp, -	xfs_buftarg_t	*target, -	xfs_daddr_t	blkno, -	int		len) -{ -	xfs_log_item_chunk_t	*licp; -	xfs_log_item_desc_t	*lidp; -	xfs_buf_log_item_t	*blip; -	xfs_buf_t		*bp; -	int			i; - -	bp = NULL; -	len = BBTOB(len); -	for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { -		if (xfs_lic_are_all_free(licp)) { -			ASSERT(licp == &tp->t_items); -			ASSERT(licp->lic_next == NULL); -			return NULL; -		} -		for (i = 0; i < licp->lic_unused; i++) { -			/* -			 * Skip unoccupied slots. -			 */ -			if (xfs_lic_isfree(licp, i)) { -				continue; -			} - -			lidp = xfs_lic_slot(licp, i); -			blip = (xfs_buf_log_item_t *)lidp->lid_item; -			if (blip->bli_item.li_type != XFS_LI_BUF) { -				continue; -			} - -			bp = blip->bli_buf; -			if ((XFS_BUF_TARGET(bp) == target) && -			    (XFS_BUF_ADDR(bp) == blkno) && -			    (XFS_BUF_COUNT(bp) == len)) { -				/* -				 * We found it.  Break out and -				 * return the pointer to the buffer. -				 */ -				return bp; -			} -		} -	} -	return NULL; -}  |