xfs: streamline xfs_attr3_leaf_inactive

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: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2020-01-14 14:31:49 -08:00
parent e8db2aafce
commit 0bb9d159bd
2 changed files with 32 additions and 84 deletions

View File

@ -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.
*========================================================================*/

View File

@ -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;
@ -69,8 +65,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;
@ -84,84 +80,45 @@ xfs_attr3_rmt_stale(
*/
STATIC int
xfs_attr3_leaf_inactive(
struct xfs_trans **trans,
struct xfs_inode *dp,
struct xfs_buf *bp)
struct xfs_trans **trans,
struct xfs_inode *dp,
struct xfs_buf *bp)
{
struct xfs_attr_leafblock *leaf;
struct xfs_attr3_icleaf_hdr ichdr;
struct xfs_attr_leaf_entry *entry;
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;
int error;
int i;
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 (!entry->nameidx || (entry->flags & XFS_ATTR_LOCAL))
continue;
name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
if (!name_rmt->valueblk)
continue;
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;
}
/*
* 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);
/*
* 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() */
/*
* 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 */
}
kmem_free(list);
xfs_trans_brelse(*trans, bp);
err:
return error;
}