/* Insert d_key'th (delimiting) key from buffer cfr to head of dest. * Copy n node pointers and n - 1 items from buffer src to buffer dest. * Replace d_key'th key in buffer cfr. * Delete n items and node pointers from buffer src. */ static void internal_shift_right(int mode, /* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S */ struct tree_balance *tb, int h, int pointer_amount) { struct buffer_info dest_bi, src_bi; struct buffer_head *cf; int d_key_position; int nr; internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi, &d_key_position, &cf); nr = B_NR_ITEMS(src_bi.bi_bh); if (pointer_amount > 0) { /* insert delimiting key from common father of dest and src to dest node into position 0 */ internal_insert_key(&dest_bi, 0, cf, d_key_position); if (nr == pointer_amount - 1) { RFALSE(src_bi.bi_bh != PATH_H_PBUFFER(tb->tb_path, h) /*tb->S[h] */ || dest_bi.bi_bh != tb->R[h], "src (%p) must be == tb->S[h](%p) when it disappears", src_bi.bi_bh, PATH_H_PBUFFER(tb->tb_path, h)); /* when S[h] disappers replace left delemiting key as well */ if (tb->CFL[h]) replace_key(tb, cf, d_key_position, tb->CFL[h], tb->lkey[h]); } else replace_key(tb, cf, d_key_position, src_bi.bi_bh, nr - pointer_amount); } /* last parameter is del_parameter */ internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST, pointer_amount, 0); }
/* this can be invoked both to shift from S to L and from R to S */ static void internal_shift_left(int mode, /* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S */ struct tree_balance *tb, int h, int pointer_amount) { struct buffer_info dest_bi, src_bi; struct buffer_head *cf; int d_key_position; internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi, &d_key_position, &cf); /*printk("pointer_amount = %d\n",pointer_amount); */ if (pointer_amount) { /* insert delimiting key from common father of dest and src to node dest into position B_NR_ITEM(dest) */ internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf, d_key_position); if (B_NR_ITEMS(src_bi.bi_bh) == pointer_amount - 1) { if (src_bi.bi_position /*src->b_item_order */ == 0) replace_key(tb, cf, d_key_position, src_bi. bi_parent /*src->b_parent */ , 0); } else replace_key(tb, cf, d_key_position, src_bi.bi_bh, pointer_amount - 1); } /* last parameter is del_parameter */ internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST, pointer_amount, 0); }
static int reduce_file_callback(FS *fs, BLOCK *block, KEY *key, EFFECT *effect, void *data) { struct reduce_file_baton *baton = (struct reduce_file_baton *) data; char extent_prefix[MAX_INTERNAL_NAME+1]; unsigned long int start, stop; unsigned long int first_to_go; unsigned long int i; sprintf(extent_prefix, "%ld/X", baton->label); if (key->type == K_INVALID || strncmp(key->name, extent_prefix, strlen(extent_prefix)) != 0) return 0; sscanf(key->name + strlen(extent_prefix), "%ld-%ld", &start, &stop); if (stop < baton->new_num_blocks) { baton->num_blocks = stop+1; return 0; } first_to_go = MAX2(start, baton->new_num_blocks); for (i = first_to_go; i <= stop; i++) deallocate_block(fs, B_DATA, key->pointer + (i - start)); if (first_to_go <= start) delete_key(fs, block, key->name, effect); else { sprintf(extent_prefix, "%ld/X%08ld-%08ld", baton->label, start, first_to_go - 1); replace_key(fs, block, key->name, extent_prefix, K_ATTRIBUTE, key->pointer, effect); } baton->num_blocks = first_to_go; return 1; }
static int get_file_data_block_callback(FS *fs, BLOCK *block, KEY *key, EFFECT *effect, void *data) { struct get_file_data_block_baton *baton = (struct get_file_data_block_baton *) data; char extent_prefix[MAX_INTERNAL_NAME+1]; unsigned long int start = -1, stop = -1; BLOCK *b; sprintf(extent_prefix, "%ld/X", baton->fh->label); if (key->type != K_INVALID && strncmp(key->name, extent_prefix, strlen(extent_prefix)) == 0) { sscanf(key->name + strlen(extent_prefix), "%ld-%ld", &start, &stop); if (start <= baton->block_num && baton->block_num <= stop) { baton->location = key->pointer + (baton->block_num - start); return 1; } } b = allocate_block(fs, B_DATA, baton->predecessor); if (key->type != K_INVALID && strncmp(key->name, extent_prefix, strlen(extent_prefix)) == 0 && stop == baton->block_num - 1 && key->pointer + (stop - start) == b->location - 1) { sprintf(extent_prefix, "%ld/X%08ld-%08ld", baton->fh->label, start, baton->block_num); replace_key(fs, block, key->name, extent_prefix, K_ATTRIBUTE, key->pointer, effect); } else { sprintf(extent_prefix, "%ld/X%08ld-%08ld", baton->fh->label, baton->block_num, baton->block_num); insert_key(fs, block, extent_prefix, K_ATTRIBUTE, b->location, effect); } baton->location = b->location; return 1; }