kmemtrace: SLOB hooks.
[linux-2.6/kmemtrace.git] / fs / reiserfs / lbalance.c
blob6de060a6aa7fc79c04a6f1d3d3a6b70648bd2af6
1 /*
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */
5 #include <asm/uaccess.h>
6 #include <linux/string.h>
7 #include <linux/time.h>
8 #include <linux/reiserfs_fs.h>
9 #include <linux/buffer_head.h>
11 /* these are used in do_balance.c */
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
23 /* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
24 static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
25 struct buffer_head *source, int last_first,
26 int item_num, int from, int copy_count)
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;
38 ih = B_N_PITEM_HEAD(source, item_num);
40 RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
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)) -
47 deh_location(&(deh[from + copy_count - 1]));
48 records =
49 source->b_data + ih_location(ih) +
50 deh_location(&(deh[from + copy_count - 1]));
51 } else {
52 copy_records_len = 0;
53 records = NULL;
56 /* when copy last to first, dest buffer can contain 0 items */
57 item_num_in_dest =
58 (last_first ==
59 LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
60 - 1);
62 /* if there are no items in dest or the first/last item in dest is not item of the same directory */
63 if ((item_num_in_dest == -1) ||
64 (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
65 (last_first == LAST_TO_FIRST
66 && comp_short_le_keys /*COMP_SHORT_KEYS */ (&ih->ih_key,
67 B_N_PKEY(dest,
68 item_num_in_dest))))
70 /* create new item in dest */
71 struct item_head new_ih;
73 /* form item header */
74 memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
75 put_ih_version(&new_ih, KEY_FORMAT_3_5);
76 /* calculate item len */
77 put_ih_item_len(&new_ih,
78 DEH_SIZE * copy_count + copy_records_len);
79 put_ih_entry_count(&new_ih, 0);
81 if (last_first == LAST_TO_FIRST) {
82 /* form key by the following way */
83 if (from < I_ENTRY_COUNT(ih)) {
84 set_le_ih_k_offset(&new_ih,
85 deh_offset(&(deh[from])));
86 /*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE); */
87 } else {
88 /* no entries will be copied to this item in this function */
89 set_le_ih_k_offset(&new_ih, U32_MAX);
90 /* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
92 set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key),
93 TYPE_DIRENTRY);
96 /* insert item into dest buffer */
97 leaf_insert_into_buf(dest_bi,
98 (last_first ==
99 LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest),
100 &new_ih, NULL, 0);
101 } else {
102 /* prepare space for entries */
103 leaf_paste_in_buffer(dest_bi,
104 (last_first ==
105 FIRST_TO_LAST) ? (B_NR_ITEMS(dest) -
106 1) : 0, MAX_US_INT,
107 DEH_SIZE * copy_count + copy_records_len,
108 records, 0);
111 item_num_in_dest =
112 (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
114 leaf_paste_entries(dest_bi->bi_bh, item_num_in_dest,
115 (last_first ==
116 FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD(dest,
117 item_num_in_dest))
118 : 0, copy_count, deh + from, records,
119 DEH_SIZE * copy_count + copy_records_len);
122 /* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or
123 part of it or nothing (see the return 0 below) from SOURCE to the end
124 (if last_first) or beginning (!last_first) of the DEST */
125 /* returns 1 if anything was copied, else 0 */
126 static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
127 struct buffer_head *src, int last_first,
128 int bytes_or_entries)
130 struct buffer_head *dest = dest_bi->bi_bh;
131 int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */
132 struct item_head *ih;
133 struct item_head *dih;
135 dest_nr_item = B_NR_ITEMS(dest);
137 if (last_first == FIRST_TO_LAST) {
138 /* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
139 or of different types ) then there is no need to treat this item differently from the other items
140 that we copy, so we return */
141 ih = B_N_PITEM_HEAD(src, 0);
142 dih = B_N_PITEM_HEAD(dest, dest_nr_item - 1);
143 if (!dest_nr_item
144 || (!op_is_left_mergeable(&(ih->ih_key), src->b_size)))
145 /* there is nothing to merge */
146 return 0;
148 RFALSE(!ih_item_len(ih),
149 "vs-10010: item can not have empty length");
151 if (is_direntry_le_ih(ih)) {
152 if (bytes_or_entries == -1)
153 /* copy all entries to dest */
154 bytes_or_entries = ih_entry_count(ih);
155 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, 0, 0,
156 bytes_or_entries);
157 return 1;
160 /* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST
161 part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
163 if (bytes_or_entries == -1)
164 bytes_or_entries = ih_item_len(ih);
166 #ifdef CONFIG_REISERFS_CHECK
167 else {
168 if (bytes_or_entries == ih_item_len(ih)
169 && is_indirect_le_ih(ih))
170 if (get_ih_free_space(ih))
171 reiserfs_panic(NULL,
172 "vs-10020: leaf_copy_boundary_item: "
173 "last unformatted node must be filled entirely (%h)",
174 ih);
176 #endif
178 /* merge first item (or its part) of src buffer with the last
179 item of dest buffer. Both are of the same file */
180 leaf_paste_in_buffer(dest_bi,
181 dest_nr_item - 1, ih_item_len(dih),
182 bytes_or_entries, B_I_PITEM(src, ih), 0);
184 if (is_indirect_le_ih(dih)) {
185 RFALSE(get_ih_free_space(dih),
186 "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
187 ih);
188 if (bytes_or_entries == ih_item_len(ih))
189 set_ih_free_space(dih, get_ih_free_space(ih));
192 return 1;
195 /* copy boundary item to right (last_first == LAST_TO_FIRST) */
197 /* ( DEST is empty or last item of SOURCE and first item of DEST
198 are the items of different object or of different types )
200 src_nr_item = B_NR_ITEMS(src);
201 ih = B_N_PITEM_HEAD(src, src_nr_item - 1);
202 dih = B_N_PITEM_HEAD(dest, 0);
204 if (!dest_nr_item || !op_is_left_mergeable(&(dih->ih_key), src->b_size))
205 return 0;
207 if (is_direntry_le_ih(ih)) {
208 if (bytes_or_entries == -1)
209 /* bytes_or_entries = entries number in last item body of SOURCE */
210 bytes_or_entries = ih_entry_count(ih);
212 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
213 src_nr_item - 1,
214 ih_entry_count(ih) - bytes_or_entries,
215 bytes_or_entries);
216 return 1;
219 /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
220 part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
221 don't create new item header
224 RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
225 "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
226 ih);
228 if (bytes_or_entries == -1) {
229 /* bytes_or_entries = length of last item body of SOURCE */
230 bytes_or_entries = ih_item_len(ih);
232 RFALSE(le_ih_k_offset(dih) !=
233 le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
234 "vs-10050: items %h and %h do not match", ih, dih);
236 /* change first item key of the DEST */
237 set_le_ih_k_offset(dih, le_ih_k_offset(ih));
239 /* item becomes non-mergeable */
240 /* or mergeable if left item was */
241 set_le_ih_k_type(dih, le_ih_k_type(ih));
242 } else {
243 /* merge to right only part of item */
244 RFALSE(ih_item_len(ih) <= bytes_or_entries,
245 "vs-10060: no so much bytes %lu (needed %lu)",
246 (unsigned long)ih_item_len(ih),
247 (unsigned long)bytes_or_entries);
249 /* change first item key of the DEST */
250 if (is_direct_le_ih(dih)) {
251 RFALSE(le_ih_k_offset(dih) <=
252 (unsigned long)bytes_or_entries,
253 "vs-10070: dih %h, bytes_or_entries(%d)", dih,
254 bytes_or_entries);
255 set_le_ih_k_offset(dih,
256 le_ih_k_offset(dih) -
257 bytes_or_entries);
258 } else {
259 RFALSE(le_ih_k_offset(dih) <=
260 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
261 "vs-10080: dih %h, bytes_or_entries(%d)",
262 dih,
263 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
264 set_le_ih_k_offset(dih,
265 le_ih_k_offset(dih) -
266 ((bytes_or_entries / UNFM_P_SIZE) *
267 dest->b_size));
271 leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
272 B_I_PITEM(src,
273 ih) + ih_item_len(ih) - bytes_or_entries,
275 return 1;
278 /* copy cpy_mun items from buffer src to buffer dest
279 * last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning from first-th item in src to tail of dest
280 * last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning from first-th item in src to head of dest
282 static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
283 struct buffer_head *src, int last_first,
284 int first, int cpy_num)
286 struct buffer_head *dest;
287 int nr, free_space;
288 int dest_before;
289 int last_loc, last_inserted_loc, location;
290 int i, j;
291 struct block_head *blkh;
292 struct item_head *ih;
294 RFALSE(last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST,
295 "vs-10090: bad last_first parameter %d", last_first);
296 RFALSE(B_NR_ITEMS(src) - first < cpy_num,
297 "vs-10100: too few items in source %d, required %d from %d",
298 B_NR_ITEMS(src), cpy_num, first);
299 RFALSE(cpy_num < 0, "vs-10110: can not copy negative amount of items");
300 RFALSE(!dest_bi, "vs-10120: can not copy negative amount of items");
302 dest = dest_bi->bi_bh;
304 RFALSE(!dest, "vs-10130: can not copy negative amount of items");
306 if (cpy_num == 0)
307 return;
309 blkh = B_BLK_HEAD(dest);
310 nr = blkh_nr_item(blkh);
311 free_space = blkh_free_space(blkh);
313 /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
314 dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
316 /* location of head of first new item */
317 ih = B_N_PITEM_HEAD(dest, dest_before);
319 RFALSE(blkh_free_space(blkh) < cpy_num * IH_SIZE,
320 "vs-10140: not enough free space for headers %d (needed %d)",
321 B_FREE_SPACE(dest), cpy_num * IH_SIZE);
323 /* prepare space for headers */
324 memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
326 /* copy item headers */
327 memcpy(ih, B_N_PITEM_HEAD(src, first), cpy_num * IH_SIZE);
329 free_space -= (IH_SIZE * cpy_num);
330 set_blkh_free_space(blkh, free_space);
332 /* location of unmovable item */
333 j = location = (dest_before == 0) ? dest->b_size : ih_location(ih - 1);
334 for (i = dest_before; i < nr + cpy_num; i++) {
335 location -= ih_item_len(ih + i - dest_before);
336 put_ih_location(ih + i - dest_before, location);
339 /* prepare space for items */
340 last_loc = ih_location(&(ih[nr + cpy_num - 1 - dest_before]));
341 last_inserted_loc = ih_location(&(ih[cpy_num - 1]));
343 /* check free space */
344 RFALSE(free_space < j - last_inserted_loc,
345 "vs-10150: not enough free space for items %d (needed %d)",
346 free_space, j - last_inserted_loc);
348 memmove(dest->b_data + last_loc,
349 dest->b_data + last_loc + j - last_inserted_loc,
350 last_inserted_loc - last_loc);
352 /* copy items */
353 memcpy(dest->b_data + last_inserted_loc,
354 B_N_PITEM(src, (first + cpy_num - 1)), j - last_inserted_loc);
356 /* sizes, item number */
357 set_blkh_nr_item(blkh, nr + cpy_num);
358 set_blkh_free_space(blkh, free_space - (j - last_inserted_loc));
360 do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
362 if (dest_bi->bi_parent) {
363 struct disk_child *t_dc;
364 t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
365 RFALSE(dc_block_number(t_dc) != dest->b_blocknr,
366 "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
367 (long unsigned)dest->b_blocknr,
368 (long unsigned)dc_block_number(t_dc));
369 put_dc_size(t_dc,
370 dc_size(t_dc) + (j - last_inserted_loc +
371 IH_SIZE * cpy_num));
373 do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
378 /* This function splits the (liquid) item into two items (useful when
379 shifting part of an item into another node.) */
380 static void leaf_item_bottle(struct buffer_info *dest_bi,
381 struct buffer_head *src, int last_first,
382 int item_num, int cpy_bytes)
384 struct buffer_head *dest = dest_bi->bi_bh;
385 struct item_head *ih;
387 RFALSE(cpy_bytes == -1,
388 "vs-10170: bytes == - 1 means: do not split item");
390 if (last_first == FIRST_TO_LAST) {
391 /* if ( if item in position item_num in buffer SOURCE is directory item ) */
392 if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
393 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
394 item_num, 0, cpy_bytes);
395 else {
396 struct item_head n_ih;
398 /* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST
399 part defined by 'cpy_bytes'; create new item header; change old item_header (????);
400 n_ih = new item_header;
402 memcpy(&n_ih, ih, IH_SIZE);
403 put_ih_item_len(&n_ih, cpy_bytes);
404 if (is_indirect_le_ih(ih)) {
405 RFALSE(cpy_bytes == ih_item_len(ih)
406 && get_ih_free_space(ih),
407 "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
408 (long unsigned)get_ih_free_space(ih));
409 set_ih_free_space(&n_ih, 0);
412 RFALSE(op_is_left_mergeable(&(ih->ih_key), src->b_size),
413 "vs-10190: bad mergeability of item %h", ih);
414 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
415 leaf_insert_into_buf(dest_bi, B_NR_ITEMS(dest), &n_ih,
416 B_N_PITEM(src, item_num), 0);
418 } else {
419 /* if ( if item in position item_num in buffer SOURCE is directory item ) */
420 if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
421 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
422 item_num,
423 I_ENTRY_COUNT(ih) - cpy_bytes,
424 cpy_bytes);
425 else {
426 struct item_head n_ih;
428 /* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST
429 part defined by 'cpy_bytes'; create new item header;
430 n_ih = new item_header;
432 memcpy(&n_ih, ih, SHORT_KEY_SIZE);
434 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
436 if (is_direct_le_ih(ih)) {
437 set_le_ih_k_offset(&n_ih,
438 le_ih_k_offset(ih) +
439 ih_item_len(ih) - cpy_bytes);
440 set_le_ih_k_type(&n_ih, TYPE_DIRECT);
441 set_ih_free_space(&n_ih, MAX_US_INT);
442 } else {
443 /* indirect item */
444 RFALSE(!cpy_bytes && get_ih_free_space(ih),
445 "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
446 set_le_ih_k_offset(&n_ih,
447 le_ih_k_offset(ih) +
448 (ih_item_len(ih) -
449 cpy_bytes) / UNFM_P_SIZE *
450 dest->b_size);
451 set_le_ih_k_type(&n_ih, TYPE_INDIRECT);
452 set_ih_free_space(&n_ih, get_ih_free_space(ih));
455 /* set item length */
456 put_ih_item_len(&n_ih, cpy_bytes);
458 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
460 leaf_insert_into_buf(dest_bi, 0, &n_ih,
461 B_N_PITEM(src,
462 item_num) +
463 ih_item_len(ih) - cpy_bytes, 0);
468 /* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST.
469 If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST.
470 From last item copy cpy_num bytes for regular item and cpy_num directory entries for
471 directory item. */
472 static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
473 int last_first, int cpy_num, int cpy_bytes)
475 struct buffer_head *dest;
476 int pos, i, src_nr_item, bytes;
478 dest = dest_bi->bi_bh;
479 RFALSE(!dest || !src, "vs-10210: !dest || !src");
480 RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
481 "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
482 RFALSE(B_NR_ITEMS(src) < cpy_num,
483 "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src),
484 cpy_num);
485 RFALSE(cpy_num < 0, "vs-10240: cpy_num < 0 (%d)", cpy_num);
487 if (cpy_num == 0)
488 return 0;
490 if (last_first == FIRST_TO_LAST) {
491 /* copy items to left */
492 pos = 0;
493 if (cpy_num == 1)
494 bytes = cpy_bytes;
495 else
496 bytes = -1;
498 /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */
499 i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
500 cpy_num -= i;
501 if (cpy_num == 0)
502 return i;
503 pos += i;
504 if (cpy_bytes == -1)
505 /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */
506 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
507 pos, cpy_num);
508 else {
509 /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */
510 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
511 pos, cpy_num - 1);
513 /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */
514 leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
515 cpy_num + pos - 1, cpy_bytes);
517 } else {
518 /* copy items to right */
519 src_nr_item = B_NR_ITEMS(src);
520 if (cpy_num == 1)
521 bytes = cpy_bytes;
522 else
523 bytes = -1;
525 /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */
526 i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
528 cpy_num -= i;
529 if (cpy_num == 0)
530 return i;
532 pos = src_nr_item - cpy_num - i;
533 if (cpy_bytes == -1) {
534 /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */
535 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
536 pos, cpy_num);
537 } else {
538 /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */
539 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
540 pos + 1, cpy_num - 1);
542 /* copy part of the item which number is pos to the begin of the DEST */
543 leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
544 cpy_bytes);
547 return i;
550 /* there are types of coping: from S[0] to L[0], from S[0] to R[0],
551 from R[0] to L[0]. for each of these we have to define parent and
552 positions of destination and source buffers */
553 static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
554 struct buffer_info *dest_bi,
555 struct buffer_info *src_bi,
556 int *first_last,
557 struct buffer_head *Snew)
559 memset(dest_bi, 0, sizeof(struct buffer_info));
560 memset(src_bi, 0, sizeof(struct buffer_info));
562 /* define dest, src, dest parent, dest position */
563 switch (shift_mode) {
564 case LEAF_FROM_S_TO_L: /* it is used in leaf_shift_left */
565 src_bi->tb = tb;
566 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
567 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
568 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0); /* src->b_item_order */
569 dest_bi->tb = tb;
570 dest_bi->bi_bh = tb->L[0];
571 dest_bi->bi_parent = tb->FL[0];
572 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
573 *first_last = FIRST_TO_LAST;
574 break;
576 case LEAF_FROM_S_TO_R: /* it is used in leaf_shift_right */
577 src_bi->tb = tb;
578 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
579 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
580 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
581 dest_bi->tb = tb;
582 dest_bi->bi_bh = tb->R[0];
583 dest_bi->bi_parent = tb->FR[0];
584 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
585 *first_last = LAST_TO_FIRST;
586 break;
588 case LEAF_FROM_R_TO_L: /* it is used in balance_leaf_when_delete */
589 src_bi->tb = tb;
590 src_bi->bi_bh = tb->R[0];
591 src_bi->bi_parent = tb->FR[0];
592 src_bi->bi_position = get_right_neighbor_position(tb, 0);
593 dest_bi->tb = tb;
594 dest_bi->bi_bh = tb->L[0];
595 dest_bi->bi_parent = tb->FL[0];
596 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
597 *first_last = FIRST_TO_LAST;
598 break;
600 case LEAF_FROM_L_TO_R: /* it is used in balance_leaf_when_delete */
601 src_bi->tb = tb;
602 src_bi->bi_bh = tb->L[0];
603 src_bi->bi_parent = tb->FL[0];
604 src_bi->bi_position = get_left_neighbor_position(tb, 0);
605 dest_bi->tb = tb;
606 dest_bi->bi_bh = tb->R[0];
607 dest_bi->bi_parent = tb->FR[0];
608 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
609 *first_last = LAST_TO_FIRST;
610 break;
612 case LEAF_FROM_S_TO_SNEW:
613 src_bi->tb = tb;
614 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
615 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
616 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
617 dest_bi->tb = tb;
618 dest_bi->bi_bh = Snew;
619 dest_bi->bi_parent = NULL;
620 dest_bi->bi_position = 0;
621 *first_last = LAST_TO_FIRST;
622 break;
624 default:
625 reiserfs_panic(NULL,
626 "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)",
627 shift_mode);
629 RFALSE(!src_bi->bi_bh || !dest_bi->bi_bh,
630 "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
631 shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
634 /* copy mov_num items and mov_bytes of the (mov_num-1)th item to
635 neighbor. Delete them from source */
636 int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
637 int mov_bytes, struct buffer_head *Snew)
639 int ret_value;
640 struct buffer_info dest_bi, src_bi;
641 int first_last;
643 leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
644 &first_last, Snew);
646 ret_value =
647 leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
648 mov_bytes);
650 leaf_delete_items(&src_bi, first_last,
651 (first_last ==
652 FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) -
653 mov_num), mov_num, mov_bytes);
655 return ret_value;
658 /* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)
659 from S[0] to L[0] and replace the delimiting key */
660 int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
662 struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
663 int i;
665 /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */
666 i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
668 if (shift_num) {
669 if (B_NR_ITEMS(S0) == 0) { /* number of items in S[0] == 0 */
671 RFALSE(shift_bytes != -1,
672 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
673 shift_bytes);
674 #ifdef CONFIG_REISERFS_CHECK
675 if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
676 print_cur_tb("vs-10275");
677 reiserfs_panic(tb->tb_sb,
678 "vs-10275: leaf_shift_left: balance condition corrupted (%c)",
679 tb->tb_mode);
681 #endif
683 if (PATH_H_POSITION(tb->tb_path, 1) == 0)
684 replace_key(tb, tb->CFL[0], tb->lkey[0],
685 PATH_H_PPARENT(tb->tb_path, 0), 0);
687 } else {
688 /* replace lkey in CFL[0] by 0-th key from S[0]; */
689 replace_key(tb, tb->CFL[0], tb->lkey[0], S0, 0);
691 RFALSE((shift_bytes != -1 &&
692 !(is_direntry_le_ih(B_N_PITEM_HEAD(S0, 0))
693 && !I_ENTRY_COUNT(B_N_PITEM_HEAD(S0, 0)))) &&
694 (!op_is_left_mergeable
695 (B_N_PKEY(S0, 0), S0->b_size)),
696 "vs-10280: item must be mergeable");
700 return i;
703 /* CLEANING STOPPED HERE */
705 /* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */
706 int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
708 // struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
709 int ret_value;
711 /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */
712 ret_value =
713 leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
715 /* replace rkey in CFR[0] by the 0-th key from R[0] */
716 if (shift_num) {
717 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
721 return ret_value;
724 static void leaf_delete_items_entirely(struct buffer_info *bi,
725 int first, int del_num);
726 /* If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.
727 If not.
728 If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of
729 the first item. Part defined by del_bytes. Don't delete first item header
730 If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of
731 the last item . Part defined by del_bytes. Don't delete last item header.
733 void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
734 int first, int del_num, int del_bytes)
736 struct buffer_head *bh;
737 int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
739 RFALSE(!bh, "10155: bh is not defined");
740 RFALSE(del_num < 0, "10160: del_num can not be < 0. del_num==%d",
741 del_num);
742 RFALSE(first < 0
743 || first + del_num > item_amount,
744 "10165: invalid number of first item to be deleted (%d) or "
745 "no so much items (%d) to delete (only %d)", first,
746 first + del_num, item_amount);
748 if (del_num == 0)
749 return;
751 if (first == 0 && del_num == item_amount && del_bytes == -1) {
752 make_empty_node(cur_bi);
753 do_balance_mark_leaf_dirty(cur_bi->tb, bh, 0);
754 return;
757 if (del_bytes == -1)
758 /* delete del_num items beginning from item in position first */
759 leaf_delete_items_entirely(cur_bi, first, del_num);
760 else {
761 if (last_first == FIRST_TO_LAST) {
762 /* delete del_num-1 items beginning from item in position first */
763 leaf_delete_items_entirely(cur_bi, first, del_num - 1);
765 /* delete the part of the first item of the bh
766 do not delete item header
768 leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
769 } else {
770 struct item_head *ih;
771 int len;
773 /* delete del_num-1 items beginning from item in position first+1 */
774 leaf_delete_items_entirely(cur_bi, first + 1,
775 del_num - 1);
777 if (is_direntry_le_ih
778 (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh) - 1)))
779 /* the last item is directory */
780 /* len = numbers of directory entries in this item */
781 len = ih_entry_count(ih);
782 else
783 /* len = body len of item */
784 len = ih_item_len(ih);
786 /* delete the part of the last item of the bh
787 do not delete item header
789 leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
790 len - del_bytes, del_bytes);
795 /* insert item into the leaf node in position before */
796 void leaf_insert_into_buf(struct buffer_info *bi, int before,
797 struct item_head *inserted_item_ih,
798 const char *inserted_item_body, int zeros_number)
800 struct buffer_head *bh = bi->bi_bh;
801 int nr, free_space;
802 struct block_head *blkh;
803 struct item_head *ih;
804 int i;
805 int last_loc, unmoved_loc;
806 char *to;
808 blkh = B_BLK_HEAD(bh);
809 nr = blkh_nr_item(blkh);
810 free_space = blkh_free_space(blkh);
812 /* check free space */
813 RFALSE(free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
814 "vs-10170: not enough free space in block %z, new item %h",
815 bh, inserted_item_ih);
816 RFALSE(zeros_number > ih_item_len(inserted_item_ih),
817 "vs-10172: zero number == %d, item length == %d",
818 zeros_number, ih_item_len(inserted_item_ih));
820 /* get item new item must be inserted before */
821 ih = B_N_PITEM_HEAD(bh, before);
823 /* prepare space for the body of new item */
824 last_loc = nr ? ih_location(&(ih[nr - before - 1])) : bh->b_size;
825 unmoved_loc = before ? ih_location(ih - 1) : bh->b_size;
827 memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
828 bh->b_data + last_loc, unmoved_loc - last_loc);
830 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
831 memset(to, 0, zeros_number);
832 to += zeros_number;
834 /* copy body to prepared space */
835 if (inserted_item_body)
836 memmove(to, inserted_item_body,
837 ih_item_len(inserted_item_ih) - zeros_number);
838 else
839 memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
841 /* insert item header */
842 memmove(ih + 1, ih, IH_SIZE * (nr - before));
843 memmove(ih, inserted_item_ih, IH_SIZE);
845 /* change locations */
846 for (i = before; i < nr + 1; i++) {
847 unmoved_loc -= ih_item_len(&(ih[i - before]));
848 put_ih_location(&(ih[i - before]), unmoved_loc);
851 /* sizes, free space, item number */
852 set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
853 set_blkh_free_space(blkh,
854 free_space - (IH_SIZE +
855 ih_item_len(inserted_item_ih)));
856 do_balance_mark_leaf_dirty(bi->tb, bh, 1);
858 if (bi->bi_parent) {
859 struct disk_child *t_dc;
860 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
861 put_dc_size(t_dc,
862 dc_size(t_dc) + (IH_SIZE +
863 ih_item_len(inserted_item_ih)));
864 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
868 /* paste paste_size bytes to affected_item_num-th item.
869 When item is a directory, this only prepare space for new entries */
870 void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
871 int pos_in_item, int paste_size,
872 const char *body, int zeros_number)
874 struct buffer_head *bh = bi->bi_bh;
875 int nr, free_space;
876 struct block_head *blkh;
877 struct item_head *ih;
878 int i;
879 int last_loc, unmoved_loc;
881 blkh = B_BLK_HEAD(bh);
882 nr = blkh_nr_item(blkh);
883 free_space = blkh_free_space(blkh);
885 /* check free space */
886 RFALSE(free_space < paste_size,
887 "vs-10175: not enough free space: needed %d, available %d",
888 paste_size, free_space);
890 #ifdef CONFIG_REISERFS_CHECK
891 if (zeros_number > paste_size) {
892 print_cur_tb("10177");
893 reiserfs_panic(NULL,
894 "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
895 zeros_number, paste_size);
897 #endif /* CONFIG_REISERFS_CHECK */
899 /* item to be appended */
900 ih = B_N_PITEM_HEAD(bh, affected_item_num);
902 last_loc = ih_location(&(ih[nr - affected_item_num - 1]));
903 unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
905 /* prepare space */
906 memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
907 unmoved_loc - last_loc);
909 /* change locations */
910 for (i = affected_item_num; i < nr; i++)
911 put_ih_location(&(ih[i - affected_item_num]),
912 ih_location(&(ih[i - affected_item_num])) -
913 paste_size);
915 if (body) {
916 if (!is_direntry_le_ih(ih)) {
917 if (!pos_in_item) {
918 /* shift data to right */
919 memmove(bh->b_data + ih_location(ih) +
920 paste_size,
921 bh->b_data + ih_location(ih),
922 ih_item_len(ih));
923 /* paste data in the head of item */
924 memset(bh->b_data + ih_location(ih), 0,
925 zeros_number);
926 memcpy(bh->b_data + ih_location(ih) +
927 zeros_number, body,
928 paste_size - zeros_number);
929 } else {
930 memset(bh->b_data + unmoved_loc - paste_size, 0,
931 zeros_number);
932 memcpy(bh->b_data + unmoved_loc - paste_size +
933 zeros_number, body,
934 paste_size - zeros_number);
937 } else
938 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
940 put_ih_item_len(ih, ih_item_len(ih) + paste_size);
942 /* change free space */
943 set_blkh_free_space(blkh, free_space - paste_size);
945 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
947 if (bi->bi_parent) {
948 struct disk_child *t_dc =
949 B_N_CHILD(bi->bi_parent, bi->bi_position);
950 put_dc_size(t_dc, dc_size(t_dc) + paste_size);
951 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
955 /* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
956 does not have free space, so it moves DEHs and remaining records as
957 necessary. Return value is size of removed part of directory item
958 in bytes. */
959 static int leaf_cut_entries(struct buffer_head *bh,
960 struct item_head *ih, int from, int del_count)
962 char *item;
963 struct reiserfs_de_head *deh;
964 int prev_record_offset; /* offset of record, that is (from-1)th */
965 char *prev_record; /* */
966 int cut_records_len; /* length of all removed records */
967 int i;
969 /* make sure, that item is directory and there are enough entries to
970 remove */
971 RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
972 RFALSE(I_ENTRY_COUNT(ih) < from + del_count,
973 "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
974 I_ENTRY_COUNT(ih), from, del_count);
976 if (del_count == 0)
977 return 0;
979 /* first byte of item */
980 item = bh->b_data + ih_location(ih);
982 /* entry head array */
983 deh = B_I_DEH(bh, ih);
985 /* first byte of remaining entries, those are BEFORE cut entries
986 (prev_record) and length of all removed records (cut_records_len) */
987 prev_record_offset =
988 (from ? deh_location(&(deh[from - 1])) : ih_item_len(ih));
989 cut_records_len = prev_record_offset /*from_record */ -
990 deh_location(&(deh[from + del_count - 1]));
991 prev_record = item + prev_record_offset;
993 /* adjust locations of remaining entries */
994 for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i--)
995 put_deh_location(&(deh[i]),
996 deh_location(&deh[i]) -
997 (DEH_SIZE * del_count));
999 for (i = 0; i < from; i++)
1000 put_deh_location(&(deh[i]),
1001 deh_location(&deh[i]) - (DEH_SIZE * del_count +
1002 cut_records_len));
1004 put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
1006 /* shift entry head array and entries those are AFTER removed entries */
1007 memmove((char *)(deh + from),
1008 deh + from + del_count,
1009 prev_record - cut_records_len - (char *)(deh + from +
1010 del_count));
1012 /* shift records, those are BEFORE removed entries */
1013 memmove(prev_record - cut_records_len - DEH_SIZE * del_count,
1014 prev_record, item + ih_item_len(ih) - prev_record);
1016 return DEH_SIZE * del_count + cut_records_len;
1019 /* when cut item is part of regular file
1020 pos_in_item - first byte that must be cut
1021 cut_size - number of bytes to be cut beginning from pos_in_item
1023 when cut item is part of directory
1024 pos_in_item - number of first deleted entry
1025 cut_size - count of deleted entries
1027 void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
1028 int pos_in_item, int cut_size)
1030 int nr;
1031 struct buffer_head *bh = bi->bi_bh;
1032 struct block_head *blkh;
1033 struct item_head *ih;
1034 int last_loc, unmoved_loc;
1035 int i;
1037 blkh = B_BLK_HEAD(bh);
1038 nr = blkh_nr_item(blkh);
1040 /* item head of truncated item */
1041 ih = B_N_PITEM_HEAD(bh, cut_item_num);
1043 if (is_direntry_le_ih(ih)) {
1044 /* first cut entry () */
1045 cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
1046 if (pos_in_item == 0) {
1047 /* change key */
1048 RFALSE(cut_item_num,
1049 "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
1050 cut_item_num);
1051 /* change item key by key of first entry in the item */
1052 set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
1053 /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE); */
1055 } else {
1056 /* item is direct or indirect */
1057 RFALSE(is_statdata_le_ih(ih), "10195: item is stat data");
1058 RFALSE(pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
1059 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
1060 (long unsigned)pos_in_item, (long unsigned)cut_size,
1061 (long unsigned)ih_item_len(ih));
1063 /* shift item body to left if cut is from the head of item */
1064 if (pos_in_item == 0) {
1065 memmove(bh->b_data + ih_location(ih),
1066 bh->b_data + ih_location(ih) + cut_size,
1067 ih_item_len(ih) - cut_size);
1069 /* change key of item */
1070 if (is_direct_le_ih(ih))
1071 set_le_ih_k_offset(ih,
1072 le_ih_k_offset(ih) +
1073 cut_size);
1074 else {
1075 set_le_ih_k_offset(ih,
1076 le_ih_k_offset(ih) +
1077 (cut_size / UNFM_P_SIZE) *
1078 bh->b_size);
1079 RFALSE(ih_item_len(ih) == cut_size
1080 && get_ih_free_space(ih),
1081 "10205: invalid ih_free_space (%h)", ih);
1086 /* location of the last item */
1087 last_loc = ih_location(&(ih[nr - cut_item_num - 1]));
1089 /* location of the item, which is remaining at the same place */
1090 unmoved_loc = cut_item_num ? ih_location(ih - 1) : bh->b_size;
1092 /* shift */
1093 memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1094 unmoved_loc - last_loc - cut_size);
1096 /* change item length */
1097 put_ih_item_len(ih, ih_item_len(ih) - cut_size);
1099 if (is_indirect_le_ih(ih)) {
1100 if (pos_in_item)
1101 set_ih_free_space(ih, 0);
1104 /* change locations */
1105 for (i = cut_item_num; i < nr; i++)
1106 put_ih_location(&(ih[i - cut_item_num]),
1107 ih_location(&ih[i - cut_item_num]) + cut_size);
1109 /* size, free space */
1110 set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
1112 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1114 if (bi->bi_parent) {
1115 struct disk_child *t_dc;
1116 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
1117 put_dc_size(t_dc, dc_size(t_dc) - cut_size);
1118 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1122 /* delete del_num items from buffer starting from the first'th item */
1123 static void leaf_delete_items_entirely(struct buffer_info *bi,
1124 int first, int del_num)
1126 struct buffer_head *bh = bi->bi_bh;
1127 int nr;
1128 int i, j;
1129 int last_loc, last_removed_loc;
1130 struct block_head *blkh;
1131 struct item_head *ih;
1133 RFALSE(bh == NULL, "10210: buffer is 0");
1134 RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1136 if (del_num == 0)
1137 return;
1139 blkh = B_BLK_HEAD(bh);
1140 nr = blkh_nr_item(blkh);
1142 RFALSE(first < 0 || first + del_num > nr,
1143 "10220: first=%d, number=%d, there is %d items", first, del_num,
1144 nr);
1146 if (first == 0 && del_num == nr) {
1147 /* this does not work */
1148 make_empty_node(bi);
1150 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1151 return;
1154 ih = B_N_PITEM_HEAD(bh, first);
1156 /* location of unmovable item */
1157 j = (first == 0) ? bh->b_size : ih_location(ih - 1);
1159 /* delete items */
1160 last_loc = ih_location(&(ih[nr - 1 - first]));
1161 last_removed_loc = ih_location(&(ih[del_num - 1]));
1163 memmove(bh->b_data + last_loc + j - last_removed_loc,
1164 bh->b_data + last_loc, last_removed_loc - last_loc);
1166 /* delete item headers */
1167 memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1169 /* change item location */
1170 for (i = first; i < nr - del_num; i++)
1171 put_ih_location(&(ih[i - first]),
1172 ih_location(&(ih[i - first])) + (j -
1173 last_removed_loc));
1175 /* sizes, item number */
1176 set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
1177 set_blkh_free_space(blkh,
1178 blkh_free_space(blkh) + (j - last_removed_loc +
1179 IH_SIZE * del_num));
1181 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1183 if (bi->bi_parent) {
1184 struct disk_child *t_dc =
1185 B_N_CHILD(bi->bi_parent, bi->bi_position);
1186 put_dc_size(t_dc,
1187 dc_size(t_dc) - (j - last_removed_loc +
1188 IH_SIZE * del_num));
1189 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1193 /* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */
1194 void leaf_paste_entries(struct buffer_head *bh,
1195 int item_num,
1196 int before,
1197 int new_entry_count,
1198 struct reiserfs_de_head *new_dehs,
1199 const char *records, int paste_size)
1201 struct item_head *ih;
1202 char *item;
1203 struct reiserfs_de_head *deh;
1204 char *insert_point;
1205 int i, old_entry_num;
1207 if (new_entry_count == 0)
1208 return;
1210 ih = B_N_PITEM_HEAD(bh, item_num);
1212 /* make sure, that item is directory, and there are enough records in it */
1213 RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
1214 RFALSE(I_ENTRY_COUNT(ih) < before,
1215 "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
1216 I_ENTRY_COUNT(ih), before);
1218 /* first byte of dest item */
1219 item = bh->b_data + ih_location(ih);
1221 /* entry head array */
1222 deh = B_I_DEH(bh, ih);
1224 /* new records will be pasted at this point */
1225 insert_point =
1226 item +
1227 (before ? deh_location(&(deh[before - 1]))
1228 : (ih_item_len(ih) - paste_size));
1230 /* adjust locations of records that will be AFTER new records */
1231 for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i--)
1232 put_deh_location(&(deh[i]),
1233 deh_location(&(deh[i])) +
1234 (DEH_SIZE * new_entry_count));
1236 /* adjust locations of records that will be BEFORE new records */
1237 for (i = 0; i < before; i++)
1238 put_deh_location(&(deh[i]),
1239 deh_location(&(deh[i])) + paste_size);
1241 old_entry_num = I_ENTRY_COUNT(ih);
1242 put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
1244 /* prepare space for pasted records */
1245 memmove(insert_point + paste_size, insert_point,
1246 item + (ih_item_len(ih) - paste_size) - insert_point);
1248 /* copy new records */
1249 memcpy(insert_point + DEH_SIZE * new_entry_count, records,
1250 paste_size - DEH_SIZE * new_entry_count);
1252 /* prepare space for new entry heads */
1253 deh += before;
1254 memmove((char *)(deh + new_entry_count), deh,
1255 insert_point - (char *)deh);
1257 /* copy new entry heads */
1258 deh = (struct reiserfs_de_head *)((char *)deh);
1259 memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
1261 /* set locations of new records */
1262 for (i = 0; i < new_entry_count; i++) {
1263 put_deh_location(&(deh[i]),
1264 deh_location(&(deh[i])) +
1265 (-deh_location
1266 (&(new_dehs[new_entry_count - 1])) +
1267 insert_point + DEH_SIZE * new_entry_count -
1268 item));
1271 /* change item key if necessary (when we paste before 0-th entry */
1272 if (!before) {
1273 set_le_ih_k_offset(ih, deh_offset(new_dehs));
1274 /* memcpy (&ih->ih_key.k_offset,
1275 &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
1277 #ifdef CONFIG_REISERFS_CHECK
1279 int prev, next;
1280 /* check record locations */
1281 deh = B_I_DEH(bh, ih);
1282 for (i = 0; i < I_ENTRY_COUNT(ih); i++) {
1283 next =
1284 (i <
1285 I_ENTRY_COUNT(ih) -
1286 1) ? deh_location(&(deh[i + 1])) : 0;
1287 prev = (i != 0) ? deh_location(&(deh[i - 1])) : 0;
1289 if (prev && prev <= deh_location(&(deh[i])))
1290 reiserfs_warning(NULL,
1291 "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)",
1292 ih, deh + i - 1, i, deh + i);
1293 if (next && next >= deh_location(&(deh[i])))
1294 reiserfs_warning(NULL,
1295 "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)",
1296 ih, i, deh + i, deh + i + 1);
1299 #endif