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