Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ff41b8d authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Greg Kroah-Hartman
Browse files

xfs: streamline xfs_attr3_leaf_inactive



commit 0bb9d159bd018b271e783d3b2d3bc82fa0727321 upstream.

Now that we know we don't have to take a transaction to stale the incore
buffers for a remote value, get rid of the unnecessary memory allocation
in the leaf walker and call the rmt_stale function directly.  Flatten
the loop while we're at it.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandan.babu@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c893feda
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -39,15 +39,6 @@ struct xfs_attr3_icleaf_hdr {
	} freemap[XFS_ATTR_LEAF_MAPSIZE];
};

/*
 * Used to keep a list of "remote value" extents when unlinking an inode.
 */
typedef struct xfs_attr_inactive_list {
	xfs_dablk_t	valueblk;	/* block number of value bytes */
	int		valuelen;	/* number of bytes in value */
} xfs_attr_inactive_list_t;


/*========================================================================
 * Function prototypes for the kernel.
 *========================================================================*/
+29 −72
Original line number Diff line number Diff line
@@ -37,8 +37,6 @@ xfs_attr3_rmt_stale(
	int			blkcnt)
{
	struct xfs_bmbt_irec	map;
	xfs_dablk_t		tblkno;
	int			tblkcnt;
	int			nmap;
	int			error;

@@ -46,14 +44,12 @@ xfs_attr3_rmt_stale(
	 * Roll through the "value", invalidating the attribute value's
	 * blocks.
	 */
	tblkno = blkno;
	tblkcnt = blkcnt;
	while (tblkcnt > 0) {
	while (blkcnt > 0) {
		/*
		 * Try to remember where we decided to put the value.
		 */
		nmap = 1;
		error = xfs_bmapi_read(dp, (xfs_fileoff_t)tblkno, tblkcnt,
		error = xfs_bmapi_read(dp, (xfs_fileoff_t)blkno, blkcnt,
				       &map, &nmap, XFS_BMAPI_ATTRFORK);
		if (error)
			return error;
@@ -68,8 +64,8 @@ xfs_attr3_rmt_stale(
		if (error)
			return error;

		tblkno += map.br_blockcount;
		tblkcnt -= map.br_blockcount;
		blkno += map.br_blockcount;
		blkcnt -= map.br_blockcount;
	}

	return 0;
@@ -87,80 +83,41 @@ xfs_attr3_leaf_inactive(
	struct xfs_inode		*dp,
	struct xfs_buf			*bp)
{
	struct xfs_attr_leafblock *leaf;
	struct xfs_attr3_icleaf_hdr	ichdr;
	struct xfs_mount		*mp = bp->b_mount;
	struct xfs_attr_leafblock	*leaf = bp->b_addr;
	struct xfs_attr_leaf_entry	*entry;
	struct xfs_attr_leaf_name_remote *name_rmt;
	struct xfs_attr_inactive_list *list;
	struct xfs_attr_inactive_list *lp;
	int				error;
	int			count;
	int			size;
	int			tmp;
	int				i;
	struct xfs_mount	*mp = bp->b_mount;

	leaf = bp->b_addr;
	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);

	/*
	 * Count the number of "remote" value extents.
	 * Find the remote value extents for this leaf and invalidate their
	 * incore buffers.
	 */
	count = 0;
	entry = xfs_attr3_leaf_entryp(leaf);
	for (i = 0; i < ichdr.count; entry++, i++) {
		if (be16_to_cpu(entry->nameidx) &&
		    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
			name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
			if (name_rmt->valueblk)
				count++;
		}
	}
		int		blkcnt;

	/*
	 * If there are no "remote" values, we're done.
	 */
	if (count == 0) {
		xfs_trans_brelse(*trans, bp);
		return 0;
	}

	/*
	 * Allocate storage for a list of all the "remote" value extents.
	 */
	size = count * sizeof(xfs_attr_inactive_list_t);
	list = kmem_alloc(size, 0);
		if (!entry->nameidx || (entry->flags & XFS_ATTR_LOCAL))
			continue;

	/*
	 * Identify each of the "remote" value extents.
	 */
	lp = list;
	entry = xfs_attr3_leaf_entryp(leaf);
	for (i = 0; i < ichdr.count; entry++, i++) {
		if (be16_to_cpu(entry->nameidx) &&
		    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
		name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
			if (name_rmt->valueblk) {
				lp->valueblk = be32_to_cpu(name_rmt->valueblk);
				lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
						    be32_to_cpu(name_rmt->valuelen));
				lp++;
			}
		}
	}
	xfs_trans_brelse(*trans, bp);	/* unlock for trans. in freextent() */
		if (!name_rmt->valueblk)
			continue;

	/*
	 * Invalidate each of the "remote" value extents.
	 */
	error = 0;
	for (lp = list, i = 0; i < count; i++, lp++) {
		tmp = xfs_attr3_rmt_stale(dp, lp->valueblk, lp->valuelen);
		if (error == 0)
			error = tmp;	/* save only the 1st errno */
		blkcnt = xfs_attr3_rmt_blocks(dp->i_mount,
				be32_to_cpu(name_rmt->valuelen));
		error = xfs_attr3_rmt_stale(dp,
				be32_to_cpu(name_rmt->valueblk), blkcnt);
		if (error)
			goto err;
	}

	kmem_free(list);
	xfs_trans_brelse(*trans, bp);
err:
	return error;
}