Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / reiserfs / lbalance.c
blob2406608fc5cd1a88bdff65048a3ffa9476292939
1 /*
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */
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>
12 /* these are used in do_balance.c */
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
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)
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;
39 ih = B_N_PITEM_HEAD (source, item_num);
41 RFALSE( !is_direntry_le_ih (ih), "vs-10000: item must be directory item");
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;
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);
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;
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 );
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 */
82 set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
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
94 item_num_in_dest = (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest)-1) : 0;
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
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)
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;
116 dest_nr_item = B_NR_ITEMS(dest);
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;
128 RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length");
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;
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
141 if ( bytes_or_entries == -1 )
142 bytes_or_entries = ih_item_len(ih);
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);
152 #endif
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
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));
168 return 1;
172 /* copy boundary item to right (last_first == LAST_TO_FIRST) */
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 )
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);
181 if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
182 return 0;
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);
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;
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
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);
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);
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);
210 /* change first item key of the DEST */
211 set_le_ih_k_offset (dih, le_ih_k_offset (ih));
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);
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));
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;
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
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)
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;
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");
264 dest = dest_bi->bi_bh;
266 RFALSE( ! dest, "vs-10130: can not copy negative amount of items");
268 if (cpy_num == 0)
269 return;
271 blkh = B_BLK_HEAD(dest);
272 nr = blkh_nr_item( blkh );
273 free_space = blkh_free_space(blkh);
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;
278 /* location of head of first new item */
279 ih = B_N_PITEM_HEAD (dest, dest_before);
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);
285 /* prepare space for headers */
286 memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
288 /* copy item headers */
289 memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
291 free_space -= (IH_SIZE * cpy_num);
292 set_blkh_free_space( blkh, free_space );
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 );
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]) );
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);
310 memmove (dest->b_data + last_loc,
311 dest->b_data + last_loc + j - last_inserted_loc,
312 last_inserted_loc - last_loc);
314 /* copy items */
315 memcpy (dest->b_data + last_inserted_loc, B_N_PITEM(src,(first + cpy_num - 1)),
316 j - last_inserted_loc);
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) );
322 do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
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 ) );
333 do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
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)
343 struct buffer_head * dest = dest_bi->bi_bh;
344 struct item_head * ih;
346 RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item");
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;
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;
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);
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);
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;
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;
384 memcpy (&n_ih, ih, SHORT_KEY_SIZE);
386 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
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));
401 /* set item length */
402 put_ih_item_len( &n_ih, cpy_bytes );
404 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
406 leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
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)
419 struct buffer_head * dest;
420 int pos, i, src_nr_item, bytes;
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);
430 if ( cpy_num == 0 )
431 return 0;
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;
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);
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);
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;
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);
468 cpy_num -= i;
469 if ( cpy_num == 0 )
470 return i;
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);
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);
484 return i;
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)
495 memset (dest_bi, 0, sizeof (struct buffer_info));
496 memset (src_bi, 0, sizeof (struct buffer_info));
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;
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;
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;
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;
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;
560 default:
561 reiserfs_panic (NULL, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
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);
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)
575 int ret_value;
576 struct buffer_info dest_bi, src_bi;
577 int first_last;
579 leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);
581 ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);
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);
586 return ret_value;
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)
594 struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
595 int i;
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);
600 if ( shift_num ) {
601 if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */
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);
611 #endif
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);
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);
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");
628 return i;
635 /* CLEANING STOPPED HERE */
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
647 // struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
648 int ret_value;
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);
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);
659 return ret_value;
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.
673 void leaf_delete_items (struct buffer_info * cur_bi, int last_first,
674 int first, int del_num, int del_bytes)
676 struct buffer_head * bh;
677 int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);
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);
686 if ( del_num == 0 )
687 return;
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;
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);
703 /* delete the part of the first item of the bh
704 do not delete item header
706 leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);
707 } else {
708 struct item_head * ih;
709 int len;
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);
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);
721 /* delete the part of the last item of the bh
722 do not delete item header
724 leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);
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)
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;
745 blkh = B_BLK_HEAD(bh);
746 nr = blkh_nr_item(blkh);
747 free_space = blkh_free_space( blkh );
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));
758 /* get item new item must be inserted before */
759 ih = B_N_PITEM_HEAD (bh, before);
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;
766 memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih),
767 bh->b_data + last_loc, unmoved_loc - last_loc);
769 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
770 memset (to, 0, zeros_number);
771 to += zeros_number;
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);
779 /* insert item header */
780 memmove (ih + 1, ih, IH_SIZE * (nr - before));
781 memmove (ih, inserted_item_ih, IH_SIZE);
783 /* change locations */
784 for (i = before; i < nr + 1; i ++)
786 unmoved_loc -= ih_item_len( &(ih[i-before]));
787 put_ih_location( &(ih[i-before]), unmoved_loc );
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);
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);
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)
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;
819 blkh = B_BLK_HEAD(bh);
820 nr = blkh_nr_item(blkh);
821 free_space = blkh_free_space(blkh);
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);
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);
835 #endif /* CONFIG_REISERFS_CHECK */
838 /* item to be appended */
839 ih = B_N_PITEM_HEAD(bh, affected_item_num);
841 last_loc = ih_location( &(ih[nr - affected_item_num - 1]) );
842 unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size;
844 /* prepare space */
845 memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
846 unmoved_loc - last_loc);
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 );
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);
869 else
870 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
872 put_ih_item_len( ih, ih_item_len(ih) + paste_size );
874 /* change free space */
875 set_blkh_free_space( blkh, free_space - paste_size );
877 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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
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;
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);
913 if (del_count == 0)
914 return 0;
916 /* first byte of item */
917 item = bh->b_data + ih_location(ih);
919 /* entry head array */
920 deh = B_I_DEH (bh, ih);
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;
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 ) );
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) );
939 put_ih_entry_count( ih, ih_entry_count(ih) - del_count );
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));
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);
950 return DEH_SIZE * del_count + cut_records_len;
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
958 when cut item is part of directory
959 pos_in_item - number of first deleted entry
960 cut_size - count of deleted entries
962 void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num,
963 int pos_in_item, int cut_size)
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;
972 blkh = B_BLK_HEAD(bh);
973 nr = blkh_nr_item(blkh);
975 /* item head of truncated item */
976 ih = B_N_PITEM_HEAD (bh, cut_item_num);
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);*/
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));
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);
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);
1015 /* location of the last item */
1016 last_loc = ih_location( &(ih[nr - cut_item_num - 1]) );
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;
1022 /* shift */
1023 memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1024 unmoved_loc - last_loc - cut_size);
1026 /* change item length */
1027 put_ih_item_len( ih, ih_item_len(ih) - cut_size );
1029 if (is_indirect_le_ih (ih)) {
1030 if (pos_in_item)
1031 set_ih_free_space (ih, 0);
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 );
1038 /* size, free space */
1039 set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
1041 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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)
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;
1063 RFALSE( bh == NULL, "10210: buffer is 0");
1064 RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1066 if (del_num == 0)
1067 return;
1069 blkh = B_BLK_HEAD(bh);
1070 nr = blkh_nr_item(blkh);
1072 RFALSE( first < 0 || first + del_num > nr,
1073 "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
1075 if (first == 0 && del_num == nr) {
1076 /* this does not work */
1077 make_empty_node (bi);
1079 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1080 return;
1083 ih = B_N_PITEM_HEAD (bh, first);
1085 /* location of unmovable item */
1086 j = (first == 0) ? bh->b_size : ih_location(ih-1);
1088 /* delete items */
1089 last_loc = ih_location( &(ih[nr-1-first]) );
1090 last_removed_loc = ih_location( &(ih[del_num-1]) );
1092 memmove (bh->b_data + last_loc + j - last_removed_loc,
1093 bh->b_data + last_loc, last_removed_loc - last_loc);
1095 /* delete item headers */
1096 memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
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) );
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) );
1106 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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
1131 struct item_head * ih;
1132 char * item;
1133 struct reiserfs_de_head * deh;
1134 char * insert_point;
1135 int i, old_entry_num;
1137 if (new_entry_count == 0)
1138 return;
1140 ih = B_N_PITEM_HEAD(bh, item_num);
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);
1149 /* first byte of dest item */
1150 item = bh->b_data + ih_location(ih);
1152 /* entry head array */
1153 deh = B_I_DEH (bh, ih);
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));
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 ));
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 );
1167 old_entry_num = I_ENTRY_COUNT(ih);
1168 put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count );
1170 /* prepare space for pasted records */
1171 memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point);
1173 /* copy new records */
1174 memcpy (insert_point + DEH_SIZE * new_entry_count, records,
1175 paste_size - DEH_SIZE * new_entry_count);
1177 /* prepare space for new entry heads */
1178 deh += before;
1179 memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh);
1181 /* copy new entry heads */
1182 deh = (struct reiserfs_de_head *)((char *)deh);
1183 memcpy (deh, new_dehs, DEH_SIZE * new_entry_count);
1185 /* set locations of new records */
1186 for (i = 0; i < new_entry_count; i ++)
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));
1195 /* change item key if necessary (when we paste before 0-th entry */
1196 if (!before)
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);*/
1203 #ifdef CONFIG_REISERFS_CHECK
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;
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);
1220 #endif