Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3  */
  4 
  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>
 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 /* 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)
 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)) -
 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;
 54         }
 55 
 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);
 61 
 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))))
 69         {
 70                 /* create new item in dest */
 71                 struct item_head new_ih;
 72 
 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);
 80 
 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 */
 91                         }
 92                         set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key),
 93                                           TYPE_DIRENTRY);
 94                 }
 95 
 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);
109         }
110 
111         item_num_in_dest =
112             (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
113 
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);
120 }
121 
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)
129 {
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;
134 
135         dest_nr_item = B_NR_ITEMS(dest);
136 
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;
147 
148                 RFALSE(!ih_item_len(ih),
149                        "vs-10010: item can not have empty length");
150 
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;
158                 }
159 
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
162                  */
163                 if (bytes_or_entries == -1)
164                         bytes_or_entries = ih_item_len(ih);
165 
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);
175                 }
176 #endif
177 
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);
183 
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));
190                 }
191 
192                 return 1;
193         }
194 
195         /* copy boundary item to right (last_first == LAST_TO_FIRST) */
196 
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 )
199          */
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);
203 
204         if (!dest_nr_item || !op_is_left_mergeable(&(dih->ih_key), src->b_size))
205                 return 0;
206 
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);
211 
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;
217         }
218 
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
222          */
223 
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);
227 
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);
231 
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);
235 
236                 /* change first item key of the DEST */
237                 set_le_ih_k_offset(dih, le_ih_k_offset(ih));
238 
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);
248 
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));
268                 }
269         }
270 
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,
274                              0);
275         return 1;
276 }
277 
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
281  */
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)
285 {
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;
293 
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");
301 
302         dest = dest_bi->bi_bh;
303 
304         RFALSE(!dest, "vs-10130: can not copy negative amount of items");
305 
306         if (cpy_num == 0)
307                 return;
308 
309         blkh = B_BLK_HEAD(dest);
310         nr = blkh_nr_item(blkh);
311         free_space = blkh_free_space(blkh);
312 
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;
315 
316         /* location of head of first new item */
317         ih = B_N_PITEM_HEAD(dest, dest_before);
318 
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);
322 
323         /* prepare space for headers */
324         memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
325 
326         /* copy item headers */
327         memcpy(ih, B_N_PITEM_HEAD(src, first), cpy_num * IH_SIZE);
328 
329         free_space -= (IH_SIZE * cpy_num);
330         set_blkh_free_space(blkh, free_space);
331 
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);
337         }
338 
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]));
342 
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);
347 
348         memmove(dest->b_data + last_loc,
349                 dest->b_data + last_loc + j - last_inserted_loc,
350                 last_inserted_loc - last_loc);
351 
352         /* copy items */
353         memcpy(dest->b_data + last_inserted_loc,
354                B_N_PITEM(src, (first + cpy_num - 1)), j - last_inserted_loc);
355 
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));
359 
360         do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
361 
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));
372 
373                 do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
374                                                0);
375         }
376 }
377 
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)
383 {
384         struct buffer_head *dest = dest_bi->bi_bh;
385         struct item_head *ih;
386 
387         RFALSE(cpy_bytes == -1,
388                "vs-10170: bytes == - 1 means: do not split item");
389 
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;
397 
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;
401                          */
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);
410                         }
411 
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);
417                 }
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;
427 
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;
431                          */
432                         memcpy(&n_ih, ih, SHORT_KEY_SIZE);
433 
434                         n_ih.ih_version = ih->ih_version;       /* JDM Endian safe, both le */
435 
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));
453                         }
454 
455                         /* set item length */
456                         put_ih_item_len(&n_ih, cpy_bytes);
457 
458                         n_ih.ih_version = ih->ih_version;       /* JDM Endian safe, both le */
459 
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);
464                 }
465         }
466 }
467 
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)
474 {
475         struct buffer_head *dest;
476         int pos, i, src_nr_item, bytes;
477 
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);
486 
487         if (cpy_num == 0)
488                 return 0;
489 
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;
497 
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);
512 
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);
516                 }
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;
524 
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);
527 
528                 cpy_num -= i;
529                 if (cpy_num == 0)
530                         return i;
531 
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);
541 
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);
545                 }
546         }
547         return i;
548 }
549 
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)
558 {
559         memset(dest_bi, 0, sizeof(struct buffer_info));
560         memset(src_bi, 0, sizeof(struct buffer_info));
561 
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;
575 
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;
587 
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;
599 
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;
611 
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;
623 
624         default:
625                 reiserfs_panic(NULL,
626                                "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)",
627                                shift_mode);
628         }
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);
632 }
633 
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)
638 {
639         int ret_value;
640         struct buffer_info dest_bi, src_bi;
641         int first_last;
642 
643         leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
644                                    &first_last, Snew);
645 
646         ret_value =
647             leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
648                             mov_bytes);
649 
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);
654 
655         return ret_value;
656 }
657 
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)
661 {
662         struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
663         int i;
664 
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);
667 
668         if (shift_num) {
669                 if (B_NR_ITEMS(S0) == 0) {      /* number of items in S[0] == 0 */
670 
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);
680                         }
681 #endif
682 
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);
686 
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);
690 
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");
697                 }
698         }
699 
700         return i;
701 }
702 
703 /* CLEANING STOPPED HERE */
704 
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)
707 {
708         //  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
709         int ret_value;
710 
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);
714 
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);
718 
719         }
720 
721         return ret_value;
722 }
723 
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.
732 */
733 void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
734                        int first, int del_num, int del_bytes)
735 {
736         struct buffer_head *bh;
737         int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
738 
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);
747 
748         if (del_num == 0)
749                 return;
750 
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;
755         }
756 
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);
764 
765                         /* delete the part of the first item of the bh
766                            do not delete item header
767                          */
768                         leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
769                 } else {
770                         struct item_head *ih;
771                         int len;
772 
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);
776 
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);
785 
786                         /* delete the part of the last item of the bh 
787                            do not delete item header
788                          */
789                         leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
790                                              len - del_bytes, del_bytes);
791                 }
792         }
793 }
794 
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)
799 {
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;
807 
808         blkh = B_BLK_HEAD(bh);
809         nr = blkh_nr_item(blkh);
810         free_space = blkh_free_space(blkh);
811 
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));
819 
820         /* get item new item must be inserted before */
821         ih = B_N_PITEM_HEAD(bh, before);
822 
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;
826 
827         memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
828                 bh->b_data + last_loc, unmoved_loc - last_loc);
829 
830         to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
831         memset(to, 0, zeros_number);
832         to += zeros_number;
833 
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);
840 
841         /* insert item header */
842         memmove(ih + 1, ih, IH_SIZE * (nr - before));
843         memmove(ih, inserted_item_ih, IH_SIZE);
844 
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);
849         }
850 
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);
857 
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);
865         }
866 }
867 
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)
873 {
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;
880 
881         blkh = B_BLK_HEAD(bh);
882         nr = blkh_nr_item(blkh);
883         free_space = blkh_free_space(blkh);
884 
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);
889 
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);
896         }
897 #endif                          /* CONFIG_REISERFS_CHECK */
898 
899         /* item to be appended */
900         ih = B_N_PITEM_HEAD(bh, affected_item_num);
901 
902         last_loc = ih_location(&(ih[nr - affected_item_num - 1]));
903         unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
904 
905         /* prepare space */
906         memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
907                 unmoved_loc - last_loc);
908 
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);
914 
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);
935                         }
936                 }
937         } else
938                 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
939 
940         put_ih_item_len(ih, ih_item_len(ih) + paste_size);
941 
942         /* change free space */
943         set_blkh_free_space(blkh, free_space - paste_size);
944 
945         do_balance_mark_leaf_dirty(bi->tb, bh, 0);
946 
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);
952         }
953 }
954 
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)
961 {
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;
968 
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);
975 
976         if (del_count == 0)
977                 return 0;
978 
979         /* first byte of item */
980         item = bh->b_data + ih_location(ih);
981 
982         /* entry head array */
983         deh = B_I_DEH(bh, ih);
984 
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;
992 
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));
998 
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));
1003 
1004         put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
1005 
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));
1011 
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);
1015 
1016         return DEH_SIZE * del_count + cut_records_len;
1017 }
1018 
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
1022  
1023    when cut item is part of directory
1024         pos_in_item - number of first deleted entry
1025         cut_size - count of deleted entries
1026     */
1027 void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
1028                           int pos_in_item, int cut_size)
1029 {
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;
1036 
1037         blkh = B_BLK_HEAD(bh);
1038         nr = blkh_nr_item(blkh);
1039 
1040         /* item head of truncated item */
1041         ih = B_N_PITEM_HEAD(bh, cut_item_num);
1042 
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); */
1054                 }
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));
1062 
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);
1068 
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);
1082                         }
1083                 }
1084         }
1085 
1086         /* location of the last item */
1087         last_loc = ih_location(&(ih[nr - cut_item_num - 1]));
1088 
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;
1091 
1092         /* shift */
1093         memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1094                 unmoved_loc - last_loc - cut_size);
1095 
1096         /* change item length */
1097         put_ih_item_len(ih, ih_item_len(ih) - cut_size);
1098 
1099         if (is_indirect_le_ih(ih)) {
1100                 if (pos_in_item)
1101                         set_ih_free_space(ih, 0);
1102         }
1103 
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);
1108 
1109         /* size, free space */
1110         set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
1111 
1112         do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1113 
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);
1119         }
1120 }
1121 
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)
1125 {
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;
1132 
1133         RFALSE(bh == NULL, "10210: buffer is 0");
1134         RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1135 
1136         if (del_num == 0)
1137                 return;
1138 
1139         blkh = B_BLK_HEAD(bh);
1140         nr = blkh_nr_item(blkh);
1141 
1142         RFALSE(first < 0 || first + del_num > nr,
1143                "10220: first=%d, number=%d, there is %d items", first, del_num,
1144                nr);
1145 
1146         if (first == 0 && del_num == nr) {
1147                 /* this does not work */
1148                 make_empty_node(bi);
1149 
1150                 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1151                 return;
1152         }
1153 
1154         ih = B_N_PITEM_HEAD(bh, first);
1155 
1156         /* location of unmovable item */
1157         j = (first == 0) ? bh->b_size : ih_location(ih - 1);
1158 
1159         /* delete items */
1160         last_loc = ih_location(&(ih[nr - 1 - first]));
1161         last_removed_loc = ih_location(&(ih[del_num - 1]));
1162 
1163         memmove(bh->b_data + last_loc + j - last_removed_loc,
1164                 bh->b_data + last_loc, last_removed_loc - last_loc);
1165 
1166         /* delete item headers */
1167         memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1168 
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));
1174 
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));
1180 
1181         do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1182 
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);
1190         }
1191 }
1192 
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)
1200 {
1201         struct item_head *ih;
1202         char *item;
1203         struct reiserfs_de_head *deh;
1204         char *insert_point;
1205         int i, old_entry_num;
1206 
1207         if (new_entry_count == 0)
1208                 return;
1209 
1210         ih = B_N_PITEM_HEAD(bh, item_num);
1211 
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);
1217 
1218         /* first byte of dest item */
1219         item = bh->b_data + ih_location(ih);
1220 
1221         /* entry head array */
1222         deh = B_I_DEH(bh, ih);
1223 
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));
1229 
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));
1235 
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);
1240 
1241         old_entry_num = I_ENTRY_COUNT(ih);
1242         put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
1243 
1244         /* prepare space for pasted records */
1245         memmove(insert_point + paste_size, insert_point,
1246                 item + (ih_item_len(ih) - paste_size) - insert_point);
1247 
1248         /* copy new records */
1249         memcpy(insert_point + DEH_SIZE * new_entry_count, records,
1250                paste_size - DEH_SIZE * new_entry_count);
1251 
1252         /* prepare space for new entry heads */
1253         deh += before;
1254         memmove((char *)(deh + new_entry_count), deh,
1255                 insert_point - (char *)deh);
1256 
1257         /* copy new entry heads */
1258         deh = (struct reiserfs_de_head *)((char *)deh);
1259         memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
1260 
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));
1269         }
1270 
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);*/
1276         }
1277 #ifdef CONFIG_REISERFS_CHECK
1278         {
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;
1288 
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);
1297                 }
1298         }
1299 #endif
1300 
1301 }
1302 
  This page was automatically generated by the LXR engine.