1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/uaccess.h>
14#include <linux/time.h>
15#include "reiserfs.h"
16#include <linux/buffer_head.h>
17#include <linux/kernel.h>
18
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
56inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
57 struct buffer_head *bh, int flag)
58{
59 journal_mark_dirty(tb->transaction_handle, bh);
60}
61
62#define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
63#define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
64
65
66
67
68
69
70
71
72
73
74
75
76
77static void balance_leaf_when_delete_del(struct tree_balance *tb)
78{
79 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
80 int item_pos = PATH_LAST_POSITION(tb->tb_path);
81 struct buffer_info bi;
82#ifdef CONFIG_REISERFS_CHECK
83 struct item_head *ih = item_head(tbS0, item_pos);
84#endif
85
86 RFALSE(ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
87 "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
88 -tb->insert_size[0], ih);
89
90 buffer_info_init_tbS0(tb, &bi);
91 leaf_delete_items(&bi, 0, item_pos, 1, -1);
92
93 if (!item_pos && tb->CFL[0]) {
94 if (B_NR_ITEMS(tbS0)) {
95 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
96 } else {
97 if (!PATH_H_POSITION(tb->tb_path, 1))
98 replace_key(tb, tb->CFL[0], tb->lkey[0],
99 PATH_H_PPARENT(tb->tb_path, 0), 0);
100 }
101 }
102
103 RFALSE(!item_pos && !tb->CFL[0],
104 "PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0],
105 tb->L[0]);
106}
107
108
109static void balance_leaf_when_delete_cut(struct tree_balance *tb)
110{
111 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
112 int item_pos = PATH_LAST_POSITION(tb->tb_path);
113 struct item_head *ih = item_head(tbS0, item_pos);
114 int pos_in_item = tb->tb_path->pos_in_item;
115 struct buffer_info bi;
116 buffer_info_init_tbS0(tb, &bi);
117
118 if (is_direntry_le_ih(ih)) {
119
120
121
122
123
124
125
126 tb->insert_size[0] = -1;
127 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
128 -tb->insert_size[0]);
129
130 RFALSE(!item_pos && !pos_in_item && !tb->CFL[0],
131 "PAP-12030: can not change delimiting key. CFL[0]=%p",
132 tb->CFL[0]);
133
134 if (!item_pos && !pos_in_item && tb->CFL[0])
135 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
136 } else {
137 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
138 -tb->insert_size[0]);
139
140 RFALSE(!ih_item_len(ih),
141 "PAP-12035: cut must leave non-zero dynamic "
142 "length of item");
143 }
144}
145
146static int balance_leaf_when_delete_left(struct tree_balance *tb)
147{
148 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
149 int n = B_NR_ITEMS(tbS0);
150
151
152 if (tb->lnum[0] == -1) {
153
154 if (tb->rnum[0] == -1) {
155 if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) {
156
157
158
159
160 if (PATH_H_POSITION(tb->tb_path, 1) == 0 &&
161 1 < B_NR_ITEMS(tb->FR[0]))
162 replace_key(tb, tb->CFL[0],
163 tb->lkey[0], tb->FR[0], 1);
164
165 leaf_move_items(LEAF_FROM_S_TO_L, tb, n, -1,
166 NULL);
167 leaf_move_items(LEAF_FROM_R_TO_L, tb,
168 B_NR_ITEMS(tb->R[0]), -1,
169 NULL);
170
171 reiserfs_invalidate_buffer(tb, tbS0);
172 reiserfs_invalidate_buffer(tb, tb->R[0]);
173
174 return 0;
175 }
176
177
178 leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1, NULL);
179 leaf_move_items(LEAF_FROM_L_TO_R, tb,
180 B_NR_ITEMS(tb->L[0]), -1, NULL);
181
182
183 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
184
185 reiserfs_invalidate_buffer(tb, tbS0);
186 reiserfs_invalidate_buffer(tb, tb->L[0]);
187
188 return -1;
189 }
190
191 RFALSE(tb->rnum[0] != 0,
192 "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
193
194 leaf_shift_left(tb, n, -1);
195
196 reiserfs_invalidate_buffer(tb, tbS0);
197
198 return 0;
199 }
200
201
202
203
204
205
206 RFALSE((tb->lnum[0] + tb->rnum[0] < n) ||
207 (tb->lnum[0] + tb->rnum[0] > n + 1),
208 "PAP-12050: rnum(%d) and lnum(%d) and item "
209 "number(%d) in S[0] are not consistent",
210 tb->rnum[0], tb->lnum[0], n);
211 RFALSE((tb->lnum[0] + tb->rnum[0] == n) &&
212 (tb->lbytes != -1 || tb->rbytes != -1),
213 "PAP-12055: bad rbytes (%d)/lbytes (%d) "
214 "parameters when items are not split",
215 tb->rbytes, tb->lbytes);
216 RFALSE((tb->lnum[0] + tb->rnum[0] == n + 1) &&
217 (tb->lbytes < 1 || tb->rbytes != -1),
218 "PAP-12060: bad rbytes (%d)/lbytes (%d) "
219 "parameters when items are split",
220 tb->rbytes, tb->lbytes);
221
222 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
223 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
224
225 reiserfs_invalidate_buffer(tb, tbS0);
226
227 return 0;
228}
229
230
231
232
233
234
235
236
237
238
239static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
240{
241 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
242 struct buffer_info bi;
243 int n;
244
245 RFALSE(tb->FR[0] && B_LEVEL(tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
246 "vs- 12000: level: wrong FR %z", tb->FR[0]);
247 RFALSE(tb->blknum[0] > 1,
248 "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
249 RFALSE(!tb->blknum[0] && !PATH_H_PPARENT(tb->tb_path, 0),
250 "PAP-12010: tree can not be empty");
251
252 buffer_info_init_tbS0(tb, &bi);
253
254
255
256 BUG_ON(flag != M_DELETE && flag != M_CUT);
257 if (flag == M_DELETE)
258 balance_leaf_when_delete_del(tb);
259 else
260 balance_leaf_when_delete_cut(tb);
261
262
263
264
265
266
267 n = B_NR_ITEMS(tbS0);
268
269
270
271 if (tb->lnum[0])
272 return balance_leaf_when_delete_left(tb);
273
274 if (tb->rnum[0] == -1) {
275
276 leaf_shift_right(tb, n, -1);
277 reiserfs_invalidate_buffer(tb, tbS0);
278 return 0;
279 }
280
281 RFALSE(tb->rnum[0],
282 "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
283 return 0;
284}
285
286static unsigned int balance_leaf_insert_left(struct tree_balance *tb,
287 struct item_head *const ih,
288 const char * const body)
289{
290 int ret;
291 struct buffer_info bi;
292 int n = B_NR_ITEMS(tb->L[0]);
293 unsigned body_shift_bytes = 0;
294
295 if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) {
296
297 int new_item_len, shift;
298
299 ret = leaf_shift_left(tb, tb->lnum[0] - 1, -1);
300
301
302 new_item_len = ih_item_len(ih) - tb->lbytes;
303
304
305 put_ih_item_len(ih, ih_item_len(ih) - new_item_len);
306
307 RFALSE(ih_item_len(ih) <= 0,
308 "PAP-12080: there is nothing to insert into L[0]: "
309 "ih_item_len=%d", ih_item_len(ih));
310
311
312 buffer_info_init_left(tb, &bi);
313 leaf_insert_into_buf(&bi, n + tb->item_pos - ret, ih, body,
314 min_t(int, tb->zeroes_num, ih_item_len(ih)));
315
316
317
318
319
320 shift = 0;
321 if (is_indirect_le_ih(ih))
322 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
323
324 add_le_ih_k_offset(ih, tb->lbytes << shift);
325
326 put_ih_item_len(ih, new_item_len);
327 if (tb->lbytes > tb->zeroes_num) {
328 body_shift_bytes = tb->lbytes - tb->zeroes_num;
329 tb->zeroes_num = 0;
330 } else
331 tb->zeroes_num -= tb->lbytes;
332
333 RFALSE(ih_item_len(ih) <= 0,
334 "PAP-12085: there is nothing to insert into S[0]: "
335 "ih_item_len=%d", ih_item_len(ih));
336 } else {
337
338
339 ret = leaf_shift_left(tb, tb->lnum[0] - 1, tb->lbytes);
340
341
342 buffer_info_init_left(tb, &bi);
343 leaf_insert_into_buf(&bi, n + tb->item_pos - ret, ih, body,
344 tb->zeroes_num);
345 tb->insert_size[0] = 0;
346 tb->zeroes_num = 0;
347 }
348 return body_shift_bytes;
349}
350
351static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb,
352 struct item_head * const ih,
353 const char * const body)
354{
355 int n = B_NR_ITEMS(tb->L[0]);
356 struct buffer_info bi;
357
358 RFALSE(tb->zeroes_num,
359 "PAP-12090: invalid parameter in case of a directory");
360
361
362 if (tb->lbytes > tb->pos_in_item) {
363
364 struct item_head *pasted;
365 int ret, l_pos_in_item = tb->pos_in_item;
366
367
368
369
370
371 ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes - 1);
372 if (ret && !tb->item_pos) {
373 pasted = item_head(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1);
374 l_pos_in_item += ih_entry_count(pasted) -
375 (tb->lbytes - 1);
376 }
377
378
379 buffer_info_init_left(tb, &bi);
380 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret,
381 l_pos_in_item, tb->insert_size[0],
382 body, tb->zeroes_num);
383
384
385
386
387
388
389
390
391
392
393
394
395 leaf_paste_entries(&bi, n + tb->item_pos - ret,
396 l_pos_in_item, 1,
397 (struct reiserfs_de_head *) body,
398 body + DEH_SIZE, tb->insert_size[0]);
399 tb->insert_size[0] = 0;
400 } else {
401
402
403
404
405
406 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
407 }
408
409
410 tb->pos_in_item -= tb->lbytes;
411}
412
413static unsigned int balance_leaf_paste_left_shift(struct tree_balance *tb,
414 struct item_head * const ih,
415 const char * const body)
416{
417 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
418 int n = B_NR_ITEMS(tb->L[0]);
419 struct buffer_info bi;
420 int body_shift_bytes = 0;
421
422 if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) {
423 balance_leaf_paste_left_shift_dirent(tb, ih, body);
424 return 0;
425 }
426
427 RFALSE(tb->lbytes <= 0,
428 "PAP-12095: there is nothing to shift to L[0]. "
429 "lbytes=%d", tb->lbytes);
430 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)),
431 "PAP-12100: incorrect position to paste: "
432 "item_len=%d, pos_in_item=%d",
433 ih_item_len(item_head(tbS0, tb->item_pos)), tb->pos_in_item);
434
435
436 if (tb->lbytes >= tb->pos_in_item) {
437 struct item_head *tbS0_pos_ih, *tbL0_ih;
438 struct item_head *tbS0_0_ih;
439 struct reiserfs_key *left_delim_key;
440 int ret, l_n, version, temp_l;
441
442 tbS0_pos_ih = item_head(tbS0, tb->item_pos);
443 tbS0_0_ih = item_head(tbS0, 0);
444
445
446
447
448
449 l_n = tb->lbytes - tb->pos_in_item;
450
451
452 tb->insert_size[0] -= l_n;
453
454 RFALSE(tb->insert_size[0] <= 0,
455 "PAP-12105: there is nothing to paste into "
456 "L[0]. insert_size=%d", tb->insert_size[0]);
457
458 ret = leaf_shift_left(tb, tb->lnum[0],
459 ih_item_len(tbS0_pos_ih));
460
461 tbL0_ih = item_head(tb->L[0], n + tb->item_pos - ret);
462
463
464 buffer_info_init_left(tb, &bi);
465 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret,
466 ih_item_len(tbL0_ih), l_n, body,
467 min_t(int, l_n, tb->zeroes_num));
468
469
470
471
472
473 temp_l = l_n;
474
475 RFALSE(ih_item_len(tbS0_0_ih),
476 "PAP-12106: item length must be 0");
477 RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key,
478 leaf_key(tb->L[0], n + tb->item_pos - ret)),
479 "PAP-12107: items must be of the same file");
480
481 if (is_indirect_le_ih(tbL0_ih)) {
482 int shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
483 temp_l = l_n << shift;
484 }
485
486 version = ih_version(tbS0_0_ih);
487 add_le_key_k_offset(version, &tbS0_0_ih->ih_key, temp_l);
488
489
490 left_delim_key = internal_key(tb->CFL[0], tb->lkey[0]);
491 add_le_key_k_offset(version, left_delim_key, temp_l);
492
493
494
495
496
497 if (l_n > tb->zeroes_num) {
498 body_shift_bytes = l_n - tb->zeroes_num;
499 tb->zeroes_num = 0;
500 } else
501 tb->zeroes_num -= l_n;
502 tb->pos_in_item = 0;
503
504 RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key,
505 leaf_key(tb->L[0],
506 B_NR_ITEMS(tb->L[0]) - 1)) ||
507 !op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size) ||
508 !op_is_left_mergeable(left_delim_key, tbS0->b_size),
509 "PAP-12120: item must be merge-able with left "
510 "neighboring item");
511 } else {
512
513
514
515 tb->pos_in_item -= tb->lbytes;
516
517 RFALSE(tb->pos_in_item <= 0,
518 "PAP-12125: no place for paste. pos_in_item=%d",
519 tb->pos_in_item);
520
521
522
523
524
525 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
526 }
527 return body_shift_bytes;
528}
529
530
531
532static void balance_leaf_paste_left_whole(struct tree_balance *tb,
533 struct item_head * const ih,
534 const char * const body)
535{
536 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
537 int n = B_NR_ITEMS(tb->L[0]);
538 struct buffer_info bi;
539 struct item_head *pasted;
540 int ret;
541
542
543 if (!tb->item_pos &&
544 op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)) {
545
546
547
548
549 pasted = item_head(tb->L[0], n - 1);
550 if (is_direntry_le_ih(pasted))
551 tb->pos_in_item += ih_entry_count(pasted);
552 else
553 tb->pos_in_item += ih_item_len(pasted);
554 }
555
556
557
558
559
560 ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
561
562
563 buffer_info_init_left(tb, &bi);
564 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret, tb->pos_in_item,
565 tb->insert_size[0], body, tb->zeroes_num);
566
567
568 pasted = item_head(tb->L[0], n + tb->item_pos - ret);
569 if (is_direntry_le_ih(pasted))
570 leaf_paste_entries(&bi, n + tb->item_pos - ret,
571 tb->pos_in_item, 1,
572 (struct reiserfs_de_head *)body,
573 body + DEH_SIZE, tb->insert_size[0]);
574
575
576
577
578
579 if (is_indirect_le_ih(pasted))
580 set_ih_free_space(pasted, 0);
581
582 tb->insert_size[0] = 0;
583 tb->zeroes_num = 0;
584}
585
586static unsigned int balance_leaf_paste_left(struct tree_balance *tb,
587 struct item_head * const ih,
588 const char * const body)
589{
590
591 if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1)
592 return balance_leaf_paste_left_shift(tb, ih, body);
593 else
594 balance_leaf_paste_left_whole(tb, ih, body);
595 return 0;
596}
597
598
599static unsigned int balance_leaf_left(struct tree_balance *tb,
600 struct item_head * const ih,
601 const char * const body, int flag)
602{
603 if (tb->lnum[0] <= 0)
604 return 0;
605
606
607 if (tb->item_pos < tb->lnum[0]) {
608 BUG_ON(flag != M_INSERT && flag != M_PASTE);
609
610 if (flag == M_INSERT)
611 return balance_leaf_insert_left(tb, ih, body);
612 else
613 return balance_leaf_paste_left(tb, ih, body);
614 } else
615
616 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
617 return 0;
618}
619
620
621static void balance_leaf_insert_right(struct tree_balance *tb,
622 struct item_head * const ih,
623 const char * const body)
624{
625
626 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
627 int n = B_NR_ITEMS(tbS0);
628 struct buffer_info bi;
629
630
631 if (n - tb->rnum[0] >= tb->item_pos) {
632 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
633 return;
634 }
635
636
637
638
639 if (tb->item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) {
640 loff_t old_key_comp, old_len, r_zeroes_number;
641 const char *r_body;
642 int shift;
643 loff_t offset;
644
645 leaf_shift_right(tb, tb->rnum[0] - 1, -1);
646
647
648 old_key_comp = le_ih_k_offset(ih);
649 old_len = ih_item_len(ih);
650
651
652
653
654
655 shift = 0;
656 if (is_indirect_le_ih(ih))
657 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
658 offset = le_ih_k_offset(ih) + ((old_len - tb->rbytes) << shift);
659 set_le_ih_k_offset(ih, offset);
660 put_ih_item_len(ih, tb->rbytes);
661
662
663 buffer_info_init_right(tb, &bi);
664 if ((old_len - tb->rbytes) > tb->zeroes_num) {
665 r_zeroes_number = 0;
666 r_body = body + (old_len - tb->rbytes) - tb->zeroes_num;
667 } else {
668 r_body = body;
669 r_zeroes_number = tb->zeroes_num -
670 (old_len - tb->rbytes);
671 tb->zeroes_num -= r_zeroes_number;
672 }
673
674 leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number);
675
676
677 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
678
679
680
681
682
683 set_le_ih_k_offset(ih, old_key_comp);
684 put_ih_item_len(ih, old_len - tb->rbytes);
685
686 tb->insert_size[0] -= tb->rbytes;
687
688 } else {
689
690
691
692 leaf_shift_right(tb, tb->rnum[0] - 1, tb->rbytes);
693
694
695 buffer_info_init_right(tb, &bi);
696 leaf_insert_into_buf(&bi, tb->item_pos - n + tb->rnum[0] - 1,
697 ih, body, tb->zeroes_num);
698
699 if (tb->item_pos - n + tb->rnum[0] - 1 == 0)
700 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
701
702 tb->zeroes_num = tb->insert_size[0] = 0;
703 }
704}
705
706
707static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb,
708 struct item_head * const ih,
709 const char * const body)
710{
711 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
712 struct buffer_info bi;
713 int entry_count;
714
715 RFALSE(tb->zeroes_num,
716 "PAP-12145: invalid parameter in case of a directory");
717 entry_count = ih_entry_count(item_head(tbS0, tb->item_pos));
718
719
720 if (entry_count - tb->rbytes < tb->pos_in_item) {
721 int paste_entry_position;
722
723 RFALSE(tb->rbytes - 1 >= entry_count || !tb->insert_size[0],
724 "PAP-12150: no enough of entries to shift to R[0]: "
725 "rbytes=%d, entry_count=%d", tb->rbytes, entry_count);
726
727
728
729
730
731
732 leaf_shift_right(tb, tb->rnum[0], tb->rbytes - 1);
733
734
735 paste_entry_position = tb->pos_in_item - entry_count +
736 tb->rbytes - 1;
737 buffer_info_init_right(tb, &bi);
738 leaf_paste_in_buffer(&bi, 0, paste_entry_position,
739 tb->insert_size[0], body, tb->zeroes_num);
740
741
742 leaf_paste_entries(&bi, 0, paste_entry_position, 1,
743 (struct reiserfs_de_head *) body,
744 body + DEH_SIZE, tb->insert_size[0]);
745
746
747 if (paste_entry_position == 0)
748 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
749
750 tb->insert_size[0] = 0;
751 tb->pos_in_item++;
752 } else {
753
754 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
755 }
756}
757
758static void balance_leaf_paste_right_shift(struct tree_balance *tb,
759 struct item_head * const ih,
760 const char * const body)
761{
762 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
763 int n_shift, n_rem, r_zeroes_number, version;
764 unsigned long temp_rem;
765 const char *r_body;
766 struct buffer_info bi;
767
768
769 if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) {
770 balance_leaf_paste_right_shift_dirent(tb, ih, body);
771 return;
772 }
773
774
775
776
777
778
779
780 n_shift = tb->rbytes - tb->insert_size[0];
781 if (n_shift < 0)
782 n_shift = 0;
783
784 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)),
785 "PAP-12155: invalid position to paste. ih_item_len=%d, "
786 "pos_in_item=%d", tb->pos_in_item,
787 ih_item_len(item_head(tbS0, tb->item_pos)));
788
789 leaf_shift_right(tb, tb->rnum[0], n_shift);
790
791
792
793
794
795 n_rem = tb->insert_size[0] - tb->rbytes;
796 if (n_rem < 0)
797 n_rem = 0;
798
799 temp_rem = n_rem;
800
801 version = ih_version(item_head(tb->R[0], 0));
802
803 if (is_indirect_le_key(version, leaf_key(tb->R[0], 0))) {
804 int shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
805 temp_rem = n_rem << shift;
806 }
807
808 add_le_key_k_offset(version, leaf_key(tb->R[0], 0), temp_rem);
809 add_le_key_k_offset(version, internal_key(tb->CFR[0], tb->rkey[0]),
810 temp_rem);
811
812 do_balance_mark_internal_dirty(tb, tb->CFR[0], 0);
813
814
815 buffer_info_init_right(tb, &bi);
816 if (n_rem > tb->zeroes_num) {
817 r_zeroes_number = 0;
818 r_body = body + n_rem - tb->zeroes_num;
819 } else {
820 r_body = body;
821 r_zeroes_number = tb->zeroes_num - n_rem;
822 tb->zeroes_num -= r_zeroes_number;
823 }
824
825 leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem,
826 r_body, r_zeroes_number);
827
828 if (is_indirect_le_ih(item_head(tb->R[0], 0)))
829 set_ih_free_space(item_head(tb->R[0], 0), 0);
830
831 tb->insert_size[0] = n_rem;
832 if (!n_rem)
833 tb->pos_in_item++;
834}
835
836static void balance_leaf_paste_right_whole(struct tree_balance *tb,
837 struct item_head * const ih,
838 const char * const body)
839{
840 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
841 int n = B_NR_ITEMS(tbS0);
842 struct item_head *pasted;
843 struct buffer_info bi;
844
845 buffer_info_init_right(tb, &bi);
846 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
847
848
849 if (tb->pos_in_item >= 0) {
850 buffer_info_init_right(tb, &bi);
851 leaf_paste_in_buffer(&bi, tb->item_pos - n + tb->rnum[0],
852 tb->pos_in_item, tb->insert_size[0], body,
853 tb->zeroes_num);
854 }
855
856
857 pasted = item_head(tb->R[0], tb->item_pos - n + tb->rnum[0]);
858 if (is_direntry_le_ih(pasted) && tb->pos_in_item >= 0) {
859 leaf_paste_entries(&bi, tb->item_pos - n + tb->rnum[0],
860 tb->pos_in_item, 1,
861 (struct reiserfs_de_head *)body,
862 body + DEH_SIZE, tb->insert_size[0]);
863
864 if (!tb->pos_in_item) {
865
866 RFALSE(tb->item_pos - n + tb->rnum[0],
867 "PAP-12165: directory item must be first "
868 "item of node when pasting is in 0th position");
869
870
871 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
872 }
873 }
874
875 if (is_indirect_le_ih(pasted))
876 set_ih_free_space(pasted, 0);
877 tb->zeroes_num = tb->insert_size[0] = 0;
878}
879
880static void balance_leaf_paste_right(struct tree_balance *tb,
881 struct item_head * const ih,
882 const char * const body)
883{
884 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
885 int n = B_NR_ITEMS(tbS0);
886
887
888 if (n - tb->rnum[0] > tb->item_pos) {
889 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
890 return;
891 }
892
893
894
895 if (tb->item_pos == n - tb->rnum[0] && tb->rbytes != -1)
896
897 balance_leaf_paste_right_shift(tb, ih, body);
898 else
899
900 balance_leaf_paste_right_whole(tb, ih, body);
901}
902
903
904static void balance_leaf_right(struct tree_balance *tb,
905 struct item_head * const ih,
906 const char * const body, int flag)
907{
908 if (tb->rnum[0] <= 0)
909 return;
910
911 BUG_ON(flag != M_INSERT && flag != M_PASTE);
912
913 if (flag == M_INSERT)
914 balance_leaf_insert_right(tb, ih, body);
915 else
916 balance_leaf_paste_right(tb, ih, body);
917}
918
919static void balance_leaf_new_nodes_insert(struct tree_balance *tb,
920 struct item_head * const ih,
921 const char * const body,
922 struct item_head *insert_key,
923 struct buffer_head **insert_ptr,
924 int i)
925{
926 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
927 int n = B_NR_ITEMS(tbS0);
928 struct buffer_info bi;
929 int shift;
930
931
932 if (n - tb->snum[i] >= tb->item_pos) {
933 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
934 tb->snum[i], tb->sbytes[i], tb->S_new[i]);
935 return;
936 }
937
938
939
940
941 if (tb->item_pos == n - tb->snum[i] + 1 && tb->sbytes[i] != -1) {
942 int old_key_comp, old_len, r_zeroes_number;
943 const char *r_body;
944
945
946 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i] - 1, -1,
947 tb->S_new[i]);
948
949
950 old_key_comp = le_ih_k_offset(ih);
951 old_len = ih_item_len(ih);
952
953
954
955
956
957 shift = 0;
958 if (is_indirect_le_ih(ih))
959 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
960 set_le_ih_k_offset(ih,
961 le_ih_k_offset(ih) +
962 ((old_len - tb->sbytes[i]) << shift));
963
964 put_ih_item_len(ih, tb->sbytes[i]);
965
966
967 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
968
969 if ((old_len - tb->sbytes[i]) > tb->zeroes_num) {
970 r_zeroes_number = 0;
971 r_body = body + (old_len - tb->sbytes[i]) -
972 tb->zeroes_num;
973 } else {
974 r_body = body;
975 r_zeroes_number = tb->zeroes_num - (old_len -
976 tb->sbytes[i]);
977 tb->zeroes_num -= r_zeroes_number;
978 }
979
980 leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number);
981
982
983
984
985
986 set_le_ih_k_offset(ih, old_key_comp);
987 put_ih_item_len(ih, old_len - tb->sbytes[i]);
988 tb->insert_size[0] -= tb->sbytes[i];
989 } else {
990
991
992
993
994
995
996 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
997 tb->snum[i] - 1, tb->sbytes[i], tb->S_new[i]);
998
999
1000 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1001 leaf_insert_into_buf(&bi, tb->item_pos - n + tb->snum[i] - 1,
1002 ih, body, tb->zeroes_num);
1003
1004 tb->zeroes_num = tb->insert_size[0] = 0;
1005 }
1006}
1007
1008
1009static void balance_leaf_new_nodes_paste_dirent(struct tree_balance *tb,
1010 struct item_head * const ih,
1011 const char * const body,
1012 struct item_head *insert_key,
1013 struct buffer_head **insert_ptr,
1014 int i)
1015{
1016 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1017 struct item_head *aux_ih = item_head(tbS0, tb->item_pos);
1018 int entry_count = ih_entry_count(aux_ih);
1019 struct buffer_info bi;
1020
1021 if (entry_count - tb->sbytes[i] < tb->pos_in_item &&
1022 tb->pos_in_item <= entry_count) {
1023
1024
1025 RFALSE(!tb->insert_size[0],
1026 "PAP-12215: insert_size is already 0");
1027 RFALSE(tb->sbytes[i] - 1 >= entry_count,
1028 "PAP-12220: there are no so much entries (%d), only %d",
1029 tb->sbytes[i] - 1, entry_count);
1030
1031
1032
1033
1034
1035
1036 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i],
1037 tb->sbytes[i] - 1, tb->S_new[i]);
1038
1039
1040
1041
1042
1043 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1044 leaf_paste_in_buffer(&bi, 0, tb->pos_in_item - entry_count +
1045 tb->sbytes[i] - 1, tb->insert_size[0],
1046 body, tb->zeroes_num);
1047
1048
1049 leaf_paste_entries(&bi, 0, tb->pos_in_item - entry_count +
1050 tb->sbytes[i] - 1, 1,
1051 (struct reiserfs_de_head *) body,
1052 body + DEH_SIZE, tb->insert_size[0]);
1053
1054 tb->insert_size[0] = 0;
1055 tb->pos_in_item++;
1056 } else {
1057
1058 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i],
1059 tb->sbytes[i], tb->S_new[i]);
1060 }
1061
1062}
1063
1064static void balance_leaf_new_nodes_paste_shift(struct tree_balance *tb,
1065 struct item_head * const ih,
1066 const char * const body,
1067 struct item_head *insert_key,
1068 struct buffer_head **insert_ptr,
1069 int i)
1070{
1071 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1072 struct item_head *aux_ih = item_head(tbS0, tb->item_pos);
1073 int n_shift, n_rem, r_zeroes_number, shift;
1074 const char *r_body;
1075 struct item_head *tmp;
1076 struct buffer_info bi;
1077
1078 RFALSE(ih, "PAP-12210: ih must be 0");
1079
1080 if (is_direntry_le_ih(aux_ih)) {
1081 balance_leaf_new_nodes_paste_dirent(tb, ih, body, insert_key,
1082 insert_ptr, i);
1083 return;
1084 }
1085
1086
1087
1088
1089 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)) ||
1090 tb->insert_size[0] <= 0,
1091 "PAP-12225: item too short or insert_size <= 0");
1092
1093
1094
1095
1096 n_shift = tb->sbytes[i] - tb->insert_size[0];
1097 if (n_shift < 0)
1098 n_shift = 0;
1099 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], n_shift,
1100 tb->S_new[i]);
1101
1102
1103
1104
1105
1106 n_rem = tb->insert_size[0] - tb->sbytes[i];
1107 if (n_rem < 0)
1108 n_rem = 0;
1109
1110
1111 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1112 if (n_rem > tb->zeroes_num) {
1113 r_zeroes_number = 0;
1114 r_body = body + n_rem - tb->zeroes_num;
1115 } else {
1116 r_body = body;
1117 r_zeroes_number = tb->zeroes_num - n_rem;
1118 tb->zeroes_num -= r_zeroes_number;
1119 }
1120
1121 leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem,
1122 r_body, r_zeroes_number);
1123
1124 tmp = item_head(tb->S_new[i], 0);
1125 shift = 0;
1126 if (is_indirect_le_ih(tmp)) {
1127 set_ih_free_space(tmp, 0);
1128 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
1129 }
1130 add_le_ih_k_offset(tmp, n_rem << shift);
1131
1132 tb->insert_size[0] = n_rem;
1133 if (!n_rem)
1134 tb->pos_in_item++;
1135}
1136
1137static void balance_leaf_new_nodes_paste_whole(struct tree_balance *tb,
1138 struct item_head * const ih,
1139 const char * const body,
1140 struct item_head *insert_key,
1141 struct buffer_head **insert_ptr,
1142 int i)
1143
1144{
1145 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1146 int n = B_NR_ITEMS(tbS0);
1147 int leaf_mi;
1148 struct item_head *pasted;
1149 struct buffer_info bi;
1150
1151#ifdef CONFIG_REISERFS_CHECK
1152 struct item_head *ih_check = item_head(tbS0, tb->item_pos);
1153
1154 if (!is_direntry_le_ih(ih_check) &&
1155 (tb->pos_in_item != ih_item_len(ih_check) ||
1156 tb->insert_size[0] <= 0))
1157 reiserfs_panic(tb->tb_sb,
1158 "PAP-12235",
1159 "pos_in_item must be equal to ih_item_len");
1160#endif
1161
1162 leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i],
1163 tb->sbytes[i], tb->S_new[i]);
1164
1165 RFALSE(leaf_mi,
1166 "PAP-12240: unexpected value returned by leaf_move_items (%d)",
1167 leaf_mi);
1168
1169
1170 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
1171 leaf_paste_in_buffer(&bi, tb->item_pos - n + tb->snum[i],
1172 tb->pos_in_item, tb->insert_size[0],
1173 body, tb->zeroes_num);
1174
1175 pasted = item_head(tb->S_new[i], tb->item_pos - n +
1176 tb->snum[i]);
1177 if (is_direntry_le_ih(pasted))
1178 leaf_paste_entries(&bi, tb->item_pos - n + tb->snum[i],
1179 tb->pos_in_item, 1,
1180 (struct reiserfs_de_head *)body,
1181 body + DEH_SIZE, tb->insert_size[0]);
1182
1183
1184 if (is_indirect_le_ih(pasted))
1185 set_ih_free_space(pasted, 0);
1186
1187 tb->zeroes_num = tb->insert_size[0] = 0;
1188
1189}
1190static void balance_leaf_new_nodes_paste(struct tree_balance *tb,
1191 struct item_head * const ih,
1192 const char * const body,
1193 struct item_head *insert_key,
1194 struct buffer_head **insert_ptr,
1195 int i)
1196{
1197 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1198 int n = B_NR_ITEMS(tbS0);
1199
1200
1201 if (n - tb->snum[i] > tb->item_pos) {
1202 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
1203 tb->snum[i], tb->sbytes[i], tb->S_new[i]);
1204 return;
1205 }
1206
1207
1208
1209 if (tb->item_pos == n - tb->snum[i] && tb->sbytes[i] != -1)
1210
1211 balance_leaf_new_nodes_paste_shift(tb, ih, body, insert_key,
1212 insert_ptr, i);
1213 else
1214
1215 balance_leaf_new_nodes_paste_whole(tb, ih, body, insert_key,
1216 insert_ptr, i);
1217}
1218
1219
1220static void balance_leaf_new_nodes(struct tree_balance *tb,
1221 struct item_head * const ih,
1222 const char * const body,
1223 struct item_head *insert_key,
1224 struct buffer_head **insert_ptr,
1225 int flag)
1226{
1227 int i;
1228 for (i = tb->blknum[0] - 2; i >= 0; i--) {
1229 BUG_ON(flag != M_INSERT && flag != M_PASTE);
1230
1231 RFALSE(!tb->snum[i],
1232 "PAP-12200: snum[%d] == %d. Must be > 0", i,
1233 tb->snum[i]);
1234
1235
1236
1237 tb->S_new[i] = get_FEB(tb);
1238
1239
1240 set_blkh_level(B_BLK_HEAD(tb->S_new[i]), DISK_LEAF_NODE_LEVEL);
1241
1242 if (flag == M_INSERT)
1243 balance_leaf_new_nodes_insert(tb, ih, body, insert_key,
1244 insert_ptr, i);
1245 else
1246 balance_leaf_new_nodes_paste(tb, ih, body, insert_key,
1247 insert_ptr, i);
1248
1249 memcpy(insert_key + i, leaf_key(tb->S_new[i], 0), KEY_SIZE);
1250 insert_ptr[i] = tb->S_new[i];
1251
1252 RFALSE(!buffer_journaled(tb->S_new[i])
1253 || buffer_journal_dirty(tb->S_new[i])
1254 || buffer_dirty(tb->S_new[i]),
1255 "PAP-12247: S_new[%d] : (%b)",
1256 i, tb->S_new[i]);
1257 }
1258}
1259
1260static void balance_leaf_finish_node_insert(struct tree_balance *tb,
1261 struct item_head * const ih,
1262 const char * const body)
1263{
1264 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1265 struct buffer_info bi;
1266 buffer_info_init_tbS0(tb, &bi);
1267 leaf_insert_into_buf(&bi, tb->item_pos, ih, body, tb->zeroes_num);
1268
1269
1270 if (tb->item_pos == 0) {
1271 if (tb->CFL[0])
1272 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
1273
1274 }
1275}
1276
1277static void balance_leaf_finish_node_paste_dirent(struct tree_balance *tb,
1278 struct item_head * const ih,
1279 const char * const body)
1280{
1281 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1282 struct item_head *pasted = item_head(tbS0, tb->item_pos);
1283 struct buffer_info bi;
1284
1285 if (tb->pos_in_item >= 0 && tb->pos_in_item <= ih_entry_count(pasted)) {
1286 RFALSE(!tb->insert_size[0],
1287 "PAP-12260: insert_size is 0 already");
1288
1289
1290 buffer_info_init_tbS0(tb, &bi);
1291 leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item,
1292 tb->insert_size[0], body, tb->zeroes_num);
1293
1294
1295 leaf_paste_entries(&bi, tb->item_pos, tb->pos_in_item, 1,
1296 (struct reiserfs_de_head *)body,
1297 body + DEH_SIZE, tb->insert_size[0]);
1298
1299 if (!tb->item_pos && !tb->pos_in_item) {
1300 RFALSE(!tb->CFL[0] || !tb->L[0],
1301 "PAP-12270: CFL[0]/L[0] must be specified");
1302 if (tb->CFL[0])
1303 replace_key(tb, tb->CFL[0], tb->lkey[0],
1304 tbS0, 0);
1305 }
1306
1307 tb->insert_size[0] = 0;
1308 }
1309}
1310
1311static void balance_leaf_finish_node_paste(struct tree_balance *tb,
1312 struct item_head * const ih,
1313 const char * const body)
1314{
1315 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1316 struct buffer_info bi;
1317 struct item_head *pasted = item_head(tbS0, tb->item_pos);
1318
1319
1320 if (is_direntry_le_ih(pasted)) {
1321 balance_leaf_finish_node_paste_dirent(tb, ih, body);
1322 return;
1323 }
1324
1325
1326
1327 if (tb->pos_in_item == ih_item_len(pasted)) {
1328 RFALSE(tb->insert_size[0] <= 0,
1329 "PAP-12275: insert size must not be %d",
1330 tb->insert_size[0]);
1331 buffer_info_init_tbS0(tb, &bi);
1332 leaf_paste_in_buffer(&bi, tb->item_pos,
1333 tb->pos_in_item, tb->insert_size[0], body,
1334 tb->zeroes_num);
1335
1336 if (is_indirect_le_ih(pasted))
1337 set_ih_free_space(pasted, 0);
1338
1339 tb->insert_size[0] = 0;
1340 }
1341#ifdef CONFIG_REISERFS_CHECK
1342 else if (tb->insert_size[0]) {
1343 print_cur_tb("12285");
1344 reiserfs_panic(tb->tb_sb, "PAP-12285",
1345 "insert_size must be 0 (%d)", tb->insert_size[0]);
1346 }
1347#endif
1348}
1349
1350
1351
1352
1353
1354
1355static void balance_leaf_finish_node(struct tree_balance *tb,
1356 struct item_head * const ih,
1357 const char * const body, int flag)
1358{
1359
1360 if (0 <= tb->item_pos && tb->item_pos < tb->s0num) {
1361 if (flag == M_INSERT)
1362 balance_leaf_finish_node_insert(tb, ih, body);
1363 else
1364 balance_leaf_finish_node_paste(tb, ih, body);
1365 }
1366}
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382static int balance_leaf(struct tree_balance *tb, struct item_head *ih,
1383 const char *body, int flag,
1384 struct item_head *insert_key,
1385 struct buffer_head **insert_ptr)
1386{
1387 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
1388
1389 PROC_INFO_INC(tb->tb_sb, balance_at[0]);
1390
1391
1392 if (tb->insert_size[0] < 0)
1393 return balance_leaf_when_delete(tb, flag);
1394
1395 tb->item_pos = PATH_LAST_POSITION(tb->tb_path),
1396 tb->pos_in_item = tb->tb_path->pos_in_item,
1397 tb->zeroes_num = 0;
1398 if (flag == M_INSERT && !body)
1399 tb->zeroes_num = ih_item_len(ih);
1400
1401
1402
1403
1404
1405 if (flag != M_INSERT
1406 && is_indirect_le_ih(item_head(tbS0, tb->item_pos)))
1407 tb->pos_in_item *= UNFM_P_SIZE;
1408
1409 body += balance_leaf_left(tb, ih, body, flag);
1410
1411
1412
1413 tb->item_pos -= (tb->lnum[0] - ((tb->lbytes != -1) ? 1 : 0));
1414
1415 balance_leaf_right(tb, ih, body, flag);
1416
1417
1418 RFALSE(tb->blknum[0] > 3,
1419 "PAP-12180: blknum can not be %d. It must be <= 3", tb->blknum[0]);
1420 RFALSE(tb->blknum[0] < 0,
1421 "PAP-12185: blknum can not be %d. It must be >= 0", tb->blknum[0]);
1422
1423
1424
1425
1426
1427
1428 if (tb->blknum[0] == 0) {
1429
1430 RFALSE(!tb->lnum[0] || !tb->rnum[0],
1431 "PAP-12190: lnum and rnum must not be zero");
1432
1433
1434
1435
1436
1437 if (tb->CFL[0]) {
1438 if (!tb->CFR[0])
1439 reiserfs_panic(tb->tb_sb, "vs-12195",
1440 "CFR not initialized");
1441 copy_key(internal_key(tb->CFL[0], tb->lkey[0]),
1442 internal_key(tb->CFR[0], tb->rkey[0]));
1443 do_balance_mark_internal_dirty(tb, tb->CFL[0], 0);
1444 }
1445
1446 reiserfs_invalidate_buffer(tb, tbS0);
1447 return 0;
1448 }
1449
1450 balance_leaf_new_nodes(tb, ih, body, insert_key, insert_ptr, flag);
1451
1452 balance_leaf_finish_node(tb, ih, body, flag);
1453
1454#ifdef CONFIG_REISERFS_CHECK
1455 if (flag == M_PASTE && tb->insert_size[0]) {
1456 print_cur_tb("12290");
1457 reiserfs_panic(tb->tb_sb,
1458 "PAP-12290", "insert_size is still not 0 (%d)",
1459 tb->insert_size[0]);
1460 }
1461#endif
1462
1463
1464 return 0;
1465}
1466
1467
1468void make_empty_node(struct buffer_info *bi)
1469{
1470 struct block_head *blkh;
1471
1472 RFALSE(bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
1473
1474 blkh = B_BLK_HEAD(bi->bi_bh);
1475 set_blkh_nr_item(blkh, 0);
1476 set_blkh_free_space(blkh, MAX_CHILD_SIZE(bi->bi_bh));
1477
1478 if (bi->bi_parent)
1479 B_N_CHILD(bi->bi_parent, bi->bi_position)->dc_size = 0;
1480}
1481
1482
1483struct buffer_head *get_FEB(struct tree_balance *tb)
1484{
1485 int i;
1486 struct buffer_info bi;
1487
1488 for (i = 0; i < MAX_FEB_SIZE; i++)
1489 if (tb->FEB[i] != NULL)
1490 break;
1491
1492 if (i == MAX_FEB_SIZE)
1493 reiserfs_panic(tb->tb_sb, "vs-12300", "FEB list is empty");
1494
1495 buffer_info_init_bh(tb, &bi, tb->FEB[i]);
1496 make_empty_node(&bi);
1497 set_buffer_uptodate(tb->FEB[i]);
1498 tb->used[i] = tb->FEB[i];
1499 tb->FEB[i] = NULL;
1500
1501 return tb->used[i];
1502}
1503
1504
1505static void store_thrown(struct tree_balance *tb, struct buffer_head *bh)
1506{
1507 int i;
1508
1509 if (buffer_dirty(bh))
1510 reiserfs_warning(tb->tb_sb, "reiserfs-12320",
1511 "called with dirty buffer");
1512 for (i = 0; i < ARRAY_SIZE(tb->thrown); i++)
1513 if (!tb->thrown[i]) {
1514 tb->thrown[i] = bh;
1515 get_bh(bh);
1516 return;
1517 }
1518 reiserfs_warning(tb->tb_sb, "reiserfs-12321",
1519 "too many thrown buffers");
1520}
1521
1522static void free_thrown(struct tree_balance *tb)
1523{
1524 int i;
1525 b_blocknr_t blocknr;
1526 for (i = 0; i < ARRAY_SIZE(tb->thrown); i++) {
1527 if (tb->thrown[i]) {
1528 blocknr = tb->thrown[i]->b_blocknr;
1529 if (buffer_dirty(tb->thrown[i]))
1530 reiserfs_warning(tb->tb_sb, "reiserfs-12322",
1531 "called with dirty buffer %d",
1532 blocknr);
1533 brelse(tb->thrown[i]);
1534 reiserfs_free_block(tb->transaction_handle, NULL,
1535 blocknr, 0);
1536 }
1537 }
1538}
1539
1540void reiserfs_invalidate_buffer(struct tree_balance *tb, struct buffer_head *bh)
1541{
1542 struct block_head *blkh;
1543 blkh = B_BLK_HEAD(bh);
1544 set_blkh_level(blkh, FREE_LEVEL);
1545 set_blkh_nr_item(blkh, 0);
1546
1547 clear_buffer_dirty(bh);
1548 store_thrown(tb, bh);
1549}
1550
1551
1552void replace_key(struct tree_balance *tb, struct buffer_head *dest, int n_dest,
1553 struct buffer_head *src, int n_src)
1554{
1555
1556 RFALSE(dest == NULL || src == NULL,
1557 "vs-12305: source or destination buffer is 0 (src=%p, dest=%p)",
1558 src, dest);
1559 RFALSE(!B_IS_KEYS_LEVEL(dest),
1560 "vs-12310: invalid level (%z) for destination buffer. dest must be leaf",
1561 dest);
1562 RFALSE(n_dest < 0 || n_src < 0,
1563 "vs-12315: src(%d) or dest(%d) key number < 0", n_src, n_dest);
1564 RFALSE(n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src),
1565 "vs-12320: src(%d(%d)) or dest(%d(%d)) key number is too big",
1566 n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
1567
1568 if (B_IS_ITEMS_LEVEL(src))
1569
1570 memcpy(internal_key(dest, n_dest), item_head(src, n_src),
1571 KEY_SIZE);
1572 else
1573 memcpy(internal_key(dest, n_dest), internal_key(src, n_src),
1574 KEY_SIZE);
1575
1576 do_balance_mark_internal_dirty(tb, dest, 0);
1577}
1578
1579int get_left_neighbor_position(struct tree_balance *tb, int h)
1580{
1581 int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
1582
1583 RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FL[h] == NULL,
1584 "vs-12325: FL[%d](%p) or F[%d](%p) does not exist",
1585 h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h));
1586
1587 if (Sh_position == 0)
1588 return B_NR_ITEMS(tb->FL[h]);
1589 else
1590 return Sh_position - 1;
1591}
1592
1593int get_right_neighbor_position(struct tree_balance *tb, int h)
1594{
1595 int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
1596
1597 RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FR[h] == NULL,
1598 "vs-12330: F[%d](%p) or FR[%d](%p) does not exist",
1599 h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]);
1600
1601 if (Sh_position == B_NR_ITEMS(PATH_H_PPARENT(tb->tb_path, h)))
1602 return 0;
1603 else
1604 return Sh_position + 1;
1605}
1606
1607#ifdef CONFIG_REISERFS_CHECK
1608
1609int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
1610static void check_internal_node(struct super_block *s, struct buffer_head *bh,
1611 char *mes)
1612{
1613 struct disk_child *dc;
1614 int i;
1615
1616 RFALSE(!bh, "PAP-12336: bh == 0");
1617
1618 if (!bh || !B_IS_IN_TREE(bh))
1619 return;
1620
1621 RFALSE(!buffer_dirty(bh) &&
1622 !(buffer_journaled(bh) || buffer_journal_dirty(bh)),
1623 "PAP-12337: buffer (%b) must be dirty", bh);
1624 dc = B_N_CHILD(bh, 0);
1625
1626 for (i = 0; i <= B_NR_ITEMS(bh); i++, dc++) {
1627 if (!is_reusable(s, dc_block_number(dc), 1)) {
1628 print_cur_tb(mes);
1629 reiserfs_panic(s, "PAP-12338",
1630 "invalid child pointer %y in %b",
1631 dc, bh);
1632 }
1633 }
1634}
1635
1636static int locked_or_not_in_tree(struct tree_balance *tb,
1637 struct buffer_head *bh, char *which)
1638{
1639 if ((!buffer_journal_prepared(bh) && buffer_locked(bh)) ||
1640 !B_IS_IN_TREE(bh)) {
1641 reiserfs_warning(tb->tb_sb, "vs-12339", "%s (%b)", which, bh);
1642 return 1;
1643 }
1644 return 0;
1645}
1646
1647static int check_before_balancing(struct tree_balance *tb)
1648{
1649 int retval = 0;
1650
1651 if (REISERFS_SB(tb->tb_sb)->cur_tb) {
1652 reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule "
1653 "occurred based on cur_tb not being null at "
1654 "this point in code. do_balance cannot properly "
1655 "handle concurrent tree accesses on a same "
1656 "mount point.");
1657 }
1658
1659
1660
1661
1662
1663 if (tb->lnum[0]) {
1664 retval |= locked_or_not_in_tree(tb, tb->L[0], "L[0]");
1665 retval |= locked_or_not_in_tree(tb, tb->FL[0], "FL[0]");
1666 retval |= locked_or_not_in_tree(tb, tb->CFL[0], "CFL[0]");
1667 check_leaf(tb->L[0]);
1668 }
1669 if (tb->rnum[0]) {
1670 retval |= locked_or_not_in_tree(tb, tb->R[0], "R[0]");
1671 retval |= locked_or_not_in_tree(tb, tb->FR[0], "FR[0]");
1672 retval |= locked_or_not_in_tree(tb, tb->CFR[0], "CFR[0]");
1673 check_leaf(tb->R[0]);
1674 }
1675 retval |= locked_or_not_in_tree(tb, PATH_PLAST_BUFFER(tb->tb_path),
1676 "S[0]");
1677 check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
1678
1679 return retval;
1680}
1681
1682static void check_after_balance_leaf(struct tree_balance *tb)
1683{
1684 if (tb->lnum[0]) {
1685 if (B_FREE_SPACE(tb->L[0]) !=
1686 MAX_CHILD_SIZE(tb->L[0]) -
1687 dc_size(B_N_CHILD
1688 (tb->FL[0], get_left_neighbor_position(tb, 0)))) {
1689 print_cur_tb("12221");
1690 reiserfs_panic(tb->tb_sb, "PAP-12355",
1691 "shift to left was incorrect");
1692 }
1693 }
1694 if (tb->rnum[0]) {
1695 if (B_FREE_SPACE(tb->R[0]) !=
1696 MAX_CHILD_SIZE(tb->R[0]) -
1697 dc_size(B_N_CHILD
1698 (tb->FR[0], get_right_neighbor_position(tb, 0)))) {
1699 print_cur_tb("12222");
1700 reiserfs_panic(tb->tb_sb, "PAP-12360",
1701 "shift to right was incorrect");
1702 }
1703 }
1704 if (PATH_H_PBUFFER(tb->tb_path, 1) &&
1705 (B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0)) !=
1706 (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
1707 dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
1708 PATH_H_POSITION(tb->tb_path, 1)))))) {
1709 int left = B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0));
1710 int right = (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
1711 dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
1712 PATH_H_POSITION(tb->tb_path,
1713 1))));
1714 print_cur_tb("12223");
1715 reiserfs_warning(tb->tb_sb, "reiserfs-12363",
1716 "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
1717 "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d",
1718 left,
1719 MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)),
1720 PATH_H_PBUFFER(tb->tb_path, 1),
1721 PATH_H_POSITION(tb->tb_path, 1),
1722 dc_size(B_N_CHILD
1723 (PATH_H_PBUFFER(tb->tb_path, 1),
1724 PATH_H_POSITION(tb->tb_path, 1))),
1725 right);
1726 reiserfs_panic(tb->tb_sb, "PAP-12365", "S is incorrect");
1727 }
1728}
1729
1730static void check_leaf_level(struct tree_balance *tb)
1731{
1732 check_leaf(tb->L[0]);
1733 check_leaf(tb->R[0]);
1734 check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
1735}
1736
1737static void check_internal_levels(struct tree_balance *tb)
1738{
1739 int h;
1740
1741
1742 for (h = 1; tb->insert_size[h]; h++) {
1743 check_internal_node(tb->tb_sb, PATH_H_PBUFFER(tb->tb_path, h),
1744 "BAD BUFFER ON PATH");
1745 if (tb->lnum[h])
1746 check_internal_node(tb->tb_sb, tb->L[h], "BAD L");
1747 if (tb->rnum[h])
1748 check_internal_node(tb->tb_sb, tb->R[h], "BAD R");
1749 }
1750
1751}
1752
1753#endif
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789static inline void do_balance_starts(struct tree_balance *tb)
1790{
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800 RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
1801#ifdef CONFIG_REISERFS_CHECK
1802 REISERFS_SB(tb->tb_sb)->cur_tb = tb;
1803#endif
1804}
1805
1806static inline void do_balance_completed(struct tree_balance *tb)
1807{
1808
1809#ifdef CONFIG_REISERFS_CHECK
1810 check_leaf_level(tb);
1811 check_internal_levels(tb);
1812 REISERFS_SB(tb->tb_sb)->cur_tb = NULL;
1813#endif
1814
1815
1816
1817
1818
1819
1820
1821 REISERFS_SB(tb->tb_sb)->s_do_balance++;
1822
1823
1824 unfix_nodes(tb);
1825
1826 free_thrown(tb);
1827}
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847void do_balance(struct tree_balance *tb, struct item_head *ih,
1848 const char *body, int flag)
1849{
1850 int child_pos;
1851 int h;
1852
1853
1854
1855
1856
1857
1858
1859 struct item_head insert_key[2];
1860
1861
1862 struct buffer_head *insert_ptr[2];
1863
1864 tb->tb_mode = flag;
1865 tb->need_balance_dirty = 0;
1866
1867 if (FILESYSTEM_CHANGED_TB(tb)) {
1868 reiserfs_panic(tb->tb_sb, "clm-6000", "fs generation has "
1869 "changed");
1870 }
1871
1872 if (!tb->insert_size[0]) {
1873 reiserfs_warning(tb->tb_sb, "PAP-12350",
1874 "insert_size == 0, mode == %c", flag);
1875 unfix_nodes(tb);
1876 return;
1877 }
1878
1879 atomic_inc(&fs_generation(tb->tb_sb));
1880 do_balance_starts(tb);
1881
1882
1883
1884
1885
1886
1887 child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) +
1888 balance_leaf(tb, ih, body, flag, insert_key, insert_ptr);
1889
1890#ifdef CONFIG_REISERFS_CHECK
1891 check_after_balance_leaf(tb);
1892#endif
1893
1894
1895 for (h = 1; h < MAX_HEIGHT && tb->insert_size[h]; h++)
1896 child_pos = balance_internal(tb, h, child_pos, insert_key,
1897 insert_ptr);
1898
1899 do_balance_completed(tb);
1900}
1901