reiserfs: cleanup, remove sb argument from journal_end
[deliverable/linux.git] / fs / reiserfs / do_balan.c
CommitLineData
1da177e4
LT
1/*
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */
4
098297b2
JM
5/*
6 * Now we have all buffers that must be used in balancing of the tree
7 * Further calculations can not cause schedule(), and thus the buffer
8 * tree will be stable until the balancing will be finished
9 * balance the tree according to the analysis made before,
10 * and using buffers obtained after all above.
11 */
1da177e4 12
1da177e4
LT
13#include <asm/uaccess.h>
14#include <linux/time.h>
f466c6fd 15#include "reiserfs.h"
1da177e4 16#include <linux/buffer_head.h>
79a81aef 17#include <linux/kernel.h>
1da177e4 18
fba4ebb5
JM
19static inline void buffer_info_init_left(struct tree_balance *tb,
20 struct buffer_info *bi)
21{
22 bi->tb = tb;
23 bi->bi_bh = tb->L[0];
24 bi->bi_parent = tb->FL[0];
25 bi->bi_position = get_left_neighbor_position(tb, 0);
26}
27
28static inline void buffer_info_init_right(struct tree_balance *tb,
29 struct buffer_info *bi)
30{
31 bi->tb = tb;
32 bi->bi_bh = tb->R[0];
33 bi->bi_parent = tb->FR[0];
34 bi->bi_position = get_right_neighbor_position(tb, 0);
35}
36
37static inline void buffer_info_init_tbS0(struct tree_balance *tb,
38 struct buffer_info *bi)
39{
40 bi->tb = tb;
41 bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
42 bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
43 bi->bi_position = PATH_H_POSITION(tb->tb_path, 1);
44}
45
46static inline void buffer_info_init_bh(struct tree_balance *tb,
47 struct buffer_info *bi,
48 struct buffer_head *bh)
49{
50 bi->tb = tb;
51 bi->bi_bh = bh;
52 bi->bi_parent = NULL;
53 bi->bi_position = 0;
54}
55
bd4c625c
LT
56inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
57 struct buffer_head *bh, int flag)
1da177e4 58{
bd4c625c
LT
59 journal_mark_dirty(tb->transaction_handle,
60 tb->transaction_handle->t_super, bh);
1da177e4
LT
61}
62
63#define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
64#define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
65
098297b2
JM
66/*
67 * summary:
68 * if deleting something ( tb->insert_size[0] < 0 )
69 * return(balance_leaf_when_delete()); (flag d handled here)
70 * else
71 * if lnum is larger than 0 we put items into the left node
72 * if rnum is larger than 0 we put items into the right node
73 * if snum1 is larger than 0 we put items into the new node s1
74 * if snum2 is larger than 0 we put items into the new node s2
75 * Note that all *num* count new items being created.
76 *
77 * It would be easier to read balance_leaf() if each of these summary
78 * lines was a separate procedure rather than being inlined. I think
79 * that there are many passages here and in balance_leaf_when_delete() in
80 * which two calls to one procedure can replace two passages, and it
81 * might save cache space and improve software maintenance costs to do so.
82 *
83 * Vladimir made the perceptive comment that we should offload most of
84 * the decision making in this function into fix_nodes/check_balance, and
85 * then create some sort of structure in tb that says what actions should
86 * be performed by do_balance.
87 *
88 * -Hans
89 */
90
91/*
92 * Balance leaf node in case of delete or cut: insert_size[0] < 0
1da177e4
LT
93 *
94 * lnum, rnum can have values >= -1
95 * -1 means that the neighbor must be joined with S
96 * 0 means that nothing should be done with the neighbor
098297b2
JM
97 * >0 means to shift entirely or partly the specified number of items
98 * to the neighbor
1da177e4 99 */
bd4c625c 100static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
1da177e4 101{
bd4c625c
LT
102 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
103 int item_pos = PATH_LAST_POSITION(tb->tb_path);
104 int pos_in_item = tb->tb_path->pos_in_item;
105 struct buffer_info bi;
106 int n;
107 struct item_head *ih;
1da177e4 108
bd4c625c
LT
109 RFALSE(tb->FR[0] && B_LEVEL(tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
110 "vs- 12000: level: wrong FR %z", tb->FR[0]);
111 RFALSE(tb->blknum[0] > 1,
112 "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
113 RFALSE(!tb->blknum[0] && !PATH_H_PPARENT(tb->tb_path, 0),
114 "PAP-12010: tree can not be empty");
1da177e4 115
4cf5f7ad 116 ih = item_head(tbS0, item_pos);
fba4ebb5 117 buffer_info_init_tbS0(tb, &bi);
1da177e4 118
bd4c625c 119 /* Delete or truncate the item */
1da177e4 120
bd4c625c
LT
121 switch (flag) {
122 case M_DELETE: /* delete item in S[0] */
123
124 RFALSE(ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
125 "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
126 -tb->insert_size[0], ih);
127
bd4c625c
LT
128 leaf_delete_items(&bi, 0, item_pos, 1, -1);
129
130 if (!item_pos && tb->CFL[0]) {
131 if (B_NR_ITEMS(tbS0)) {
132 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0,
133 0);
134 } else {
135 if (!PATH_H_POSITION(tb->tb_path, 1))
136 replace_key(tb, tb->CFL[0], tb->lkey[0],
137 PATH_H_PPARENT(tb->tb_path,
138 0), 0);
139 }
140 }
1da177e4 141
bd4c625c
LT
142 RFALSE(!item_pos && !tb->CFL[0],
143 "PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0],
144 tb->L[0]);
1da177e4 145
bd4c625c
LT
146 break;
147
148 case M_CUT:{ /* cut item in S[0] */
bd4c625c
LT
149 if (is_direntry_le_ih(ih)) {
150
098297b2
JM
151 /*
152 * UFS unlink semantics are such that you
153 * can only delete one directory entry at
154 * a time.
155 */
156
157 /*
158 * when we cut a directory tb->insert_size[0]
159 * means number of entries to be cut (always 1)
160 */
bd4c625c
LT
161 tb->insert_size[0] = -1;
162 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
163 -tb->insert_size[0]);
164
165 RFALSE(!item_pos && !pos_in_item && !tb->CFL[0],
166 "PAP-12030: can not change delimiting key. CFL[0]=%p",
167 tb->CFL[0]);
168
169 if (!item_pos && !pos_in_item && tb->CFL[0]) {
170 replace_key(tb, tb->CFL[0], tb->lkey[0],
171 tbS0, 0);
172 }
173 } else {
174 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
175 -tb->insert_size[0]);
176
177 RFALSE(!ih_item_len(ih),
178 "PAP-12035: cut must leave non-zero dynamic length of item");
179 }
180 break;
1da177e4 181 }
1da177e4 182
bd4c625c
LT
183 default:
184 print_cur_tb("12040");
c3a9c210
JM
185 reiserfs_panic(tb->tb_sb, "PAP-12040",
186 "unexpected mode: %s(%d)",
bd4c625c
LT
187 (flag ==
188 M_PASTE) ? "PASTE" : ((flag ==
189 M_INSERT) ? "INSERT" :
190 "UNKNOWN"), flag);
191 }
1da177e4 192
098297b2
JM
193 /*
194 * the rule is that no shifting occurs unless by shifting
195 * a node can be freed
196 */
bd4c625c 197 n = B_NR_ITEMS(tbS0);
098297b2
JM
198 /* L[0] takes part in balancing */
199 if (tb->lnum[0]) {
200 /* L[0] must be joined with S[0] */
201 if (tb->lnum[0] == -1) {
202 /* R[0] must be also joined with S[0] */
203 if (tb->rnum[0] == -1) {
bd4c625c 204 if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) {
098297b2
JM
205 /*
206 * all contents of all the 3 buffers
207 * will be in L[0]
208 */
bd4c625c
LT
209 if (PATH_H_POSITION(tb->tb_path, 1) == 0
210 && 1 < B_NR_ITEMS(tb->FR[0]))
211 replace_key(tb, tb->CFL[0],
212 tb->lkey[0],
213 tb->FR[0], 1);
214
215 leaf_move_items(LEAF_FROM_S_TO_L, tb, n,
216 -1, NULL);
217 leaf_move_items(LEAF_FROM_R_TO_L, tb,
218 B_NR_ITEMS(tb->R[0]),
219 -1, NULL);
220
221 reiserfs_invalidate_buffer(tb, tbS0);
222 reiserfs_invalidate_buffer(tb,
223 tb->R[0]);
224
225 return 0;
226 }
098297b2
JM
227 /*
228 * all contents of all the 3 buffers will
229 * be in R[0]
230 */
bd4c625c
LT
231 leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1,
232 NULL);
233 leaf_move_items(LEAF_FROM_L_TO_R, tb,
234 B_NR_ITEMS(tb->L[0]), -1, NULL);
235
236 /* right_delimiting_key is correct in R[0] */
237 replace_key(tb, tb->CFR[0], tb->rkey[0],
238 tb->R[0], 0);
1da177e4 239
bd4c625c
LT
240 reiserfs_invalidate_buffer(tb, tbS0);
241 reiserfs_invalidate_buffer(tb, tb->L[0]);
1da177e4 242
bd4c625c
LT
243 return -1;
244 }
1da177e4 245
bd4c625c
LT
246 RFALSE(tb->rnum[0] != 0,
247 "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
248 /* all contents of L[0] and S[0] will be in L[0] */
249 leaf_shift_left(tb, n, -1);
1da177e4 250
bd4c625c
LT
251 reiserfs_invalidate_buffer(tb, tbS0);
252
253 return 0;
254 }
098297b2
JM
255
256 /*
257 * a part of contents of S[0] will be in L[0] and the
258 * rest part of S[0] will be in R[0]
259 */
bd4c625c
LT
260
261 RFALSE((tb->lnum[0] + tb->rnum[0] < n) ||
262 (tb->lnum[0] + tb->rnum[0] > n + 1),
263 "PAP-12050: rnum(%d) and lnum(%d) and item number(%d) in S[0] are not consistent",
264 tb->rnum[0], tb->lnum[0], n);
265 RFALSE((tb->lnum[0] + tb->rnum[0] == n) &&
266 (tb->lbytes != -1 || tb->rbytes != -1),
267 "PAP-12055: bad rbytes (%d)/lbytes (%d) parameters when items are not split",
268 tb->rbytes, tb->lbytes);
269 RFALSE((tb->lnum[0] + tb->rnum[0] == n + 1) &&
270 (tb->lbytes < 1 || tb->rbytes != -1),
271 "PAP-12060: bad rbytes (%d)/lbytes (%d) parameters when items are split",
272 tb->rbytes, tb->lbytes);
273
274 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
275 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
276
277 reiserfs_invalidate_buffer(tb, tbS0);
278
279 return 0;
1da177e4 280 }
1da177e4 281
bd4c625c
LT
282 if (tb->rnum[0] == -1) {
283 /* all contents of R[0] and S[0] will be in R[0] */
284 leaf_shift_right(tb, n, -1);
285 reiserfs_invalidate_buffer(tb, tbS0);
286 return 0;
287 }
1da177e4 288
bd4c625c
LT
289 RFALSE(tb->rnum[0],
290 "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
1da177e4 291 return 0;
1da177e4
LT
292}
293
bd4c625c
LT
294static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item header of inserted item (this is on little endian) */
295 const char *body, /* body of inserted item or bytes to paste */
296 int flag, /* i - insert, d - delete, c - cut, p - paste
297 (see comment to do_balance) */
298 struct item_head *insert_key, /* in our processing of one level we sometimes determine what
299 must be inserted into the next higher level. This insertion
300 consists of a key or two keys and their corresponding
301 pointers */
302 struct buffer_head **insert_ptr /* inserted node-ptrs for the next level */
1da177e4
LT
303 )
304{
bd4c625c 305 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0222e657 306 int item_pos = PATH_LAST_POSITION(tb->tb_path); /* index into the array of item headers in S[0]
bd4c625c
LT
307 of the affected item */
308 struct buffer_info bi;
309 struct buffer_head *S_new[2]; /* new nodes allocated to hold what could not fit into S */
310 int snum[2]; /* number of items that will be placed
311 into S_new (includes partially shifted
312 items) */
0222e657
JM
313 int sbytes[2]; /* if an item is partially shifted into S_new then
314 if it is a directory item
bd4c625c
LT
315 it is the number of entries from the item that are shifted into S_new
316 else
317 it is the number of bytes from the item that are shifted into S_new
318 */
319 int n, i;
320 int ret_val;
321 int pos_in_item;
322 int zeros_num;
323
324 PROC_INFO_INC(tb->tb_sb, balance_at[0]);
325
326 /* Make balance in case insert_size[0] < 0 */
327 if (tb->insert_size[0] < 0)
328 return balance_leaf_when_delete(tb, flag);
329
330 zeros_num = 0;
9dce07f1 331 if (flag == M_INSERT && !body)
bd4c625c
LT
332 zeros_num = ih_item_len(ih);
333
334 pos_in_item = tb->tb_path->pos_in_item;
335 /* for indirect item pos_in_item is measured in unformatted node
336 pointers. Recalculate to bytes */
337 if (flag != M_INSERT
4cf5f7ad 338 && is_indirect_le_ih(item_head(tbS0, item_pos)))
bd4c625c
LT
339 pos_in_item *= UNFM_P_SIZE;
340
341 if (tb->lnum[0] > 0) {
342 /* Shift lnum[0] items from S[0] to the left neighbor L[0] */
343 if (item_pos < tb->lnum[0]) {
344 /* new item or it part falls to L[0], shift it too */
345 n = B_NR_ITEMS(tb->L[0]);
346
347 switch (flag) {
348 case M_INSERT: /* insert item into L[0] */
349
416e2abd 350 if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) {
bd4c625c
LT
351 /* part of new item falls into L[0] */
352 int new_item_len;
353 int version;
354
416e2abd 355 ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, -1);
bd4c625c
LT
356
357 /* Calculate item length to insert to S[0] */
416e2abd 358 new_item_len = ih_item_len(ih) - tb->lbytes;
bd4c625c 359 /* Calculate and check item length to insert to L[0] */
416e2abd 360 put_ih_item_len(ih, ih_item_len(ih) - new_item_len);
bd4c625c
LT
361
362 RFALSE(ih_item_len(ih) <= 0,
363 "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
364 ih_item_len(ih));
365
366 /* Insert new item into L[0] */
fba4ebb5 367 buffer_info_init_left(tb, &bi);
bd4c625c 368 leaf_insert_into_buf(&bi,
416e2abd
DJ
369 n + item_pos - ret_val, ih, body,
370 zeros_num > ih_item_len(ih) ? ih_item_len(ih) : zeros_num);
bd4c625c
LT
371
372 version = ih_version(ih);
373
374 /* Calculate key component, item length and body to insert into S[0] */
416e2abd
DJ
375 set_le_ih_k_offset(ih, le_ih_k_offset(ih) +
376 (tb-> lbytes << (is_indirect_le_ih(ih) ? tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0)));
bd4c625c
LT
377
378 put_ih_item_len(ih, new_item_len);
379 if (tb->lbytes > zeros_num) {
416e2abd 380 body += (tb->lbytes - zeros_num);
bd4c625c
LT
381 zeros_num = 0;
382 } else
383 zeros_num -= tb->lbytes;
384
385 RFALSE(ih_item_len(ih) <= 0,
386 "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
387 ih_item_len(ih));
388 } else {
389 /* new item in whole falls into L[0] */
390 /* Shift lnum[0]-1 items to L[0] */
416e2abd 391 ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, tb->lbytes);
bd4c625c 392 /* Insert new item into L[0] */
fba4ebb5 393 buffer_info_init_left(tb, &bi);
416e2abd 394 leaf_insert_into_buf(&bi, n + item_pos - ret_val, ih, body, zeros_num);
bd4c625c
LT
395 tb->insert_size[0] = 0;
396 zeros_num = 0;
1da177e4 397 }
bd4c625c
LT
398 break;
399
400 case M_PASTE: /* append item in L[0] */
401
416e2abd 402 if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) {
bd4c625c 403 /* we must shift the part of the appended item */
4cf5f7ad 404 if (is_direntry_le_ih(item_head(tbS0, item_pos))) {
bd4c625c
LT
405
406 RFALSE(zeros_num,
407 "PAP-12090: invalid parameter in case of a directory");
408 /* directory item */
409 if (tb->lbytes > pos_in_item) {
410 /* new directory entry falls into L[0] */
416e2abd
DJ
411 struct item_head *pasted;
412 int l_pos_in_item = pos_in_item;
bd4c625c
LT
413
414 /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */
416e2abd
DJ
415 ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes-1);
416 if (ret_val && !item_pos) {
4cf5f7ad
JM
417 pasted = item_head(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1);
418 l_pos_in_item += ih_entry_count(pasted) - (tb->lbytes -1);
bd4c625c
LT
419 }
420
421 /* Append given directory entry to directory item */
fba4ebb5 422 buffer_info_init_left(tb, &bi);
416e2abd 423 leaf_paste_in_buffer(&bi, n + item_pos - ret_val, l_pos_in_item, tb->insert_size[0], body, zeros_num);
bd4c625c
LT
424
425 /* previous string prepared space for pasting new entry, following string pastes this entry */
426
427 /* when we have merge directory item, pos_in_item has been changed too */
428
429 /* paste new directory entry. 1 is entry number */
416e2abd
DJ
430 leaf_paste_entries(&bi, n + item_pos - ret_val, l_pos_in_item,
431 1, (struct reiserfs_de_head *) body,
432 body + DEH_SIZE, tb->insert_size[0]);
bd4c625c
LT
433 tb->insert_size[0] = 0;
434 } else {
435 /* new directory item doesn't fall into L[0] */
436 /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */
416e2abd 437 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
bd4c625c
LT
438 }
439 /* Calculate new position to append in item body */
440 pos_in_item -= tb->lbytes;
441 } else {
442 /* regular object */
416e2abd 443 RFALSE(tb->lbytes <= 0, "PAP-12095: there is nothing to shift to L[0]. lbytes=%d", tb->lbytes);
4cf5f7ad 444 RFALSE(pos_in_item != ih_item_len(item_head(tbS0, item_pos)),
bd4c625c 445 "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
4cf5f7ad 446 ih_item_len(item_head(tbS0, item_pos)),pos_in_item);
bd4c625c
LT
447
448 if (tb->lbytes >= pos_in_item) {
449 /* appended item will be in L[0] in whole */
450 int l_n;
451
452 /* this bytes number must be appended to the last item of L[h] */
416e2abd 453 l_n = tb->lbytes - pos_in_item;
bd4c625c
LT
454
455 /* Calculate new insert_size[0] */
416e2abd 456 tb->insert_size[0] -= l_n;
bd4c625c 457
416e2abd 458 RFALSE(tb->insert_size[0] <= 0,
bd4c625c 459 "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
416e2abd
DJ
460 tb->insert_size[0]);
461 ret_val = leaf_shift_left(tb, tb->lnum[0], ih_item_len
4cf5f7ad 462 (item_head(tbS0, item_pos)));
bd4c625c 463 /* Append to body of item in L[0] */
fba4ebb5 464 buffer_info_init_left(tb, &bi);
bd4c625c 465 leaf_paste_in_buffer
416e2abd 466 (&bi, n + item_pos - ret_val, ih_item_len
4cf5f7ad 467 (item_head(tb->L[0], n + item_pos - ret_val)),
416e2abd
DJ
468 l_n, body,
469 zeros_num > l_n ? l_n : zeros_num);
bd4c625c
LT
470 /* 0-th item in S0 can be only of DIRECT type when l_n != 0 */
471 {
472 int version;
416e2abd
DJ
473 int temp_l = l_n;
474
4cf5f7ad 475 RFALSE(ih_item_len(item_head(tbS0, 0)),
bd4c625c 476 "PAP-12106: item length must be 0");
4cf5f7ad 477 RFALSE(comp_short_le_keys(leaf_key(tbS0, 0), leaf_key
416e2abd 478 (tb->L[0], n + item_pos - ret_val)),
bd4c625c 479 "PAP-12107: items must be of the same file");
4cf5f7ad 480 if (is_indirect_le_ih(item_head(tb->L[0], n + item_pos - ret_val))) {
416e2abd 481 temp_l = l_n << (tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT);
bd4c625c
LT
482 }
483 /* update key of first item in S0 */
4cf5f7ad
JM
484 version = ih_version(item_head(tbS0, 0));
485 set_le_key_k_offset(version, leaf_key(tbS0, 0),
486 le_key_k_offset(version,leaf_key(tbS0, 0)) + temp_l);
bd4c625c 487 /* update left delimiting key */
4cf5f7ad
JM
488 set_le_key_k_offset(version, internal_key(tb->CFL[0], tb->lkey[0]),
489 le_key_k_offset(version, internal_key(tb->CFL[0], tb->lkey[0])) + temp_l);
bd4c625c
LT
490 }
491
492 /* Calculate new body, position in item and insert_size[0] */
493 if (l_n > zeros_num) {
416e2abd 494 body += (l_n - zeros_num);
bd4c625c
LT
495 zeros_num = 0;
496 } else
416e2abd 497 zeros_num -= l_n;
bd4c625c
LT
498 pos_in_item = 0;
499
4cf5f7ad
JM
500 RFALSE(comp_short_le_keys(leaf_key(tbS0, 0), leaf_key(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1))
501 || !op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)
502 || !op_is_left_mergeable(internal_key(tb->CFL[0], tb->lkey[0]), tbS0->b_size),
bd4c625c
LT
503 "PAP-12120: item must be merge-able with left neighboring item");
504 } else { /* only part of the appended item will be in L[0] */
505
506 /* Calculate position in item for append in S[0] */
416e2abd 507 pos_in_item -= tb->lbytes;
bd4c625c 508
416e2abd 509 RFALSE(pos_in_item <= 0, "PAP-12125: no place for paste. pos_in_item=%d", pos_in_item);
bd4c625c
LT
510
511 /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
416e2abd 512 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
bd4c625c
LT
513 }
514 }
515 } else { /* appended item will be in L[0] in whole */
516
517 struct item_head *pasted;
518
4cf5f7ad 519 if (!item_pos && op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)) { /* if we paste into first item of S[0] and it is left mergable */
bd4c625c 520 /* then increment pos_in_item by the size of the last item in L[0] */
4cf5f7ad 521 pasted = item_head(tb->L[0], n - 1);
bd4c625c 522 if (is_direntry_le_ih(pasted))
416e2abd 523 pos_in_item += ih_entry_count(pasted);
bd4c625c 524 else
416e2abd 525 pos_in_item += ih_item_len(pasted);
bd4c625c
LT
526 }
527
528 /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
416e2abd 529 ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
bd4c625c 530 /* Append to body of item in L[0] */
fba4ebb5 531 buffer_info_init_left(tb, &bi);
416e2abd 532 leaf_paste_in_buffer(&bi, n + item_pos - ret_val,
bd4c625c
LT
533 pos_in_item,
534 tb->insert_size[0],
535 body, zeros_num);
536
537 /* if appended item is directory, paste entry */
4cf5f7ad 538 pasted = item_head(tb->L[0], n + item_pos - ret_val);
bd4c625c 539 if (is_direntry_le_ih(pasted))
416e2abd
DJ
540 leaf_paste_entries(&bi, n + item_pos - ret_val,
541 pos_in_item, 1,
542 (struct reiserfs_de_head *) body,
543 body + DEH_SIZE,
544 tb->insert_size[0]);
bd4c625c
LT
545 /* if appended item is indirect item, put unformatted node into un list */
546 if (is_indirect_le_ih(pasted))
547 set_ih_free_space(pasted, 0);
548 tb->insert_size[0] = 0;
549 zeros_num = 0;
550 }
551 break;
552 default: /* cases d and t */
c3a9c210
JM
553 reiserfs_panic(tb->tb_sb, "PAP-12130",
554 "lnum > 0: unexpected mode: "
555 " %s(%d)",
416e2abd 556 (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
1da177e4 557 }
bd4c625c
LT
558 } else {
559 /* new item doesn't fall into L[0] */
560 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
1da177e4 561 }
1da177e4 562 }
1da177e4 563
bd4c625c
LT
564 /* tb->lnum[0] > 0 */
565 /* Calculate new item position */
566 item_pos -= (tb->lnum[0] - ((tb->lbytes != -1) ? 1 : 0));
567
568 if (tb->rnum[0] > 0) {
569 /* shift rnum[0] items from S[0] to the right neighbor R[0] */
570 n = B_NR_ITEMS(tbS0);
571 switch (flag) {
572
573 case M_INSERT: /* insert item */
574 if (n - tb->rnum[0] < item_pos) { /* new item or its part falls to R[0] */
575 if (item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) { /* part of new item falls into R[0] */
416e2abd 576 loff_t old_key_comp, old_len, r_zeros_number;
bd4c625c
LT
577 const char *r_body;
578 int version;
579 loff_t offset;
580
416e2abd 581 leaf_shift_right(tb, tb->rnum[0] - 1, -1);
bd4c625c
LT
582
583 version = ih_version(ih);
584 /* Remember key component and item length */
585 old_key_comp = le_ih_k_offset(ih);
586 old_len = ih_item_len(ih);
587
588 /* Calculate key component and item length to insert into R[0] */
416e2abd 589 offset = le_ih_k_offset(ih) + ((old_len - tb->rbytes) << (is_indirect_le_ih(ih) ? tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT : 0));
bd4c625c
LT
590 set_le_ih_k_offset(ih, offset);
591 put_ih_item_len(ih, tb->rbytes);
592 /* Insert part of the item into R[0] */
fba4ebb5 593 buffer_info_init_right(tb, &bi);
bd4c625c
LT
594 if ((old_len - tb->rbytes) > zeros_num) {
595 r_zeros_number = 0;
416e2abd 596 r_body = body + (old_len - tb->rbytes) - zeros_num;
bd4c625c
LT
597 } else {
598 r_body = body;
416e2abd 599 r_zeros_number = zeros_num - (old_len - tb->rbytes);
bd4c625c
LT
600 zeros_num -= r_zeros_number;
601 }
602
603 leaf_insert_into_buf(&bi, 0, ih, r_body,
604 r_zeros_number);
605
606 /* Replace right delimiting key by first key in R[0] */
607 replace_key(tb, tb->CFR[0], tb->rkey[0],
608 tb->R[0], 0);
609
610 /* Calculate key component and item length to insert into S[0] */
611 set_le_ih_k_offset(ih, old_key_comp);
416e2abd 612 put_ih_item_len(ih, old_len - tb->rbytes);
bd4c625c
LT
613
614 tb->insert_size[0] -= tb->rbytes;
615
616 } else { /* whole new item falls into R[0] */
617
618 /* Shift rnum[0]-1 items to R[0] */
416e2abd 619 ret_val = leaf_shift_right(tb, tb->rnum[0] - 1, tb->rbytes);
bd4c625c 620 /* Insert new item into R[0] */
fba4ebb5 621 buffer_info_init_right(tb, &bi);
416e2abd
DJ
622 leaf_insert_into_buf(&bi, item_pos - n + tb->rnum[0] - 1,
623 ih, body, zeros_num);
bd4c625c
LT
624
625 if (item_pos - n + tb->rnum[0] - 1 == 0) {
626 replace_key(tb, tb->CFR[0],
627 tb->rkey[0],
628 tb->R[0], 0);
629
630 }
631 zeros_num = tb->insert_size[0] = 0;
632 }
633 } else { /* new item or part of it doesn't fall into R[0] */
1da177e4 634
bd4c625c 635 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
1da177e4 636 }
bd4c625c
LT
637 break;
638
639 case M_PASTE: /* append item */
640
641 if (n - tb->rnum[0] <= item_pos) { /* pasted item or part of it falls to R[0] */
642 if (item_pos == n - tb->rnum[0] && tb->rbytes != -1) { /* we must shift the part of the appended item */
4cf5f7ad 643 if (is_direntry_le_ih(item_head(tbS0, item_pos))) { /* we append to directory item */
bd4c625c
LT
644 int entry_count;
645
646 RFALSE(zeros_num,
647 "PAP-12145: invalid parameter in case of a directory");
4cf5f7ad 648 entry_count = ih_entry_count(item_head
416e2abd 649 (tbS0, item_pos));
bd4c625c
LT
650 if (entry_count - tb->rbytes <
651 pos_in_item)
652 /* new directory entry falls into R[0] */
653 {
654 int paste_entry_position;
655
416e2abd 656 RFALSE(tb->rbytes - 1 >= entry_count || !tb-> insert_size[0],
bd4c625c 657 "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
416e2abd 658 tb->rbytes, entry_count);
bd4c625c 659 /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */
416e2abd 660 leaf_shift_right(tb, tb->rnum[0], tb->rbytes - 1);
bd4c625c 661 /* Paste given directory entry to directory item */
416e2abd 662 paste_entry_position = pos_in_item - entry_count + tb->rbytes - 1;
fba4ebb5 663 buffer_info_init_right(tb, &bi);
416e2abd 664 leaf_paste_in_buffer(&bi, 0, paste_entry_position, tb->insert_size[0], body, zeros_num);
bd4c625c 665 /* paste entry */
416e2abd
DJ
666 leaf_paste_entries(&bi, 0, paste_entry_position, 1,
667 (struct reiserfs_de_head *) body,
668 body + DEH_SIZE, tb->insert_size[0]);
669
670 if (paste_entry_position == 0) {
bd4c625c 671 /* change delimiting keys */
416e2abd 672 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0],0);
bd4c625c
LT
673 }
674
675 tb->insert_size[0] = 0;
676 pos_in_item++;
677 } else { /* new directory entry doesn't fall into R[0] */
678
416e2abd 679 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
bd4c625c
LT
680 }
681 } else { /* regular object */
682
416e2abd 683 int n_shift, n_rem, r_zeros_number;
bd4c625c
LT
684 const char *r_body;
685
686 /* Calculate number of bytes which must be shifted from appended item */
416e2abd 687 if ((n_shift = tb->rbytes - tb->insert_size[0]) < 0)
bd4c625c
LT
688 n_shift = 0;
689
416e2abd 690 RFALSE(pos_in_item != ih_item_len
4cf5f7ad 691 (item_head(tbS0, item_pos)),
bd4c625c 692 "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
416e2abd 693 pos_in_item, ih_item_len
4cf5f7ad 694 (item_head(tbS0, item_pos)));
416e2abd
DJ
695
696 leaf_shift_right(tb, tb->rnum[0], n_shift);
bd4c625c 697 /* Calculate number of bytes which must remain in body after appending to R[0] */
416e2abd 698 if ((n_rem = tb->insert_size[0] - tb->rbytes) < 0)
bd4c625c
LT
699 n_rem = 0;
700
701 {
702 int version;
416e2abd
DJ
703 unsigned long temp_rem = n_rem;
704
4cf5f7ad
JM
705 version = ih_version(item_head(tb->R[0], 0));
706 if (is_indirect_le_key(version, leaf_key(tb->R[0], 0))) {
416e2abd 707 temp_rem = n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT);
bd4c625c 708 }
4cf5f7ad
JM
709 set_le_key_k_offset(version, leaf_key(tb->R[0], 0),
710 le_key_k_offset(version, leaf_key(tb->R[0], 0)) + temp_rem);
711 set_le_key_k_offset(version, internal_key(tb->CFR[0], tb->rkey[0]),
712 le_key_k_offset(version, internal_key(tb->CFR[0], tb->rkey[0])) + temp_rem);
bd4c625c 713 }
4cf5f7ad
JM
714/* k_offset (leaf_key(tb->R[0],0)) += n_rem;
715 k_offset (internal_key(tb->CFR[0],tb->rkey[0])) += n_rem;*/
416e2abd 716 do_balance_mark_internal_dirty(tb, tb->CFR[0], 0);
bd4c625c
LT
717
718 /* Append part of body into R[0] */
fba4ebb5 719 buffer_info_init_right(tb, &bi);
bd4c625c
LT
720 if (n_rem > zeros_num) {
721 r_zeros_number = 0;
416e2abd 722 r_body = body + n_rem - zeros_num;
bd4c625c
LT
723 } else {
724 r_body = body;
416e2abd
DJ
725 r_zeros_number = zeros_num - n_rem;
726 zeros_num -= r_zeros_number;
bd4c625c
LT
727 }
728
416e2abd
DJ
729 leaf_paste_in_buffer(&bi, 0, n_shift,
730 tb->insert_size[0] - n_rem,
731 r_body, r_zeros_number);
732
4cf5f7ad 733 if (is_indirect_le_ih(item_head(tb->R[0], 0))) {
1da177e4 734#if 0
bd4c625c
LT
735 RFALSE(n_rem,
736 "PAP-12160: paste more than one unformatted node pointer");
1da177e4 737#endif
4cf5f7ad 738 set_ih_free_space(item_head(tb->R[0], 0), 0);
bd4c625c
LT
739 }
740 tb->insert_size[0] = n_rem;
741 if (!n_rem)
742 pos_in_item++;
743 }
744 } else { /* pasted item in whole falls into R[0] */
745
746 struct item_head *pasted;
747
416e2abd 748 ret_val = leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
bd4c625c
LT
749 /* append item in R[0] */
750 if (pos_in_item >= 0) {
fba4ebb5 751 buffer_info_init_right(tb, &bi);
416e2abd
DJ
752 leaf_paste_in_buffer(&bi, item_pos - n + tb->rnum[0], pos_in_item,
753 tb->insert_size[0], body, zeros_num);
bd4c625c
LT
754 }
755
756 /* paste new entry, if item is directory item */
4cf5f7ad 757 pasted = item_head(tb->R[0], item_pos - n + tb->rnum[0]);
416e2abd
DJ
758 if (is_direntry_le_ih(pasted) && pos_in_item >= 0) {
759 leaf_paste_entries(&bi, item_pos - n + tb->rnum[0],
760 pos_in_item, 1,
761 (struct reiserfs_de_head *) body,
762 body + DEH_SIZE, tb->insert_size[0]);
bd4c625c
LT
763 if (!pos_in_item) {
764
416e2abd 765 RFALSE(item_pos - n + tb->rnum[0],
bd4c625c
LT
766 "PAP-12165: directory item must be first item of node when pasting is in 0th position");
767
768 /* update delimiting keys */
416e2abd 769 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
bd4c625c
LT
770 }
771 }
772
773 if (is_indirect_le_ih(pasted))
774 set_ih_free_space(pasted, 0);
775 zeros_num = tb->insert_size[0] = 0;
776 }
777 } else { /* new item doesn't fall into R[0] */
1da177e4 778
bd4c625c 779 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
1da177e4 780 }
bd4c625c
LT
781 break;
782 default: /* cases d and t */
c3a9c210
JM
783 reiserfs_panic(tb->tb_sb, "PAP-12175",
784 "rnum > 0: unexpected mode: %s(%d)",
416e2abd 785 (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
1da177e4 786 }
1da177e4 787
bd4c625c 788 }
1da177e4 789
bd4c625c
LT
790 /* tb->rnum[0] > 0 */
791 RFALSE(tb->blknum[0] > 3,
416e2abd 792 "PAP-12180: blknum can not be %d. It must be <= 3", tb->blknum[0]);
bd4c625c 793 RFALSE(tb->blknum[0] < 0,
416e2abd 794 "PAP-12185: blknum can not be %d. It must be >= 0", tb->blknum[0]);
bd4c625c
LT
795
796 /* if while adding to a node we discover that it is possible to split
797 it in two, and merge the left part into the left neighbor and the
798 right part into the right neighbor, eliminating the node */
799 if (tb->blknum[0] == 0) { /* node S[0] is empty now */
800
801 RFALSE(!tb->lnum[0] || !tb->rnum[0],
802 "PAP-12190: lnum and rnum must not be zero");
803 /* if insertion was done before 0-th position in R[0], right
804 delimiting key of the tb->L[0]'s and left delimiting key are
805 not set correctly */
806 if (tb->CFL[0]) {
807 if (!tb->CFR[0])
c3a9c210
JM
808 reiserfs_panic(tb->tb_sb, "vs-12195",
809 "CFR not initialized");
4cf5f7ad
JM
810 copy_key(internal_key(tb->CFL[0], tb->lkey[0]),
811 internal_key(tb->CFR[0], tb->rkey[0]));
bd4c625c
LT
812 do_balance_mark_internal_dirty(tb, tb->CFL[0], 0);
813 }
1da177e4 814
bd4c625c
LT
815 reiserfs_invalidate_buffer(tb, tbS0);
816 return 0;
817 }
1da177e4 818
bd4c625c
LT
819 /* Fill new nodes that appear in place of S[0] */
820
821 /* I am told that this copying is because we need an array to enable
822 the looping code. -Hans */
823 snum[0] = tb->s1num, snum[1] = tb->s2num;
824 sbytes[0] = tb->s1bytes;
825 sbytes[1] = tb->s2bytes;
826 for (i = tb->blknum[0] - 2; i >= 0; i--) {
827
828 RFALSE(!snum[i], "PAP-12200: snum[%d] == %d. Must be > 0", i,
829 snum[i]);
830
831 /* here we shift from S to S_new nodes */
832
833 S_new[i] = get_FEB(tb);
834
835 /* initialized block type and tree level */
836 set_blkh_level(B_BLK_HEAD(S_new[i]), DISK_LEAF_NODE_LEVEL);
837
838 n = B_NR_ITEMS(tbS0);
839
840 switch (flag) {
841 case M_INSERT: /* insert item */
842
843 if (n - snum[i] < item_pos) { /* new item or it's part falls to first new node S_new[i] */
844 if (item_pos == n - snum[i] + 1 && sbytes[i] != -1) { /* part of new item falls into S_new[i] */
416e2abd 845 int old_key_comp, old_len, r_zeros_number;
bd4c625c
LT
846 const char *r_body;
847 int version;
848
849 /* Move snum[i]-1 items from S[0] to S_new[i] */
850 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
851 snum[i] - 1, -1,
852 S_new[i]);
853 /* Remember key component and item length */
854 version = ih_version(ih);
855 old_key_comp = le_ih_k_offset(ih);
856 old_len = ih_item_len(ih);
857
858 /* Calculate key component and item length to insert into S_new[i] */
416e2abd
DJ
859 set_le_ih_k_offset(ih, le_ih_k_offset(ih) +
860 ((old_len - sbytes[i]) << (is_indirect_le_ih(ih) ? tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0)));
bd4c625c
LT
861
862 put_ih_item_len(ih, sbytes[i]);
863
864 /* Insert part of the item into S_new[i] before 0-th item */
fba4ebb5 865 buffer_info_init_bh(tb, &bi, S_new[i]);
bd4c625c
LT
866
867 if ((old_len - sbytes[i]) > zeros_num) {
868 r_zeros_number = 0;
416e2abd 869 r_body = body + (old_len - sbytes[i]) - zeros_num;
bd4c625c
LT
870 } else {
871 r_body = body;
416e2abd 872 r_zeros_number = zeros_num - (old_len - sbytes[i]);
bd4c625c
LT
873 zeros_num -= r_zeros_number;
874 }
875
416e2abd 876 leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeros_number);
bd4c625c
LT
877
878 /* Calculate key component and item length to insert into S[i] */
879 set_le_ih_k_offset(ih, old_key_comp);
416e2abd 880 put_ih_item_len(ih, old_len - sbytes[i]);
bd4c625c
LT
881 tb->insert_size[0] -= sbytes[i];
882 } else { /* whole new item falls into S_new[i] */
883
884 /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */
885 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
416e2abd 886 snum[i] - 1, sbytes[i], S_new[i]);
bd4c625c
LT
887
888 /* Insert new item into S_new[i] */
fba4ebb5 889 buffer_info_init_bh(tb, &bi, S_new[i]);
416e2abd
DJ
890 leaf_insert_into_buf(&bi, item_pos - n + snum[i] - 1,
891 ih, body, zeros_num);
bd4c625c
LT
892
893 zeros_num = tb->insert_size[0] = 0;
894 }
895 }
1da177e4 896
bd4c625c 897 else { /* new item or it part don't falls into S_new[i] */
1da177e4 898
bd4c625c
LT
899 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
900 snum[i], sbytes[i], S_new[i]);
1da177e4 901 }
bd4c625c
LT
902 break;
903
904 case M_PASTE: /* append item */
905
906 if (n - snum[i] <= item_pos) { /* pasted item or part if it falls to S_new[i] */
907 if (item_pos == n - snum[i] && sbytes[i] != -1) { /* we must shift part of the appended item */
908 struct item_head *aux_ih;
909
910 RFALSE(ih, "PAP-12210: ih must be 0");
911
4cf5f7ad 912 aux_ih = item_head(tbS0, item_pos);
1d965fe0 913 if (is_direntry_le_ih(aux_ih)) {
bd4c625c
LT
914 /* we append to directory item */
915
916 int entry_count;
917
416e2abd 918 entry_count = ih_entry_count(aux_ih);
bd4c625c 919
416e2abd 920 if (entry_count - sbytes[i] < pos_in_item && pos_in_item <= entry_count) {
bd4c625c
LT
921 /* new directory entry falls into S_new[i] */
922
416e2abd
DJ
923 RFALSE(!tb->insert_size[0], "PAP-12215: insert_size is already 0");
924 RFALSE(sbytes[i] - 1 >= entry_count,
bd4c625c 925 "PAP-12220: there are no so much entries (%d), only %d",
416e2abd 926 sbytes[i] - 1, entry_count);
bd4c625c
LT
927
928 /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
416e2abd 929 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i] - 1, S_new[i]);
bd4c625c 930 /* Paste given directory entry to directory item */
fba4ebb5 931 buffer_info_init_bh(tb, &bi, S_new[i]);
416e2abd
DJ
932 leaf_paste_in_buffer(&bi, 0, pos_in_item - entry_count + sbytes[i] - 1,
933 tb->insert_size[0], body, zeros_num);
bd4c625c 934 /* paste new directory entry */
416e2abd
DJ
935 leaf_paste_entries(&bi, 0, pos_in_item - entry_count + sbytes[i] - 1, 1,
936 (struct reiserfs_de_head *) body,
937 body + DEH_SIZE, tb->insert_size[0]);
bd4c625c
LT
938 tb->insert_size[0] = 0;
939 pos_in_item++;
940 } else { /* new directory entry doesn't fall into S_new[i] */
416e2abd 941 leaf_move_items(LEAF_FROM_S_TO_SNEW,tb, snum[i], sbytes[i], S_new[i]);
bd4c625c
LT
942 }
943 } else { /* regular object */
944
416e2abd 945 int n_shift, n_rem, r_zeros_number;
bd4c625c
LT
946 const char *r_body;
947
4cf5f7ad 948 RFALSE(pos_in_item != ih_item_len(item_head(tbS0, item_pos)) || tb->insert_size[0] <= 0,
bd4c625c
LT
949 "PAP-12225: item too short or insert_size <= 0");
950
951 /* Calculate number of bytes which must be shifted from appended item */
416e2abd 952 n_shift = sbytes[i] - tb->insert_size[0];
bd4c625c
LT
953 if (n_shift < 0)
954 n_shift = 0;
416e2abd 955 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, snum[i], n_shift, S_new[i]);
bd4c625c
LT
956
957 /* Calculate number of bytes which must remain in body after append to S_new[i] */
416e2abd 958 n_rem = tb->insert_size[0] - sbytes[i];
bd4c625c
LT
959 if (n_rem < 0)
960 n_rem = 0;
961 /* Append part of body into S_new[0] */
fba4ebb5 962 buffer_info_init_bh(tb, &bi, S_new[i]);
bd4c625c
LT
963 if (n_rem > zeros_num) {
964 r_zeros_number = 0;
416e2abd 965 r_body = body + n_rem - zeros_num;
bd4c625c
LT
966 } else {
967 r_body = body;
416e2abd
DJ
968 r_zeros_number = zeros_num - n_rem;
969 zeros_num -= r_zeros_number;
bd4c625c
LT
970 }
971
416e2abd
DJ
972 leaf_paste_in_buffer(&bi, 0, n_shift,
973 tb->insert_size[0] - n_rem,
974 r_body, r_zeros_number);
bd4c625c
LT
975 {
976 struct item_head *tmp;
977
4cf5f7ad 978 tmp = item_head(S_new[i], 0);
bd4c625c
LT
979 if (is_indirect_le_ih
980 (tmp)) {
416e2abd
DJ
981 set_ih_free_space(tmp, 0);
982 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT)));
bd4c625c 983 } else {
416e2abd 984 set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + n_rem);
bd4c625c
LT
985 }
986 }
987
988 tb->insert_size[0] = n_rem;
989 if (!n_rem)
990 pos_in_item++;
991 }
992 } else
993 /* item falls wholly into S_new[i] */
994 {
8acc570f 995 int leaf_mi;
bd4c625c 996 struct item_head *pasted;
1da177e4 997
bd4c625c 998#ifdef CONFIG_REISERFS_CHECK
4cf5f7ad 999 struct item_head *ih_check = item_head(tbS0, item_pos);
bd4c625c 1000
8acc570f
HH
1001 if (!is_direntry_le_ih(ih_check)
1002 && (pos_in_item != ih_item_len(ih_check)
bd4c625c
LT
1003 || tb->insert_size[0] <= 0))
1004 reiserfs_panic(tb->tb_sb,
c3a9c210
JM
1005 "PAP-12235",
1006 "pos_in_item "
1007 "must be equal "
1008 "to ih_item_len");
bd4c625c
LT
1009#endif /* CONFIG_REISERFS_CHECK */
1010
416e2abd 1011 leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW,
bd4c625c
LT
1012 tb, snum[i],
1013 sbytes[i],
1014 S_new[i]);
1015
8acc570f 1016 RFALSE(leaf_mi,
bd4c625c 1017 "PAP-12240: unexpected value returned by leaf_move_items (%d)",
8acc570f 1018 leaf_mi);
bd4c625c
LT
1019
1020 /* paste into item */
fba4ebb5 1021 buffer_info_init_bh(tb, &bi, S_new[i]);
bd4c625c 1022 leaf_paste_in_buffer(&bi,
416e2abd 1023 item_pos - n + snum[i],
bd4c625c
LT
1024 pos_in_item,
1025 tb->insert_size[0],
1026 body, zeros_num);
1027
4cf5f7ad 1028 pasted = item_head(S_new[i], item_pos - n + snum[i]);
bd4c625c 1029 if (is_direntry_le_ih(pasted)) {
eba00305 1030 leaf_paste_entries(&bi,
416e2abd
DJ
1031 item_pos - n + snum[i],
1032 pos_in_item, 1,
1033 (struct reiserfs_de_head *)body,
1034 body + DEH_SIZE,
1035 tb->insert_size[0]
bd4c625c
LT
1036 );
1037 }
1038
1039 /* if we paste to indirect item update ih_free_space */
1040 if (is_indirect_le_ih(pasted))
1041 set_ih_free_space(pasted, 0);
1042 zeros_num = tb->insert_size[0] = 0;
1043 }
1da177e4
LT
1044 }
1045
bd4c625c 1046 else { /* pasted item doesn't fall into S_new[i] */
1da177e4 1047
bd4c625c
LT
1048 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
1049 snum[i], sbytes[i], S_new[i]);
1050 }
1051 break;
1052 default: /* cases d and t */
c3a9c210
JM
1053 reiserfs_panic(tb->tb_sb, "PAP-12245",
1054 "blknum > 2: unexpected mode: %s(%d)",
416e2abd 1055 (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
1da177e4 1056 }
1da177e4 1057
4cf5f7ad 1058 memcpy(insert_key + i, leaf_key(S_new[i], 0), KEY_SIZE);
bd4c625c
LT
1059 insert_ptr[i] = S_new[i];
1060
1061 RFALSE(!buffer_journaled(S_new[i])
1062 || buffer_journal_dirty(S_new[i])
1063 || buffer_dirty(S_new[i]), "PAP-12247: S_new[%d] : (%b)",
1064 i, S_new[i]);
1da177e4
LT
1065 }
1066
bd4c625c
LT
1067 /* if the affected item was not wholly shifted then we perform all necessary operations on that part or whole of the
1068 affected item which remains in S */
1069 if (0 <= item_pos && item_pos < tb->s0num) { /* if we must insert or append into buffer S[0] */
1070
1071 switch (flag) {
1072 case M_INSERT: /* insert item into S[0] */
fba4ebb5 1073 buffer_info_init_tbS0(tb, &bi);
bd4c625c
LT
1074 leaf_insert_into_buf(&bi, item_pos, ih, body,
1075 zeros_num);
1076
1077 /* If we insert the first key change the delimiting key */
1078 if (item_pos == 0) {
1079 if (tb->CFL[0]) /* can be 0 in reiserfsck */
416e2abd 1080 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
1da177e4 1081 }
bd4c625c
LT
1082 break;
1083
1084 case M_PASTE:{ /* append item in S[0] */
1085 struct item_head *pasted;
1086
4cf5f7ad 1087 pasted = item_head(tbS0, item_pos);
bd4c625c
LT
1088 /* when directory, may be new entry already pasted */
1089 if (is_direntry_le_ih(pasted)) {
416e2abd 1090 if (pos_in_item >= 0 && pos_in_item <= ih_entry_count(pasted)) {
bd4c625c
LT
1091
1092 RFALSE(!tb->insert_size[0],
1093 "PAP-12260: insert_size is 0 already");
1094
1095 /* prepare space */
fba4ebb5 1096 buffer_info_init_tbS0(tb, &bi);
416e2abd
DJ
1097 leaf_paste_in_buffer(&bi, item_pos, pos_in_item,
1098 tb->insert_size[0], body,
bd4c625c
LT
1099 zeros_num);
1100
1101 /* paste entry */
416e2abd
DJ
1102 leaf_paste_entries(&bi, item_pos, pos_in_item, 1,
1103 (struct reiserfs_de_head *)body,
1104 body + DEH_SIZE,
1105 tb->insert_size[0]);
bd4c625c 1106 if (!item_pos && !pos_in_item) {
416e2abd 1107 RFALSE(!tb->CFL[0] || !tb->L[0],
bd4c625c 1108 "PAP-12270: CFL[0]/L[0] must be specified");
416e2abd
DJ
1109 if (tb->CFL[0])
1110 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
bd4c625c
LT
1111 }
1112 tb->insert_size[0] = 0;
1113 }
1114 } else { /* regular object */
1115 if (pos_in_item == ih_item_len(pasted)) {
1116
1117 RFALSE(tb->insert_size[0] <= 0,
1118 "PAP-12275: insert size must not be %d",
1119 tb->insert_size[0]);
fba4ebb5 1120 buffer_info_init_tbS0(tb, &bi);
416e2abd
DJ
1121 leaf_paste_in_buffer(&bi, item_pos, pos_in_item,
1122 tb->insert_size[0], body, zeros_num);
bd4c625c
LT
1123
1124 if (is_indirect_le_ih(pasted)) {
1da177e4 1125#if 0
bd4c625c
LT
1126 RFALSE(tb->
1127 insert_size[0] !=
1128 UNFM_P_SIZE,
1129 "PAP-12280: insert_size for indirect item must be %d, not %d",
1130 UNFM_P_SIZE,
1131 tb->
1132 insert_size[0]);
1da177e4 1133#endif
416e2abd 1134 set_ih_free_space(pasted, 0);
bd4c625c
LT
1135 }
1136 tb->insert_size[0] = 0;
1137 }
1da177e4 1138#ifdef CONFIG_REISERFS_CHECK
bd4c625c
LT
1139 else {
1140 if (tb->insert_size[0]) {
1141 print_cur_tb("12285");
416e2abd 1142 reiserfs_panic(tb->tb_sb,
c3a9c210
JM
1143 "PAP-12285",
1144 "insert_size "
1145 "must be 0 "
1146 "(%d)",
1147 tb->insert_size[0]);
bd4c625c
LT
1148 }
1149 }
1150#endif /* CONFIG_REISERFS_CHECK */
1151
1152 }
1153 } /* case M_PASTE: */
1da177e4 1154 }
1da177e4 1155 }
1da177e4 1156#ifdef CONFIG_REISERFS_CHECK
bd4c625c
LT
1157 if (flag == M_PASTE && tb->insert_size[0]) {
1158 print_cur_tb("12290");
1159 reiserfs_panic(tb->tb_sb,
c3a9c210 1160 "PAP-12290", "insert_size is still not 0 (%d)",
bd4c625c
LT
1161 tb->insert_size[0]);
1162 }
1163#endif /* CONFIG_REISERFS_CHECK */
bd4c625c
LT
1164 return 0;
1165} /* Leaf level of the tree is balanced (end of balance_leaf) */
1da177e4
LT
1166
1167/* Make empty node */
bd4c625c 1168void make_empty_node(struct buffer_info *bi)
1da177e4 1169{
bd4c625c 1170 struct block_head *blkh;
1da177e4 1171
bd4c625c 1172 RFALSE(bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
1da177e4 1173
bd4c625c
LT
1174 blkh = B_BLK_HEAD(bi->bi_bh);
1175 set_blkh_nr_item(blkh, 0);
1176 set_blkh_free_space(blkh, MAX_CHILD_SIZE(bi->bi_bh));
1da177e4 1177
bd4c625c
LT
1178 if (bi->bi_parent)
1179 B_N_CHILD(bi->bi_parent, bi->bi_position)->dc_size = 0; /* Endian safe if 0 */
1da177e4
LT
1180}
1181
1da177e4 1182/* Get first empty buffer */
bd4c625c 1183struct buffer_head *get_FEB(struct tree_balance *tb)
1da177e4 1184{
bd4c625c 1185 int i;
bd4c625c 1186 struct buffer_info bi;
1da177e4 1187
bd4c625c 1188 for (i = 0; i < MAX_FEB_SIZE; i++)
9dce07f1 1189 if (tb->FEB[i] != NULL)
bd4c625c
LT
1190 break;
1191
1192 if (i == MAX_FEB_SIZE)
c3a9c210 1193 reiserfs_panic(tb->tb_sb, "vs-12300", "FEB list is empty");
bd4c625c 1194
fba4ebb5 1195 buffer_info_init_bh(tb, &bi, tb->FEB[i]);
bd4c625c 1196 make_empty_node(&bi);
fba4ebb5
JM
1197 set_buffer_uptodate(tb->FEB[i]);
1198 tb->used[i] = tb->FEB[i];
bd4c625c 1199 tb->FEB[i] = NULL;
bd4c625c 1200
fba4ebb5 1201 return tb->used[i];
bd4c625c 1202}
1da177e4 1203
098297b2 1204/* This is now used because reiserfs_free_block has to be able to schedule. */
bd4c625c 1205static void store_thrown(struct tree_balance *tb, struct buffer_head *bh)
1da177e4 1206{
bd4c625c
LT
1207 int i;
1208
1209 if (buffer_dirty(bh))
45b03d5e
JM
1210 reiserfs_warning(tb->tb_sb, "reiserfs-12320",
1211 "called with dirty buffer");
79a81aef 1212 for (i = 0; i < ARRAY_SIZE(tb->thrown); i++)
bd4c625c
LT
1213 if (!tb->thrown[i]) {
1214 tb->thrown[i] = bh;
1215 get_bh(bh); /* free_thrown puts this */
1216 return;
1217 }
45b03d5e
JM
1218 reiserfs_warning(tb->tb_sb, "reiserfs-12321",
1219 "too many thrown buffers");
1da177e4
LT
1220}
1221
bd4c625c
LT
1222static void free_thrown(struct tree_balance *tb)
1223{
1224 int i;
1225 b_blocknr_t blocknr;
79a81aef 1226 for (i = 0; i < ARRAY_SIZE(tb->thrown); i++) {
bd4c625c
LT
1227 if (tb->thrown[i]) {
1228 blocknr = tb->thrown[i]->b_blocknr;
1229 if (buffer_dirty(tb->thrown[i]))
45b03d5e
JM
1230 reiserfs_warning(tb->tb_sb, "reiserfs-12322",
1231 "called with dirty buffer %d",
bd4c625c
LT
1232 blocknr);
1233 brelse(tb->thrown[i]); /* incremented in store_thrown */
1234 reiserfs_free_block(tb->transaction_handle, NULL,
1235 blocknr, 0);
1236 }
1da177e4 1237 }
1da177e4
LT
1238}
1239
bd4c625c 1240void reiserfs_invalidate_buffer(struct tree_balance *tb, struct buffer_head *bh)
1da177e4 1241{
bd4c625c
LT
1242 struct block_head *blkh;
1243 blkh = B_BLK_HEAD(bh);
1244 set_blkh_level(blkh, FREE_LEVEL);
1245 set_blkh_nr_item(blkh, 0);
1246
1247 clear_buffer_dirty(bh);
1248 store_thrown(tb, bh);
1da177e4
LT
1249}
1250
1251/* Replace n_dest'th key in buffer dest by n_src'th key of buffer src.*/
bd4c625c
LT
1252void replace_key(struct tree_balance *tb, struct buffer_head *dest, int n_dest,
1253 struct buffer_head *src, int n_src)
1da177e4
LT
1254{
1255
bd4c625c
LT
1256 RFALSE(dest == NULL || src == NULL,
1257 "vs-12305: source or destination buffer is 0 (src=%p, dest=%p)",
1258 src, dest);
1259 RFALSE(!B_IS_KEYS_LEVEL(dest),
1260 "vs-12310: invalid level (%z) for destination buffer. dest must be leaf",
1261 dest);
1262 RFALSE(n_dest < 0 || n_src < 0,
1263 "vs-12315: src(%d) or dest(%d) key number < 0", n_src, n_dest);
1264 RFALSE(n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src),
1265 "vs-12320: src(%d(%d)) or dest(%d(%d)) key number is too big",
1266 n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
1267
1268 if (B_IS_ITEMS_LEVEL(src))
1269 /* source buffer contains leaf node */
4cf5f7ad 1270 memcpy(internal_key(dest, n_dest), item_head(src, n_src),
bd4c625c
LT
1271 KEY_SIZE);
1272 else
4cf5f7ad 1273 memcpy(internal_key(dest, n_dest), internal_key(src, n_src),
bd4c625c
LT
1274 KEY_SIZE);
1275
1276 do_balance_mark_internal_dirty(tb, dest, 0);
1da177e4
LT
1277}
1278
bd4c625c 1279int get_left_neighbor_position(struct tree_balance *tb, int h)
1da177e4 1280{
bd4c625c 1281 int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
1da177e4 1282
9dce07f1 1283 RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FL[h] == NULL,
bd4c625c
LT
1284 "vs-12325: FL[%d](%p) or F[%d](%p) does not exist",
1285 h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h));
1da177e4 1286
bd4c625c
LT
1287 if (Sh_position == 0)
1288 return B_NR_ITEMS(tb->FL[h]);
1289 else
1290 return Sh_position - 1;
1da177e4
LT
1291}
1292
bd4c625c 1293int get_right_neighbor_position(struct tree_balance *tb, int h)
1da177e4 1294{
bd4c625c 1295 int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
1da177e4 1296
9dce07f1 1297 RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FR[h] == NULL,
bd4c625c
LT
1298 "vs-12330: F[%d](%p) or FR[%d](%p) does not exist",
1299 h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]);
1da177e4 1300
bd4c625c
LT
1301 if (Sh_position == B_NR_ITEMS(PATH_H_PPARENT(tb->tb_path, h)))
1302 return 0;
1303 else
1304 return Sh_position + 1;
1da177e4
LT
1305}
1306
1da177e4
LT
1307#ifdef CONFIG_REISERFS_CHECK
1308
bd4c625c
LT
1309int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
1310static void check_internal_node(struct super_block *s, struct buffer_head *bh,
1311 char *mes)
1da177e4 1312{
bd4c625c
LT
1313 struct disk_child *dc;
1314 int i;
1da177e4 1315
bd4c625c 1316 RFALSE(!bh, "PAP-12336: bh == 0");
1da177e4 1317
bd4c625c
LT
1318 if (!bh || !B_IS_IN_TREE(bh))
1319 return;
1da177e4 1320
bd4c625c
LT
1321 RFALSE(!buffer_dirty(bh) &&
1322 !(buffer_journaled(bh) || buffer_journal_dirty(bh)),
1323 "PAP-12337: buffer (%b) must be dirty", bh);
1324 dc = B_N_CHILD(bh, 0);
1da177e4 1325
bd4c625c
LT
1326 for (i = 0; i <= B_NR_ITEMS(bh); i++, dc++) {
1327 if (!is_reusable(s, dc_block_number(dc), 1)) {
1328 print_cur_tb(mes);
c3a9c210
JM
1329 reiserfs_panic(s, "PAP-12338",
1330 "invalid child pointer %y in %b",
bd4c625c
LT
1331 dc, bh);
1332 }
1333 }
1da177e4
LT
1334}
1335
45b03d5e
JM
1336static int locked_or_not_in_tree(struct tree_balance *tb,
1337 struct buffer_head *bh, char *which)
bd4c625c
LT
1338{
1339 if ((!buffer_journal_prepared(bh) && buffer_locked(bh)) ||
1340 !B_IS_IN_TREE(bh)) {
45b03d5e 1341 reiserfs_warning(tb->tb_sb, "vs-12339", "%s (%b)", which, bh);
bd4c625c
LT
1342 return 1;
1343 }
1344 return 0;
1345}
1da177e4 1346
bd4c625c 1347static int check_before_balancing(struct tree_balance *tb)
1da177e4 1348{
bd4c625c
LT
1349 int retval = 0;
1350
08f14fc8 1351 if (REISERFS_SB(tb->tb_sb)->cur_tb) {
c3a9c210
JM
1352 reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule "
1353 "occurred based on cur_tb not being null at "
1354 "this point in code. do_balance cannot properly "
08f14fc8
FW
1355 "handle concurrent tree accesses on a same "
1356 "mount point.");
1da177e4 1357 }
bd4c625c 1358
098297b2
JM
1359 /*
1360 * double check that buffers that we will modify are unlocked.
1361 * (fix_nodes should already have prepped all of these for us).
1362 */
bd4c625c 1363 if (tb->lnum[0]) {
45b03d5e
JM
1364 retval |= locked_or_not_in_tree(tb, tb->L[0], "L[0]");
1365 retval |= locked_or_not_in_tree(tb, tb->FL[0], "FL[0]");
1366 retval |= locked_or_not_in_tree(tb, tb->CFL[0], "CFL[0]");
bd4c625c 1367 check_leaf(tb->L[0]);
1da177e4 1368 }
bd4c625c 1369 if (tb->rnum[0]) {
45b03d5e
JM
1370 retval |= locked_or_not_in_tree(tb, tb->R[0], "R[0]");
1371 retval |= locked_or_not_in_tree(tb, tb->FR[0], "FR[0]");
1372 retval |= locked_or_not_in_tree(tb, tb->CFR[0], "CFR[0]");
bd4c625c
LT
1373 check_leaf(tb->R[0]);
1374 }
45b03d5e
JM
1375 retval |= locked_or_not_in_tree(tb, PATH_PLAST_BUFFER(tb->tb_path),
1376 "S[0]");
bd4c625c 1377 check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
1da177e4 1378
bd4c625c
LT
1379 return retval;
1380}
1da177e4 1381
bd4c625c 1382static void check_after_balance_leaf(struct tree_balance *tb)
1da177e4 1383{
bd4c625c
LT
1384 if (tb->lnum[0]) {
1385 if (B_FREE_SPACE(tb->L[0]) !=
1386 MAX_CHILD_SIZE(tb->L[0]) -
1387 dc_size(B_N_CHILD
1388 (tb->FL[0], get_left_neighbor_position(tb, 0)))) {
1389 print_cur_tb("12221");
c3a9c210
JM
1390 reiserfs_panic(tb->tb_sb, "PAP-12355",
1391 "shift to left was incorrect");
bd4c625c
LT
1392 }
1393 }
1394 if (tb->rnum[0]) {
1395 if (B_FREE_SPACE(tb->R[0]) !=
1396 MAX_CHILD_SIZE(tb->R[0]) -
1397 dc_size(B_N_CHILD
1398 (tb->FR[0], get_right_neighbor_position(tb, 0)))) {
1399 print_cur_tb("12222");
c3a9c210
JM
1400 reiserfs_panic(tb->tb_sb, "PAP-12360",
1401 "shift to right was incorrect");
bd4c625c
LT
1402 }
1403 }
1404 if (PATH_H_PBUFFER(tb->tb_path, 1) &&
1405 (B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0)) !=
1406 (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
1407 dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
1408 PATH_H_POSITION(tb->tb_path, 1)))))) {
1409 int left = B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0));
1410 int right = (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
1411 dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
1412 PATH_H_POSITION(tb->tb_path,
1413 1))));
1414 print_cur_tb("12223");
45b03d5e 1415 reiserfs_warning(tb->tb_sb, "reiserfs-12363",
bd4c625c
LT
1416 "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
1417 "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d",
1418 left,
1419 MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)),
1420 PATH_H_PBUFFER(tb->tb_path, 1),
1421 PATH_H_POSITION(tb->tb_path, 1),
1422 dc_size(B_N_CHILD
1423 (PATH_H_PBUFFER(tb->tb_path, 1),
1424 PATH_H_POSITION(tb->tb_path, 1))),
1425 right);
c3a9c210 1426 reiserfs_panic(tb->tb_sb, "PAP-12365", "S is incorrect");
bd4c625c 1427 }
1da177e4
LT
1428}
1429
bd4c625c 1430static void check_leaf_level(struct tree_balance *tb)
1da177e4 1431{
bd4c625c
LT
1432 check_leaf(tb->L[0]);
1433 check_leaf(tb->R[0]);
1434 check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
1435}
1da177e4 1436
bd4c625c
LT
1437static void check_internal_levels(struct tree_balance *tb)
1438{
1439 int h;
1440
1441 /* check all internal nodes */
1442 for (h = 1; tb->insert_size[h]; h++) {
1443 check_internal_node(tb->tb_sb, PATH_H_PBUFFER(tb->tb_path, h),
1444 "BAD BUFFER ON PATH");
1445 if (tb->lnum[h])
1446 check_internal_node(tb->tb_sb, tb->L[h], "BAD L");
1447 if (tb->rnum[h])
1448 check_internal_node(tb->tb_sb, tb->R[h], "BAD R");
1449 }
1da177e4
LT
1450
1451}
1452
1453#endif
1454
098297b2
JM
1455/*
1456 * Now we have all of the buffers that must be used in balancing of
1457 * the tree. We rely on the assumption that schedule() will not occur
1458 * while do_balance works. ( Only interrupt handlers are acceptable.)
1459 * We balance the tree according to the analysis made before this,
1460 * using buffers already obtained. For SMP support it will someday be
1461 * necessary to add ordered locking of tb.
1462 */
1da177e4 1463
098297b2
JM
1464/*
1465 * Some interesting rules of balancing:
1466 * we delete a maximum of two nodes per level per balancing: we never
1467 * delete R, when we delete two of three nodes L, S, R then we move
1468 * them into R.
1469 *
1470 * we only delete L if we are deleting two nodes, if we delete only
1471 * one node we delete S
1472 *
1473 * if we shift leaves then we shift as much as we can: this is a
1474 * deliberate policy of extremism in node packing which results in
1475 * higher average utilization after repeated random balance operations
1476 * at the cost of more memory copies and more balancing as a result of
1477 * small insertions to full nodes.
1478 *
1479 * if we shift internal nodes we try to evenly balance the node
1480 * utilization, with consequent less balancing at the cost of lower
1481 * utilization.
1482 *
1483 * one could argue that the policy for directories in leaves should be
1484 * that of internal nodes, but we will wait until another day to
1485 * evaluate this.... It would be nice to someday measure and prove
1486 * these assumptions as to what is optimal....
1487 */
1da177e4 1488
bd4c625c 1489static inline void do_balance_starts(struct tree_balance *tb)
1da177e4 1490{
098297b2 1491 /* use print_cur_tb() to see initial state of struct tree_balance */
1da177e4 1492
bd4c625c 1493 /* store_print_tb (tb); */
1da177e4 1494
bd4c625c 1495 /* do not delete, just comment it out */
098297b2
JM
1496 /*
1497 print_tb(flag, PATH_LAST_POSITION(tb->tb_path),
1498 tb->tb_path->pos_in_item, tb, "check");
1499 */
bd4c625c 1500 RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
1da177e4 1501#ifdef CONFIG_REISERFS_CHECK
08f14fc8 1502 REISERFS_SB(tb->tb_sb)->cur_tb = tb;
1da177e4
LT
1503#endif
1504}
1505
bd4c625c 1506static inline void do_balance_completed(struct tree_balance *tb)
1da177e4 1507{
bd4c625c 1508
1da177e4 1509#ifdef CONFIG_REISERFS_CHECK
bd4c625c
LT
1510 check_leaf_level(tb);
1511 check_internal_levels(tb);
08f14fc8 1512 REISERFS_SB(tb->tb_sb)->cur_tb = NULL;
1da177e4
LT
1513#endif
1514
098297b2
JM
1515 /*
1516 * reiserfs_free_block is no longer schedule safe. So, we need to
1517 * put the buffers we want freed on the thrown list during do_balance,
1518 * and then free them now
bd4c625c 1519 */
1da177e4 1520
bd4c625c 1521 REISERFS_SB(tb->tb_sb)->s_do_balance++;
1da177e4 1522
bd4c625c
LT
1523 /* release all nodes hold to perform the balancing */
1524 unfix_nodes(tb);
1da177e4 1525
bd4c625c 1526 free_thrown(tb);
1da177e4
LT
1527}
1528
098297b2
JM
1529/*
1530 * do_balance - balance the tree
1531 *
1532 * @tb: tree_balance structure
1533 * @ih: item header of inserted item
1534 * @body: body of inserted item or bytes to paste
1535 * @flag: 'i' - insert, 'd' - delete, 'c' - cut, 'p' paste
1536 *
1537 * Cut means delete part of an item (includes removing an entry from a
1538 * directory).
1539 *
1540 * Delete means delete whole item.
1541 *
1542 * Insert means add a new item into the tree.
1543 *
1544 * Paste means to append to the end of an existing file or to
1545 * insert a directory entry.
1546 */
1547void do_balance(struct tree_balance *tb, struct item_head *ih,
1548 const char *body, int flag)
1549{
1550 int child_pos; /* position of a child node in its parent */
1551 int h; /* level of the tree being processed */
1552
1553 /*
1554 * in our processing of one level we sometimes determine what
1555 * must be inserted into the next higher level. This insertion
1556 * consists of a key or two keys and their corresponding
1557 * pointers
1558 */
1559 struct item_head insert_key[2];
1560
1561 /* inserted node-ptrs for the next level */
1562 struct buffer_head *insert_ptr[2];
bd4c625c
LT
1563
1564 tb->tb_mode = flag;
1565 tb->need_balance_dirty = 0;
1566
1567 if (FILESYSTEM_CHANGED_TB(tb)) {
c3a9c210
JM
1568 reiserfs_panic(tb->tb_sb, "clm-6000", "fs generation has "
1569 "changed");
bd4c625c
LT
1570 }
1571 /* if we have no real work to do */
1572 if (!tb->insert_size[0]) {
45b03d5e
JM
1573 reiserfs_warning(tb->tb_sb, "PAP-12350",
1574 "insert_size == 0, mode == %c", flag);
bd4c625c
LT
1575 unfix_nodes(tb);
1576 return;
1577 }
1da177e4 1578
bd4c625c
LT
1579 atomic_inc(&(fs_generation(tb->tb_sb)));
1580 do_balance_starts(tb);
1da177e4 1581
098297b2
JM
1582 /*
1583 * balance_leaf returns 0 except if combining L R and S into
1584 * one node. see balance_internal() for explanation of this
1585 * line of code.
1586 */
bd4c625c
LT
1587 child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) +
1588 balance_leaf(tb, ih, body, flag, insert_key, insert_ptr);
1da177e4
LT
1589
1590#ifdef CONFIG_REISERFS_CHECK
bd4c625c 1591 check_after_balance_leaf(tb);
1da177e4
LT
1592#endif
1593
bd4c625c
LT
1594 /* Balance internal level of the tree. */
1595 for (h = 1; h < MAX_HEIGHT && tb->insert_size[h]; h++)
1596 child_pos =
1597 balance_internal(tb, h, child_pos, insert_key, insert_ptr);
1da177e4 1598
bd4c625c 1599 do_balance_completed(tb);
1da177e4
LT
1600
1601}
This page took 0.750505 seconds and 5 git commands to generate.