static int balance_leaf(struct tree_balance *tb,
struct item_head *ih, /* item header of inserted item (this is on little endian) */
const char *body, /* body of inserted item or bytes to paste */
int flag, /* i - insert, d - delete, c - cut, p - paste
(see comment to do_balance) */
struct item_head *insert_key, /* in our processing of one level we sometimes determine what
must be inserted into the next higher level. This insertion
consists of a key or two keys and their corresponding
pointers */
struct buffer_head **insert_ptr /* inserted node-ptrs for the next level */
)
{
struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
int item_pos = PATH_LAST_POSITION(tb->tb_path); /* index into the array of item headers in S[0]
of the affected item */
struct buffer_info bi;
struct buffer_head *S_new[2]; /* new nodes allocated to hold what could not fit into S */
int snum[2]; /* number of items that will be placed
into S_new (includes partially shifted
items) */
int sbytes[2]; /* if an item is partially shifted into S_new then
if it is a directory item
it is the number of entries from the item that are shifted into S_new
else
it is the number of bytes from the item that are shifted into S_new
*/
int n, i;
int ret_val;
int pos_in_item;
int zeros_num;
PROC_INFO_INC(tb->tb_sb, balance_at[0]);
/* Make balance in case insert_size[0] < 0 */
if (tb->insert_size[0] < 0)
return balance_leaf_when_delete(tb, flag);
zeros_num = 0;
if (flag == M_INSERT && body == 0)
/*
* 2008-1-30 21:46
* linux-2.6.23.12
* @@@@@@@@@@@@@@@@@@@@@@@@@@@@
* potential ih NULL pointer @
* @@@@@@@@@@@@@@@@@@@@@@@@@@@@
*/
zeros_num = ih_item_len(ih);
pos_in_item = tb->tb_path->pos_in_item;
/* for indirect item pos_in_item is measured in unformatted node
pointers. Recalculate to bytes */
if (flag != M_INSERT
&& is_indirect_le_ih(B_N_PITEM_HEAD(tbS0, item_pos)))
pos_in_item *= UNFM_P_SIZE;
[...]
}
int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th,
struct treepath *p_s_search_path, /* Path to the pasted item */
const struct cpu_key *p_s_key, /* Key to search for the needed item */
struct inode *inode, /* Inode that item belongs to */
const char *p_c_body, /* Pointer to the bytes to paste */
int n_pasted_size) /* Size of pasted bytes */
{
[...]
/* Perform balancing after all resources are collected by fix_nodes, and
* accessing them will not risk triggering schedule.
*/
if (retval == CARRY_ON) {
/*
* source-01
*/
do_balance(&s_paste_balance, NULL, /*ih*/ p_c_body, M_PASTE);
return 0;
}
retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
[...]
}
void do_balance(struct tree_balance *tb, /* tree_balance structure */
struct item_head *ih, /* item header of inserted item */
const char *body, /* body of inserted item or bytes to paste */
int flag)
/* i - insert, d - delete
c - cut, p - paste
Cut means delete part of an item
(includes removing an entry from a directory).
Delete means delete whole item.
Insert means add a new item into the tree.
Paste means to append to the end of an
existing file or to insert a directory entry.
*/
{
[...]
do_balance_starts(tb);
/* balance leaf returns 0 except
* if combining L R and S into one node.
*
* see balance_internal() for explanation of this line of code.
*/
child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) +
/*
* source-02
*/
balance_leaf(tb, ih, body, flag, insert_key, insert_ptr);
[...]
}