⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xfs_trans_buf.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		  xfs_buf_t	*bp,		  uint		first,		  uint		last){	xfs_buf_log_item_t	*bip;	xfs_log_item_desc_t	*lidp;	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);	ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));	ASSERT((XFS_BUF_IODONE_FUNC(bp) == NULL) ||	       (XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks));	/*	 * Mark the buffer as needing to be written out eventually,	 * and set its iodone function to remove the buffer's buf log	 * item from the AIL and free it when the buffer is flushed	 * to disk.  See xfs_buf_attach_iodone() for more details	 * on li_cb and xfs_buf_iodone_callbacks().	 * If we end up aborting this transaction, we trap this buffer	 * inside the b_bdstrat callback so that this won't get written to	 * disk.	 */	XFS_BUF_DELAYWRITE(bp);	XFS_BUF_DONE(bp);	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);	ASSERT(atomic_read(&bip->bli_refcount) > 0);	XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks);	bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))xfs_buf_iodone;	/*	 * If we invalidated the buffer within this transaction, then	 * cancel the invalidation now that we're dirtying the buffer	 * again.  There are no races with the code in xfs_buf_item_unpin(),	 * because we have a reference to the buffer this entire time.	 */	if (bip->bli_flags & XFS_BLI_STALE) {		xfs_buf_item_trace("BLOG UNSTALE", bip);		bip->bli_flags &= ~XFS_BLI_STALE;		ASSERT(XFS_BUF_ISSTALE(bp));		XFS_BUF_UNSTALE(bp);		bip->bli_format.blf_flags &= ~XFS_BLI_CANCEL;	}	lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);	ASSERT(lidp != NULL);	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);	xfs_buf_item_trace("BLOG", bip);}/* * This called to invalidate a buffer that is being used within * a transaction.  Typically this is because the blocks in the * buffer are being freed, so we need to prevent it from being * written out when we're done.  Allowing it to be written again * might overwrite data in the free blocks if they are reallocated * to a file. * * We prevent the buffer from being written out by clearing the * B_DELWRI flag.  We can't always * get rid of the buf log item at this point, though, because * the buffer may still be pinned by another transaction.  If that * is the case, then we'll wait until the buffer is committed to * disk for the last time (we can tell by the ref count) and * free it in xfs_buf_item_unpin().  Until it is cleaned up we * will keep the buffer locked so that the buffer and buf log item * are not reused. */voidxfs_trans_binval(	xfs_trans_t	*tp,	xfs_buf_t	*bp){	xfs_log_item_desc_t	*lidp;	xfs_buf_log_item_t	*bip;	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);	lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);	ASSERT(lidp != NULL);	ASSERT(atomic_read(&bip->bli_refcount) > 0);	if (bip->bli_flags & XFS_BLI_STALE) {		/*		 * If the buffer is already invalidated, then		 * just return.		 */		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(lidp->lid_flags & XFS_LID_DIRTY);		ASSERT(tp->t_flags & XFS_TRANS_DIRTY);		xfs_buftrace("XFS_BINVAL RECUR", bp);		xfs_buf_item_trace("BINVAL RECUR", bip);		return;	}	/*	 * Clear the dirty bit in the buffer and set the STALE flag	 * 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	 * 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.	 * We mark the item descriptor and the transaction dirty so	 * that we'll hold the buffer until after the commit.	 *	 * Since we're invalidating the buffer, we also clear the state	 * about which parts of the buffer have been logged.  We also	 * clear the flag indicating that this is an inode buffer since	 * the data in the buffer will no longer be valid.	 *	 * We set the stale bit in the buffer as well since we're getting	 * rid of it.	 */	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;	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;	tp->t_flags |= XFS_TRANS_DIRTY;	xfs_buftrace("XFS_BINVAL", bp);	xfs_buf_item_trace("BINVAL", bip);}/* * 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. *//* ARGSUSED */voidxfs_trans_inode_buf(	xfs_trans_t	*tp,	xfs_buf_t	*bp){	xfs_buf_log_item_t	*bip;	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);	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;}/* * This call is used to indicate that the buffer is going to * be staled and was an inode buffer. This means it gets * special processing during unpin - where any inodes  * associated with the buffer should be removed from ail. * There is also special processing during recovery, * any replay of the inodes in the buffer needs to be * prevented as the buffer may have been reused. */voidxfs_trans_stale_inode_buf(	xfs_trans_t	*tp,	xfs_buf_t	*bp){	xfs_buf_log_item_t	*bip;	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);	ASSERT(atomic_read(&bip->bli_refcount) > 0);	bip->bli_flags |= XFS_BLI_STALE_INODE;	bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))		xfs_buf_iodone;}/* * Mark the buffer as being one which contains newly allocated * inodes.  We need to make sure that even if this buffer is * relogged as an 'inode buf' we still recover all of the inode * images in the face of a crash.  This works in coordination with * xfs_buf_item_committed() to ensure that the buffer remains in the * AIL at its original location even after it has been relogged. *//* ARGSUSED */voidxfs_trans_inode_alloc_buf(	xfs_trans_t	*tp,	xfs_buf_t	*bp){	xfs_buf_log_item_t	*bip;	ASSERT(XFS_BUF_ISBUSY(bp));	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);	ASSERT(atomic_read(&bip->bli_refcount) > 0);	bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;}/* * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of * dquots. However, unlike in inode buffer recovery, dquot buffers get * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag). * The only thing that makes dquot buffers different from regular * buffers is that we must not replay dquot bufs when recovering * if a _corresponding_ quotaoff has happened. We also have to distinguish * between usr dquot bufs and grp dquot bufs, because usr and grp quotas * can be turned off independently. *//* ARGSUSED */voidxfs_trans_dquot_buf(	xfs_trans_t	*tp,	xfs_buf_t	*bp,	uint		type){	xfs_buf_log_item_t	*bip;	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);	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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -