staticenum ocfs2_contig_type
ocfs2_extent_rec_contig(struct super_block *sb, struct ocfs2_extent_rec *ext, struct ocfs2_extent_rec *insert_rec); /* * Operations for a specific extent tree type. * * To implement an on-disk btree (extent tree) type in ocfs2, add * an ocfs2_extent_tree_operations structure and the matching * ocfs2_init_<thingy>_extent_tree() function. That's pretty much it * for the allocation portion of the extent tree.
*/ struct ocfs2_extent_tree_operations { /* * last_eb_blk is the block number of the right most leaf extent * block. Most on-disk structures containing an extent tree store * this value for fast access. The ->eo_set_last_eb_blk() and * ->eo_get_last_eb_blk() operations access this value. They are * both required.
*/ void (*eo_set_last_eb_blk)(struct ocfs2_extent_tree *et,
u64 blkno);
u64 (*eo_get_last_eb_blk)(struct ocfs2_extent_tree *et);
/* * The on-disk structure usually keeps track of how many total * clusters are stored in this extent tree. This function updates * that value. new_clusters is the delta, and must be * added to the total. Required.
*/ void (*eo_update_clusters)(struct ocfs2_extent_tree *et,
u32 new_clusters);
/* * If this extent tree is supported by an extent map, insert * a record into the map.
*/ void (*eo_extent_map_insert)(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec);
/* * If this extent tree is supported by an extent map, truncate the * map to clusters,
*/ void (*eo_extent_map_truncate)(struct ocfs2_extent_tree *et,
u32 clusters);
/* * If ->eo_insert_check() exists, it is called before rec is * inserted into the extent tree. It is optional.
*/ int (*eo_insert_check)(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec); int (*eo_sanity_check)(struct ocfs2_extent_tree *et);
/* * -------------------------------------------------------------- * The remaining are internal to ocfs2_extent_tree and don't have * accessor functions
*/
/* * ->eo_fill_root_el() takes et->et_object and sets et->et_root_el. * It is required.
*/ void (*eo_fill_root_el)(struct ocfs2_extent_tree *et);
/* * ->eo_fill_max_leaf_clusters sets et->et_max_leaf_clusters if * it exists. If it does not, et->et_max_leaf_clusters is set * to 0 (unlimited). Optional.
*/ void (*eo_fill_max_leaf_clusters)(struct ocfs2_extent_tree *et);
/* * ->eo_extent_contig test whether the 2 ocfs2_extent_rec * are contiguous or not. Optional. Don't need to set it if use * ocfs2_extent_rec as the tree leaf.
*/ enum ocfs2_contig_type
(*eo_extent_contig)(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *ext, struct ocfs2_extent_rec *insert_rec);
};
/* * Pre-declare ocfs2_dinode_et_ops so we can use it as a sanity check * in the methods.
*/ static u64 ocfs2_dinode_get_last_eb_blk(struct ocfs2_extent_tree *et); staticvoid ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et,
u64 blkno); staticvoid ocfs2_dinode_update_clusters(struct ocfs2_extent_tree *et,
u32 clusters); staticvoid ocfs2_dinode_extent_map_insert(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec); staticvoid ocfs2_dinode_extent_map_truncate(struct ocfs2_extent_tree *et,
u32 clusters); staticint ocfs2_dinode_insert_check(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec); staticint ocfs2_dinode_sanity_check(struct ocfs2_extent_tree *et); staticvoid ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et);
staticint ocfs2_reuse_blk_from_dealloc(handle_t *handle, struct ocfs2_extent_tree *et, struct buffer_head **new_eb_bh, int blk_wanted, int *blk_given); staticint ocfs2_is_dealloc_empty(struct ocfs2_extent_tree *et);
staticinlineint ocfs2_et_insert_check(struct ocfs2_extent_tree *et, struct ocfs2_extent_rec *rec)
{ int ret = 0;
if (et->et_ops->eo_insert_check)
ret = et->et_ops->eo_insert_check(et, rec); return ret;
}
staticinlineint ocfs2_et_sanity_check(struct ocfs2_extent_tree *et)
{ int ret = 0;
if (et->et_ops->eo_sanity_check)
ret = et->et_ops->eo_sanity_check(et); return ret;
}
staticint ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt, struct ocfs2_extent_block *eb); staticvoid ocfs2_adjust_rightmost_records(handle_t *handle, struct ocfs2_extent_tree *et, struct ocfs2_path *path, struct ocfs2_extent_rec *insert_rec); /* * Reset the actual path elements so that we can reuse the structure * to build another path. Generally, this involves freeing the buffer * heads.
*/ void ocfs2_reinit_path(struct ocfs2_path *path, int keep_root)
{ int i, start = 0, depth = 0; struct ocfs2_path_item *node;
/* * Tree depth may change during truncate, or insert. If we're * keeping the root extent list, then make sure that our path * structure reflects the proper depth.
*/ if (keep_root)
depth = le16_to_cpu(path_root_el(path)->l_tree_depth); else
path_root_access(path) = NULL;
/* * All the elements of src into dest. After this call, src could be freed * without affecting dest. * * Both paths should have the same root. Any non-root elements of dest * will be freed.
*/ staticvoid ocfs2_cp_path(struct ocfs2_path *dest, struct ocfs2_path *src)
{ int i;
if (dest->p_node[i].bh)
get_bh(dest->p_node[i].bh);
}
}
/* * Make the *dest path the same as src and re-initialize src path to * have a root only.
*/ staticvoid ocfs2_mv_path(struct ocfs2_path *dest, struct ocfs2_path *src)
{ int i;
/* * Insert an extent block at given index. * * This will not take an additional reference on eb_bh.
*/ staticinlinevoid ocfs2_path_insert_eb(struct ocfs2_path *path, int index, struct buffer_head *eb_bh)
{ struct ocfs2_extent_block *eb = (struct ocfs2_extent_block *)eb_bh->b_data;
/* * Right now, no root bh is an extent block, so this helps * catch code errors with dinode trees. The assertion can be * safely removed if we ever need to insert extent block * structures at the root.
*/
BUG_ON(index == 0);
/* * Journal the buffer at depth idx. All idx>0 are extent_blocks, * otherwise it's the root_access function. * * I don't like the way this function's name looks next to * ocfs2_journal_access_path(), but I don't have a better one.
*/ int ocfs2_path_bh_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, struct ocfs2_path *path, int idx)
{
ocfs2_journal_access_func access = path_root_access(path);
/* * Convenience function to journal all components in a path.
*/ int ocfs2_journal_access_path(struct ocfs2_caching_info *ci,
handle_t *handle, struct ocfs2_path *path)
{ int i, ret = 0;
if (!path) goto out;
for(i = 0; i < path_num_items(path); i++) {
ret = ocfs2_path_bh_journal_access(handle, ci, path, i); if (ret < 0) {
mlog_errno(ret); goto out;
}
}
out: return ret;
}
/* * Return the index of the extent record which contains cluster #v_cluster. * -1 is returned if it was not found. * * Should work fine on interior and exterior nodes.
*/ int ocfs2_search_extent_list(struct ocfs2_extent_list *el, u32 v_cluster)
{ int ret = -1; int i; struct ocfs2_extent_rec *rec;
u32 rec_end, rec_start, clusters;
/* * Refuse to coalesce extent records with different flag * fields - we don't want to mix unwritten extents with user * data.
*/ if (ext->e_flags != insert_rec->e_flags) return CONTIG_NONE;
if (ocfs2_extents_adjacent(ext, insert_rec) &&
ocfs2_block_extent_contig(sb, ext, blkno)) return CONTIG_RIGHT;
/* * NOTE: We can have pretty much any combination of contiguousness and * appending. * * The usefulness of APPEND_TAIL is more in that it lets us know that * we'll have to update the path to that leaf.
*/ enum ocfs2_append_type {
APPEND_NONE = 0,
APPEND_TAIL,
};
/* * If the ecc fails, we return the error but otherwise * leave the filesystem running. We know any error is * local to this block.
*/
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &eb->h_check); if (rc) {
mlog(ML_ERROR, "Checksum failed for extent block %llu\n",
(unsignedlonglong)bh->b_blocknr); return rc;
}
/* * Errors after here are fatal.
*/
if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
rc = ocfs2_error(sb, "Extent block #%llu has bad signature %.*s\n",
(unsignedlonglong)bh->b_blocknr, 7,
eb->h_signature); goto bail;
}
if (le64_to_cpu(eb->h_blkno) != bh->b_blocknr) {
rc = ocfs2_error(sb, "Extent block #%llu has an invalid h_blkno of %llu\n",
(unsignedlonglong)bh->b_blocknr,
(unsignedlonglong)le64_to_cpu(eb->h_blkno)); goto bail;
}
if (le32_to_cpu(eb->h_fs_generation) != OCFS2_SB(sb)->fs_generation)
rc = ocfs2_error(sb, "Extent block #%llu has an invalid h_fs_generation of #%u\n",
(unsignedlonglong)bh->b_blocknr,
le32_to_cpu(eb->h_fs_generation));
bail: return rc;
}
int ocfs2_read_extent_block(struct ocfs2_caching_info *ci, u64 eb_blkno, struct buffer_head **bh)
{ int rc; struct buffer_head *tmp = *bh;
/* If ocfs2_read_block() got us a new bh, pass it up. */ if (!rc && !*bh)
*bh = tmp;
return rc;
}
/* * How many free extents have we got before we need more meta data?
*/ int ocfs2_num_free_extents(struct ocfs2_extent_tree *et)
{ int retval; struct ocfs2_extent_list *el = NULL; struct ocfs2_extent_block *eb; struct buffer_head *eb_bh = NULL;
u64 last_eb_blk = 0;
el = et->et_root_el;
last_eb_blk = ocfs2_et_get_last_eb_blk(et);
if (last_eb_blk) {
retval = ocfs2_read_extent_block(et->et_ci, last_eb_blk,
&eb_bh); if (retval < 0) {
mlog_errno(retval); goto bail;
}
eb = (struct ocfs2_extent_block *) eb_bh->b_data;
el = &eb->h_list;
}
if (el->l_tree_depth != 0) {
retval = ocfs2_error(ocfs2_metadata_cache_get_super(et->et_ci), "Owner %llu has leaf extent block %llu with an invalid l_tree_depth of %u\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(et->et_ci),
(unsignedlonglong)last_eb_blk,
le16_to_cpu(el->l_tree_depth)); goto bail;
}
/* We'll also be dirtied by the caller, so
* this isn't absolutely necessary. */
ocfs2_journal_dirty(handle, bhs[i]);
}
count += num_got;
}
status = 0;
bail: if (status < 0) { for(i = 0; i < wanted; i++) {
brelse(bhs[i]);
bhs[i] = NULL;
}
} return status;
}
/* * Helper function for ocfs2_add_branch() and ocfs2_shift_tree_depth(). * * Returns the sum of the rightmost extent rec logical offset and * cluster count. * * ocfs2_add_branch() uses this to determine what logical cluster * value should be populated into the leftmost new branch records. * * ocfs2_shift_tree_depth() uses this to determine the # clusters * value for the new topmost tree record.
*/ staticinline u32 ocfs2_sum_rightmost_rec(struct ocfs2_extent_list *el)
{ int i;
/* * Change range of the branches in the right most path according to the leaf * extent block's rightmost record.
*/ staticint ocfs2_adjust_rightmost_branch(handle_t *handle, struct ocfs2_extent_tree *et)
{ int status; struct ocfs2_path *path = NULL; struct ocfs2_extent_list *el; struct ocfs2_extent_rec *rec;
path = ocfs2_new_path_from_et(et); if (!path) {
status = -ENOMEM; return status;
}
status = ocfs2_find_path(et->et_ci, path, UINT_MAX); if (status < 0) {
mlog_errno(status); goto out;
}
status = ocfs2_extend_trans(handle, path_num_items(path)); if (status < 0) {
mlog_errno(status); goto out;
}
status = ocfs2_journal_access_path(et->et_ci, handle, path); if (status < 0) {
mlog_errno(status); goto out;
}
el = path_leaf_el(path);
rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1];
ocfs2_adjust_rightmost_records(handle, et, path, rec);
out:
ocfs2_free_path(path); return status;
}
/* * Add an entire tree branch to our inode. eb_bh is the extent block * to start at, if we don't want to start the branch at the root * structure. * * last_eb_bh is required as we have to update it's next_leaf pointer * for the new last extent block. * * the new branch will be 'empty' in the sense that every block will * contain a single record with cluster count == 0.
*/ staticint ocfs2_add_branch(handle_t *handle, struct ocfs2_extent_tree *et, struct buffer_head *eb_bh, struct buffer_head **last_eb_bh, struct ocfs2_alloc_context *meta_ac)
{ int status, new_blocks, i, block_given = 0;
u64 next_blkno, new_last_eb_blk; struct buffer_head *bh; struct buffer_head **new_eb_bhs = NULL; struct ocfs2_extent_block *eb; struct ocfs2_extent_list *eb_el; struct ocfs2_extent_list *el;
u32 new_cpos, root_end;
BUG_ON(!last_eb_bh || !*last_eb_bh);
if (eb_bh) {
eb = (struct ocfs2_extent_block *) eb_bh->b_data;
el = &eb->h_list;
} else
el = et->et_root_el;
/* we never add a branch to a leaf. */
BUG_ON(!el->l_tree_depth);
/* * If there is a gap before the root end and the real end * of the rightmost leaf block, we need to remove the gap * between new_cpos and root_end first so that the tree * is consistent after we add a new branch(it will start * from new_cpos).
*/ if (root_end > new_cpos) {
trace_ocfs2_adjust_rightmost_branch(
(unsignedlonglong)
ocfs2_metadata_cache_owner(et->et_ci),
root_end, new_cpos);
status = ocfs2_adjust_rightmost_branch(handle, et); if (status) {
mlog_errno(status); goto bail;
}
}
/* allocate the number of new eb blocks we need */
new_eb_bhs = kcalloc(new_blocks, sizeof(struct buffer_head *),
GFP_KERNEL); if (!new_eb_bhs) {
status = -ENOMEM;
mlog_errno(status); goto bail;
}
/* Firstyly, try to reuse dealloc since we have already estimated how * many extent blocks we may use.
*/ if (!ocfs2_is_dealloc_empty(et)) {
status = ocfs2_reuse_blk_from_dealloc(handle, et,
new_eb_bhs, new_blocks,
&block_given); if (status < 0) {
mlog_errno(status); goto bail;
}
}
BUG_ON(block_given > new_blocks);
if (block_given < new_blocks) {
BUG_ON(!meta_ac);
status = ocfs2_create_new_meta_bhs(handle, et,
new_blocks - block_given,
meta_ac,
&new_eb_bhs[block_given]); if (status < 0) {
mlog_errno(status); goto bail;
}
}
/* Note: new_eb_bhs[new_blocks - 1] is the guy which will be * linked with the rest of the tree. * conversely, new_eb_bhs[0] is the new bottommost leaf. * * when we leave the loop, new_last_eb_blk will point to the * newest leaf, and next_blkno will point to the topmost extent
* block. */
next_blkno = new_last_eb_blk = 0; for(i = 0; i < new_blocks; i++) {
bh = new_eb_bhs[i];
eb = (struct ocfs2_extent_block *) bh->b_data; /* ocfs2_create_new_meta_bhs() should create it right! */
BUG_ON(!OCFS2_IS_VALID_EXTENT_BLOCK(eb));
eb_el = &eb->h_list;
status = ocfs2_journal_access_eb(handle, et->et_ci, bh,
OCFS2_JOURNAL_ACCESS_CREATE); if (status < 0) {
mlog_errno(status); goto bail;
}
eb->h_next_leaf_blk = 0;
eb_el->l_tree_depth = cpu_to_le16(i);
eb_el->l_next_free_rec = cpu_to_le16(1); /* * This actually counts as an empty extent as * c_clusters == 0
*/
eb_el->l_recs[0].e_cpos = cpu_to_le32(new_cpos);
eb_el->l_recs[0].e_blkno = cpu_to_le64(next_blkno); /* * eb_el isn't always an interior node, but even leaf * nodes want a zero'd flags and reserved field so * this gets the whole 32 bits regardless of use.
*/
eb_el->l_recs[0].e_int_clusters = cpu_to_le32(0); if (!eb_el->l_tree_depth)
new_last_eb_blk = le64_to_cpu(eb->h_blkno);
/* This is a bit hairy. We want to update up to three blocks * here without leaving any of them in an inconsistent state * in case of error. We don't have to worry about * journal_dirty erroring as it won't unless we've aborted the * handle (in which case we would never be here) so reserving
* the write with journal_access is all we need to do. */
status = ocfs2_journal_access_eb(handle, et->et_ci, *last_eb_bh,
OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) {
mlog_errno(status); goto bail;
}
status = ocfs2_et_root_journal_access(handle, et,
OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) {
mlog_errno(status); goto bail;
} if (eb_bh) {
status = ocfs2_journal_access_eb(handle, et->et_ci, eb_bh,
OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) {
mlog_errno(status); goto bail;
}
}
/* Link the new branch into the rest of the tree (el will
* either be on the root_bh, or the extent block passed in. */
i = le16_to_cpu(el->l_next_free_rec);
el->l_recs[i].e_blkno = cpu_to_le64(next_blkno);
el->l_recs[i].e_cpos = cpu_to_le32(new_cpos);
el->l_recs[i].e_int_clusters = 0;
le16_add_cpu(&el->l_next_free_rec, 1);
/* fe needs a new last extent block pointer, as does the
* next_leaf on the previously last-extent-block. */
ocfs2_et_set_last_eb_blk(et, new_last_eb_blk);
ocfs2_journal_dirty(handle, *last_eb_bh);
ocfs2_journal_dirty(handle, et->et_root_bh); if (eb_bh)
ocfs2_journal_dirty(handle, eb_bh);
/* * Some callers want to track the rightmost leaf so pass it * back here.
*/
brelse(*last_eb_bh);
get_bh(new_eb_bhs[0]);
*last_eb_bh = new_eb_bhs[0];
status = 0;
bail: if (new_eb_bhs) { for (i = 0; i < new_blocks; i++)
brelse(new_eb_bhs[i]);
kfree(new_eb_bhs);
}
return status;
}
/* * adds another level to the allocation tree. * returns back the new extent block so you can add a branch to it * after this call.
*/ staticint ocfs2_shift_tree_depth(handle_t *handle, struct ocfs2_extent_tree *et, struct ocfs2_alloc_context *meta_ac, struct buffer_head **ret_new_eb_bh)
{ int status, i, block_given = 0;
u32 new_clusters; struct buffer_head *new_eb_bh = NULL; struct ocfs2_extent_block *eb; struct ocfs2_extent_list *root_el; struct ocfs2_extent_list *eb_el;
if (!ocfs2_is_dealloc_empty(et)) {
status = ocfs2_reuse_blk_from_dealloc(handle, et,
&new_eb_bh, 1,
&block_given);
} elseif (meta_ac) {
status = ocfs2_create_new_meta_bhs(handle, et, 1, meta_ac,
&new_eb_bh);
} else {
BUG();
}
if (status < 0) {
mlog_errno(status); goto bail;
}
eb = (struct ocfs2_extent_block *) new_eb_bh->b_data; /* ocfs2_create_new_meta_bhs() should create it right! */
BUG_ON(!OCFS2_IS_VALID_EXTENT_BLOCK(eb));
eb_el = &eb->h_list;
root_el = et->et_root_el;
status = ocfs2_journal_access_eb(handle, et->et_ci, new_eb_bh,
OCFS2_JOURNAL_ACCESS_CREATE); if (status < 0) {
mlog_errno(status); goto bail;
}
/* copy the root extent list data into the new extent block */
eb_el->l_tree_depth = root_el->l_tree_depth;
eb_el->l_next_free_rec = root_el->l_next_free_rec; for (i = 0; i < le16_to_cpu(root_el->l_next_free_rec); i++)
eb_el->l_recs[i] = root_el->l_recs[i];
ocfs2_journal_dirty(handle, new_eb_bh);
status = ocfs2_et_root_journal_access(handle, et,
OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) {
mlog_errno(status); goto bail;
}
new_clusters = ocfs2_sum_rightmost_rec(eb_el);
/* update root_bh now */
le16_add_cpu(&root_el->l_tree_depth, 1);
root_el->l_recs[0].e_cpos = 0;
root_el->l_recs[0].e_blkno = eb->h_blkno;
root_el->l_recs[0].e_int_clusters = cpu_to_le32(new_clusters); for (i = 1; i < le16_to_cpu(root_el->l_next_free_rec); i++)
memset(&root_el->l_recs[i], 0, sizeof(struct ocfs2_extent_rec));
root_el->l_next_free_rec = cpu_to_le16(1);
/* If this is our 1st tree depth shift, then last_eb_blk
* becomes the allocated extent block */ if (root_el->l_tree_depth == cpu_to_le16(1))
ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
/* * Should only be called when there is no space left in any of the * leaf nodes. What we want to do is find the lowest tree depth * non-leaf extent block with room for new records. There are three * valid results of this search: * * 1) a lowest extent block is found, then we pass it back in * *lowest_eb_bh and return '0' * * 2) the search fails to find anything, but the root_el has room. We * pass NULL back in *lowest_eb_bh, but still return '0' * * 3) the search fails to find anything AND the root_el is full, in * which case we return > 0 * * return status < 0 indicates an error.
*/ staticint ocfs2_find_branch_target(struct ocfs2_extent_tree *et, struct buffer_head **target_bh)
{ int status = 0, i;
u64 blkno; struct ocfs2_extent_block *eb; struct ocfs2_extent_list *el; struct buffer_head *bh = NULL; struct buffer_head *lowest_bh = NULL;
*target_bh = NULL;
el = et->et_root_el;
while(le16_to_cpu(el->l_tree_depth) > 1) { if (le16_to_cpu(el->l_next_free_rec) == 0) {
status = ocfs2_error(ocfs2_metadata_cache_get_super(et->et_ci), "Owner %llu has empty extent list (next_free_rec == 0)\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(et->et_ci)); goto bail;
}
i = le16_to_cpu(el->l_next_free_rec) - 1;
blkno = le64_to_cpu(el->l_recs[i].e_blkno); if (!blkno) {
status = ocfs2_error(ocfs2_metadata_cache_get_super(et->et_ci), "Owner %llu has extent list where extent # %d has no physical block start\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(et->et_ci), i); goto bail;
}
brelse(bh);
bh = NULL;
status = ocfs2_read_extent_block(et->et_ci, blkno, &bh); if (status < 0) {
mlog_errno(status); goto bail;
}
eb = (struct ocfs2_extent_block *) bh->b_data;
el = &eb->h_list;
/* If we didn't find one and the fe doesn't have any room,
* then return '1' */
el = et->et_root_el; if (!lowest_bh && (el->l_next_free_rec == el->l_count))
status = 1;
*target_bh = lowest_bh;
bail:
brelse(bh);
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. * * *last_eb_bh will be updated by ocfs2_add_branch().
*/ staticint ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et, int *final_depth, struct buffer_head **last_eb_bh, struct ocfs2_alloc_context *meta_ac)
{ int ret, shift; struct ocfs2_extent_list *el = et->et_root_el; int depth = le16_to_cpu(el->l_tree_depth); struct buffer_head *bh = NULL;
shift = ocfs2_find_branch_target(et, &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);
trace_ocfs2_grow_tree(
(unsignedlonglong)
ocfs2_metadata_cache_owner(et->et_ci),
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(handle, et, meta_ac, &bh); if (ret < 0) {
mlog_errno(ret); goto out;
}
depth++; if (depth == 1) { /* * Special case: we have room now if we shifted from * tree_depth 0, so no more work needs to be done. * * We won't be calling add_branch, so pass * back *last_eb_bh as the new leaf. At depth * zero, it should always be null so there's * no reason to brelse.
*/
BUG_ON(*last_eb_bh);
get_bh(bh);
*last_eb_bh = bh; goto out;
}
}
/* call ocfs2_add_branch to add the final part of the tree with
* the new data. */
ret = ocfs2_add_branch(handle, et, bh, last_eb_bh,
meta_ac); if (ret < 0)
mlog_errno(ret);
out: if (final_depth)
*final_depth = depth;
brelse(bh); return ret;
}
/* * This function will discard the rightmost extent record.
*/ staticvoid ocfs2_shift_records_right(struct ocfs2_extent_list *el)
{ int next_free = le16_to_cpu(el->l_next_free_rec); int count = le16_to_cpu(el->l_count); unsignedint num_bytes;
BUG_ON(!next_free); /* This will cause us to go off the end of our extent list. */
BUG_ON(next_free >= count);
/* The tree code before us didn't allow enough room in the leaf. */
BUG_ON(el->l_next_free_rec == el->l_count && !has_empty);
/* * The easiest way to approach this is to just remove the * empty extent and temporarily decrement next_free.
*/ if (has_empty) { /* * If next_free was 1 (only an empty extent), this * loop won't execute, which is fine. We still want * the decrement above to happen.
*/ for(i = 0; i < (next_free - 1); i++)
el->l_recs[i] = el->l_recs[i+1];
next_free--;
}
/* * Figure out what the new record index should be.
*/ for(i = 0; i < next_free; i++) {
rec = &el->l_recs[i];
if (insert_cpos < le32_to_cpu(rec->e_cpos)) break;
}
insert_index = i;
/* * Either we had an empty extent, and need to re-increment or * there was no empty extent on a non full rightmost leaf node, * in which case we still need to increment.
*/
next_free++;
el->l_next_free_rec = cpu_to_le16(next_free); /* * Make sure none of the math above just messed up our tree.
*/
BUG_ON(le16_to_cpu(el->l_next_free_rec) > le16_to_cpu(el->l_count));
el->l_recs[insert_index] = *insert_rec;
}
staticvoid ocfs2_remove_empty_extent(struct ocfs2_extent_list *el)
{ int size, num_recs = le16_to_cpu(el->l_next_free_rec);
/* * Create an empty extent record . * * l_next_free_rec may be updated. * * If an empty extent already exists do nothing.
*/ staticvoid ocfs2_create_empty_extent(struct ocfs2_extent_list *el)
{ int next_free = le16_to_cpu(el->l_next_free_rec);
BUG_ON(le16_to_cpu(el->l_tree_depth) != 0);
if (next_free == 0) goto set_and_inc;
if (ocfs2_is_empty_extent(&el->l_recs[0])) return;
mlog_bug_on_msg(el->l_count == el->l_next_free_rec, "Asked to create an empty extent in a full list:\n" "count = %u, tree depth = %u",
le16_to_cpu(el->l_count),
le16_to_cpu(el->l_tree_depth));
/* * For a rotation which involves two leaf nodes, the "root node" is * the lowest level tree node which contains a path to both leafs. This * resulting set of information can be used to form a complete "subtree" * * This function is passed two full paths from the dinode down to a * pair of adjacent leaves. It's task is to figure out which path * index contains the subtree root - this can be the root index itself * in a worst-case rotation. * * The array index of the subtree root is passed back.
*/ int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, struct ocfs2_path *left, struct ocfs2_path *right)
{ int i = 0;
/* * Check that the caller passed in two paths from the same tree.
*/
BUG_ON(path_root_bh(left) != path_root_bh(right));
do {
i++;
/* * The caller didn't pass two adjacent paths.
*/
mlog_bug_on_msg(i > left->p_tree_depth, "Owner %llu, left depth %u, right depth %u\n" "left leaf blk %llu, right leaf blk %llu\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(et->et_ci),
left->p_tree_depth, right->p_tree_depth,
(unsignedlonglong)path_leaf_bh(left)->b_blocknr,
(unsignedlonglong)path_leaf_bh(right)->b_blocknr);
} while (left->p_node[i].bh->b_blocknr ==
right->p_node[i].bh->b_blocknr);
/* * Traverse a btree path in search of cpos, starting at root_el. * * This code can be called with a cpos larger than the tree, in which * case it will return the rightmost path.
*/ staticint __ocfs2_find_path(struct ocfs2_caching_info *ci, struct ocfs2_extent_list *root_el, u32 cpos,
path_insert_t *func, void *data)
{ int i, ret = 0;
u32 range;
u64 blkno; struct buffer_head *bh = NULL; struct ocfs2_extent_block *eb; struct ocfs2_extent_list *el; struct ocfs2_extent_rec *rec;
el = root_el; while (el->l_tree_depth) { if (unlikely(le16_to_cpu(el->l_tree_depth) >= OCFS2_MAX_PATH_DEPTH)) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci), "Owner %llu has invalid tree depth %u in extent list\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(ci),
le16_to_cpu(el->l_tree_depth));
ret = -EROFS; goto out;
} if (le16_to_cpu(el->l_next_free_rec) == 0) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci), "Owner %llu has empty extent list at depth %u\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(ci),
le16_to_cpu(el->l_tree_depth));
ret = -EROFS; goto out;
/* * In the case that cpos is off the allocation * tree, this should just wind up returning the * rightmost record.
*/
range = le32_to_cpu(rec->e_cpos) +
ocfs2_rec_clusters(el, rec); if (cpos >= le32_to_cpu(rec->e_cpos) && cpos < range) break;
}
blkno = le64_to_cpu(el->l_recs[i].e_blkno); if (blkno == 0) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci), "Owner %llu has bad blkno in extent list at depth %u (index %d)\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(ci),
le16_to_cpu(el->l_tree_depth), i);
ret = -EROFS; goto out;
}
brelse(bh);
bh = NULL;
ret = ocfs2_read_extent_block(ci, blkno, &bh); if (ret) {
mlog_errno(ret); goto out;
}
eb = (struct ocfs2_extent_block *) bh->b_data;
el = &eb->h_list;
if (le16_to_cpu(el->l_next_free_rec) >
le16_to_cpu(el->l_count)) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci), "Owner %llu has bad count in extent list at block %llu (next free=%u, count=%u)\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(ci),
(unsignedlonglong)bh->b_blocknr,
le16_to_cpu(el->l_next_free_rec),
le16_to_cpu(el->l_count));
ret = -EROFS; goto out;
}
if (func)
func(data, bh);
}
out: /* * Catch any trailing bh that the loop didn't handle.
*/
brelse(bh);
return ret;
}
/* * Given an initialized path (that is, it has a valid root extent * list), this function will traverse the btree in search of the path * which would contain cpos. * * The path traveled is recorded in the path structure. * * Note that this will not do any comparisons on leaf node extent * records, so it will work fine in the case that we just added a tree * branch.
*/ struct find_path_data { int index; struct ocfs2_path *path;
}; staticvoid find_path_ins(void *data, struct buffer_head *bh)
{ struct find_path_data *fp = data;
/* We want to retain only the leaf block. */ if (le16_to_cpu(el->l_tree_depth) == 0) {
get_bh(bh);
*ret = bh;
}
} /* * Find the leaf block in the tree which would contain cpos. No * checking of the actual leaf is done. * * Some paths want to call this instead of allocating a path structure * and calling ocfs2_find_path(). * * This function doesn't handle non btree extent lists.
*/ int ocfs2_find_leaf(struct ocfs2_caching_info *ci, struct ocfs2_extent_list *root_el, u32 cpos, struct buffer_head **leaf_bh)
{ int ret; struct buffer_head *bh = NULL;
ret = __ocfs2_find_path(ci, root_el, cpos, find_leaf_ins, &bh); if (ret) {
mlog_errno(ret); goto out;
}
*leaf_bh = bh;
out: return ret;
}
/* * Adjust the adjacent records (left_rec, right_rec) involved in a rotation. * * Basically, we've moved stuff around at the bottom of the tree and * we need to fix up the extent records above the changes to reflect * the new changes. * * left_rec: the record on the left. * right_rec: the record to the right of left_rec * right_child_el: is the child list pointed to by right_rec * * By definition, this only works on interior nodes.
*/ staticvoid ocfs2_adjust_adjacent_records(struct ocfs2_extent_rec *left_rec, struct ocfs2_extent_rec *right_rec, struct ocfs2_extent_list *right_child_el)
{
u32 left_clusters, right_end;
/* * Interior nodes never have holes. Their cpos is the cpos of * the leftmost record in their child list. Their cluster * count covers the full theoretical range of their child list * - the range between their cpos and the cpos of the record * immediately to their right.
*/
left_clusters = le32_to_cpu(right_child_el->l_recs[0].e_cpos); if (!ocfs2_rec_clusters(right_child_el, &right_child_el->l_recs[0])) {
BUG_ON(right_child_el->l_tree_depth);
BUG_ON(le16_to_cpu(right_child_el->l_next_free_rec) <= 1);
left_clusters = le32_to_cpu(right_child_el->l_recs[1].e_cpos);
}
left_clusters -= le32_to_cpu(left_rec->e_cpos);
left_rec->e_int_clusters = cpu_to_le32(left_clusters);
/* * Calculate the rightmost cluster count boundary before * moving cpos - we will need to adjust clusters after * updating e_cpos to keep the same highest cluster count.
*/
right_end = le32_to_cpu(right_rec->e_cpos);
right_end += le32_to_cpu(right_rec->e_int_clusters);
/* * Adjust the adjacent root node records involved in a * rotation. left_el_blkno is passed in as a key so that we can easily * find it's index in the root list.
*/ staticvoid ocfs2_adjust_root_records(struct ocfs2_extent_list *root_el, struct ocfs2_extent_list *left_el, struct ocfs2_extent_list *right_el,
u64 left_el_blkno)
{ int i;
for(i = 0; i < le16_to_cpu(root_el->l_next_free_rec) - 1; i++) { if (le64_to_cpu(root_el->l_recs[i].e_blkno) == left_el_blkno) break;
}
/* * The path walking code should have never returned a root and * two paths which are not adjacent.
*/
BUG_ON(i >= (le16_to_cpu(root_el->l_next_free_rec) - 1));
/* * We've changed a leaf block (in right_path) and need to reflect that * change back up the subtree. * * This happens in multiple places: * - When we've moved an extent record from the left path leaf to the right * path leaf to make room for an empty extent in the left path leaf. * - When our insert into the right path leaf is at the leftmost edge * and requires an update of the path immediately to it's left. This * can occur at the end of some types of rotation and appending inserts. * - When we've adjusted the last extent record in the left path leaf and the * 1st extent record in the right path leaf during cross extent block merge.
*/ staticvoid ocfs2_complete_edge_insert(handle_t *handle, struct ocfs2_path *left_path, struct ocfs2_path *right_path, int subtree_index)
{ int i, idx; struct ocfs2_extent_list *el, *left_el, *right_el; struct ocfs2_extent_rec *left_rec, *right_rec; struct buffer_head *root_bh;
/* * Update the counts and position values within all the * interior nodes to reflect the leaf rotation we just did. * * The root node is handled below the loop. * * We begin the loop with right_el and left_el pointing to the * leaf lists and work our way up. * * NOTE: within this loop, left_el and right_el always refer * to the *child* lists.
*/
left_el = path_leaf_el(left_path);
right_el = path_leaf_el(right_path); for(i = left_path->p_tree_depth - 1; i > subtree_index; i--) {
trace_ocfs2_complete_edge_insert(i);
/* * One nice property of knowing that all of these * nodes are below the root is that we only deal with * the leftmost right node record and the rightmost * left node record.
*/
el = left_path->p_node[i].el;
idx = le16_to_cpu(left_el->l_next_free_rec) - 1;
left_rec = &el->l_recs[idx];
el = right_path->p_node[i].el;
right_rec = &el->l_recs[0];
/* * Setup our list pointers now so that the current * parents become children in the next iteration.
*/
left_el = left_path->p_node[i].el;
right_el = right_path->p_node[i].el;
}
/* * At the root node, adjust the two adjacent records which * begin our path to the leaves.
*/
/* This is a code error, not a disk corruption. */
mlog_bug_on_msg(!right_el->l_next_free_rec, "Inode %llu: Rotate fails " "because rightmost leaf block %llu is empty\n",
(unsignedlonglong)ocfs2_metadata_cache_owner(et->et_ci),
(unsignedlonglong)right_leaf_bh->b_blocknr);
ocfs2_create_empty_extent(right_el);
ocfs2_journal_dirty(handle, right_leaf_bh);
/* Do the copy now. */
i = le16_to_cpu(left_el->l_next_free_rec) - 1;
move_rec = left_el->l_recs[i];
right_el->l_recs[0] = move_rec;
/* * Clear out the record we just copied and shift everything * over, leaving an empty extent in the left leaf. * * We temporarily subtract from next_free_rec so that the * shift will lose the tail record (which is now defunct).
*/
le16_add_cpu(&left_el->l_next_free_rec, -1);
ocfs2_shift_records_right(left_el);
memset(&left_el->l_recs[0], 0, sizeof(struct ocfs2_extent_rec));
le16_add_cpu(&left_el->l_next_free_rec, 1);
/* * Given a full path, determine what cpos value would return us a path * containing the leaf immediately to the left of the current one. * * Will return zero if the path passed in is already the leftmost path.
*/ int ocfs2_find_cpos_for_left_leaf(struct super_block *sb, struct ocfs2_path *path, u32 *cpos)
{ int i, j, ret = 0;
u64 blkno; struct ocfs2_extent_list *el;
BUG_ON(path->p_tree_depth == 0);
*cpos = 0;
blkno = path_leaf_bh(path)->b_blocknr;
/* Start at the tree node just above the leaf and work our way up. */
i = path->p_tree_depth - 1; while (i >= 0) {
el = path->p_node[i].el;
/* * Find the extent record just before the one in our * path.
*/ for(j = 0; j < le16_to_cpu(el->l_next_free_rec); j++) { if (le64_to_cpu(el->l_recs[j].e_blkno) == blkno) { if (j == 0) { if (i == 0) { /* * We've determined that the * path specified is already * the leftmost one - return a * cpos of zero.
*/ goto out;
} /* * The leftmost record points to our * leaf - we need to travel up the * tree one level.
*/ goto next_node;
}
/* * If we got here, we never found a valid node where * the tree indicated one should be.
*/
ocfs2_error(sb, "Invalid extent tree at extent block %llu\n",
(unsignedlonglong)blkno);
ret = -EROFS; goto out;
/* * Extend the transaction by enough credits to complete the rotation, * and still leave at least the original number of credits allocated * to this transaction.
*/ staticint ocfs2_extend_rotate_transaction(handle_t *handle, int subtree_depth, int op_credits, struct ocfs2_path *path)
{ int ret = 0; int credits = (path->p_tree_depth - subtree_depth) * 2 + 1 + op_credits;
if (jbd2_handle_buffer_credits(handle) < credits)
ret = ocfs2_extend_trans(handle,
credits - jbd2_handle_buffer_credits(handle));
return ret;
}
/* * Trap the case where we're inserting into the theoretical range past * the _actual_ left leaf range. Otherwise, we'll rotate a record * whose cpos is less than ours into the right leaf. * * It's only necessary to look at the rightmost record of the left * leaf because the logic that calls us should ensure that the * theoretical ranges in the path components above the leaves are * correct.
*/ staticint ocfs2_rotate_requires_path_adjustment(struct ocfs2_path *left_path,
u32 insert_cpos)
{ struct ocfs2_extent_list *left_el; struct ocfs2_extent_rec *rec; int next_free;
rec = &el->l_recs[0]; if (ocfs2_is_empty_extent(rec)) { /* Empty list. */ if (next_free == 1) return 0;
rec = &el->l_recs[1];
}
range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec); if (cpos >= le32_to_cpu(rec->e_cpos) && cpos < range) return 1; return 0;
}
/* * Rotate all the records in a btree right one record, starting at insert_cpos. * * The path to the rightmost leaf should be passed in. * * The array is assumed to be large enough to hold an entire path (tree depth). * * Upon successful return from this function: * * - The 'right_path' array will contain a path to the leaf block * whose range contains e_cpos. * - That leaf block will have a single empty extent in list index 0. * - In the case that the rotation requires a post-insert update, * *ret_left_path will contain a valid path which can be passed to * ocfs2_insert_path().
*/ staticint ocfs2_rotate_tree_right(handle_t *handle, struct ocfs2_extent_tree *et, enum ocfs2_split_type split,
u32 insert_cpos, struct ocfs2_path *right_path, struct ocfs2_path **ret_left_path)
{ int ret, start, orig_credits = jbd2_handle_buffer_credits(handle);
u32 cpos; struct ocfs2_path *left_path = NULL; struct super_block *sb = ocfs2_metadata_cache_get_super(et->et_ci);
*ret_left_path = NULL;
left_path = ocfs2_new_path_from_path(right_path); if (!left_path) {
ret = -ENOMEM;
mlog_errno(ret); goto out;
}
ret = ocfs2_find_cpos_for_left_leaf(sb, right_path, &cpos); if (ret) {
mlog_errno(ret); goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.