0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/uaccess.h>
0014 #include <linux/time.h>
0015 #include "reiserfs.h"
0016 #include <linux/buffer_head.h>
0017 #include <linux/kernel.h>
0018
0019 static inline void buffer_info_init_left(struct tree_balance *tb,
0020 struct buffer_info *bi)
0021 {
0022 bi->tb = tb;
0023 bi->bi_bh = tb->L[0];
0024 bi->bi_parent = tb->FL[0];
0025 bi->bi_position = get_left_neighbor_position(tb, 0);
0026 }
0027
0028 static inline void buffer_info_init_right(struct tree_balance *tb,
0029 struct buffer_info *bi)
0030 {
0031 bi->tb = tb;
0032 bi->bi_bh = tb->R[0];
0033 bi->bi_parent = tb->FR[0];
0034 bi->bi_position = get_right_neighbor_position(tb, 0);
0035 }
0036
0037 static inline void buffer_info_init_tbS0(struct tree_balance *tb,
0038 struct buffer_info *bi)
0039 {
0040 bi->tb = tb;
0041 bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
0042 bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
0043 bi->bi_position = PATH_H_POSITION(tb->tb_path, 1);
0044 }
0045
0046 static inline void buffer_info_init_bh(struct tree_balance *tb,
0047 struct buffer_info *bi,
0048 struct buffer_head *bh)
0049 {
0050 bi->tb = tb;
0051 bi->bi_bh = bh;
0052 bi->bi_parent = NULL;
0053 bi->bi_position = 0;
0054 }
0055
0056 inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
0057 struct buffer_head *bh, int flag)
0058 {
0059 journal_mark_dirty(tb->transaction_handle, bh);
0060 }
0061
0062 #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
0063 #define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static void balance_leaf_when_delete_del(struct tree_balance *tb)
0078 {
0079 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0080 int item_pos = PATH_LAST_POSITION(tb->tb_path);
0081 struct buffer_info bi;
0082 #ifdef CONFIG_REISERFS_CHECK
0083 struct item_head *ih = item_head(tbS0, item_pos);
0084 #endif
0085
0086 RFALSE(ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
0087 "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
0088 -tb->insert_size[0], ih);
0089
0090 buffer_info_init_tbS0(tb, &bi);
0091 leaf_delete_items(&bi, 0, item_pos, 1, -1);
0092
0093 if (!item_pos && tb->CFL[0]) {
0094 if (B_NR_ITEMS(tbS0)) {
0095 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
0096 } else {
0097 if (!PATH_H_POSITION(tb->tb_path, 1))
0098 replace_key(tb, tb->CFL[0], tb->lkey[0],
0099 PATH_H_PPARENT(tb->tb_path, 0), 0);
0100 }
0101 }
0102
0103 RFALSE(!item_pos && !tb->CFL[0],
0104 "PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0],
0105 tb->L[0]);
0106 }
0107
0108
0109 static void balance_leaf_when_delete_cut(struct tree_balance *tb)
0110 {
0111 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0112 int item_pos = PATH_LAST_POSITION(tb->tb_path);
0113 struct item_head *ih = item_head(tbS0, item_pos);
0114 int pos_in_item = tb->tb_path->pos_in_item;
0115 struct buffer_info bi;
0116 buffer_info_init_tbS0(tb, &bi);
0117
0118 if (is_direntry_le_ih(ih)) {
0119
0120
0121
0122
0123
0124
0125
0126 tb->insert_size[0] = -1;
0127 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
0128 -tb->insert_size[0]);
0129
0130 RFALSE(!item_pos && !pos_in_item && !tb->CFL[0],
0131 "PAP-12030: can not change delimiting key. CFL[0]=%p",
0132 tb->CFL[0]);
0133
0134 if (!item_pos && !pos_in_item && tb->CFL[0])
0135 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
0136 } else {
0137 leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
0138 -tb->insert_size[0]);
0139
0140 RFALSE(!ih_item_len(ih),
0141 "PAP-12035: cut must leave non-zero dynamic "
0142 "length of item");
0143 }
0144 }
0145
0146 static int balance_leaf_when_delete_left(struct tree_balance *tb)
0147 {
0148 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0149 int n = B_NR_ITEMS(tbS0);
0150
0151
0152 if (tb->lnum[0] == -1) {
0153
0154 if (tb->rnum[0] == -1) {
0155 if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) {
0156
0157
0158
0159
0160 if (PATH_H_POSITION(tb->tb_path, 1) == 0 &&
0161 1 < B_NR_ITEMS(tb->FR[0]))
0162 replace_key(tb, tb->CFL[0],
0163 tb->lkey[0], tb->FR[0], 1);
0164
0165 leaf_move_items(LEAF_FROM_S_TO_L, tb, n, -1,
0166 NULL);
0167 leaf_move_items(LEAF_FROM_R_TO_L, tb,
0168 B_NR_ITEMS(tb->R[0]), -1,
0169 NULL);
0170
0171 reiserfs_invalidate_buffer(tb, tbS0);
0172 reiserfs_invalidate_buffer(tb, tb->R[0]);
0173
0174 return 0;
0175 }
0176
0177
0178 leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1, NULL);
0179 leaf_move_items(LEAF_FROM_L_TO_R, tb,
0180 B_NR_ITEMS(tb->L[0]), -1, NULL);
0181
0182
0183 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0184
0185 reiserfs_invalidate_buffer(tb, tbS0);
0186 reiserfs_invalidate_buffer(tb, tb->L[0]);
0187
0188 return -1;
0189 }
0190
0191 RFALSE(tb->rnum[0] != 0,
0192 "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
0193
0194 leaf_shift_left(tb, n, -1);
0195
0196 reiserfs_invalidate_buffer(tb, tbS0);
0197
0198 return 0;
0199 }
0200
0201
0202
0203
0204
0205
0206 RFALSE((tb->lnum[0] + tb->rnum[0] < n) ||
0207 (tb->lnum[0] + tb->rnum[0] > n + 1),
0208 "PAP-12050: rnum(%d) and lnum(%d) and item "
0209 "number(%d) in S[0] are not consistent",
0210 tb->rnum[0], tb->lnum[0], n);
0211 RFALSE((tb->lnum[0] + tb->rnum[0] == n) &&
0212 (tb->lbytes != -1 || tb->rbytes != -1),
0213 "PAP-12055: bad rbytes (%d)/lbytes (%d) "
0214 "parameters when items are not split",
0215 tb->rbytes, tb->lbytes);
0216 RFALSE((tb->lnum[0] + tb->rnum[0] == n + 1) &&
0217 (tb->lbytes < 1 || tb->rbytes != -1),
0218 "PAP-12060: bad rbytes (%d)/lbytes (%d) "
0219 "parameters when items are split",
0220 tb->rbytes, tb->lbytes);
0221
0222 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
0223 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
0224
0225 reiserfs_invalidate_buffer(tb, tbS0);
0226
0227 return 0;
0228 }
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
0240 {
0241 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0242 struct buffer_info bi;
0243 int n;
0244
0245 RFALSE(tb->FR[0] && B_LEVEL(tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
0246 "vs- 12000: level: wrong FR %z", tb->FR[0]);
0247 RFALSE(tb->blknum[0] > 1,
0248 "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
0249 RFALSE(!tb->blknum[0] && !PATH_H_PPARENT(tb->tb_path, 0),
0250 "PAP-12010: tree can not be empty");
0251
0252 buffer_info_init_tbS0(tb, &bi);
0253
0254
0255
0256 BUG_ON(flag != M_DELETE && flag != M_CUT);
0257 if (flag == M_DELETE)
0258 balance_leaf_when_delete_del(tb);
0259 else
0260 balance_leaf_when_delete_cut(tb);
0261
0262
0263
0264
0265
0266
0267 n = B_NR_ITEMS(tbS0);
0268
0269
0270
0271 if (tb->lnum[0])
0272 return balance_leaf_when_delete_left(tb);
0273
0274 if (tb->rnum[0] == -1) {
0275
0276 leaf_shift_right(tb, n, -1);
0277 reiserfs_invalidate_buffer(tb, tbS0);
0278 return 0;
0279 }
0280
0281 RFALSE(tb->rnum[0],
0282 "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
0283 return 0;
0284 }
0285
0286 static unsigned int balance_leaf_insert_left(struct tree_balance *tb,
0287 struct item_head *const ih,
0288 const char * const body)
0289 {
0290 int ret;
0291 struct buffer_info bi;
0292 int n = B_NR_ITEMS(tb->L[0]);
0293 unsigned body_shift_bytes = 0;
0294
0295 if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) {
0296
0297 int new_item_len, shift;
0298
0299 ret = leaf_shift_left(tb, tb->lnum[0] - 1, -1);
0300
0301
0302 new_item_len = ih_item_len(ih) - tb->lbytes;
0303
0304
0305 put_ih_item_len(ih, ih_item_len(ih) - new_item_len);
0306
0307 RFALSE(ih_item_len(ih) <= 0,
0308 "PAP-12080: there is nothing to insert into L[0]: "
0309 "ih_item_len=%d", ih_item_len(ih));
0310
0311
0312 buffer_info_init_left(tb, &bi);
0313 leaf_insert_into_buf(&bi, n + tb->item_pos - ret, ih, body,
0314 min_t(int, tb->zeroes_num, ih_item_len(ih)));
0315
0316
0317
0318
0319
0320 shift = 0;
0321 if (is_indirect_le_ih(ih))
0322 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
0323
0324 add_le_ih_k_offset(ih, tb->lbytes << shift);
0325
0326 put_ih_item_len(ih, new_item_len);
0327 if (tb->lbytes > tb->zeroes_num) {
0328 body_shift_bytes = tb->lbytes - tb->zeroes_num;
0329 tb->zeroes_num = 0;
0330 } else
0331 tb->zeroes_num -= tb->lbytes;
0332
0333 RFALSE(ih_item_len(ih) <= 0,
0334 "PAP-12085: there is nothing to insert into S[0]: "
0335 "ih_item_len=%d", ih_item_len(ih));
0336 } else {
0337
0338
0339 ret = leaf_shift_left(tb, tb->lnum[0] - 1, tb->lbytes);
0340
0341
0342 buffer_info_init_left(tb, &bi);
0343 leaf_insert_into_buf(&bi, n + tb->item_pos - ret, ih, body,
0344 tb->zeroes_num);
0345 tb->insert_size[0] = 0;
0346 tb->zeroes_num = 0;
0347 }
0348 return body_shift_bytes;
0349 }
0350
0351 static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb,
0352 struct item_head * const ih,
0353 const char * const body)
0354 {
0355 int n = B_NR_ITEMS(tb->L[0]);
0356 struct buffer_info bi;
0357
0358 RFALSE(tb->zeroes_num,
0359 "PAP-12090: invalid parameter in case of a directory");
0360
0361
0362 if (tb->lbytes > tb->pos_in_item) {
0363
0364 struct item_head *pasted;
0365 int ret, l_pos_in_item = tb->pos_in_item;
0366
0367
0368
0369
0370
0371 ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes - 1);
0372 if (ret && !tb->item_pos) {
0373 pasted = item_head(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1);
0374 l_pos_in_item += ih_entry_count(pasted) -
0375 (tb->lbytes - 1);
0376 }
0377
0378
0379 buffer_info_init_left(tb, &bi);
0380 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret,
0381 l_pos_in_item, tb->insert_size[0],
0382 body, tb->zeroes_num);
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395 leaf_paste_entries(&bi, n + tb->item_pos - ret,
0396 l_pos_in_item, 1,
0397 (struct reiserfs_de_head *) body,
0398 body + DEH_SIZE, tb->insert_size[0]);
0399 tb->insert_size[0] = 0;
0400 } else {
0401
0402
0403
0404
0405
0406 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
0407 }
0408
0409
0410 tb->pos_in_item -= tb->lbytes;
0411 }
0412
0413 static unsigned int balance_leaf_paste_left_shift(struct tree_balance *tb,
0414 struct item_head * const ih,
0415 const char * const body)
0416 {
0417 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0418 int n = B_NR_ITEMS(tb->L[0]);
0419 struct buffer_info bi;
0420 int body_shift_bytes = 0;
0421
0422 if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) {
0423 balance_leaf_paste_left_shift_dirent(tb, ih, body);
0424 return 0;
0425 }
0426
0427 RFALSE(tb->lbytes <= 0,
0428 "PAP-12095: there is nothing to shift to L[0]. "
0429 "lbytes=%d", tb->lbytes);
0430 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)),
0431 "PAP-12100: incorrect position to paste: "
0432 "item_len=%d, pos_in_item=%d",
0433 ih_item_len(item_head(tbS0, tb->item_pos)), tb->pos_in_item);
0434
0435
0436 if (tb->lbytes >= tb->pos_in_item) {
0437 struct item_head *tbS0_pos_ih, *tbL0_ih;
0438 struct item_head *tbS0_0_ih;
0439 struct reiserfs_key *left_delim_key;
0440 int ret, l_n, version, temp_l;
0441
0442 tbS0_pos_ih = item_head(tbS0, tb->item_pos);
0443 tbS0_0_ih = item_head(tbS0, 0);
0444
0445
0446
0447
0448
0449 l_n = tb->lbytes - tb->pos_in_item;
0450
0451
0452 tb->insert_size[0] -= l_n;
0453
0454 RFALSE(tb->insert_size[0] <= 0,
0455 "PAP-12105: there is nothing to paste into "
0456 "L[0]. insert_size=%d", tb->insert_size[0]);
0457
0458 ret = leaf_shift_left(tb, tb->lnum[0],
0459 ih_item_len(tbS0_pos_ih));
0460
0461 tbL0_ih = item_head(tb->L[0], n + tb->item_pos - ret);
0462
0463
0464 buffer_info_init_left(tb, &bi);
0465 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret,
0466 ih_item_len(tbL0_ih), l_n, body,
0467 min_t(int, l_n, tb->zeroes_num));
0468
0469
0470
0471
0472
0473 temp_l = l_n;
0474
0475 RFALSE(ih_item_len(tbS0_0_ih),
0476 "PAP-12106: item length must be 0");
0477 RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key,
0478 leaf_key(tb->L[0], n + tb->item_pos - ret)),
0479 "PAP-12107: items must be of the same file");
0480
0481 if (is_indirect_le_ih(tbL0_ih)) {
0482 int shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
0483 temp_l = l_n << shift;
0484 }
0485
0486 version = ih_version(tbS0_0_ih);
0487 add_le_key_k_offset(version, &tbS0_0_ih->ih_key, temp_l);
0488
0489
0490 left_delim_key = internal_key(tb->CFL[0], tb->lkey[0]);
0491 add_le_key_k_offset(version, left_delim_key, temp_l);
0492
0493
0494
0495
0496
0497 if (l_n > tb->zeroes_num) {
0498 body_shift_bytes = l_n - tb->zeroes_num;
0499 tb->zeroes_num = 0;
0500 } else
0501 tb->zeroes_num -= l_n;
0502 tb->pos_in_item = 0;
0503
0504 RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key,
0505 leaf_key(tb->L[0],
0506 B_NR_ITEMS(tb->L[0]) - 1)) ||
0507 !op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size) ||
0508 !op_is_left_mergeable(left_delim_key, tbS0->b_size),
0509 "PAP-12120: item must be merge-able with left "
0510 "neighboring item");
0511 } else {
0512
0513
0514
0515 tb->pos_in_item -= tb->lbytes;
0516
0517 RFALSE(tb->pos_in_item <= 0,
0518 "PAP-12125: no place for paste. pos_in_item=%d",
0519 tb->pos_in_item);
0520
0521
0522
0523
0524
0525 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
0526 }
0527 return body_shift_bytes;
0528 }
0529
0530
0531
0532 static void balance_leaf_paste_left_whole(struct tree_balance *tb,
0533 struct item_head * const ih,
0534 const char * const body)
0535 {
0536 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0537 int n = B_NR_ITEMS(tb->L[0]);
0538 struct buffer_info bi;
0539 struct item_head *pasted;
0540 int ret;
0541
0542
0543 if (!tb->item_pos &&
0544 op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)) {
0545
0546
0547
0548
0549 pasted = item_head(tb->L[0], n - 1);
0550 if (is_direntry_le_ih(pasted))
0551 tb->pos_in_item += ih_entry_count(pasted);
0552 else
0553 tb->pos_in_item += ih_item_len(pasted);
0554 }
0555
0556
0557
0558
0559
0560 ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
0561
0562
0563 buffer_info_init_left(tb, &bi);
0564 leaf_paste_in_buffer(&bi, n + tb->item_pos - ret, tb->pos_in_item,
0565 tb->insert_size[0], body, tb->zeroes_num);
0566
0567
0568 pasted = item_head(tb->L[0], n + tb->item_pos - ret);
0569 if (is_direntry_le_ih(pasted))
0570 leaf_paste_entries(&bi, n + tb->item_pos - ret,
0571 tb->pos_in_item, 1,
0572 (struct reiserfs_de_head *)body,
0573 body + DEH_SIZE, tb->insert_size[0]);
0574
0575
0576
0577
0578
0579 if (is_indirect_le_ih(pasted))
0580 set_ih_free_space(pasted, 0);
0581
0582 tb->insert_size[0] = 0;
0583 tb->zeroes_num = 0;
0584 }
0585
0586 static unsigned int balance_leaf_paste_left(struct tree_balance *tb,
0587 struct item_head * const ih,
0588 const char * const body)
0589 {
0590
0591 if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1)
0592 return balance_leaf_paste_left_shift(tb, ih, body);
0593 else
0594 balance_leaf_paste_left_whole(tb, ih, body);
0595 return 0;
0596 }
0597
0598
0599 static unsigned int balance_leaf_left(struct tree_balance *tb,
0600 struct item_head * const ih,
0601 const char * const body, int flag)
0602 {
0603 if (tb->lnum[0] <= 0)
0604 return 0;
0605
0606
0607 if (tb->item_pos < tb->lnum[0]) {
0608 BUG_ON(flag != M_INSERT && flag != M_PASTE);
0609
0610 if (flag == M_INSERT)
0611 return balance_leaf_insert_left(tb, ih, body);
0612 else
0613 return balance_leaf_paste_left(tb, ih, body);
0614 } else
0615
0616 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
0617 return 0;
0618 }
0619
0620
0621 static void balance_leaf_insert_right(struct tree_balance *tb,
0622 struct item_head * const ih,
0623 const char * const body)
0624 {
0625
0626 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0627 int n = B_NR_ITEMS(tbS0);
0628 struct buffer_info bi;
0629
0630
0631 if (n - tb->rnum[0] >= tb->item_pos) {
0632 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
0633 return;
0634 }
0635
0636
0637
0638
0639 if (tb->item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) {
0640 loff_t old_key_comp, old_len, r_zeroes_number;
0641 const char *r_body;
0642 int shift;
0643 loff_t offset;
0644
0645 leaf_shift_right(tb, tb->rnum[0] - 1, -1);
0646
0647
0648 old_key_comp = le_ih_k_offset(ih);
0649 old_len = ih_item_len(ih);
0650
0651
0652
0653
0654
0655 shift = 0;
0656 if (is_indirect_le_ih(ih))
0657 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
0658 offset = le_ih_k_offset(ih) + ((old_len - tb->rbytes) << shift);
0659 set_le_ih_k_offset(ih, offset);
0660 put_ih_item_len(ih, tb->rbytes);
0661
0662
0663 buffer_info_init_right(tb, &bi);
0664 if ((old_len - tb->rbytes) > tb->zeroes_num) {
0665 r_zeroes_number = 0;
0666 r_body = body + (old_len - tb->rbytes) - tb->zeroes_num;
0667 } else {
0668 r_body = body;
0669 r_zeroes_number = tb->zeroes_num -
0670 (old_len - tb->rbytes);
0671 tb->zeroes_num -= r_zeroes_number;
0672 }
0673
0674 leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number);
0675
0676
0677 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0678
0679
0680
0681
0682
0683 set_le_ih_k_offset(ih, old_key_comp);
0684 put_ih_item_len(ih, old_len - tb->rbytes);
0685
0686 tb->insert_size[0] -= tb->rbytes;
0687
0688 } else {
0689
0690
0691
0692 leaf_shift_right(tb, tb->rnum[0] - 1, tb->rbytes);
0693
0694
0695 buffer_info_init_right(tb, &bi);
0696 leaf_insert_into_buf(&bi, tb->item_pos - n + tb->rnum[0] - 1,
0697 ih, body, tb->zeroes_num);
0698
0699 if (tb->item_pos - n + tb->rnum[0] - 1 == 0)
0700 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0701
0702 tb->zeroes_num = tb->insert_size[0] = 0;
0703 }
0704 }
0705
0706
0707 static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb,
0708 struct item_head * const ih,
0709 const char * const body)
0710 {
0711 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0712 struct buffer_info bi;
0713 int entry_count;
0714
0715 RFALSE(tb->zeroes_num,
0716 "PAP-12145: invalid parameter in case of a directory");
0717 entry_count = ih_entry_count(item_head(tbS0, tb->item_pos));
0718
0719
0720 if (entry_count - tb->rbytes < tb->pos_in_item) {
0721 int paste_entry_position;
0722
0723 RFALSE(tb->rbytes - 1 >= entry_count || !tb->insert_size[0],
0724 "PAP-12150: no enough of entries to shift to R[0]: "
0725 "rbytes=%d, entry_count=%d", tb->rbytes, entry_count);
0726
0727
0728
0729
0730
0731
0732 leaf_shift_right(tb, tb->rnum[0], tb->rbytes - 1);
0733
0734
0735 paste_entry_position = tb->pos_in_item - entry_count +
0736 tb->rbytes - 1;
0737 buffer_info_init_right(tb, &bi);
0738 leaf_paste_in_buffer(&bi, 0, paste_entry_position,
0739 tb->insert_size[0], body, tb->zeroes_num);
0740
0741
0742 leaf_paste_entries(&bi, 0, paste_entry_position, 1,
0743 (struct reiserfs_de_head *) body,
0744 body + DEH_SIZE, tb->insert_size[0]);
0745
0746
0747 if (paste_entry_position == 0)
0748 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0749
0750 tb->insert_size[0] = 0;
0751 tb->pos_in_item++;
0752 } else {
0753
0754 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
0755 }
0756 }
0757
0758 static void balance_leaf_paste_right_shift(struct tree_balance *tb,
0759 struct item_head * const ih,
0760 const char * const body)
0761 {
0762 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0763 int n_shift, n_rem, r_zeroes_number, version;
0764 unsigned long temp_rem;
0765 const char *r_body;
0766 struct buffer_info bi;
0767
0768
0769 if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) {
0770 balance_leaf_paste_right_shift_dirent(tb, ih, body);
0771 return;
0772 }
0773
0774
0775
0776
0777
0778
0779
0780 n_shift = tb->rbytes - tb->insert_size[0];
0781 if (n_shift < 0)
0782 n_shift = 0;
0783
0784 RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)),
0785 "PAP-12155: invalid position to paste. ih_item_len=%d, "
0786 "pos_in_item=%d", tb->pos_in_item,
0787 ih_item_len(item_head(tbS0, tb->item_pos)));
0788
0789 leaf_shift_right(tb, tb->rnum[0], n_shift);
0790
0791
0792
0793
0794
0795 n_rem = tb->insert_size[0] - tb->rbytes;
0796 if (n_rem < 0)
0797 n_rem = 0;
0798
0799 temp_rem = n_rem;
0800
0801 version = ih_version(item_head(tb->R[0], 0));
0802
0803 if (is_indirect_le_key(version, leaf_key(tb->R[0], 0))) {
0804 int shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
0805 temp_rem = n_rem << shift;
0806 }
0807
0808 add_le_key_k_offset(version, leaf_key(tb->R[0], 0), temp_rem);
0809 add_le_key_k_offset(version, internal_key(tb->CFR[0], tb->rkey[0]),
0810 temp_rem);
0811
0812 do_balance_mark_internal_dirty(tb, tb->CFR[0], 0);
0813
0814
0815 buffer_info_init_right(tb, &bi);
0816 if (n_rem > tb->zeroes_num) {
0817 r_zeroes_number = 0;
0818 r_body = body + n_rem - tb->zeroes_num;
0819 } else {
0820 r_body = body;
0821 r_zeroes_number = tb->zeroes_num - n_rem;
0822 tb->zeroes_num -= r_zeroes_number;
0823 }
0824
0825 leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem,
0826 r_body, r_zeroes_number);
0827
0828 if (is_indirect_le_ih(item_head(tb->R[0], 0)))
0829 set_ih_free_space(item_head(tb->R[0], 0), 0);
0830
0831 tb->insert_size[0] = n_rem;
0832 if (!n_rem)
0833 tb->pos_in_item++;
0834 }
0835
0836 static void balance_leaf_paste_right_whole(struct tree_balance *tb,
0837 struct item_head * const ih,
0838 const char * const body)
0839 {
0840 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0841 int n = B_NR_ITEMS(tbS0);
0842 struct item_head *pasted;
0843 struct buffer_info bi;
0844
0845 buffer_info_init_right(tb, &bi);
0846 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
0847
0848
0849 if (tb->pos_in_item >= 0) {
0850 buffer_info_init_right(tb, &bi);
0851 leaf_paste_in_buffer(&bi, tb->item_pos - n + tb->rnum[0],
0852 tb->pos_in_item, tb->insert_size[0], body,
0853 tb->zeroes_num);
0854 }
0855
0856
0857 pasted = item_head(tb->R[0], tb->item_pos - n + tb->rnum[0]);
0858 if (is_direntry_le_ih(pasted) && tb->pos_in_item >= 0) {
0859 leaf_paste_entries(&bi, tb->item_pos - n + tb->rnum[0],
0860 tb->pos_in_item, 1,
0861 (struct reiserfs_de_head *)body,
0862 body + DEH_SIZE, tb->insert_size[0]);
0863
0864 if (!tb->pos_in_item) {
0865
0866 RFALSE(tb->item_pos - n + tb->rnum[0],
0867 "PAP-12165: directory item must be first "
0868 "item of node when pasting is in 0th position");
0869
0870
0871 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0872 }
0873 }
0874
0875 if (is_indirect_le_ih(pasted))
0876 set_ih_free_space(pasted, 0);
0877 tb->zeroes_num = tb->insert_size[0] = 0;
0878 }
0879
0880 static void balance_leaf_paste_right(struct tree_balance *tb,
0881 struct item_head * const ih,
0882 const char * const body)
0883 {
0884 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0885 int n = B_NR_ITEMS(tbS0);
0886
0887
0888 if (n - tb->rnum[0] > tb->item_pos) {
0889 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
0890 return;
0891 }
0892
0893
0894
0895 if (tb->item_pos == n - tb->rnum[0] && tb->rbytes != -1)
0896
0897 balance_leaf_paste_right_shift(tb, ih, body);
0898 else
0899
0900 balance_leaf_paste_right_whole(tb, ih, body);
0901 }
0902
0903
0904 static void balance_leaf_right(struct tree_balance *tb,
0905 struct item_head * const ih,
0906 const char * const body, int flag)
0907 {
0908 if (tb->rnum[0] <= 0)
0909 return;
0910
0911 BUG_ON(flag != M_INSERT && flag != M_PASTE);
0912
0913 if (flag == M_INSERT)
0914 balance_leaf_insert_right(tb, ih, body);
0915 else
0916 balance_leaf_paste_right(tb, ih, body);
0917 }
0918
0919 static void balance_leaf_new_nodes_insert(struct tree_balance *tb,
0920 struct item_head * const ih,
0921 const char * const body,
0922 struct item_head *insert_key,
0923 struct buffer_head **insert_ptr,
0924 int i)
0925 {
0926 struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
0927 int n = B_NR_ITEMS(tbS0);
0928 struct buffer_info bi;
0929 int shift;
0930
0931
0932 if (n - tb->snum[i] >= tb->item_pos) {
0933 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
0934 tb->snum[i], tb->sbytes[i], tb->S_new[i]);
0935 return;
0936 }
0937
0938
0939
0940
0941 if (tb->item_pos == n - tb->snum[i] + 1 && tb->sbytes[i] != -1) {
0942 int old_key_comp, old_len, r_zeroes_number;
0943 const char *r_body;
0944
0945
0946 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i] - 1, -1,
0947 tb->S_new[i]);
0948
0949
0950 old_key_comp = le_ih_k_offset(ih);
0951 old_len = ih_item_len(ih);
0952
0953
0954
0955
0956
0957 shift = 0;
0958 if (is_indirect_le_ih(ih))
0959 shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT;
0960 set_le_ih_k_offset(ih,
0961 le_ih_k_offset(ih) +
0962 ((old_len - tb->sbytes[i]) << shift));
0963
0964 put_ih_item_len(ih, tb->sbytes[i]);
0965
0966
0967 buffer_info_init_bh(tb, &bi, tb->S_new[i]);
0968
0969 if ((old_len - tb->sbytes[i]) > tb->zeroes_num) {
0970 r_zeroes_number = 0;
0971 r_body = body + (old_len - tb->sbytes[i]) -
0972 tb->zeroes_num;
0973 } else {
0974 r_body = body;
0975 r_zeroes_number = tb->zeroes_num - (old_len -
0976 tb->sbytes[i]);
0977 tb->zeroes_num -= r_zeroes_number;
0978 }
0979
0980 leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number);
0981
0982
0983
0984
0985
0986 set_le_ih_k_offset(ih, old_key_comp);
0987 put_ih_item_len(ih, old_len - tb->sbytes[i]);
0988 tb->insert_size[0] -= tb->sbytes[i];
0989 } else {
0990
0991
0992
0993
0994
0995
0996 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
0997 tb->snum[i] - 1, tb->sbytes[i], tb->S_new[i]);
0998
0999
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
1009 static 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
1064 static 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
1137 static 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 }
1190 static 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
1220 static 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
1260 static 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
1277 static 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
1311 static 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
1355 static 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
1382 static 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
1468 void 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
1483 struct 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
1505 static 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
1522 static 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
1540 void 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
1552 void 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
1579 int 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
1593 int 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
1609 int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
1610 static 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
1636 static 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
1647 static 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
1682 static 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
1730 static 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
1737 static 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
1789 static 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
1806 static 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
1847 void 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 }