Commit 8edbb26b authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: refactor remote attr value buffer invalidation



Hoist the code that invalidates remote extended attribute value buffers
into a separate helper function.  This prepares us for a memory
corruption fix in the next patch.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 7b53b868
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -552,6 +552,33 @@ xfs_attr_rmtval_set(
	return 0;
}

/* Mark stale any incore buffers for the remote value. */
int
xfs_attr_rmtval_stale(
	struct xfs_inode	*ip,
	struct xfs_bmbt_irec	*map,
	xfs_buf_flags_t		incore_flags)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_buf		*bp;

	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));

	if (XFS_IS_CORRUPT(mp, map->br_startblock == DELAYSTARTBLOCK) ||
	    XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK))
		return -EFSCORRUPTED;

	bp = xfs_buf_incore(mp->m_ddev_targp,
			XFS_FSB_TO_DADDR(mp, map->br_startblock),
			XFS_FSB_TO_BB(mp, map->br_blockcount), incore_flags);
	if (bp) {
		xfs_buf_stale(bp);
		xfs_buf_relse(bp);
	}

	return 0;
}

/*
 * Remove the value associated with an attribute by deleting the
 * out-of-line buffer that it is stored on.
@@ -560,7 +587,6 @@ int
xfs_attr_rmtval_remove(
	struct xfs_da_args	*args)
{
	struct xfs_mount	*mp = args->dp->i_mount;
	xfs_dablk_t		lblkno;
	int			blkcnt;
	int			error;
@@ -575,9 +601,6 @@ xfs_attr_rmtval_remove(
	blkcnt = args->rmtblkcnt;
	while (blkcnt > 0) {
		struct xfs_bmbt_irec	map;
		struct xfs_buf		*bp;
		xfs_daddr_t		dblkno;
		int			dblkcnt;
		int			nmap;

		/*
@@ -588,22 +611,11 @@ xfs_attr_rmtval_remove(
				       blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK);
		if (error)
			return error;
		ASSERT(nmap == 1);
		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
		       (map.br_startblock != HOLESTARTBLOCK));

		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
		dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);

		/*
		 * If the "remote" value is in the cache, remove it.
		 */
		bp = xfs_buf_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK);
		if (bp) {
			xfs_buf_stale(bp);
			xfs_buf_relse(bp);
			bp = NULL;
		}
		if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1))
			return -EFSCORRUPTED;
		error = xfs_attr_rmtval_stale(args->dp, &map, XBF_TRYLOCK);
		if (error)
			return error;

		lblkno += map.br_blockcount;
		blkcnt -= map.br_blockcount;
+2 −0
Original line number Diff line number Diff line
@@ -11,5 +11,7 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
int xfs_attr_rmtval_get(struct xfs_da_args *args);
int xfs_attr_rmtval_set(struct xfs_da_args *args);
int xfs_attr_rmtval_remove(struct xfs_da_args *args);
int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
		xfs_buf_flags_t incore_flags);

#endif /* __XFS_ATTR_REMOTE_H__ */