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