/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/reiserfs_fs.h>
#include <linux/buffer_head.h>
/* these are used in do_balance.c */
/* leaf_move_items
leaf_shift_left
leaf_shift_right
leaf_delete_items
leaf_insert_into_buf
leaf_paste_in_buffer
leaf_cut_from_buffer
leaf_paste_entries
*/
/* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
struct buffer_head *source, int last_first,
int item_num, int from, int copy_count)
{
struct buffer_head *dest = dest_bi->bi_bh;
int item_num_in_dest; /* either the number of target item,
or if we must create a new item,
the number of the item we will
create it next to */
struct item_head *ih;
struct reiserfs_de_head *deh;
int copy_records_len; /* length of all records in item to be copied */
char *records;
ih = B_N_PITEM_HEAD(source, item_num);
RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
/* length of all record to be copied and first byte of the last of them */
deh = B_I_DEH(source, ih);
if (copy_count) {
copy_records_len = (from ? deh_location(&(deh[from - 1])) :
ih_item_len(ih)) -
deh_location(&(deh[from + copy_count - 1]));
records =
source->b_data + ih_location(ih) +
deh_location(&(deh[from + copy_count - 1]));
} else {
copy_records_len = 0;
records = NULL;
}
/* when copy last to first, dest buffer can contain 0 items */
item_num_in_dest =
(last_first ==
LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
- 1);
/* if there are no items in dest or the first/last item in dest is not item of the same directory */
if ((item_num_in_dest == -1) ||
(last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
(last_first == LAST_TO_FIRST
&& comp_short_le_keys /*COMP_SHORT_KEYS */ (&ih->ih_key,
B_N_PKEY(dest,
item_num_in_dest))))
{
/* create new item in dest */
struct item_head new_ih;
/* form item header */
memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
put_ih_version(&new_ih, KEY_FORMAT_3_5);