From c3afcbb34426a9291e4c038540129053a72c3cd8 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 29 May 2007 14:28:51 -0700 Subject: ocfs2: abstract btree growing calls The top level calls and logic for growing a tree can easily be abstracted out of ocfs2_insert_extent() into a seperate function - ocfs2_grow_tree(). This allows future code to easily grow btrees when needed. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.c | 119 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 45 deletions(-) (limited to 'fs/ocfs2') diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index b5327b4cdb34..a02d026cb0e4 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -824,6 +824,74 @@ bail: return status; } +/* + * Grow a b-tree so that it has more records. + * + * We might shift the tree depth in which case existing paths should + * be considered invalid. + * + * Tree depth after the grow is returned via *final_depth. + */ +static int ocfs2_grow_tree(struct inode *inode, handle_t *handle, + struct buffer_head *di_bh, int *final_depth, + struct buffer_head *last_eb_bh, + struct ocfs2_alloc_context *meta_ac) +{ + int ret, shift; + struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; + int depth = le16_to_cpu(di->id2.i_list.l_tree_depth); + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct buffer_head *bh = NULL; + + BUG_ON(meta_ac == NULL); + + shift = ocfs2_find_branch_target(osb, inode, di_bh, &bh); + if (shift < 0) { + ret = shift; + mlog_errno(ret); + goto out; + } + + /* We traveled all the way to the bottom of the allocation tree + * and didn't find room for any more extents - we need to add + * another tree level */ + if (shift) { + BUG_ON(bh); + mlog(0, "need to shift tree depth (current = %d)\n", depth); + + /* ocfs2_shift_tree_depth will return us a buffer with + * the new extent block (so we can pass that to + * ocfs2_add_branch). */ + ret = ocfs2_shift_tree_depth(osb, handle, inode, di_bh, + meta_ac, &bh); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + depth++; + /* Special case: we have room now if we shifted from + * tree_depth 0 */ + if (depth == 1) + goto out; + } + + /* call ocfs2_add_branch to add the final part of the tree with + * the new data. */ + mlog(0, "add branch. bh = %p\n", bh); + ret = ocfs2_add_branch(osb, handle, inode, di_bh, bh, last_eb_bh, + meta_ac); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + +out: + if (final_depth) + *final_depth = depth; + brelse(bh); + return ret; +} + /* * This is only valid for leaf nodes, which are the only ones that can * have empty extents anyway. @@ -2325,7 +2393,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, u32 new_clusters, struct ocfs2_alloc_context *meta_ac) { - int status, shift; + int status; struct buffer_head *last_eb_bh = NULL; struct buffer_head *bh = NULL; struct ocfs2_insert_type insert = {0, }; @@ -2360,55 +2428,16 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, insert.ins_appending, insert.ins_contig, insert.ins_contig_index, insert.ins_free_records, insert.ins_tree_depth); - /* - * Avoid growing the tree unless we're out of records and the - * insert type requres one. - */ - if (insert.ins_contig != CONTIG_NONE || insert.ins_free_records) - goto out_add; - - shift = ocfs2_find_branch_target(osb, inode, fe_bh, &bh); - if (shift < 0) { - status = shift; - mlog_errno(status); - goto bail; - } - - /* We traveled all the way to the bottom of the allocation tree - * and didn't find room for any more extents - we need to add - * another tree level */ - if (shift) { - BUG_ON(bh); - mlog(0, "need to shift tree depth " - "(current = %d)\n", insert.ins_tree_depth); - - /* ocfs2_shift_tree_depth will return us a buffer with - * the new extent block (so we can pass that to - * ocfs2_add_branch). */ - status = ocfs2_shift_tree_depth(osb, handle, inode, fe_bh, - meta_ac, &bh); - if (status < 0) { + if (insert.ins_contig == CONTIG_NONE && insert.ins_free_records == 0) { + status = ocfs2_grow_tree(inode, handle, fe_bh, + &insert.ins_tree_depth, last_eb_bh, + meta_ac); + if (status) { mlog_errno(status); goto bail; } - insert.ins_tree_depth++; - /* Special case: we have room now if we shifted from - * tree_depth 0 */ - if (insert.ins_tree_depth == 1) - goto out_add; - } - - /* call ocfs2_add_branch to add the final part of the tree with - * the new data. */ - mlog(0, "add branch. bh = %p\n", bh); - status = ocfs2_add_branch(osb, handle, inode, fe_bh, bh, last_eb_bh, - meta_ac); - if (status < 0) { - mlog_errno(status); - goto bail; } -out_add: /* Finally, we can add clusters. This might rotate the tree for us. */ status = ocfs2_do_insert_extent(inode, handle, fe_bh, &rec, &insert); if (status < 0) -- cgit v1.2.3-59-g8ed1b