From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from aserp1040.oracle.com ([141.146.126.69]:31666 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750974AbdJZFt1 (ORCPT ); Thu, 26 Oct 2017 01:49:27 -0400 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v9Q5nQik015708 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 26 Oct 2017 05:49:26 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v9Q5nPAb021130 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 26 Oct 2017 05:49:26 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id v9Q5nPTZ015209 for ; Thu, 26 Oct 2017 05:49:25 GMT Subject: [PATCH 1/4] xfs: refactor extended attribute list operation From: "Darrick J. Wong" Date: Wed, 25 Oct 2017 22:49:24 -0700 Message-ID: <150899696463.18095.9642473908739425678.stgit@magnolia> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-xfs-owner@vger.kernel.org List-ID: List-Id: xfs To: linux-xfs@vger.kernel.org, darrick.wong@oracle.com From: Darrick J. Wong When we're iterating the attribute list and we can't find our previous location based off the attribute cursor, we'll instead walk down the attribute btree from the root trying to find where we left off. Move this code into a separate function for later cleanups. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_attr_list.c | 136 ++++++++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 52 deletions(-) diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 5816786..48423eb 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -204,19 +204,89 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) return 0; } +/* + * We didn't find the block & hash mentioned in the cursor state, so + * walk down the attr btree looking for the hash. + */ STATIC int -xfs_attr_node_list(xfs_attr_list_context_t *context) +xfs_attr_node_list_lookup( + struct xfs_attr_list_context *context, + struct attrlist_cursor_kern *cursor, + struct xfs_buf **pbp) { - attrlist_cursor_kern_t *cursor; - xfs_attr_leafblock_t *leaf; - xfs_da_intnode_t *node; - struct xfs_attr3_icleaf_hdr leafhdr; - struct xfs_da3_icnode_hdr nodehdr; - struct xfs_da_node_entry *btree; - int error, i; - struct xfs_buf *bp; - struct xfs_inode *dp = context->dp; - struct xfs_mount *mp = dp->i_mount; + struct xfs_da3_icnode_hdr nodehdr; + struct xfs_da_intnode *node; + struct xfs_da_node_entry *btree; + struct xfs_inode *dp = context->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_trans *tp = context->tp; + int i; + int error = 0; + uint16_t magic; + + ASSERT(*pbp == NULL); + cursor->blkno = 0; + for (;;) { + error = xfs_da3_node_read(tp, dp, cursor->blkno, -1, pbp, + XFS_ATTR_FORK); + if (error) + return error; + node = (*pbp)->b_addr; + magic = be16_to_cpu(node->hdr.info.magic); + switch (magic) { + case XFS_ATTR_LEAF_MAGIC: + case XFS_ATTR3_LEAF_MAGIC: + goto found_leaf; + case XFS_DA_NODE_MAGIC: + case XFS_DA3_NODE_MAGIC: + /* process btree node below */ + break; + default: + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + node); + goto out_corruptbuf; + } + + dp->d_ops->node_hdr_from_disk(&nodehdr, node); + + btree = dp->d_ops->node_tree_p(node); + for (i = 0; i < nodehdr.count; btree++, i++) { + if (cursor->hashval <= be32_to_cpu(btree->hashval)) { + cursor->blkno = be32_to_cpu(btree->before); + trace_xfs_attr_list_node_descend(context, + btree); + break; + } + } + if (i == nodehdr.count) + goto out_buf; + + xfs_trans_brelse(tp, *pbp); + } + +found_leaf: + return error; + +out_corruptbuf: + error = -EFSCORRUPTED; +out_buf: + xfs_trans_brelse(tp, *pbp); + *pbp = NULL; + return error; +} + +STATIC int +xfs_attr_node_list( + struct xfs_attr_list_context *context) +{ + struct xfs_attr3_icleaf_hdr leafhdr; + struct attrlist_cursor_kern *cursor; + struct xfs_attr_leafblock *leaf; + struct xfs_da_intnode *node; + struct xfs_buf *bp; + struct xfs_inode *dp = context->dp; + struct xfs_mount *mp = dp->i_mount; + int error; trace_xfs_attr_node_list(context); @@ -277,47 +347,9 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) * Note that start of node block is same as start of leaf block. */ if (bp == NULL) { - cursor->blkno = 0; - for (;;) { - uint16_t magic; - - error = xfs_da3_node_read(context->tp, dp, - cursor->blkno, -1, &bp, - XFS_ATTR_FORK); - if (error) - return error; - node = bp->b_addr; - magic = be16_to_cpu(node->hdr.info.magic); - if (magic == XFS_ATTR_LEAF_MAGIC || - magic == XFS_ATTR3_LEAF_MAGIC) - break; - if (magic != XFS_DA_NODE_MAGIC && - magic != XFS_DA3_NODE_MAGIC) { - XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)", - XFS_ERRLEVEL_LOW, - context->dp->i_mount, - node); - xfs_trans_brelse(context->tp, bp); - return -EFSCORRUPTED; - } - - dp->d_ops->node_hdr_from_disk(&nodehdr, node); - btree = dp->d_ops->node_tree_p(node); - for (i = 0; i < nodehdr.count; btree++, i++) { - if (cursor->hashval - <= be32_to_cpu(btree->hashval)) { - cursor->blkno = be32_to_cpu(btree->before); - trace_xfs_attr_list_node_descend(context, - btree); - break; - } - } - if (i == nodehdr.count) { - xfs_trans_brelse(context->tp, bp); - return 0; - } - xfs_trans_brelse(context->tp, bp); - } + error = xfs_attr_node_list_lookup(context, cursor, &bp); + if (error || !bp) + return error; } ASSERT(bp != NULL);