xref: /openbmc/linux/fs/reiserfs/lbalance.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3  */
4 
5 #include <linux/config.h>
6 #include <asm/uaccess.h>
7 #include <linux/string.h>
8 #include <linux/time.h>
9 #include <linux/reiserfs_fs.h>
10 #include <linux/buffer_head.h>
11 
12 /* these are used in do_balance.c */
13 
14 /* leaf_move_items
15    leaf_shift_left
16    leaf_shift_right
17    leaf_delete_items
18    leaf_insert_into_buf
19    leaf_paste_in_buffer
20    leaf_cut_from_buffer
21    leaf_paste_entries
22    */
23 
24 
25 /* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
26 static void leaf_copy_dir_entries (struct buffer_info * dest_bi, struct buffer_head * source,
27 				   int last_first, int item_num, int from, int copy_count)
28 {
29     struct buffer_head * dest = dest_bi->bi_bh;
30     int item_num_in_dest;		/* either the number of target item,
31 					   or if we must create a new item,
32 					   the number of the item we will
33 					   create it next to */
34     struct item_head * ih;
35     struct reiserfs_de_head * deh;
36     int copy_records_len;			/* length of all records in item to be copied */
37     char * records;
38 
39     ih = B_N_PITEM_HEAD (source, item_num);
40 
41     RFALSE( !is_direntry_le_ih (ih), "vs-10000: item must be directory item");
42 
43     /* length of all record to be copied and first byte of the last of them */
44     deh = B_I_DEH (source, ih);
45     if (copy_count) {
46 	copy_records_len = (from ? deh_location( &(deh[from - 1]) ) :
47             ih_item_len(ih)) - deh_location( &(deh[from + copy_count - 1]));
48 	records = source->b_data + ih_location(ih) +
49                                 deh_location( &(deh[from + copy_count - 1]));
50     } else {
51 	copy_records_len = 0;
52 	records = NULL;
53     }
54 
55     /* when copy last to first, dest buffer can contain 0 items */
56     item_num_in_dest = (last_first == LAST_TO_FIRST) ? (( B_NR_ITEMS(dest) ) ? 0 : -1) : (B_NR_ITEMS(dest) - 1);
57 
58     /* if there are no items in dest or the first/last item in dest is not item of the same directory */
59     if ( (item_num_in_dest == - 1) ||
60 	(last_first == FIRST_TO_LAST && le_ih_k_offset (ih) == DOT_OFFSET) ||
61 	    (last_first == LAST_TO_FIRST && comp_short_le_keys/*COMP_SHORT_KEYS*/ (&ih->ih_key, B_N_PKEY (dest, item_num_in_dest)))) {
62 	/* create new item in dest */
63 	struct item_head new_ih;
64 
65 	/* form item header */
66 	memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
67 	put_ih_version( &new_ih, KEY_FORMAT_3_5 );
68 	/* calculate item len */
69 	put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len );
70 	put_ih_entry_count( &new_ih, 0 );
71 
72 	if (last_first == LAST_TO_FIRST) {
73 	    /* form key by the following way */
74 	    if (from < I_ENTRY_COUNT(ih)) {
75 		set_le_ih_k_offset( &new_ih, deh_offset( &(deh[from]) ) );
76 		/*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE);*/
77 	    } else {
78 		/* no entries will be copied to this item in this function */
79 		set_le_ih_k_offset (&new_ih, U32_MAX);
80 		/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
81 	    }
82 	    set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
83 	}
84 
85 	/* insert item into dest buffer */
86 	leaf_insert_into_buf (dest_bi, (last_first == LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest), &new_ih, NULL, 0);
87     } else {
88 	/* prepare space for entries */
89 	leaf_paste_in_buffer (dest_bi, (last_first==FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0, MAX_US_INT,
90 			      DEH_SIZE * copy_count + copy_records_len, records, 0
91 	    );
92     }
93 
94     item_num_in_dest = (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest)-1) : 0;
95 
96     leaf_paste_entries (dest_bi->bi_bh, item_num_in_dest,
97 			(last_first == FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD (dest, item_num_in_dest)) : 0,
98 			copy_count, deh + from, records,
99 			DEH_SIZE * copy_count + copy_records_len
100 	);
101 }
102 
103 
104 /* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or
105    part of it or nothing (see the return 0 below) from SOURCE to the end
106    (if last_first) or beginning (!last_first) of the DEST */
107 /* returns 1 if anything was copied, else 0 */
108 static int leaf_copy_boundary_item (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
109 				    int bytes_or_entries)
110 {
111   struct buffer_head * dest = dest_bi->bi_bh;
112   int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */
113   struct item_head * ih;
114   struct item_head * dih;
115 
116   dest_nr_item = B_NR_ITEMS(dest);
117 
118   if ( last_first == FIRST_TO_LAST ) {
119     /* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
120        or of different types ) then there is no need to treat this item differently from the other items
121        that we copy, so we return */
122     ih = B_N_PITEM_HEAD (src, 0);
123     dih = B_N_PITEM_HEAD (dest, dest_nr_item - 1);
124     if (!dest_nr_item || (!op_is_left_mergeable (&(ih->ih_key), src->b_size)))
125       /* there is nothing to merge */
126       return 0;
127 
128     RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length");
129 
130     if ( is_direntry_le_ih (ih) ) {
131       if ( bytes_or_entries == -1 )
132 	/* copy all entries to dest */
133 	bytes_or_entries = ih_entry_count(ih);
134       leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, 0, 0, bytes_or_entries);
135       return 1;
136     }
137 
138     /* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST
139        part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
140        */
141     if ( bytes_or_entries == -1 )
142       bytes_or_entries = ih_item_len(ih);
143 
144 #ifdef CONFIG_REISERFS_CHECK
145     else {
146       if (bytes_or_entries == ih_item_len(ih) && is_indirect_le_ih(ih))
147 	if (get_ih_free_space (ih))
148 	  reiserfs_panic (NULL, "vs-10020: leaf_copy_boundary_item: "
149 			  "last unformatted node must be filled entirely (%h)",
150 			  ih);
151     }
152 #endif
153 
154     /* merge first item (or its part) of src buffer with the last
155        item of dest buffer. Both are of the same file */
156     leaf_paste_in_buffer (dest_bi,
157 			  dest_nr_item - 1, ih_item_len(dih), bytes_or_entries, B_I_PITEM(src,ih), 0
158 			  );
159 
160     if (is_indirect_le_ih (dih)) {
161       RFALSE( get_ih_free_space (dih),
162               "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
163               ih);
164       if (bytes_or_entries == ih_item_len(ih))
165 	set_ih_free_space (dih, get_ih_free_space (ih));
166     }
167 
168     return 1;
169   }
170 
171 
172   /* copy boundary item to right (last_first == LAST_TO_FIRST) */
173 
174   /* ( DEST is empty or last item of SOURCE and first item of DEST
175      are the items of different object or of different types )
176      */
177   src_nr_item = B_NR_ITEMS (src);
178   ih = B_N_PITEM_HEAD (src, src_nr_item - 1);
179   dih = B_N_PITEM_HEAD (dest, 0);
180 
181   if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
182     return 0;
183 
184   if ( is_direntry_le_ih (ih)) {
185     if ( bytes_or_entries == -1 )
186       /* bytes_or_entries = entries number in last item body of SOURCE */
187       bytes_or_entries = ih_entry_count(ih);
188 
189     leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, src_nr_item - 1, ih_entry_count(ih) - bytes_or_entries, bytes_or_entries);
190     return 1;
191   }
192 
193   /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
194      part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
195      don't create new item header
196      */
197 
198   RFALSE( is_indirect_le_ih(ih) && get_ih_free_space (ih),
199           "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
200 		    ih);
201 
202   if ( bytes_or_entries == -1 ) {
203     /* bytes_or_entries = length of last item body of SOURCE */
204     bytes_or_entries = ih_item_len(ih);
205 
206     RFALSE( le_ih_k_offset (dih) !=
207             le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
208             "vs-10050: items %h and %h do not match", ih, dih);
209 
210     /* change first item key of the DEST */
211     set_le_ih_k_offset (dih, le_ih_k_offset (ih));
212 
213     /* item becomes non-mergeable */
214     /* or mergeable if left item was */
215     set_le_ih_k_type (dih, le_ih_k_type (ih));
216   } else {
217     /* merge to right only part of item */
218     RFALSE( ih_item_len(ih) <= bytes_or_entries,
219             "vs-10060: no so much bytes %lu (needed %lu)",
220             ( unsigned long )ih_item_len(ih), ( unsigned long )bytes_or_entries);
221 
222     /* change first item key of the DEST */
223     if ( is_direct_le_ih (dih) ) {
224       RFALSE( le_ih_k_offset (dih) <= (unsigned long)bytes_or_entries,
225 	      "vs-10070: dih %h, bytes_or_entries(%d)", dih, bytes_or_entries);
226       set_le_ih_k_offset (dih, le_ih_k_offset (dih) - bytes_or_entries);
227     } else {
228       RFALSE( le_ih_k_offset (dih) <=
229               (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
230               "vs-10080: dih %h, bytes_or_entries(%d)",
231               dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
232       set_le_ih_k_offset (dih, le_ih_k_offset (dih) - ((bytes_or_entries / UNFM_P_SIZE) * dest->b_size));
233     }
234   }
235 
236   leaf_paste_in_buffer (dest_bi, 0, 0, bytes_or_entries, B_I_PITEM(src,ih) + ih_item_len(ih) - bytes_or_entries, 0);
237   return 1;
238 }
239 
240 
241 /* copy cpy_mun items from buffer src to buffer dest
242  * last_first == FIRST_TO_LAST means, that we copy cpy_num  items beginning from first-th item in src to tail of dest
243  * last_first == LAST_TO_FIRST means, that we copy cpy_num  items beginning from first-th item in src to head of dest
244  */
245 static void leaf_copy_items_entirely (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
246 				      int first, int cpy_num)
247 {
248     struct buffer_head * dest;
249     int nr, free_space;
250     int dest_before;
251     int last_loc, last_inserted_loc, location;
252     int i, j;
253     struct block_head * blkh;
254     struct item_head * ih;
255 
256     RFALSE( last_first != LAST_TO_FIRST  && last_first != FIRST_TO_LAST,
257 	    "vs-10090: bad last_first parameter %d", last_first);
258     RFALSE( B_NR_ITEMS (src) - first < cpy_num,
259 	    "vs-10100: too few items in source %d, required %d from %d",
260 	    B_NR_ITEMS(src), cpy_num, first);
261     RFALSE( cpy_num < 0, "vs-10110: can not copy negative amount of items");
262     RFALSE( ! dest_bi, "vs-10120: can not copy negative amount of items");
263 
264     dest = dest_bi->bi_bh;
265 
266     RFALSE( ! dest, "vs-10130: can not copy negative amount of items");
267 
268     if (cpy_num == 0)
269 	return;
270 
271     blkh = B_BLK_HEAD(dest);
272     nr = blkh_nr_item( blkh );
273     free_space = blkh_free_space(blkh);
274 
275     /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
276     dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
277 
278     /* location of head of first new item */
279     ih = B_N_PITEM_HEAD (dest, dest_before);
280 
281     RFALSE( blkh_free_space(blkh) < cpy_num * IH_SIZE,
282             "vs-10140: not enough free space for headers %d (needed %d)",
283             B_FREE_SPACE (dest), cpy_num * IH_SIZE);
284 
285     /* prepare space for headers */
286     memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
287 
288     /* copy item headers */
289     memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
290 
291     free_space -= (IH_SIZE * cpy_num);
292     set_blkh_free_space( blkh, free_space );
293 
294     /* location of unmovable item */
295     j = location = (dest_before == 0) ? dest->b_size : ih_location(ih-1);
296     for (i = dest_before; i < nr + cpy_num; i ++) {
297         location -= ih_item_len( ih + i - dest_before );
298         put_ih_location( ih + i - dest_before, location );
299     }
300 
301     /* prepare space for items */
302     last_loc = ih_location( &(ih[nr+cpy_num-1-dest_before]) );
303     last_inserted_loc = ih_location( &(ih[cpy_num-1]) );
304 
305     /* check free space */
306     RFALSE( free_space < j - last_inserted_loc,
307 	    "vs-10150: not enough free space for items %d (needed %d)",
308             free_space, j - last_inserted_loc);
309 
310     memmove (dest->b_data + last_loc,
311 	     dest->b_data + last_loc + j - last_inserted_loc,
312 	     last_inserted_loc - last_loc);
313 
314     /* copy items */
315     memcpy (dest->b_data + last_inserted_loc, B_N_PITEM(src,(first + cpy_num - 1)),
316 	    j - last_inserted_loc);
317 
318     /* sizes, item number */
319     set_blkh_nr_item( blkh, nr + cpy_num );
320     set_blkh_free_space( blkh, free_space - (j - last_inserted_loc) );
321 
322     do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
323 
324     if (dest_bi->bi_parent) {
325 	struct disk_child *t_dc;
326 	t_dc = B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position);
327 	RFALSE( dc_block_number(t_dc) != dest->b_blocknr,
328 	        "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
329                 ( long unsigned ) dest->b_blocknr,
330 		( long unsigned ) dc_block_number(t_dc));
331 	put_dc_size( t_dc, dc_size(t_dc) + (j - last_inserted_loc + IH_SIZE * cpy_num ) );
332 
333 	do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
334     }
335 }
336 
337 
338 /* This function splits the (liquid) item into two items (useful when
339    shifting part of an item into another node.) */
340 static void leaf_item_bottle (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
341 			      int item_num, int cpy_bytes)
342 {
343     struct buffer_head * dest = dest_bi->bi_bh;
344     struct item_head * ih;
345 
346     RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item");
347 
348     if ( last_first == FIRST_TO_LAST ) {
349 	/* if ( if item in position item_num in buffer SOURCE is directory item ) */
350 	if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(src,item_num)))
351 	    leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, item_num, 0, cpy_bytes);
352 	else {
353 	    struct item_head n_ih;
354 
355 	    /* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST
356 	       part defined by 'cpy_bytes'; create new item header; change old item_header (????);
357 	       n_ih = new item_header;
358 	    */
359 	    memcpy (&n_ih, ih, IH_SIZE);
360 	    put_ih_item_len( &n_ih, cpy_bytes );
361 	    if (is_indirect_le_ih (ih)) {
362 		RFALSE( cpy_bytes == ih_item_len(ih) && get_ih_free_space(ih),
363 		        "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
364                         ( long unsigned ) get_ih_free_space (ih));
365 		set_ih_free_space (&n_ih, 0);
366 	    }
367 
368 	    RFALSE( op_is_left_mergeable (&(ih->ih_key), src->b_size),
369 		    "vs-10190: bad mergeability of item %h", ih);
370 	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
371 	    leaf_insert_into_buf (dest_bi, B_NR_ITEMS(dest), &n_ih, B_N_PITEM (src, item_num), 0);
372 	}
373     } else {
374 	/*  if ( if item in position item_num in buffer SOURCE is directory item ) */
375 	if (is_direntry_le_ih(ih = B_N_PITEM_HEAD (src, item_num)))
376 	    leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, item_num, I_ENTRY_COUNT(ih) - cpy_bytes, cpy_bytes);
377 	else {
378 	    struct item_head n_ih;
379 
380 	    /* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST
381 	       part defined by 'cpy_bytes'; create new item header;
382 	       n_ih = new item_header;
383 	    */
384 	    memcpy (&n_ih, ih, SHORT_KEY_SIZE);
385 
386 	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
387 
388 	    if (is_direct_le_ih (ih)) {
389 		set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + ih_item_len(ih) - cpy_bytes);
390 		set_le_ih_k_type (&n_ih, TYPE_DIRECT);
391 		set_ih_free_space (&n_ih, MAX_US_INT);
392 	    } else {
393 		/* indirect item */
394 		RFALSE( !cpy_bytes && get_ih_free_space (ih),
395 		        "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
396 		set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (ih_item_len(ih) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
397 		set_le_ih_k_type (&n_ih, TYPE_INDIRECT);
398 		set_ih_free_space (&n_ih, get_ih_free_space (ih));
399 	    }
400 
401 	    /* set item length */
402 	    put_ih_item_len( &n_ih, cpy_bytes );
403 
404 	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
405 
406 	    leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
407 	}
408     }
409 }
410 
411 
412 /* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST.
413    If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST.
414    From last item copy cpy_num bytes for regular item and cpy_num directory entries for
415    directory item. */
416 static int leaf_copy_items (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, int cpy_num,
417 			    int cpy_bytes)
418 {
419   struct buffer_head * dest;
420   int pos, i, src_nr_item, bytes;
421 
422   dest = dest_bi->bi_bh;
423   RFALSE( !dest || !src, "vs-10210: !dest || !src");
424   RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
425 	  "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
426   RFALSE( B_NR_ITEMS(src) < cpy_num,
427 	  "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src), cpy_num);
428   RFALSE( cpy_num < 0,"vs-10240: cpy_num < 0 (%d)", cpy_num);
429 
430  if ( cpy_num == 0 )
431    return 0;
432 
433  if ( last_first == FIRST_TO_LAST ) {
434    /* copy items to left */
435    pos = 0;
436    if ( cpy_num == 1 )
437      bytes = cpy_bytes;
438    else
439      bytes = -1;
440 
441    /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */
442    i = leaf_copy_boundary_item (dest_bi, src, FIRST_TO_LAST, bytes);
443    cpy_num -= i;
444    if ( cpy_num == 0 )
445      return i;
446    pos += i;
447    if ( cpy_bytes == -1 )
448      /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */
449      leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num);
450    else {
451      /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */
452      leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num-1);
453 
454      /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */
455      leaf_item_bottle (dest_bi, src, FIRST_TO_LAST, cpy_num+pos-1, cpy_bytes);
456    }
457  } else {
458    /* copy items to right */
459    src_nr_item = B_NR_ITEMS (src);
460    if ( cpy_num == 1 )
461      bytes = cpy_bytes;
462    else
463      bytes = -1;
464 
465    /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */
466    i = leaf_copy_boundary_item (dest_bi, src, LAST_TO_FIRST, bytes);
467 
468    cpy_num -= i;
469    if ( cpy_num == 0 )
470      return i;
471 
472    pos = src_nr_item - cpy_num - i;
473    if ( cpy_bytes == -1 ) {
474      /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */
475      leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos, cpy_num);
476    } else {
477      /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */
478      leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos+1, cpy_num-1);
479 
480      /* copy part of the item which number is pos to the begin of the DEST */
481      leaf_item_bottle (dest_bi, src, LAST_TO_FIRST, pos, cpy_bytes);
482    }
483  }
484  return i;
485 }
486 
487 
488 /* there are types of coping: from S[0] to L[0], from S[0] to R[0],
489    from R[0] to L[0]. for each of these we have to define parent and
490    positions of destination and source buffers */
491 static void leaf_define_dest_src_infos (int shift_mode, struct tree_balance * tb, struct buffer_info * dest_bi,
492 					struct buffer_info * src_bi, int * first_last,
493 					struct buffer_head * Snew)
494 {
495     memset (dest_bi, 0, sizeof (struct buffer_info));
496     memset (src_bi, 0, sizeof (struct buffer_info));
497 
498     /* define dest, src, dest parent, dest position */
499     switch (shift_mode) {
500     case LEAF_FROM_S_TO_L:    /* it is used in leaf_shift_left */
501 	src_bi->tb = tb;
502 	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
503 	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
504 	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	/* src->b_item_order */
505 	dest_bi->tb = tb;
506 	dest_bi->bi_bh = tb->L[0];
507 	dest_bi->bi_parent = tb->FL[0];
508 	dest_bi->bi_position = get_left_neighbor_position (tb, 0);
509 	*first_last = FIRST_TO_LAST;
510 	break;
511 
512     case LEAF_FROM_S_TO_R:  /* it is used in leaf_shift_right */
513 	src_bi->tb = tb;
514 	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
515 	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
516 	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);
517 	dest_bi->tb = tb;
518 	dest_bi->bi_bh = tb->R[0];
519 	dest_bi->bi_parent = tb->FR[0];
520 	dest_bi->bi_position = get_right_neighbor_position (tb, 0);
521 	*first_last = LAST_TO_FIRST;
522 	break;
523 
524     case LEAF_FROM_R_TO_L:  /* it is used in balance_leaf_when_delete */
525 	src_bi->tb = tb;
526 	src_bi->bi_bh = tb->R[0];
527 	src_bi->bi_parent = tb->FR[0];
528 	src_bi->bi_position = get_right_neighbor_position (tb, 0);
529 	dest_bi->tb = tb;
530 	dest_bi->bi_bh = tb->L[0];
531 	dest_bi->bi_parent = tb->FL[0];
532 	dest_bi->bi_position = get_left_neighbor_position (tb, 0);
533 	*first_last = FIRST_TO_LAST;
534 	break;
535 
536     case LEAF_FROM_L_TO_R:  /* it is used in balance_leaf_when_delete */
537 	src_bi->tb = tb;
538 	src_bi->bi_bh = tb->L[0];
539 	src_bi->bi_parent = tb->FL[0];
540 	src_bi->bi_position = get_left_neighbor_position (tb, 0);
541 	dest_bi->tb = tb;
542 	dest_bi->bi_bh = tb->R[0];
543 	dest_bi->bi_parent = tb->FR[0];
544 	dest_bi->bi_position = get_right_neighbor_position (tb, 0);
545 	*first_last = LAST_TO_FIRST;
546 	break;
547 
548     case LEAF_FROM_S_TO_SNEW:
549 	src_bi->tb = tb;
550 	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
551 	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
552 	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);
553 	dest_bi->tb = tb;
554 	dest_bi->bi_bh = Snew;
555 	dest_bi->bi_parent = NULL;
556 	dest_bi->bi_position = 0;
557 	*first_last = LAST_TO_FIRST;
558 	break;
559 
560     default:
561 	reiserfs_panic (NULL, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
562     }
563     RFALSE( src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
564 	    "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
565 	    shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
566 }
567 
568 
569 
570 
571 /* copy mov_num items and mov_bytes of the (mov_num-1)th item to
572    neighbor. Delete them from source */
573 int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew)
574 {
575   int ret_value;
576   struct buffer_info dest_bi, src_bi;
577   int first_last;
578 
579   leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);
580 
581   ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);
582 
583   leaf_delete_items (&src_bi, first_last, (first_last == FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) - mov_num), mov_num, mov_bytes);
584 
585 
586   return ret_value;
587 }
588 
589 
590 /* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)
591    from S[0] to L[0] and replace the delimiting key */
592 int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes)
593 {
594   struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
595   int i;
596 
597   /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */
598   i = leaf_move_items (LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
599 
600   if ( shift_num ) {
601     if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */
602 
603       RFALSE( shift_bytes != -1,
604 	      "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
605 	      shift_bytes);
606 #ifdef CONFIG_REISERFS_CHECK
607       if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
608 	print_cur_tb ("vs-10275");
609 	reiserfs_panic (tb->tb_sb, "vs-10275: leaf_shift_left: balance condition corrupted (%c)", tb->tb_mode);
610       }
611 #endif
612 
613       if (PATH_H_POSITION (tb->tb_path, 1) == 0)
614 	replace_key (tb, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0);
615 
616     } else {
617       /* replace lkey in CFL[0] by 0-th key from S[0]; */
618       replace_key (tb, tb->CFL[0], tb->lkey[0], S0, 0);
619 
620       RFALSE( (shift_bytes != -1 &&
621               !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
622                 && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&
623 	      (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)),
624 	      "vs-10280: item must be mergeable");
625     }
626   }
627 
628   return i;
629 }
630 
631 
632 
633 
634 
635 /* CLEANING STOPPED HERE */
636 
637 
638 
639 
640 /* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */
641 int	leaf_shift_right(
642 		struct tree_balance * tb,
643 		int shift_num,
644 		int shift_bytes
645 	)
646 {
647   //  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
648   int ret_value;
649 
650   /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */
651   ret_value = leaf_move_items (LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
652 
653   /* replace rkey in CFR[0] by the 0-th key from R[0] */
654   if (shift_num) {
655     replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
656 
657   }
658 
659   return ret_value;
660 }
661 
662 
663 
664 static void leaf_delete_items_entirely (struct buffer_info * bi,
665 					int first, int del_num);
666 /*  If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.
667     If not.
668     If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of
669     the first item. Part defined by del_bytes. Don't delete first item header
670     If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of
671     the last item . Part defined by del_bytes. Don't delete last item header.
672 */
673 void leaf_delete_items (struct buffer_info * cur_bi, int last_first,
674 			int first, int del_num, int del_bytes)
675 {
676     struct buffer_head * bh;
677     int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);
678 
679     RFALSE( !bh, "10155: bh is not defined");
680     RFALSE( del_num < 0, "10160: del_num can not be < 0. del_num==%d", del_num);
681     RFALSE( first < 0 || first + del_num > item_amount,
682 	    "10165: invalid number of first item to be deleted (%d) or "
683 	    "no so much items (%d) to delete (only %d)",
684 	    first, first + del_num, item_amount);
685 
686     if ( del_num == 0 )
687 	return;
688 
689     if ( first == 0 && del_num == item_amount && del_bytes == -1 ) {
690 	make_empty_node (cur_bi);
691 	do_balance_mark_leaf_dirty (cur_bi->tb, bh, 0);
692 	return;
693     }
694 
695     if ( del_bytes == -1 )
696 	/* delete del_num items beginning from item in position first */
697 	leaf_delete_items_entirely (cur_bi, first, del_num);
698     else {
699 	if ( last_first == FIRST_TO_LAST ) {
700 	    /* delete del_num-1 items beginning from item in position first  */
701 	    leaf_delete_items_entirely (cur_bi, first, del_num-1);
702 
703 	    /* delete the part of the first item of the bh
704 	       do not delete item header
705 	    */
706 	    leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);
707 	} else  {
708 	    struct item_head * ih;
709 	    int len;
710 
711 	    /* delete del_num-1 items beginning from item in position first+1  */
712 	    leaf_delete_items_entirely (cur_bi, first+1, del_num-1);
713 
714 	    if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) 	/* the last item is directory  */
715 	        /* len = numbers of directory entries in this item */
716 		len = ih_entry_count(ih);
717 	    else
718 	        /* len = body len of item */
719 		len = ih_item_len(ih);
720 
721 	    /* delete the part of the last item of the bh
722 	       do not delete item header
723 	    */
724 	    leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);
725 	}
726     }
727 }
728 
729 
730 /* insert item into the leaf node in position before */
731 void leaf_insert_into_buf (struct buffer_info * bi, int before,
732 			   struct item_head * inserted_item_ih,
733 			   const char * inserted_item_body,
734 			   int zeros_number)
735 {
736     struct buffer_head * bh = bi->bi_bh;
737     int nr, free_space;
738     struct block_head * blkh;
739     struct item_head * ih;
740     int i;
741     int last_loc, unmoved_loc;
742     char * to;
743 
744 
745     blkh = B_BLK_HEAD(bh);
746     nr = blkh_nr_item(blkh);
747     free_space = blkh_free_space( blkh );
748 
749     /* check free space */
750     RFALSE( free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
751             "vs-10170: not enough free space in block %z, new item %h",
752             bh, inserted_item_ih);
753     RFALSE( zeros_number > ih_item_len(inserted_item_ih),
754 	    "vs-10172: zero number == %d, item length == %d",
755             zeros_number, ih_item_len(inserted_item_ih));
756 
757 
758     /* get item new item must be inserted before */
759     ih = B_N_PITEM_HEAD (bh, before);
760 
761     /* prepare space for the body of new item */
762     last_loc = nr ? ih_location( &(ih[nr - before - 1]) ) : bh->b_size;
763     unmoved_loc = before ? ih_location( ih-1 ) : bh->b_size;
764 
765 
766     memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih),
767 	     bh->b_data + last_loc, unmoved_loc - last_loc);
768 
769     to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
770     memset (to, 0, zeros_number);
771     to += zeros_number;
772 
773     /* copy body to prepared space */
774     if (inserted_item_body)
775 	memmove (to, inserted_item_body, ih_item_len(inserted_item_ih) - zeros_number);
776     else
777 	memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
778 
779     /* insert item header */
780     memmove (ih + 1, ih, IH_SIZE * (nr - before));
781     memmove (ih, inserted_item_ih, IH_SIZE);
782 
783     /* change locations */
784     for (i = before; i < nr + 1; i ++)
785     {
786         unmoved_loc -= ih_item_len( &(ih[i-before]));
787 	put_ih_location( &(ih[i-before]), unmoved_loc );
788     }
789 
790     /* sizes, free space, item number */
791     set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
792     set_blkh_free_space( blkh,
793                     free_space - (IH_SIZE + ih_item_len(inserted_item_ih ) ) );
794     do_balance_mark_leaf_dirty (bi->tb, bh, 1);
795 
796     if (bi->bi_parent) {
797 	struct disk_child *t_dc;
798 	t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
799 	put_dc_size( t_dc, dc_size(t_dc) + (IH_SIZE + ih_item_len(inserted_item_ih)));
800 	do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
801     }
802 }
803 
804 
805 /* paste paste_size bytes to affected_item_num-th item.
806    When item is a directory, this only prepare space for new entries */
807 void leaf_paste_in_buffer (struct buffer_info * bi, int affected_item_num,
808 			   int pos_in_item, int paste_size,
809 			   const char * body,
810 			   int zeros_number)
811 {
812     struct buffer_head * bh = bi->bi_bh;
813     int nr, free_space;
814     struct block_head * blkh;
815     struct item_head * ih;
816     int i;
817     int last_loc, unmoved_loc;
818 
819     blkh = B_BLK_HEAD(bh);
820     nr = blkh_nr_item(blkh);
821     free_space = blkh_free_space(blkh);
822 
823 
824     /* check free space */
825     RFALSE( free_space < paste_size,
826             "vs-10175: not enough free space: needed %d, available %d",
827             paste_size, free_space);
828 
829 #ifdef CONFIG_REISERFS_CHECK
830     if (zeros_number > paste_size) {
831 	print_cur_tb ("10177");
832 	reiserfs_panic ( NULL, "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
833                          zeros_number, paste_size);
834     }
835 #endif /* CONFIG_REISERFS_CHECK */
836 
837 
838     /* item to be appended */
839     ih = B_N_PITEM_HEAD(bh, affected_item_num);
840 
841     last_loc = ih_location( &(ih[nr - affected_item_num - 1]) );
842     unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size;
843 
844     /* prepare space */
845     memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
846 	     unmoved_loc - last_loc);
847 
848 
849     /* change locations */
850     for (i = affected_item_num; i < nr; i ++)
851 	put_ih_location( &(ih[i-affected_item_num]),
852                     ih_location( &(ih[i-affected_item_num])) - paste_size );
853 
854     if ( body ) {
855 	if (!is_direntry_le_ih (ih)) {
856 	    if (!pos_in_item) {
857 		/* shift data to right */
858 		memmove (bh->b_data + ih_location(ih) + paste_size,
859 			 bh->b_data + ih_location(ih), ih_item_len(ih));
860 		/* paste data in the head of item */
861 		memset (bh->b_data + ih_location(ih), 0, zeros_number);
862 		memcpy (bh->b_data + ih_location(ih) + zeros_number, body, paste_size - zeros_number);
863 	    } else {
864 		memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number);
865 		memcpy (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number);
866 	    }
867 	}
868     }
869     else
870 	memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
871 
872     put_ih_item_len( ih, ih_item_len(ih) + paste_size );
873 
874     /* change free space */
875     set_blkh_free_space( blkh, free_space - paste_size );
876 
877     do_balance_mark_leaf_dirty (bi->tb, bh, 0);
878 
879     if (bi->bi_parent) {
880 	struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
881 	put_dc_size( t_dc, dc_size(t_dc) + paste_size );
882 	do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
883     }
884 }
885 
886 
887 /* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
888    does not have free space, so it moves DEHs and remaining records as
889    necessary. Return value is size of removed part of directory item
890    in bytes. */
891 static int	leaf_cut_entries (
892 				struct buffer_head * bh,
893 				struct item_head * ih,
894 				int from,
895 				int del_count
896 			)
897 {
898   char * item;
899   struct reiserfs_de_head * deh;
900   int prev_record_offset;	/* offset of record, that is (from-1)th */
901   char * prev_record;		/* */
902   int cut_records_len;		/* length of all removed records */
903   int i;
904 
905 
906   /* make sure, that item is directory and there are enough entries to
907      remove */
908   RFALSE( !is_direntry_le_ih (ih), "10180: item is not directory item");
909   RFALSE( I_ENTRY_COUNT(ih) < from + del_count,
910 	  "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
911 	  I_ENTRY_COUNT(ih), from, del_count);
912 
913   if (del_count == 0)
914     return 0;
915 
916   /* first byte of item */
917   item = bh->b_data + ih_location(ih);
918 
919   /* entry head array */
920   deh = B_I_DEH (bh, ih);
921 
922   /* first byte of remaining entries, those are BEFORE cut entries
923      (prev_record) and length of all removed records (cut_records_len) */
924   prev_record_offset = (from ? deh_location( &(deh[from - 1])) : ih_item_len(ih));
925   cut_records_len = prev_record_offset/*from_record*/ -
926                                 deh_location( &(deh[from + del_count - 1]));
927   prev_record = item + prev_record_offset;
928 
929 
930   /* adjust locations of remaining entries */
931   for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i --)
932     put_deh_location( &(deh[i]),
933                         deh_location( &deh[i] ) - (DEH_SIZE * del_count ) );
934 
935   for (i = 0; i < from; i ++)
936     put_deh_location( &(deh[i]),
937         deh_location( &deh[i] ) - (DEH_SIZE * del_count + cut_records_len) );
938 
939   put_ih_entry_count( ih, ih_entry_count(ih) - del_count );
940 
941   /* shift entry head array and entries those are AFTER removed entries */
942   memmove ((char *)(deh + from),
943 	   deh + from + del_count,
944 	   prev_record - cut_records_len - (char *)(deh + from + del_count));
945 
946   /* shift records, those are BEFORE removed entries */
947   memmove (prev_record - cut_records_len - DEH_SIZE * del_count,
948 	   prev_record, item + ih_item_len(ih) - prev_record);
949 
950   return DEH_SIZE * del_count + cut_records_len;
951 }
952 
953 
954 /*  when cut item is part of regular file
955         pos_in_item - first byte that must be cut
956         cut_size - number of bytes to be cut beginning from pos_in_item
957 
958    when cut item is part of directory
959         pos_in_item - number of first deleted entry
960         cut_size - count of deleted entries
961     */
962 void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num,
963 			   int pos_in_item, int cut_size)
964 {
965     int nr;
966     struct buffer_head * bh = bi->bi_bh;
967     struct block_head * blkh;
968     struct item_head * ih;
969     int last_loc, unmoved_loc;
970     int i;
971 
972     blkh = B_BLK_HEAD(bh);
973     nr = blkh_nr_item(blkh);
974 
975     /* item head of truncated item */
976     ih = B_N_PITEM_HEAD (bh, cut_item_num);
977 
978     if (is_direntry_le_ih (ih)) {
979         /* first cut entry ()*/
980         cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size);
981         if (pos_in_item == 0) {
982 	        /* change key */
983             RFALSE( cut_item_num,
984                     "when 0-th enrty of item is cut, that item must be first in the node, not %d-th", cut_item_num);
985             /* change item key by key of first entry in the item */
986 	    set_le_ih_k_offset (ih, deh_offset(B_I_DEH (bh, ih)));
987             /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/
988 	    }
989     } else {
990         /* item is direct or indirect */
991         RFALSE( is_statdata_le_ih (ih), "10195: item is stat data");
992         RFALSE( pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
993                 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
994                 ( long unsigned ) pos_in_item, ( long unsigned ) cut_size,
995 		( long unsigned ) ih_item_len (ih));
996 
997         /* shift item body to left if cut is from the head of item */
998         if (pos_in_item == 0) {
999             memmove( bh->b_data + ih_location(ih),
1000 		     bh->b_data + ih_location(ih) + cut_size,
1001 		     ih_item_len(ih) - cut_size);
1002 
1003             /* change key of item */
1004             if (is_direct_le_ih (ih))
1005 		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + cut_size);
1006             else {
1007 		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + (cut_size / UNFM_P_SIZE) * bh->b_size);
1008                 RFALSE( ih_item_len(ih) == cut_size && get_ih_free_space (ih),
1009                         "10205: invalid ih_free_space (%h)", ih);
1010 	        }
1011 	    }
1012     }
1013 
1014 
1015     /* location of the last item */
1016     last_loc = ih_location( &(ih[nr - cut_item_num - 1]) );
1017 
1018     /* location of the item, which is remaining at the same place */
1019     unmoved_loc = cut_item_num ? ih_location(ih-1) : bh->b_size;
1020 
1021 
1022     /* shift */
1023     memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1024 	       unmoved_loc - last_loc - cut_size);
1025 
1026     /* change item length */
1027     put_ih_item_len( ih, ih_item_len(ih) - cut_size );
1028 
1029     if (is_indirect_le_ih (ih)) {
1030         if (pos_in_item)
1031             set_ih_free_space (ih, 0);
1032     }
1033 
1034     /* change locations */
1035     for (i = cut_item_num; i < nr; i ++)
1036     put_ih_location( &(ih[i-cut_item_num]), ih_location( &ih[i-cut_item_num]) + cut_size );
1037 
1038     /* size, free space */
1039     set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
1040 
1041     do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1042 
1043     if (bi->bi_parent) {
1044       struct disk_child *t_dc;
1045       t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
1046       put_dc_size( t_dc, dc_size(t_dc) - cut_size );
1047       do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
1048     }
1049 }
1050 
1051 
1052 /* delete del_num items from buffer starting from the first'th item */
1053 static void leaf_delete_items_entirely (struct buffer_info * bi,
1054 					int first, int del_num)
1055 {
1056     struct buffer_head * bh = bi->bi_bh;
1057     int nr;
1058     int i, j;
1059     int last_loc, last_removed_loc;
1060     struct block_head * blkh;
1061     struct item_head * ih;
1062 
1063   RFALSE( bh == NULL, "10210: buffer is 0");
1064   RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1065 
1066   if (del_num == 0)
1067     return;
1068 
1069   blkh = B_BLK_HEAD(bh);
1070   nr = blkh_nr_item(blkh);
1071 
1072   RFALSE( first < 0 || first + del_num > nr,
1073           "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
1074 
1075   if (first == 0 && del_num == nr) {
1076     /* this does not work */
1077     make_empty_node (bi);
1078 
1079     do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1080     return;
1081   }
1082 
1083   ih = B_N_PITEM_HEAD (bh, first);
1084 
1085   /* location of unmovable item */
1086   j = (first == 0) ? bh->b_size : ih_location(ih-1);
1087 
1088   /* delete items */
1089   last_loc = ih_location( &(ih[nr-1-first]) );
1090   last_removed_loc = ih_location( &(ih[del_num-1]) );
1091 
1092   memmove (bh->b_data + last_loc + j - last_removed_loc,
1093 	   bh->b_data + last_loc, last_removed_loc - last_loc);
1094 
1095   /* delete item headers */
1096   memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1097 
1098   /* change item location */
1099   for (i = first; i < nr - del_num; i ++)
1100     put_ih_location( &(ih[i-first]), ih_location( &(ih[i-first]) ) + (j - last_removed_loc) );
1101 
1102   /* sizes, item number */
1103   set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );
1104   set_blkh_free_space( blkh, blkh_free_space(blkh) + (j - last_removed_loc + IH_SIZE * del_num) );
1105 
1106   do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1107 
1108   if (bi->bi_parent) {
1109     struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
1110     put_dc_size( t_dc, dc_size(t_dc) -
1111 				(j - last_removed_loc + IH_SIZE * del_num));
1112     do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
1113   }
1114 }
1115 
1116 
1117 
1118 
1119 
1120 /* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */
1121 void    leaf_paste_entries (
1122 			struct buffer_head * bh,
1123 			int item_num,
1124 			int before,
1125 			int new_entry_count,
1126 			struct reiserfs_de_head * new_dehs,
1127 			const char * records,
1128 			int paste_size
1129 		)
1130 {
1131     struct item_head * ih;
1132     char * item;
1133     struct reiserfs_de_head * deh;
1134     char * insert_point;
1135     int i, old_entry_num;
1136 
1137     if (new_entry_count == 0)
1138         return;
1139 
1140     ih = B_N_PITEM_HEAD(bh, item_num);
1141 
1142   /* make sure, that item is directory, and there are enough records in it */
1143   RFALSE( !is_direntry_le_ih (ih), "10225: item is not directory item");
1144   RFALSE( I_ENTRY_COUNT (ih) < before,
1145 	  "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
1146 	  I_ENTRY_COUNT (ih), before);
1147 
1148 
1149   /* first byte of dest item */
1150   item = bh->b_data + ih_location(ih);
1151 
1152   /* entry head array */
1153   deh = B_I_DEH (bh, ih);
1154 
1155   /* new records will be pasted at this point */
1156   insert_point = item + (before ? deh_location( &(deh[before - 1])) : (ih_item_len(ih) - paste_size));
1157 
1158   /* adjust locations of records that will be AFTER new records */
1159   for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i --)
1160     put_deh_location( &(deh[i]),
1161                 deh_location(&(deh[i])) + (DEH_SIZE * new_entry_count ));
1162 
1163   /* adjust locations of records that will be BEFORE new records */
1164   for (i = 0; i < before; i ++)
1165     put_deh_location( &(deh[i]), deh_location(&(deh[i])) + paste_size );
1166 
1167   old_entry_num = I_ENTRY_COUNT(ih);
1168   put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count );
1169 
1170   /* prepare space for pasted records */
1171   memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point);
1172 
1173   /* copy new records */
1174   memcpy (insert_point + DEH_SIZE * new_entry_count, records,
1175 		   paste_size - DEH_SIZE * new_entry_count);
1176 
1177   /* prepare space for new entry heads */
1178   deh += before;
1179   memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh);
1180 
1181   /* copy new entry heads */
1182   deh = (struct reiserfs_de_head *)((char *)deh);
1183   memcpy (deh, new_dehs, DEH_SIZE * new_entry_count);
1184 
1185   /* set locations of new records */
1186   for (i = 0; i < new_entry_count; i ++)
1187   {
1188     put_deh_location( &(deh[i]),
1189         deh_location( &(deh[i] )) +
1190         (- deh_location( &(new_dehs[new_entry_count - 1])) +
1191         insert_point + DEH_SIZE * new_entry_count - item));
1192   }
1193 
1194 
1195   /* change item key if necessary (when we paste before 0-th entry */
1196   if (!before)
1197     {
1198 	set_le_ih_k_offset (ih, deh_offset(new_dehs));
1199 /*      memcpy (&ih->ih_key.k_offset,
1200 		       &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
1201     }
1202 
1203 #ifdef CONFIG_REISERFS_CHECK
1204   {
1205     int prev, next;
1206     /* check record locations */
1207     deh = B_I_DEH (bh, ih);
1208     for (i = 0; i < I_ENTRY_COUNT(ih); i ++) {
1209       next = (i < I_ENTRY_COUNT(ih) - 1) ? deh_location( &(deh[i + 1])) : 0;
1210       prev = (i != 0) ? deh_location( &(deh[i - 1]) ) : 0;
1211 
1212       if (prev && prev <= deh_location( &(deh[i])))
1213 	reiserfs_warning (NULL, "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)",
1214 			  ih, deh + i - 1, i, deh + i);
1215       if (next && next >= deh_location( &(deh[i])))
1216 	reiserfs_warning (NULL, "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)",
1217 			  ih, i, deh + i, deh + i + 1);
1218     }
1219   }
1220 #endif
1221 
1222 }
1223