Message ID | 146612636805.12839.15108503251791000478.stgit@birch.djwong.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Jun 16, 2016 at 06:19:28PM -0700, Darrick J. Wong wrote: > Refactor the btree_change_owner function into a more generic apparatus > which visits all blocks in a btree. We'll use this in a subsequent > patch for counting btree blocks for AG reservations. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > fs/xfs/libxfs/xfs_btree.c | 141 +++++++++++++++++++++++++++++---------------- > fs/xfs/libxfs/xfs_btree.h | 5 ++ > 2 files changed, 96 insertions(+), 50 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c > index 5f5cf23..eac876a 100644 > --- a/fs/xfs/libxfs/xfs_btree.c > +++ b/fs/xfs/libxfs/xfs_btree.c > @@ -4289,6 +4289,81 @@ xfs_btree_get_rec( > return 0; > } > > +/* Visit a block in a btree. */ > +STATIC int > +xfs_btree_visit_block( > + struct xfs_btree_cur *cur, > + int level, > + xfs_btree_visit_blocks_fn fn, > + void *data) > +{ > + struct xfs_btree_block *block; > + struct xfs_buf *bp; > + union xfs_btree_ptr rptr; > + int error; > + > + /* do right sibling readahead */ > + xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); > + block = xfs_btree_get_block(cur, level, &bp); > + > + /* process the block */ > + error = fn(cur, level, data); > + if (error) > + return error; > + > + /* now read rh sibling block for next iteration */ > + xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); > + if (xfs_btree_ptr_is_null(cur, &rptr)) > + return -ENOENT; > + > + return xfs_btree_lookup_get_block(cur, level, &rptr, &block); > +} > + > + > +/* Visit every block in a btree. */ > +int > +xfs_btree_visit_blocks( > + struct xfs_btree_cur *cur, > + xfs_btree_visit_blocks_fn fn, > + void *data) > +{ > + union xfs_btree_ptr lptr; > + int level; > + struct xfs_btree_block *block = NULL; > + int error = 0; > + > + cur->bc_ops->init_ptr_from_cur(cur, &lptr); > + > + /* for each level */ > + for (level = cur->bc_nlevels - 1; level >= 0; level--) { > + /* grab the left hand block */ > + error = xfs_btree_lookup_get_block(cur, level, &lptr, &block); > + if (error) > + return error; > + > + /* readahead the left most block for the next level down */ > + if (level > 0) { > + union xfs_btree_ptr *ptr; > + > + ptr = xfs_btree_ptr_addr(cur, 1, block); > + xfs_btree_readahead_ptr(cur, ptr, 1); > + > + /* save for the next iteration of the loop */ > + lptr = *ptr; > + } > + > + /* for each buffer in the level */ > + do { > + error = xfs_btree_visit_block(cur, level, fn, data); > + } while (!error); > + > + if (error != -ENOENT) > + return error; > + } > + > + return 0; > +} > + > /* > * Change the owner of a btree. > * > @@ -4313,26 +4388,27 @@ xfs_btree_get_rec( > * just queue the modified buffer as delayed write buffer so the transaction > * recovery completion writes the changes to disk. > */ > +struct xfs_btree_block_change_owner_info { > + __uint64_t new_owner; > + struct list_head *buffer_list; > +}; > + > static int > xfs_btree_block_change_owner( > struct xfs_btree_cur *cur, > int level, > - __uint64_t new_owner, > - struct list_head *buffer_list) > + void *data) > { > + struct xfs_btree_block_change_owner_info *bbcoi = data; > struct xfs_btree_block *block; > struct xfs_buf *bp; > - union xfs_btree_ptr rptr; > - > - /* do right sibling readahead */ > - xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); > > /* modify the owner */ > block = xfs_btree_get_block(cur, level, &bp); > if (cur->bc_flags & XFS_BTREE_LONG_PTRS) > - block->bb_u.l.bb_owner = cpu_to_be64(new_owner); > + block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner); > else > - block->bb_u.s.bb_owner = cpu_to_be32(new_owner); > + block->bb_u.s.bb_owner = cpu_to_be32(bbcoi->new_owner); > > /* > * If the block is a root block hosted in an inode, we might not have a > @@ -4346,19 +4422,14 @@ xfs_btree_block_change_owner( > xfs_trans_ordered_buf(cur->bc_tp, bp); > xfs_btree_log_block(cur, bp, XFS_BB_OWNER); > } else { > - xfs_buf_delwri_queue(bp, buffer_list); > + xfs_buf_delwri_queue(bp, bbcoi->buffer_list); > } > } else { > ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); > ASSERT(level == cur->bc_nlevels - 1); > } > > - /* now read rh sibling block for next iteration */ > - xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); > - if (xfs_btree_ptr_is_null(cur, &rptr)) > - return -ENOENT; > - > - return xfs_btree_lookup_get_block(cur, level, &rptr, &block); > + return 0; > } > > int > @@ -4367,43 +4438,13 @@ xfs_btree_change_owner( > __uint64_t new_owner, > struct list_head *buffer_list) > { > - union xfs_btree_ptr lptr; > - int level; > - struct xfs_btree_block *block = NULL; > - int error = 0; > + struct xfs_btree_block_change_owner_info bbcoi; > > - cur->bc_ops->init_ptr_from_cur(cur, &lptr); > + bbcoi.new_owner = new_owner; > + bbcoi.buffer_list = buffer_list; > > - /* for each level */ > - for (level = cur->bc_nlevels - 1; level >= 0; level--) { > - /* grab the left hand block */ > - error = xfs_btree_lookup_get_block(cur, level, &lptr, &block); > - if (error) > - return error; > - > - /* readahead the left most block for the next level down */ > - if (level > 0) { > - union xfs_btree_ptr *ptr; > - > - ptr = xfs_btree_ptr_addr(cur, 1, block); > - xfs_btree_readahead_ptr(cur, ptr, 1); > - > - /* save for the next iteration of the loop */ > - lptr = *ptr; > - } > - > - /* for each buffer in the level */ > - do { > - error = xfs_btree_block_change_owner(cur, level, > - new_owner, > - buffer_list); > - } while (!error); > - > - if (error != -ENOENT) > - return error; > - } > - > - return 0; > + return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner, > + &bbcoi); > } > > /** > diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h > index 898fee5..0ec3055 100644 > --- a/fs/xfs/libxfs/xfs_btree.h > +++ b/fs/xfs/libxfs/xfs_btree.h > @@ -506,4 +506,9 @@ int xfs_btree_query_range(struct xfs_btree_cur *cur, > union xfs_btree_irec *low_rec, union xfs_btree_irec *high_rec, > xfs_btree_query_range_fn fn, void *priv); > > +typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level, > + void *data); > +int xfs_btree_visit_blocks(struct xfs_btree_cur *cur, > + xfs_btree_visit_blocks_fn fn, void *data); > + > #endif /* __XFS_BTREE_H__ */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 5f5cf23..eac876a 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4289,6 +4289,81 @@ xfs_btree_get_rec( return 0; } +/* Visit a block in a btree. */ +STATIC int +xfs_btree_visit_block( + struct xfs_btree_cur *cur, + int level, + xfs_btree_visit_blocks_fn fn, + void *data) +{ + struct xfs_btree_block *block; + struct xfs_buf *bp; + union xfs_btree_ptr rptr; + int error; + + /* do right sibling readahead */ + xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); + block = xfs_btree_get_block(cur, level, &bp); + + /* process the block */ + error = fn(cur, level, data); + if (error) + return error; + + /* now read rh sibling block for next iteration */ + xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); + if (xfs_btree_ptr_is_null(cur, &rptr)) + return -ENOENT; + + return xfs_btree_lookup_get_block(cur, level, &rptr, &block); +} + + +/* Visit every block in a btree. */ +int +xfs_btree_visit_blocks( + struct xfs_btree_cur *cur, + xfs_btree_visit_blocks_fn fn, + void *data) +{ + union xfs_btree_ptr lptr; + int level; + struct xfs_btree_block *block = NULL; + int error = 0; + + cur->bc_ops->init_ptr_from_cur(cur, &lptr); + + /* for each level */ + for (level = cur->bc_nlevels - 1; level >= 0; level--) { + /* grab the left hand block */ + error = xfs_btree_lookup_get_block(cur, level, &lptr, &block); + if (error) + return error; + + /* readahead the left most block for the next level down */ + if (level > 0) { + union xfs_btree_ptr *ptr; + + ptr = xfs_btree_ptr_addr(cur, 1, block); + xfs_btree_readahead_ptr(cur, ptr, 1); + + /* save for the next iteration of the loop */ + lptr = *ptr; + } + + /* for each buffer in the level */ + do { + error = xfs_btree_visit_block(cur, level, fn, data); + } while (!error); + + if (error != -ENOENT) + return error; + } + + return 0; +} + /* * Change the owner of a btree. * @@ -4313,26 +4388,27 @@ xfs_btree_get_rec( * just queue the modified buffer as delayed write buffer so the transaction * recovery completion writes the changes to disk. */ +struct xfs_btree_block_change_owner_info { + __uint64_t new_owner; + struct list_head *buffer_list; +}; + static int xfs_btree_block_change_owner( struct xfs_btree_cur *cur, int level, - __uint64_t new_owner, - struct list_head *buffer_list) + void *data) { + struct xfs_btree_block_change_owner_info *bbcoi = data; struct xfs_btree_block *block; struct xfs_buf *bp; - union xfs_btree_ptr rptr; - - /* do right sibling readahead */ - xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); /* modify the owner */ block = xfs_btree_get_block(cur, level, &bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) - block->bb_u.l.bb_owner = cpu_to_be64(new_owner); + block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner); else - block->bb_u.s.bb_owner = cpu_to_be32(new_owner); + block->bb_u.s.bb_owner = cpu_to_be32(bbcoi->new_owner); /* * If the block is a root block hosted in an inode, we might not have a @@ -4346,19 +4422,14 @@ xfs_btree_block_change_owner( xfs_trans_ordered_buf(cur->bc_tp, bp); xfs_btree_log_block(cur, bp, XFS_BB_OWNER); } else { - xfs_buf_delwri_queue(bp, buffer_list); + xfs_buf_delwri_queue(bp, bbcoi->buffer_list); } } else { ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); ASSERT(level == cur->bc_nlevels - 1); } - /* now read rh sibling block for next iteration */ - xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); - if (xfs_btree_ptr_is_null(cur, &rptr)) - return -ENOENT; - - return xfs_btree_lookup_get_block(cur, level, &rptr, &block); + return 0; } int @@ -4367,43 +4438,13 @@ xfs_btree_change_owner( __uint64_t new_owner, struct list_head *buffer_list) { - union xfs_btree_ptr lptr; - int level; - struct xfs_btree_block *block = NULL; - int error = 0; + struct xfs_btree_block_change_owner_info bbcoi; - cur->bc_ops->init_ptr_from_cur(cur, &lptr); + bbcoi.new_owner = new_owner; + bbcoi.buffer_list = buffer_list; - /* for each level */ - for (level = cur->bc_nlevels - 1; level >= 0; level--) { - /* grab the left hand block */ - error = xfs_btree_lookup_get_block(cur, level, &lptr, &block); - if (error) - return error; - - /* readahead the left most block for the next level down */ - if (level > 0) { - union xfs_btree_ptr *ptr; - - ptr = xfs_btree_ptr_addr(cur, 1, block); - xfs_btree_readahead_ptr(cur, ptr, 1); - - /* save for the next iteration of the loop */ - lptr = *ptr; - } - - /* for each buffer in the level */ - do { - error = xfs_btree_block_change_owner(cur, level, - new_owner, - buffer_list); - } while (!error); - - if (error != -ENOENT) - return error; - } - - return 0; + return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner, + &bbcoi); } /** diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 898fee5..0ec3055 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -506,4 +506,9 @@ int xfs_btree_query_range(struct xfs_btree_cur *cur, union xfs_btree_irec *low_rec, union xfs_btree_irec *high_rec, xfs_btree_query_range_fn fn, void *priv); +typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level, + void *data); +int xfs_btree_visit_blocks(struct xfs_btree_cur *cur, + xfs_btree_visit_blocks_fn fn, void *data); + #endif /* __XFS_BTREE_H__ */
Refactor the btree_change_owner function into a more generic apparatus which visits all blocks in a btree. We'll use this in a subsequent patch for counting btree blocks for AG reservations. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/libxfs/xfs_btree.c | 141 +++++++++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_btree.h | 5 ++ 2 files changed, 96 insertions(+), 50 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html