⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbalance.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
    int pos, i, src_nr_item, bytes;    dest = dest_bi->bi_bh;    if ( cpy_num == 0 )	return 0;     if ( last_first == FIRST_TO_LAST ) {	/* copy items to left */	pos = 0;	if ( cpy_num == 1 )	    bytes = cpy_bytes;	else	    bytes = -1;   	/* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */	i = leaf_copy_boundary_item (fs, dest_bi, src, FIRST_TO_LAST, bytes);	cpy_num -= i;	if ( cpy_num == 0 )	    return i;	pos += i;	if ( cpy_bytes == -1 )	    /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */	    leaf_copy_items_entirely(fs, dest_bi, src, FIRST_TO_LAST, pos, cpy_num);	else {	    /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */	    leaf_copy_items_entirely(fs, dest_bi, src, FIRST_TO_LAST, pos, cpy_num-1);	     	    /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */	    leaf_item_bottle (fs, dest_bi, src, FIRST_TO_LAST, cpy_num+pos-1, cpy_bytes);	}     } else {	/* copy items to right */	src_nr_item = B_NR_ITEMS (src);	if ( cpy_num == 1 )	    bytes = cpy_bytes;	else	    bytes = -1;   	/* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */	i = leaf_copy_boundary_item (fs, dest_bi, src, LAST_TO_FIRST, bytes);   	cpy_num -= i;	if ( cpy_num == 0 )	    return i;   	pos = src_nr_item - cpy_num - i;	if ( cpy_bytes == -1 ) {	    /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */	    leaf_copy_items_entirely(fs, dest_bi, src, LAST_TO_FIRST, pos, cpy_num);	} else {	    /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */	    leaf_copy_items_entirely(fs, dest_bi, src, LAST_TO_FIRST, pos+1, cpy_num-1);	    /* copy part of the item which number is pos to the begin of the DEST */	    leaf_item_bottle (fs, dest_bi, src, LAST_TO_FIRST, pos, cpy_bytes);	}    }    return i;}/* there are types of coping: from S[0] to L[0], from S[0] to R[0],   from R[0] to L[0]. for each of these we have to define parent and   positions of destination and source buffers */static void leaf_define_dest_src_infos (int shift_mode, struct tree_balance * tb, struct buffer_info * dest_bi,					struct buffer_info * src_bi, int * first_last,					struct buffer_head * Snew){    /* define dest, src, dest parent, dest position */    switch (shift_mode) {    case LEAF_FROM_S_TO_L:    /* it is used in leaf_shift_left */	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	/* src->b_item_order */	dest_bi->bi_bh = tb->L[0];	dest_bi->bi_parent = tb->FL[0];	dest_bi->bi_position = get_left_neighbor_position (tb, 0);	*first_last = FIRST_TO_LAST;	break;    case LEAF_FROM_S_TO_R:  /* it is used in leaf_shift_right */	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	dest_bi->bi_bh = tb->R[0];	dest_bi->bi_parent = tb->FR[0];	dest_bi->bi_position = get_right_neighbor_position (tb, 0);	*first_last = LAST_TO_FIRST;	break;    case LEAF_FROM_R_TO_L:  /* it is used in balance_leaf_when_delete */	src_bi->bi_bh = tb->R[0];	src_bi->bi_parent = tb->FR[0];	src_bi->bi_position = get_right_neighbor_position (tb, 0);	dest_bi->bi_bh = tb->L[0];	dest_bi->bi_parent = tb->FL[0];	dest_bi->bi_position = get_left_neighbor_position (tb, 0);	*first_last = FIRST_TO_LAST;	break;        case LEAF_FROM_L_TO_R:  /* it is used in balance_leaf_when_delete */	src_bi->bi_bh = tb->L[0];	src_bi->bi_parent = tb->FL[0];	src_bi->bi_position = get_left_neighbor_position (tb, 0);	dest_bi->bi_bh = tb->R[0];	dest_bi->bi_parent = tb->FR[0];	dest_bi->bi_position = get_right_neighbor_position (tb, 0);	*first_last = LAST_TO_FIRST;	break;    case LEAF_FROM_S_TO_SNEW:	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	dest_bi->bi_bh = Snew;	dest_bi->bi_parent = 0;	dest_bi->bi_position = 0;	*first_last = LAST_TO_FIRST;	break;        default:	reiserfs_panic (0, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);    }}/* copy mov_num items and mov_bytes of the (mov_num-1)th item to   neighbor. Delete them from source */int leaf_move_items (int shift_mode, struct tree_balance * tb, 		     int mov_num, int mov_bytes, struct buffer_head * Snew){    int ret_value;    struct buffer_info dest_bi, src_bi;    int first_last;    leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);    ret_value = leaf_copy_items (tb->tb_fs, &dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);    leaf_delete_items (tb->tb_fs, &src_bi, first_last, (first_last == FIRST_TO_LAST) ? 0 : 		       (B_NR_ITEMS(src_bi.bi_bh) - mov_num), mov_num, mov_bytes);      return ret_value;}/* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)   from S[0] to L[0] and replace the delimiting key */int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes){    struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);    int i;    /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */    i = leaf_move_items (LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, 0);    if ( shift_num ) {	if (B_NR_ITEMS (S0) == 0) { 	    /* everything is moved from S[0] */	    if (PATH_H_POSITION (tb->tb_path, 1) == 0)		replace_key(tb->tb_fs, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0);	} else {	    /* replace lkey in CFL[0] by 0-th key from S[0]; */	    replace_key(tb->tb_fs, tb->CFL[0], tb->lkey[0], S0, 0);      	}    }      return i;}/* CLEANING STOPPED HERE *//* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */int leaf_shift_right (struct tree_balance * tb, int shift_num, int shift_bytes){    int ret_value;    /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */    ret_value = leaf_move_items (LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, 0);    /* replace rkey in CFR[0] by the 0-th key from R[0] */    if (shift_num) {	replace_key(tb->tb_fs, tb->CFR[0], tb->rkey[0], tb->R[0], 0);    }    return ret_value;}static void leaf_delete_items_entirely (reiserfs_filsys_t * sb,					/*struct reiserfs_transaction_handle *th,*/					struct buffer_info * bi,					int first,					int del_num);/*  If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.    If not.     If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of    the first item. Part defined by del_bytes. Don't delete first item header    If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of    the last item . Part defined by del_bytes. Don't delete last item header.*/void leaf_delete_items (reiserfs_filsys_t * fs,			struct buffer_info * cur_bi,			int last_first, 			int first, int del_num, int del_bytes){    struct buffer_head * bh;    int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);        if ( del_num == 0 )	return;        if ( first == 0 && del_num == item_amount && del_bytes == -1 ) {	make_empty_node (cur_bi);	mark_buffer_dirty (bh);	return;    }        if ( del_bytes == -1 )	/* delete del_num items beginning from item in position first */	leaf_delete_items_entirely (fs, cur_bi, first, del_num);    else {	if ( last_first == FIRST_TO_LAST ) {	    /* delete del_num-1 items beginning from item in position first  */	    leaf_delete_items_entirely (fs, cur_bi, first, del_num-1);	    	    /* delete the part of the first item of the bh do not	       delete item header */	    leaf_cut_from_buffer (fs, cur_bi, 0, 0, del_bytes);	} else  {	    struct item_head * ih;	    int len;	    	    /* delete del_num-1 items beginning from item in position first+1  */	    leaf_delete_items_entirely (fs, cur_bi, first+1, del_num-1);	    	    if (I_IS_DIRECTORY_ITEM(ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) 	/* the last item is directory  */	        /* len = numbers of directory entries in this item */	        len = get_ih_entry_count(ih);	    else		/* len = body len of item */ 	        len = get_ih_item_len (ih);	    	    /* delete the part of the last item of the bh 	       do not delete item header	    */	    leaf_cut_from_buffer (fs, cur_bi, B_NR_ITEMS(bh) - 1, len - del_bytes, del_bytes);	}    }}/* insert item into the leaf node in position before */void leaf_insert_into_buf (reiserfs_filsys_t * s,			   struct buffer_info * bi,			   int before,			   struct item_head * inserted_item_ih,			   const char * inserted_item_body,			   int zeros_number			   ){    struct buffer_head * bh = bi->bi_bh;    int nr;    struct block_head * blkh;    struct item_head * ih;    int i;    int last_loc, unmoved_loc;    char * to;    blkh = B_BLK_HEAD (bh);    nr = get_blkh_nr_items (blkh);    /* get item new item must be inserted before */    ih = B_N_PITEM_HEAD (bh, before);    /* prepare space for the body of new item */    last_loc = nr ? get_ih_location (&ih[nr - before - 1]) : bh->b_size;    unmoved_loc = before ? get_ih_location (ih-1) : bh->b_size;    memmove (bh->b_data + last_loc - get_ih_item_len (inserted_item_ih), 	     bh->b_data + last_loc, unmoved_loc - last_loc);    to = bh->b_data + unmoved_loc - get_ih_item_len (inserted_item_ih);    memset (to, 0, zeros_number);    to += zeros_number;    /* copy body to prepared space */    if (inserted_item_body)	//if (mem_mode == REISERFS_USER_MEM)	//  copy_from_user (to, inserted_item_body, inserted_item_ih->ih_item_len - zeros_number);	//else {	memmove (to, inserted_item_body, get_ih_item_len (inserted_item_ih) - zeros_number);    //}    else	memset(to, '\0', get_ih_item_len (inserted_item_ih) - zeros_number);      /* insert item header */    memmove (ih + 1, ih, IH_SIZE * (nr - before));    memmove (ih, inserted_item_ih, IH_SIZE);      /* change locations */    for (i = before; i < nr + 1; i ++) {	unmoved_loc -= get_ih_item_len (&ih[i-before]);	set_ih_location (&ih[i-before], unmoved_loc);    }      /* sizes, free space, item number */    set_blkh_nr_items (blkh, get_blkh_nr_items (blkh) + 1);    set_blkh_free_space (blkh, get_blkh_free_space (blkh) -			 (IH_SIZE + get_ih_item_len (inserted_item_ih)));    mark_buffer_dirty(bh) ;    if (bi->bi_parent) { 	struct disk_child * dc;	dc = B_N_CHILD (bi->bi_parent, bi->bi_position);	set_dc_child_size (dc, get_dc_child_size (dc) + IH_SIZE + get_ih_item_len (inserted_item_ih));	mark_buffer_dirty(bi->bi_parent) ;    }    if (is_a_leaf(bh->b_data, bh->b_size) != THE_LEAF)	reiserfs_panic ("leaf_insert_into_buf: bad leaf %lu: %b", bh->b_blocknr, bh);}/* paste paste_size bytes to affected_item_num-th item.    When item is a directory, this only prepare space for new entries */void leaf_paste_in_buffer (reiserfs_filsys_t * fs,			   struct buffer_info * bi,			   int affected_item_num,			   int pos_in_item,			   int paste_size,			   const char * body,			   int zeros_number){    struct buffer_head * bh = bi->bi_bh;    int nr;    struct block_head * blkh;    struct item_head * ih;    int i;    int last_loc, unmoved_loc;    blkh = B_BLK_HEAD (bh);    nr = get_blkh_nr_items (blkh);    /* item to be appended */    ih = B_N_PITEM_HEAD(bh, affected_item_num);    last_loc = get_ih_location (&ih[nr - affected_item_num - 1]);    unmoved_loc = affected_item_num ? get_ih_location (ih-1) : bh->b_size;      /* prepare space */    memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,	     unmoved_loc - last_loc);    /* change locations */    for (i = affected_item_num; i < nr; i ++)	set_ih_location (&ih[i-affected_item_num], get_ih_location (&ih[i-affected_item_num]) - paste_size);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -