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

📄 xfs_inode_item.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IBROOT);			vecp++;			nvecs++;			iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;		}		break;	case XFS_DINODE_FMT_LOCAL:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |			  XFS_ILOG_DEV | XFS_ILOG_UUID)));		if (iip->ili_format.ilf_fields & XFS_ILOG_DDATA) {			ASSERT(ip->i_df.if_bytes > 0);			ASSERT(ip->i_df.if_u1.if_data != NULL);			ASSERT(ip->i_d.di_size > 0);			vecp->i_addr = (xfs_caddr_t)ip->i_df.if_u1.if_data;			/*			 * Round i_bytes up to a word boundary.			 * The underlying memory is guaranteed to			 * to be there by xfs_idata_realloc().			 */			data_bytes = roundup(ip->i_df.if_bytes, 4);			ASSERT((ip->i_df.if_real_bytes == 0) ||			       (ip->i_df.if_real_bytes == data_bytes));			vecp->i_len = (int)data_bytes;			XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ILOCAL);			vecp++;			nvecs++;			iip->ili_format.ilf_dsize = (unsigned)data_bytes;		}		break;	case XFS_DINODE_FMT_DEV:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |			  XFS_ILOG_DDATA | XFS_ILOG_UUID)));		if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {			iip->ili_format.ilf_u.ilfu_rdev =				ip->i_df.if_u2.if_rdev;		}		break;	case XFS_DINODE_FMT_UUID:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT |			  XFS_ILOG_DDATA | XFS_ILOG_DEV)));		if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) {			iip->ili_format.ilf_u.ilfu_uuid =				ip->i_df.if_u2.if_uuid;		}		break;	default:		ASSERT(0);		break;	}	/*	 * If there are no attributes associated with the file,	 * then we're done.	 * Assert that no attribute-related log flags are set.	 */	if (!XFS_IFORK_Q(ip)) {		ASSERT(nvecs == iip->ili_item.li_desc->lid_size);		iip->ili_format.ilf_size = nvecs;		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT)));		return;	}	switch (ip->i_d.di_aformat) {	case XFS_DINODE_FMT_EXTENTS:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_ADATA | XFS_ILOG_ABROOT)));		if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) {			ASSERT(ip->i_afp->if_bytes > 0);			ASSERT(ip->i_afp->if_u1.if_extents != NULL);			ASSERT(ip->i_d.di_anextents > 0);#ifdef DEBUG			nrecs = ip->i_afp->if_bytes /				(uint)sizeof(xfs_bmbt_rec_t);#endif			ASSERT(nrecs > 0);			ASSERT(nrecs == ip->i_d.di_anextents);#ifdef XFS_NATIVE_HOST			/*			 * There are not delayed allocation extents			 * for attributes, so just point at the array.			 */			vecp->i_addr = (char *)(ip->i_afp->if_u1.if_extents);			vecp->i_len = ip->i_afp->if_bytes;#else			ASSERT(iip->ili_aextents_buf == NULL);			/*			 * Need to endian flip before logging			 */			ext_buffer = kmem_alloc(ip->i_afp->if_bytes,				KM_SLEEP);			iip->ili_aextents_buf = ext_buffer;			vecp->i_addr = (xfs_caddr_t)ext_buffer;			vecp->i_len = xfs_iextents_copy(ip, ext_buffer,					XFS_ATTR_FORK);#endif			XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_EXT);			iip->ili_format.ilf_asize = vecp->i_len;			vecp++;			nvecs++;		}		break;	case XFS_DINODE_FMT_BTREE:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_ADATA | XFS_ILOG_AEXT)));		if (iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) {			ASSERT(ip->i_afp->if_broot_bytes > 0);			ASSERT(ip->i_afp->if_broot != NULL);			vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot;			vecp->i_len = ip->i_afp->if_broot_bytes;			XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_BROOT);			vecp++;			nvecs++;			iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;		}		break;	case XFS_DINODE_FMT_LOCAL:		ASSERT(!(iip->ili_format.ilf_fields &			 (XFS_ILOG_ABROOT | XFS_ILOG_AEXT)));		if (iip->ili_format.ilf_fields & XFS_ILOG_ADATA) {			ASSERT(ip->i_afp->if_bytes > 0);			ASSERT(ip->i_afp->if_u1.if_data != NULL);			vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_u1.if_data;			/*			 * Round i_bytes up to a word boundary.			 * The underlying memory is guaranteed to			 * to be there by xfs_idata_realloc().			 */			data_bytes = roundup(ip->i_afp->if_bytes, 4);			ASSERT((ip->i_afp->if_real_bytes == 0) ||			       (ip->i_afp->if_real_bytes == data_bytes));			vecp->i_len = (int)data_bytes;			XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_LOCAL);			vecp++;			nvecs++;			iip->ili_format.ilf_asize = (unsigned)data_bytes;		}		break;	default:		ASSERT(0);		break;	}	ASSERT(nvecs == iip->ili_item.li_desc->lid_size);	iip->ili_format.ilf_size = nvecs;}/* * This is called to pin the inode associated with the inode log * item in memory so it cannot be written out.  Do this by calling * xfs_ipin() to bump the pin count in the inode while holding the * inode pin lock. */STATIC voidxfs_inode_item_pin(	xfs_inode_log_item_t	*iip){	ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE));	xfs_ipin(iip->ili_inode);}/* * This is called to unpin the inode associated with the inode log * item which was previously pinned with a call to xfs_inode_item_pin(). * Just call xfs_iunpin() on the inode to do this. *//* ARGSUSED */STATIC voidxfs_inode_item_unpin(	xfs_inode_log_item_t	*iip,	int			stale){	xfs_iunpin(iip->ili_inode);}/* ARGSUSED */STATIC voidxfs_inode_item_unpin_remove(	xfs_inode_log_item_t	*iip,	xfs_trans_t		*tp){	xfs_iunpin(iip->ili_inode);}/* * This is called to attempt to lock the inode associated with this * inode log item, in preparation for the push routine which does the actual * iflush.  Don't sleep on the inode lock or the flush lock. * * If the flush lock is already held, indicating that the inode has * been or is in the process of being flushed, then (ideally) we'd like to * see if the inode's buffer is still incore, and if so give it a nudge. * We delay doing so until the pushbuf routine, though, to avoid holding * the AIL lock across a call to the blackhole which is the buffer cache. * Also we don't want to sleep in any device strategy routines, which can happen * if we do the subsequent bawrite in here. */STATIC uintxfs_inode_item_trylock(	xfs_inode_log_item_t	*iip){	register xfs_inode_t	*ip;	ip = iip->ili_inode;	if (xfs_ipincount(ip) > 0) {		return XFS_ITEM_PINNED;	}	if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {		return XFS_ITEM_LOCKED;	}	if (!xfs_iflock_nowait(ip)) {		/*		 * If someone else isn't already trying to push the inode		 * buffer, we get to do it.		 */		if (iip->ili_pushbuf_flag == 0) {			iip->ili_pushbuf_flag = 1;#ifdef DEBUG			iip->ili_push_owner = current_pid();#endif			/*			 * Inode is left locked in shared mode.			 * Pushbuf routine gets to unlock it.			 */			return XFS_ITEM_PUSHBUF;		} else {			/*			 * We hold the AIL_LOCK, so we must specify the			 * NONOTIFY flag so that we won't double trip.			 */			xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);			return XFS_ITEM_FLUSHING;		}		/* NOTREACHED */	}	/* Stale items should force out the iclog */	if (ip->i_flags & XFS_ISTALE) {		xfs_ifunlock(ip);		xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);		return XFS_ITEM_PINNED;	}#ifdef DEBUG	if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {		ASSERT(iip->ili_format.ilf_fields != 0);		ASSERT(iip->ili_logged == 0);		ASSERT(iip->ili_item.li_flags & XFS_LI_IN_AIL);	}#endif	return XFS_ITEM_SUCCESS;}/* * Unlock the inode associated with the inode log item. * Clear the fields of the inode and inode log item that * are specific to the current transaction.  If the * hold flags is set, do not unlock the inode. */STATIC voidxfs_inode_item_unlock(	xfs_inode_log_item_t	*iip){	uint		hold;	uint		iolocked;	uint		lock_flags;	xfs_inode_t	*ip;	ASSERT(iip != NULL);	ASSERT(iip->ili_inode->i_itemp != NULL);	ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE));	ASSERT((!(iip->ili_inode->i_itemp->ili_flags &		  XFS_ILI_IOLOCKED_EXCL)) ||	       ismrlocked(&(iip->ili_inode->i_iolock), MR_UPDATE));	ASSERT((!(iip->ili_inode->i_itemp->ili_flags &		  XFS_ILI_IOLOCKED_SHARED)) ||	       ismrlocked(&(iip->ili_inode->i_iolock), MR_ACCESS));	/*	 * Clear the transaction pointer in the inode.	 */	ip = iip->ili_inode;	ip->i_transp = NULL;	/*	 * If the inode needed a separate buffer with which to log	 * its extents, then free it now.	 */	if (iip->ili_extents_buf != NULL) {		ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);		ASSERT(ip->i_d.di_nextents > 0);		ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_DEXT);		ASSERT(ip->i_df.if_bytes > 0);		kmem_free(iip->ili_extents_buf, ip->i_df.if_bytes);		iip->ili_extents_buf = NULL;	}	if (iip->ili_aextents_buf != NULL) {		ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);		ASSERT(ip->i_d.di_anextents > 0);		ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_AEXT);		ASSERT(ip->i_afp->if_bytes > 0);		kmem_free(iip->ili_aextents_buf, ip->i_afp->if_bytes);		iip->ili_aextents_buf = NULL;	}	/*	 * Figure out if we should unlock the inode or not.	 */	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_ilock_recur = 0;	iip->ili_iolock_recur = 0;	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);	}}/* * This is called to find out where the oldest active copy of the * inode log item in the on disk log resides now that the last log * write of it completed at the given lsn.  Since we always re-log * all dirty data in an inode, the latest copy in the on disk log * is the only one that matters.  Therefore, simply return the * given lsn. *//*ARGSUSED*/STATIC xfs_lsn_txfs_inode_item_committed(	xfs_inode_log_item_t	*iip,	xfs_lsn_t		lsn){	return (lsn);}/* * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK

⌨️ 快捷键说明

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