2 * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
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>
11 /* these are used in do_balance.c */
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)
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
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 */
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);
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]));
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);
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;
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 );
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);*/
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 */
81 set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
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);
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
93 item_num_in_dest = (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest)-1) : 0;
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
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)
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;
115 dest_nr_item = B_NR_ITEMS(dest);
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 */
127 RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length");
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);
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
140 if ( bytes_or_entries == -1 )
141 bytes_or_entries = ih_item_len(ih);
143 #ifdef CONFIG_REISERFS_CHECK
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)",
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
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",
163 if (bytes_or_entries == ih_item_len(ih))
164 set_ih_free_space (dih, get_ih_free_space (ih));
171 /* copy boundary item to right (last_first == LAST_TO_FIRST) */
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 )
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);
180 if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
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);
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);
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
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)",
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);
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);
209 /* change first item key of the DEST */
210 set_le_ih_k_offset (dih, le_ih_k_offset (ih));
212 /* item becomes non-mergeable */
213 /* or mergeable if left item was */
214 set_le_ih_k_type (dih, le_ih_k_type (ih));
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);
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);
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));
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);
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
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)
247 struct buffer_head * dest;
250 int last_loc, last_inserted_loc, location;
252 struct block_head * blkh;
253 struct item_head * ih;
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");
263 dest = dest_bi->bi_bh;
265 RFALSE( ! dest, "vs-10130: can not copy negative amount of items");
270 blkh = B_BLK_HEAD(dest);
271 nr = blkh_nr_item( blkh );
272 free_space = blkh_free_space(blkh);
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;
277 /* location of head of first new item */
278 ih = B_N_PITEM_HEAD (dest, dest_before);
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);
284 /* prepare space for headers */
285 memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
287 /* copy item headers */
288 memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
290 free_space -= (IH_SIZE * cpy_num);
291 set_blkh_free_space( blkh, free_space );
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 );
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]) );
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);
309 memmove (dest->b_data + last_loc,
310 dest->b_data + last_loc + j - last_inserted_loc,
311 last_inserted_loc - last_loc);
314 memcpy (dest->b_data + last_inserted_loc, B_N_PITEM(src,(first + cpy_num - 1)),
315 j - last_inserted_loc);
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) );
321 do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
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 ) );
332 do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
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)
342 struct buffer_head * dest = dest_bi->bi_bh;
343 struct item_head * ih;
345 RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item");
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);
352 struct item_head n_ih;
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;
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);
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);
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);
377 struct item_head n_ih;
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;
383 memcpy (&n_ih, ih, SHORT_KEY_SIZE);
385 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
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);
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));
400 /* set item length */
401 put_ih_item_len( &n_ih, cpy_bytes );
403 n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
405 leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
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
415 static int leaf_copy_items (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, int cpy_num,
418 struct buffer_head * dest;
419 int pos, i, src_nr_item, bytes;
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);
432 if ( last_first == FIRST_TO_LAST ) {
433 /* copy items to left */
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);
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);
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);
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);
457 /* copy items to right */
458 src_nr_item = B_NR_ITEMS (src);
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);
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);
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);
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);
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)
494 memset (dest_bi, 0, sizeof (struct buffer_info));
495 memset (src_bi, 0, sizeof (struct buffer_info));
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 */
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 */
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;
511 case LEAF_FROM_S_TO_R: /* it is used in leaf_shift_right */
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);
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;
523 case LEAF_FROM_R_TO_L: /* it is used in balance_leaf_when_delete */
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);
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;
535 case LEAF_FROM_L_TO_R: /* it is used in balance_leaf_when_delete */
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);
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;
547 case LEAF_FROM_S_TO_SNEW:
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);
553 dest_bi->bi_bh = Snew;
554 dest_bi->bi_parent = 0;
555 dest_bi->bi_position = 0;
556 *first_last = LAST_TO_FIRST;
560 reiserfs_panic (0, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
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);
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)
575 struct buffer_info dest_bi, src_bi;
578 leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);
580 ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);
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);
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)
593 struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
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);
600 if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */
602 RFALSE( shift_bytes != -1,
603 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
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);
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);
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);
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");
634 /* CLEANING STOPPED HERE */
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,
646 // struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
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);
652 /* replace rkey in CFR[0] by the 0-th key from R[0] */
654 replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
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.
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.
672 void leaf_delete_items (struct buffer_info * cur_bi, int last_first,
673 int first, int del_num, int del_bytes)
675 struct buffer_head * bh;
676 int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);
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);
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);
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);
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);
702 /* delete the part of the first item of the bh
703 do not delete item header
705 leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);
707 struct item_head * ih;
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);
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);
717 /* len = body len of item */
718 len = ih_item_len(ih);
720 /* delete the part of the last item of the bh
721 do not delete item header
723 leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);
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,
735 struct buffer_head * bh = bi->bi_bh;
737 struct block_head * blkh;
738 struct item_head * ih;
740 int last_loc, unmoved_loc;
744 blkh = B_BLK_HEAD(bh);
745 nr = blkh_nr_item(blkh);
746 free_space = blkh_free_space( blkh );
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));
757 /* get item new item must be inserted before */
758 ih = B_N_PITEM_HEAD (bh, before);
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;
765 memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih),
766 bh->b_data + last_loc, unmoved_loc - last_loc);
768 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
769 memset (to, 0, zeros_number);
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);
776 memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
778 /* insert item header */
779 memmove (ih + 1, ih, IH_SIZE * (nr - before));
780 memmove (ih, inserted_item_ih, IH_SIZE);
782 /* change locations */
783 for (i = before; i < nr + 1; i ++)
785 unmoved_loc -= ih_item_len( &(ih[i-before]));
786 put_ih_location( &(ih[i-before]), unmoved_loc );
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);
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);
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,
811 struct buffer_head * bh = bi->bi_bh;
813 struct block_head * blkh;
814 struct item_head * ih;
816 int last_loc, unmoved_loc;
818 blkh = B_BLK_HEAD(bh);
819 nr = blkh_nr_item(blkh);
820 free_space = blkh_free_space(blkh);
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);
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);
834 #endif /* CONFIG_REISERFS_CHECK */
837 /* item to be appended */
838 ih = B_N_PITEM_HEAD(bh, affected_item_num);
840 last_loc = ih_location( &(ih[nr - affected_item_num - 1]) );
841 unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size;
844 memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
845 unmoved_loc - last_loc);
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 );
854 if (!is_direntry_le_ih (ih)) {
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);
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);
869 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
871 put_ih_item_len( ih, ih_item_len(ih) + paste_size );
873 /* change free space */
874 set_blkh_free_space( blkh, free_space - paste_size );
876 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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
890 static int leaf_cut_entries (
891 struct buffer_head * bh,
892 struct item_head * ih,
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 */
905 /* make sure, that item is directory and there are enough entries to
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);
915 /* first byte of item */
916 item = bh->b_data + ih_location(ih);
918 /* entry head array */
919 deh = B_I_DEH (bh, ih);
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;
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 ) );
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) );
938 put_ih_entry_count( ih, ih_entry_count(ih) - del_count );
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));
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);
949 return DEH_SIZE * del_count + cut_records_len;
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
957 when cut item is part of directory
958 pos_in_item - number of first deleted entry
959 cut_size - count of deleted entries
961 void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num,
962 int pos_in_item, int cut_size)
965 struct buffer_head * bh = bi->bi_bh;
966 struct block_head * blkh;
967 struct item_head * ih;
968 int last_loc, unmoved_loc;
971 blkh = B_BLK_HEAD(bh);
972 nr = blkh_nr_item(blkh);
974 /* item head of truncated item */
975 ih = B_N_PITEM_HEAD (bh, cut_item_num);
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) {
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);*/
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));
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);
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);
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);
1014 /* location of the last item */
1015 last_loc = ih_location( &(ih[nr - cut_item_num - 1]) );
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;
1022 memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1023 unmoved_loc - last_loc - cut_size);
1025 /* change item length */
1026 put_ih_item_len( ih, ih_item_len(ih) - cut_size );
1028 if (is_indirect_le_ih (ih)) {
1030 set_ih_free_space (ih, 0);
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 );
1037 /* size, free space */
1038 set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
1040 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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)
1055 struct buffer_head * bh = bi->bi_bh;
1058 int last_loc, last_removed_loc;
1059 struct block_head * blkh;
1060 struct item_head * ih;
1062 RFALSE( bh == NULL, "10210: buffer is 0");
1063 RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1068 blkh = B_BLK_HEAD(bh);
1069 nr = blkh_nr_item(blkh);
1071 RFALSE( first < 0 || first + del_num > nr,
1072 "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
1074 if (first == 0 && del_num == nr) {
1075 /* this does not work */
1076 make_empty_node (bi);
1078 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
1082 ih = B_N_PITEM_HEAD (bh, first);
1084 /* location of unmovable item */
1085 j = (first == 0) ? bh->b_size : ih_location(ih-1);
1088 last_loc = ih_location( &(ih[nr-1-first]) );
1089 last_removed_loc = ih_location( &(ih[del_num-1]) );
1091 memmove (bh->b_data + last_loc + j - last_removed_loc,
1092 bh->b_data + last_loc, last_removed_loc - last_loc);
1094 /* delete item headers */
1095 memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
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) );
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) );
1105 do_balance_mark_leaf_dirty (bi->tb, bh, 0);
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);
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,
1124 int new_entry_count,
1125 struct reiserfs_de_head * new_dehs,
1126 const char * records,
1130 struct item_head * ih;
1132 struct reiserfs_de_head * deh;
1133 char * insert_point;
1134 int i, old_entry_num;
1136 if (new_entry_count == 0)
1139 ih = B_N_PITEM_HEAD(bh, item_num);
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);
1148 /* first byte of dest item */
1149 item = bh->b_data + ih_location(ih);
1151 /* entry head array */
1152 deh = B_I_DEH (bh, ih);
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));
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 ));
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 );
1166 old_entry_num = I_ENTRY_COUNT(ih);
1167 put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count );
1169 /* prepare space for pasted records */
1170 memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point);
1172 /* copy new records */
1173 memcpy (insert_point + DEH_SIZE * new_entry_count, records,
1174 paste_size - DEH_SIZE * new_entry_count);
1176 /* prepare space for new entry heads */
1178 memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh);
1180 /* copy new entry heads */
1181 deh = (struct reiserfs_de_head *)((char *)deh);
1182 memcpy (deh, new_dehs, DEH_SIZE * new_entry_count);
1184 /* set locations of new records */
1185 for (i = 0; i < new_entry_count; i ++)
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));
1194 /* change item key if neccessary (when we paste before 0-th entry */
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);*/
1202 #ifdef CONFIG_REISERFS_CHECK
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;
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);