0001
0002
0003
0004
0005 #include <linux/uaccess.h>
0006 #include <linux/string.h>
0007 #include <linux/time.h>
0008 #include "reiserfs.h"
0009 #include <linux/buffer_head.h>
0010
0011
0012
0013
0014
0015 static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
0016 struct buffer_head *source, int last_first,
0017 int item_num, int from, int copy_count)
0018 {
0019 struct buffer_head *dest = dest_bi->bi_bh;
0020
0021
0022
0023
0024 int item_num_in_dest;
0025
0026 struct item_head *ih;
0027 struct reiserfs_de_head *deh;
0028 int copy_records_len;
0029 char *records;
0030
0031 ih = item_head(source, item_num);
0032
0033 RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
0034
0035
0036
0037
0038
0039 deh = B_I_DEH(source, ih);
0040 if (copy_count) {
0041 copy_records_len = (from ? deh_location(&deh[from - 1]) :
0042 ih_item_len(ih)) -
0043 deh_location(&deh[from + copy_count - 1]);
0044 records =
0045 source->b_data + ih_location(ih) +
0046 deh_location(&deh[from + copy_count - 1]);
0047 } else {
0048 copy_records_len = 0;
0049 records = NULL;
0050 }
0051
0052
0053 item_num_in_dest =
0054 (last_first ==
0055 LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
0056 - 1);
0057
0058
0059
0060
0061
0062 if ((item_num_in_dest == -1) ||
0063 (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
0064 (last_first == LAST_TO_FIRST
0065 && comp_short_le_keys (&ih->ih_key,
0066 leaf_key(dest,
0067 item_num_in_dest))))
0068 {
0069
0070 struct item_head new_ih;
0071
0072
0073 memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
0074 put_ih_version(&new_ih, KEY_FORMAT_3_5);
0075
0076 put_ih_item_len(&new_ih,
0077 DEH_SIZE * copy_count + copy_records_len);
0078 put_ih_entry_count(&new_ih, 0);
0079
0080 if (last_first == LAST_TO_FIRST) {
0081
0082 if (from < ih_entry_count(ih)) {
0083 set_le_ih_k_offset(&new_ih,
0084 deh_offset(&deh[from]));
0085 } else {
0086
0087
0088
0089
0090 set_le_ih_k_offset(&new_ih, U32_MAX);
0091
0092
0093
0094
0095
0096 }
0097 set_le_key_k_type(KEY_FORMAT_3_5, &new_ih.ih_key,
0098 TYPE_DIRENTRY);
0099 }
0100
0101
0102 leaf_insert_into_buf(dest_bi,
0103 (last_first ==
0104 LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest),
0105 &new_ih, NULL, 0);
0106 } else {
0107
0108 leaf_paste_in_buffer(dest_bi,
0109 (last_first ==
0110 FIRST_TO_LAST) ? (B_NR_ITEMS(dest) -
0111 1) : 0, MAX_US_INT,
0112 DEH_SIZE * copy_count + copy_records_len,
0113 records, 0);
0114 }
0115
0116 item_num_in_dest =
0117 (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
0118
0119 leaf_paste_entries(dest_bi, item_num_in_dest,
0120 (last_first ==
0121 FIRST_TO_LAST) ? ih_entry_count(item_head(dest,
0122 item_num_in_dest))
0123 : 0, copy_count, deh + from, records,
0124 DEH_SIZE * copy_count + copy_records_len);
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134 static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
0135 struct buffer_head *src, int last_first,
0136 int bytes_or_entries)
0137 {
0138 struct buffer_head *dest = dest_bi->bi_bh;
0139
0140 int dest_nr_item, src_nr_item;
0141 struct item_head *ih;
0142 struct item_head *dih;
0143
0144 dest_nr_item = B_NR_ITEMS(dest);
0145
0146
0147
0148
0149
0150
0151
0152 if (last_first == FIRST_TO_LAST) {
0153 ih = item_head(src, 0);
0154 dih = item_head(dest, dest_nr_item - 1);
0155
0156
0157 if (!dest_nr_item
0158 || (!op_is_left_mergeable(&ih->ih_key, src->b_size)))
0159 return 0;
0160
0161 RFALSE(!ih_item_len(ih),
0162 "vs-10010: item can not have empty length");
0163
0164 if (is_direntry_le_ih(ih)) {
0165 if (bytes_or_entries == -1)
0166
0167 bytes_or_entries = ih_entry_count(ih);
0168 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, 0, 0,
0169 bytes_or_entries);
0170 return 1;
0171 }
0172
0173
0174
0175
0176
0177
0178
0179 if (bytes_or_entries == -1)
0180 bytes_or_entries = ih_item_len(ih);
0181
0182 #ifdef CONFIG_REISERFS_CHECK
0183 else {
0184 if (bytes_or_entries == ih_item_len(ih)
0185 && is_indirect_le_ih(ih))
0186 if (get_ih_free_space(ih))
0187 reiserfs_panic(sb_from_bi(dest_bi),
0188 "vs-10020",
0189 "last unformatted node "
0190 "must be filled "
0191 "entirely (%h)", ih);
0192 }
0193 #endif
0194
0195
0196
0197
0198
0199 leaf_paste_in_buffer(dest_bi,
0200 dest_nr_item - 1, ih_item_len(dih),
0201 bytes_or_entries, ih_item_body(src, ih), 0);
0202
0203 if (is_indirect_le_ih(dih)) {
0204 RFALSE(get_ih_free_space(dih),
0205 "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
0206 ih);
0207 if (bytes_or_entries == ih_item_len(ih))
0208 set_ih_free_space(dih, get_ih_free_space(ih));
0209 }
0210
0211 return 1;
0212 }
0213
0214
0215
0216
0217
0218
0219
0220 src_nr_item = B_NR_ITEMS(src);
0221 ih = item_head(src, src_nr_item - 1);
0222 dih = item_head(dest, 0);
0223
0224 if (!dest_nr_item || !op_is_left_mergeable(&dih->ih_key, src->b_size))
0225 return 0;
0226
0227 if (is_direntry_le_ih(ih)) {
0228
0229
0230
0231
0232 if (bytes_or_entries == -1)
0233 bytes_or_entries = ih_entry_count(ih);
0234
0235 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
0236 src_nr_item - 1,
0237 ih_entry_count(ih) - bytes_or_entries,
0238 bytes_or_entries);
0239 return 1;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249 RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
0250 "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
0251 ih);
0252
0253 if (bytes_or_entries == -1) {
0254
0255 bytes_or_entries = ih_item_len(ih);
0256
0257 RFALSE(le_ih_k_offset(dih) !=
0258 le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
0259 "vs-10050: items %h and %h do not match", ih, dih);
0260
0261
0262 set_le_ih_k_offset(dih, le_ih_k_offset(ih));
0263
0264
0265
0266 set_le_ih_k_type(dih, le_ih_k_type(ih));
0267 } else {
0268
0269 RFALSE(ih_item_len(ih) <= bytes_or_entries,
0270 "vs-10060: no so much bytes %lu (needed %lu)",
0271 (unsigned long)ih_item_len(ih),
0272 (unsigned long)bytes_or_entries);
0273
0274
0275 if (is_direct_le_ih(dih)) {
0276 RFALSE(le_ih_k_offset(dih) <=
0277 (unsigned long)bytes_or_entries,
0278 "vs-10070: dih %h, bytes_or_entries(%d)", dih,
0279 bytes_or_entries);
0280 set_le_ih_k_offset(dih,
0281 le_ih_k_offset(dih) -
0282 bytes_or_entries);
0283 } else {
0284 RFALSE(le_ih_k_offset(dih) <=
0285 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
0286 "vs-10080: dih %h, bytes_or_entries(%d)",
0287 dih,
0288 (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
0289 set_le_ih_k_offset(dih,
0290 le_ih_k_offset(dih) -
0291 ((bytes_or_entries / UNFM_P_SIZE) *
0292 dest->b_size));
0293 }
0294 }
0295
0296 leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
0297 ih_item_body(src,
0298 ih) + ih_item_len(ih) - bytes_or_entries,
0299 0);
0300 return 1;
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310 static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
0311 struct buffer_head *src, int last_first,
0312 int first, int cpy_num)
0313 {
0314 struct buffer_head *dest;
0315 int nr, free_space;
0316 int dest_before;
0317 int last_loc, last_inserted_loc, location;
0318 int i, j;
0319 struct block_head *blkh;
0320 struct item_head *ih;
0321
0322 RFALSE(last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST,
0323 "vs-10090: bad last_first parameter %d", last_first);
0324 RFALSE(B_NR_ITEMS(src) - first < cpy_num,
0325 "vs-10100: too few items in source %d, required %d from %d",
0326 B_NR_ITEMS(src), cpy_num, first);
0327 RFALSE(cpy_num < 0, "vs-10110: can not copy negative amount of items");
0328 RFALSE(!dest_bi, "vs-10120: can not copy negative amount of items");
0329
0330 dest = dest_bi->bi_bh;
0331
0332 RFALSE(!dest, "vs-10130: can not copy negative amount of items");
0333
0334 if (cpy_num == 0)
0335 return;
0336
0337 blkh = B_BLK_HEAD(dest);
0338 nr = blkh_nr_item(blkh);
0339 free_space = blkh_free_space(blkh);
0340
0341
0342
0343
0344
0345 dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
0346
0347
0348 ih = item_head(dest, dest_before);
0349
0350 RFALSE(blkh_free_space(blkh) < cpy_num * IH_SIZE,
0351 "vs-10140: not enough free space for headers %d (needed %d)",
0352 B_FREE_SPACE(dest), cpy_num * IH_SIZE);
0353
0354
0355 memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
0356
0357
0358 memcpy(ih, item_head(src, first), cpy_num * IH_SIZE);
0359
0360 free_space -= (IH_SIZE * cpy_num);
0361 set_blkh_free_space(blkh, free_space);
0362
0363
0364 j = location = (dest_before == 0) ? dest->b_size : ih_location(ih - 1);
0365 for (i = dest_before; i < nr + cpy_num; i++) {
0366 location -= ih_item_len(ih + i - dest_before);
0367 put_ih_location(ih + i - dest_before, location);
0368 }
0369
0370
0371 last_loc = ih_location(&ih[nr + cpy_num - 1 - dest_before]);
0372 last_inserted_loc = ih_location(&ih[cpy_num - 1]);
0373
0374
0375 RFALSE(free_space < j - last_inserted_loc,
0376 "vs-10150: not enough free space for items %d (needed %d)",
0377 free_space, j - last_inserted_loc);
0378
0379 memmove(dest->b_data + last_loc,
0380 dest->b_data + last_loc + j - last_inserted_loc,
0381 last_inserted_loc - last_loc);
0382
0383
0384 memcpy(dest->b_data + last_inserted_loc,
0385 item_body(src, (first + cpy_num - 1)),
0386 j - last_inserted_loc);
0387
0388
0389 set_blkh_nr_item(blkh, nr + cpy_num);
0390 set_blkh_free_space(blkh, free_space - (j - last_inserted_loc));
0391
0392 do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
0393
0394 if (dest_bi->bi_parent) {
0395 struct disk_child *t_dc;
0396 t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
0397 RFALSE(dc_block_number(t_dc) != dest->b_blocknr,
0398 "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
0399 (long unsigned)dest->b_blocknr,
0400 (long unsigned)dc_block_number(t_dc));
0401 put_dc_size(t_dc,
0402 dc_size(t_dc) + (j - last_inserted_loc +
0403 IH_SIZE * cpy_num));
0404
0405 do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
0406 0);
0407 }
0408 }
0409
0410
0411
0412
0413
0414 static void leaf_item_bottle(struct buffer_info *dest_bi,
0415 struct buffer_head *src, int last_first,
0416 int item_num, int cpy_bytes)
0417 {
0418 struct buffer_head *dest = dest_bi->bi_bh;
0419 struct item_head *ih;
0420
0421 RFALSE(cpy_bytes == -1,
0422 "vs-10170: bytes == - 1 means: do not split item");
0423
0424 if (last_first == FIRST_TO_LAST) {
0425
0426
0427
0428
0429 ih = item_head(src, item_num);
0430 if (is_direntry_le_ih(ih))
0431 leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
0432 item_num, 0, cpy_bytes);
0433 else {
0434 struct item_head n_ih;
0435
0436
0437
0438
0439
0440
0441
0442 memcpy(&n_ih, ih, IH_SIZE);
0443 put_ih_item_len(&n_ih, cpy_bytes);
0444 if (is_indirect_le_ih(ih)) {
0445 RFALSE(cpy_bytes == ih_item_len(ih)
0446 && get_ih_free_space(ih),
0447 "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
0448 (long unsigned)get_ih_free_space(ih));
0449 set_ih_free_space(&n_ih, 0);
0450 }
0451
0452 RFALSE(op_is_left_mergeable(&ih->ih_key, src->b_size),
0453 "vs-10190: bad mergeability of item %h", ih);
0454 n_ih.ih_version = ih->ih_version;
0455 leaf_insert_into_buf(dest_bi, B_NR_ITEMS(dest), &n_ih,
0456 item_body(src, item_num), 0);
0457 }
0458 } else {
0459
0460
0461
0462
0463 ih = item_head(src, item_num);
0464 if (is_direntry_le_ih(ih))
0465 leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
0466 item_num,
0467 ih_entry_count(ih) - cpy_bytes,
0468 cpy_bytes);
0469 else {
0470 struct item_head n_ih;
0471
0472
0473
0474
0475
0476
0477
0478 memcpy(&n_ih.ih_key, &ih->ih_key, KEY_SIZE);
0479
0480
0481 n_ih.ih_version = ih->ih_version;
0482
0483 if (is_direct_le_ih(ih)) {
0484 set_le_ih_k_offset(&n_ih,
0485 le_ih_k_offset(ih) +
0486 ih_item_len(ih) - cpy_bytes);
0487 set_le_ih_k_type(&n_ih, TYPE_DIRECT);
0488 set_ih_free_space(&n_ih, MAX_US_INT);
0489 } else {
0490
0491 RFALSE(!cpy_bytes && get_ih_free_space(ih),
0492 "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
0493 set_le_ih_k_offset(&n_ih,
0494 le_ih_k_offset(ih) +
0495 (ih_item_len(ih) -
0496 cpy_bytes) / UNFM_P_SIZE *
0497 dest->b_size);
0498 set_le_ih_k_type(&n_ih, TYPE_INDIRECT);
0499 set_ih_free_space(&n_ih, get_ih_free_space(ih));
0500 }
0501
0502
0503 put_ih_item_len(&n_ih, cpy_bytes);
0504
0505
0506 n_ih.ih_version = ih->ih_version;
0507
0508 leaf_insert_into_buf(dest_bi, 0, &n_ih,
0509 item_body(src, item_num) +
0510 ih_item_len(ih) - cpy_bytes, 0);
0511 }
0512 }
0513 }
0514
0515
0516
0517
0518
0519
0520
0521 static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
0522 int last_first, int cpy_num, int cpy_bytes)
0523 {
0524 struct buffer_head *dest;
0525 int pos, i, src_nr_item, bytes;
0526
0527 dest = dest_bi->bi_bh;
0528 RFALSE(!dest || !src, "vs-10210: !dest || !src");
0529 RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
0530 "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
0531 RFALSE(B_NR_ITEMS(src) < cpy_num,
0532 "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src),
0533 cpy_num);
0534 RFALSE(cpy_num < 0, "vs-10240: cpy_num < 0 (%d)", cpy_num);
0535
0536 if (cpy_num == 0)
0537 return 0;
0538
0539 if (last_first == FIRST_TO_LAST) {
0540
0541 pos = 0;
0542 if (cpy_num == 1)
0543 bytes = cpy_bytes;
0544 else
0545 bytes = -1;
0546
0547
0548
0549
0550
0551 i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
0552 cpy_num -= i;
0553 if (cpy_num == 0)
0554 return i;
0555 pos += i;
0556 if (cpy_bytes == -1)
0557
0558
0559
0560
0561 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
0562 pos, cpy_num);
0563 else {
0564
0565
0566
0567
0568 leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
0569 pos, cpy_num - 1);
0570
0571
0572
0573
0574
0575 leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
0576 cpy_num + pos - 1, cpy_bytes);
0577 }
0578 } else {
0579
0580 src_nr_item = B_NR_ITEMS(src);
0581 if (cpy_num == 1)
0582 bytes = cpy_bytes;
0583 else
0584 bytes = -1;
0585
0586
0587
0588
0589
0590
0591 i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
0592
0593 cpy_num -= i;
0594 if (cpy_num == 0)
0595 return i;
0596
0597 pos = src_nr_item - cpy_num - i;
0598 if (cpy_bytes == -1) {
0599
0600
0601
0602
0603 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
0604 pos, cpy_num);
0605 } else {
0606
0607
0608
0609
0610 leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
0611 pos + 1, cpy_num - 1);
0612
0613
0614
0615
0616
0617 leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
0618 cpy_bytes);
0619 }
0620 }
0621 return i;
0622 }
0623
0624
0625
0626
0627
0628
0629 static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
0630 struct buffer_info *dest_bi,
0631 struct buffer_info *src_bi,
0632 int *first_last,
0633 struct buffer_head *Snew)
0634 {
0635 memset(dest_bi, 0, sizeof(struct buffer_info));
0636 memset(src_bi, 0, sizeof(struct buffer_info));
0637
0638
0639 switch (shift_mode) {
0640 case LEAF_FROM_S_TO_L:
0641 src_bi->tb = tb;
0642 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
0643 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
0644
0645
0646 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
0647 dest_bi->tb = tb;
0648 dest_bi->bi_bh = tb->L[0];
0649 dest_bi->bi_parent = tb->FL[0];
0650 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
0651 *first_last = FIRST_TO_LAST;
0652 break;
0653
0654 case LEAF_FROM_S_TO_R:
0655 src_bi->tb = tb;
0656 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
0657 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
0658 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
0659 dest_bi->tb = tb;
0660 dest_bi->bi_bh = tb->R[0];
0661 dest_bi->bi_parent = tb->FR[0];
0662 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
0663 *first_last = LAST_TO_FIRST;
0664 break;
0665
0666 case LEAF_FROM_R_TO_L:
0667 src_bi->tb = tb;
0668 src_bi->bi_bh = tb->R[0];
0669 src_bi->bi_parent = tb->FR[0];
0670 src_bi->bi_position = get_right_neighbor_position(tb, 0);
0671 dest_bi->tb = tb;
0672 dest_bi->bi_bh = tb->L[0];
0673 dest_bi->bi_parent = tb->FL[0];
0674 dest_bi->bi_position = get_left_neighbor_position(tb, 0);
0675 *first_last = FIRST_TO_LAST;
0676 break;
0677
0678 case LEAF_FROM_L_TO_R:
0679 src_bi->tb = tb;
0680 src_bi->bi_bh = tb->L[0];
0681 src_bi->bi_parent = tb->FL[0];
0682 src_bi->bi_position = get_left_neighbor_position(tb, 0);
0683 dest_bi->tb = tb;
0684 dest_bi->bi_bh = tb->R[0];
0685 dest_bi->bi_parent = tb->FR[0];
0686 dest_bi->bi_position = get_right_neighbor_position(tb, 0);
0687 *first_last = LAST_TO_FIRST;
0688 break;
0689
0690 case LEAF_FROM_S_TO_SNEW:
0691 src_bi->tb = tb;
0692 src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
0693 src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
0694 src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
0695 dest_bi->tb = tb;
0696 dest_bi->bi_bh = Snew;
0697 dest_bi->bi_parent = NULL;
0698 dest_bi->bi_position = 0;
0699 *first_last = LAST_TO_FIRST;
0700 break;
0701
0702 default:
0703 reiserfs_panic(sb_from_bi(src_bi), "vs-10250",
0704 "shift type is unknown (%d)", shift_mode);
0705 }
0706 RFALSE(!src_bi->bi_bh || !dest_bi->bi_bh,
0707 "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
0708 shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
0709 }
0710
0711
0712
0713
0714
0715 int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
0716 int mov_bytes, struct buffer_head *Snew)
0717 {
0718 int ret_value;
0719 struct buffer_info dest_bi, src_bi;
0720 int first_last;
0721
0722 leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
0723 &first_last, Snew);
0724
0725 ret_value =
0726 leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
0727 mov_bytes);
0728
0729 leaf_delete_items(&src_bi, first_last,
0730 (first_last ==
0731 FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) -
0732 mov_num), mov_num, mov_bytes);
0733
0734 return ret_value;
0735 }
0736
0737
0738
0739
0740
0741 int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
0742 {
0743 struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
0744 int i;
0745
0746
0747
0748
0749
0750 i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
0751
0752 if (shift_num) {
0753
0754 if (B_NR_ITEMS(S0) == 0) {
0755
0756 RFALSE(shift_bytes != -1,
0757 "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
0758 shift_bytes);
0759 #ifdef CONFIG_REISERFS_CHECK
0760 if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
0761 print_cur_tb("vs-10275");
0762 reiserfs_panic(tb->tb_sb, "vs-10275",
0763 "balance condition corrupted "
0764 "(%c)", tb->tb_mode);
0765 }
0766 #endif
0767
0768 if (PATH_H_POSITION(tb->tb_path, 1) == 0)
0769 replace_key(tb, tb->CFL[0], tb->lkey[0],
0770 PATH_H_PPARENT(tb->tb_path, 0), 0);
0771
0772 } else {
0773
0774 replace_key(tb, tb->CFL[0], tb->lkey[0], S0, 0);
0775
0776 RFALSE((shift_bytes != -1 &&
0777 !(is_direntry_le_ih(item_head(S0, 0))
0778 && !ih_entry_count(item_head(S0, 0)))) &&
0779 (!op_is_left_mergeable
0780 (leaf_key(S0, 0), S0->b_size)),
0781 "vs-10280: item must be mergeable");
0782 }
0783 }
0784
0785 return i;
0786 }
0787
0788
0789
0790
0791
0792
0793
0794 int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
0795 {
0796 int ret_value;
0797
0798
0799
0800
0801
0802 ret_value =
0803 leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
0804
0805
0806 if (shift_num) {
0807 replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
0808
0809 }
0810
0811 return ret_value;
0812 }
0813
0814 static void leaf_delete_items_entirely(struct buffer_info *bi,
0815 int first, int del_num);
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
0828 int first, int del_num, int del_bytes)
0829 {
0830 struct buffer_head *bh;
0831 int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
0832
0833 RFALSE(!bh, "10155: bh is not defined");
0834 RFALSE(del_num < 0, "10160: del_num can not be < 0. del_num==%d",
0835 del_num);
0836 RFALSE(first < 0
0837 || first + del_num > item_amount,
0838 "10165: invalid number of first item to be deleted (%d) or "
0839 "no so much items (%d) to delete (only %d)", first,
0840 first + del_num, item_amount);
0841
0842 if (del_num == 0)
0843 return;
0844
0845 if (first == 0 && del_num == item_amount && del_bytes == -1) {
0846 make_empty_node(cur_bi);
0847 do_balance_mark_leaf_dirty(cur_bi->tb, bh, 0);
0848 return;
0849 }
0850
0851 if (del_bytes == -1)
0852
0853 leaf_delete_items_entirely(cur_bi, first, del_num);
0854 else {
0855 if (last_first == FIRST_TO_LAST) {
0856
0857
0858
0859
0860 leaf_delete_items_entirely(cur_bi, first, del_num - 1);
0861
0862
0863
0864
0865
0866 leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
0867 } else {
0868 struct item_head *ih;
0869 int len;
0870
0871
0872
0873
0874
0875 leaf_delete_items_entirely(cur_bi, first + 1,
0876 del_num - 1);
0877
0878 ih = item_head(bh, B_NR_ITEMS(bh) - 1);
0879 if (is_direntry_le_ih(ih))
0880
0881
0882
0883
0884
0885 len = ih_entry_count(ih);
0886 else
0887
0888 len = ih_item_len(ih);
0889
0890
0891
0892
0893
0894 leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
0895 len - del_bytes, del_bytes);
0896 }
0897 }
0898 }
0899
0900
0901 void leaf_insert_into_buf(struct buffer_info *bi, int before,
0902 struct item_head * const inserted_item_ih,
0903 const char * const inserted_item_body,
0904 int zeros_number)
0905 {
0906 struct buffer_head *bh = bi->bi_bh;
0907 int nr, free_space;
0908 struct block_head *blkh;
0909 struct item_head *ih;
0910 int i;
0911 int last_loc, unmoved_loc;
0912 char *to;
0913
0914 blkh = B_BLK_HEAD(bh);
0915 nr = blkh_nr_item(blkh);
0916 free_space = blkh_free_space(blkh);
0917
0918
0919 RFALSE(free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
0920 "vs-10170: not enough free space in block %z, new item %h",
0921 bh, inserted_item_ih);
0922 RFALSE(zeros_number > ih_item_len(inserted_item_ih),
0923 "vs-10172: zero number == %d, item length == %d",
0924 zeros_number, ih_item_len(inserted_item_ih));
0925
0926
0927 ih = item_head(bh, before);
0928
0929
0930 last_loc = nr ? ih_location(&ih[nr - before - 1]) : bh->b_size;
0931 unmoved_loc = before ? ih_location(ih - 1) : bh->b_size;
0932
0933 memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
0934 bh->b_data + last_loc, unmoved_loc - last_loc);
0935
0936 to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
0937 memset(to, 0, zeros_number);
0938 to += zeros_number;
0939
0940
0941 if (inserted_item_body)
0942 memmove(to, inserted_item_body,
0943 ih_item_len(inserted_item_ih) - zeros_number);
0944 else
0945 memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
0946
0947
0948 memmove(ih + 1, ih, IH_SIZE * (nr - before));
0949 memmove(ih, inserted_item_ih, IH_SIZE);
0950
0951
0952 for (i = before; i < nr + 1; i++) {
0953 unmoved_loc -= ih_item_len(&ih[i - before]);
0954 put_ih_location(&ih[i - before], unmoved_loc);
0955 }
0956
0957
0958 set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
0959 set_blkh_free_space(blkh,
0960 free_space - (IH_SIZE +
0961 ih_item_len(inserted_item_ih)));
0962 do_balance_mark_leaf_dirty(bi->tb, bh, 1);
0963
0964 if (bi->bi_parent) {
0965 struct disk_child *t_dc;
0966 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
0967 put_dc_size(t_dc,
0968 dc_size(t_dc) + (IH_SIZE +
0969 ih_item_len(inserted_item_ih)));
0970 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
0971 }
0972 }
0973
0974
0975
0976
0977
0978 void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
0979 int pos_in_item, int paste_size,
0980 const char *body, int zeros_number)
0981 {
0982 struct buffer_head *bh = bi->bi_bh;
0983 int nr, free_space;
0984 struct block_head *blkh;
0985 struct item_head *ih;
0986 int i;
0987 int last_loc, unmoved_loc;
0988
0989 blkh = B_BLK_HEAD(bh);
0990 nr = blkh_nr_item(blkh);
0991 free_space = blkh_free_space(blkh);
0992
0993
0994 RFALSE(free_space < paste_size,
0995 "vs-10175: not enough free space: needed %d, available %d",
0996 paste_size, free_space);
0997
0998 #ifdef CONFIG_REISERFS_CHECK
0999 if (zeros_number > paste_size) {
1000 struct super_block *sb = NULL;
1001 if (bi && bi->tb)
1002 sb = bi->tb->tb_sb;
1003 print_cur_tb("10177");
1004 reiserfs_panic(sb, "vs-10177",
1005 "zeros_number == %d, paste_size == %d",
1006 zeros_number, paste_size);
1007 }
1008 #endif
1009
1010
1011 ih = item_head(bh, affected_item_num);
1012
1013 last_loc = ih_location(&ih[nr - affected_item_num - 1]);
1014 unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
1015
1016
1017 memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
1018 unmoved_loc - last_loc);
1019
1020
1021 for (i = affected_item_num; i < nr; i++)
1022 put_ih_location(&ih[i - affected_item_num],
1023 ih_location(&ih[i - affected_item_num]) -
1024 paste_size);
1025
1026 if (body) {
1027 if (!is_direntry_le_ih(ih)) {
1028 if (!pos_in_item) {
1029
1030 memmove(bh->b_data + ih_location(ih) +
1031 paste_size,
1032 bh->b_data + ih_location(ih),
1033 ih_item_len(ih));
1034
1035 memset(bh->b_data + ih_location(ih), 0,
1036 zeros_number);
1037 memcpy(bh->b_data + ih_location(ih) +
1038 zeros_number, body,
1039 paste_size - zeros_number);
1040 } else {
1041 memset(bh->b_data + unmoved_loc - paste_size, 0,
1042 zeros_number);
1043 memcpy(bh->b_data + unmoved_loc - paste_size +
1044 zeros_number, body,
1045 paste_size - zeros_number);
1046 }
1047 }
1048 } else
1049 memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
1050
1051 put_ih_item_len(ih, ih_item_len(ih) + paste_size);
1052
1053
1054 set_blkh_free_space(blkh, free_space - paste_size);
1055
1056 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1057
1058 if (bi->bi_parent) {
1059 struct disk_child *t_dc =
1060 B_N_CHILD(bi->bi_parent, bi->bi_position);
1061 put_dc_size(t_dc, dc_size(t_dc) + paste_size);
1062 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1063 }
1064 }
1065
1066
1067
1068
1069
1070
1071
1072 static int leaf_cut_entries(struct buffer_head *bh,
1073 struct item_head *ih, int from, int del_count)
1074 {
1075 char *item;
1076 struct reiserfs_de_head *deh;
1077 int prev_record_offset;
1078 char *prev_record;
1079 int cut_records_len;
1080 int i;
1081
1082
1083
1084
1085
1086 RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
1087 RFALSE(ih_entry_count(ih) < from + del_count,
1088 "10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d",
1089 ih_entry_count(ih), from, del_count);
1090
1091 if (del_count == 0)
1092 return 0;
1093
1094
1095 item = bh->b_data + ih_location(ih);
1096
1097
1098 deh = B_I_DEH(bh, ih);
1099
1100
1101
1102
1103
1104 prev_record_offset =
1105 (from ? deh_location(&deh[from - 1]) : ih_item_len(ih));
1106 cut_records_len = prev_record_offset -
1107 deh_location(&deh[from + del_count - 1]);
1108 prev_record = item + prev_record_offset;
1109
1110
1111 for (i = ih_entry_count(ih) - 1; i > from + del_count - 1; i--)
1112 put_deh_location(&deh[i],
1113 deh_location(&deh[i]) -
1114 (DEH_SIZE * del_count));
1115
1116 for (i = 0; i < from; i++)
1117 put_deh_location(&deh[i],
1118 deh_location(&deh[i]) - (DEH_SIZE * del_count +
1119 cut_records_len));
1120
1121 put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
1122
1123
1124 memmove((char *)(deh + from),
1125 deh + from + del_count,
1126 prev_record - cut_records_len - (char *)(deh + from +
1127 del_count));
1128
1129
1130 memmove(prev_record - cut_records_len - DEH_SIZE * del_count,
1131 prev_record, item + ih_item_len(ih) - prev_record);
1132
1133 return DEH_SIZE * del_count + cut_records_len;
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
1146 int pos_in_item, int cut_size)
1147 {
1148 int nr;
1149 struct buffer_head *bh = bi->bi_bh;
1150 struct block_head *blkh;
1151 struct item_head *ih;
1152 int last_loc, unmoved_loc;
1153 int i;
1154
1155 blkh = B_BLK_HEAD(bh);
1156 nr = blkh_nr_item(blkh);
1157
1158
1159 ih = item_head(bh, cut_item_num);
1160
1161 if (is_direntry_le_ih(ih)) {
1162
1163 cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
1164 if (pos_in_item == 0) {
1165
1166 RFALSE(cut_item_num,
1167 "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
1168 cut_item_num);
1169
1170 set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
1171 }
1172 } else {
1173
1174 RFALSE(is_statdata_le_ih(ih), "10195: item is stat data");
1175 RFALSE(pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
1176 "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
1177 (long unsigned)pos_in_item, (long unsigned)cut_size,
1178 (long unsigned)ih_item_len(ih));
1179
1180
1181 if (pos_in_item == 0) {
1182 memmove(bh->b_data + ih_location(ih),
1183 bh->b_data + ih_location(ih) + cut_size,
1184 ih_item_len(ih) - cut_size);
1185
1186
1187 if (is_direct_le_ih(ih))
1188 set_le_ih_k_offset(ih,
1189 le_ih_k_offset(ih) +
1190 cut_size);
1191 else {
1192 set_le_ih_k_offset(ih,
1193 le_ih_k_offset(ih) +
1194 (cut_size / UNFM_P_SIZE) *
1195 bh->b_size);
1196 RFALSE(ih_item_len(ih) == cut_size
1197 && get_ih_free_space(ih),
1198 "10205: invalid ih_free_space (%h)", ih);
1199 }
1200 }
1201 }
1202
1203
1204 last_loc = ih_location(&ih[nr - cut_item_num - 1]);
1205
1206
1207 unmoved_loc = cut_item_num ? ih_location(ih - 1) : bh->b_size;
1208
1209
1210 memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
1211 unmoved_loc - last_loc - cut_size);
1212
1213
1214 put_ih_item_len(ih, ih_item_len(ih) - cut_size);
1215
1216 if (is_indirect_le_ih(ih)) {
1217 if (pos_in_item)
1218 set_ih_free_space(ih, 0);
1219 }
1220
1221
1222 for (i = cut_item_num; i < nr; i++)
1223 put_ih_location(&ih[i - cut_item_num],
1224 ih_location(&ih[i - cut_item_num]) + cut_size);
1225
1226
1227 set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
1228
1229 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1230
1231 if (bi->bi_parent) {
1232 struct disk_child *t_dc;
1233 t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
1234 put_dc_size(t_dc, dc_size(t_dc) - cut_size);
1235 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1236 }
1237 }
1238
1239
1240 static void leaf_delete_items_entirely(struct buffer_info *bi,
1241 int first, int del_num)
1242 {
1243 struct buffer_head *bh = bi->bi_bh;
1244 int nr;
1245 int i, j;
1246 int last_loc, last_removed_loc;
1247 struct block_head *blkh;
1248 struct item_head *ih;
1249
1250 RFALSE(bh == NULL, "10210: buffer is 0");
1251 RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
1252
1253 if (del_num == 0)
1254 return;
1255
1256 blkh = B_BLK_HEAD(bh);
1257 nr = blkh_nr_item(blkh);
1258
1259 RFALSE(first < 0 || first + del_num > nr,
1260 "10220: first=%d, number=%d, there is %d items", first, del_num,
1261 nr);
1262
1263 if (first == 0 && del_num == nr) {
1264
1265 make_empty_node(bi);
1266
1267 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1268 return;
1269 }
1270
1271 ih = item_head(bh, first);
1272
1273
1274 j = (first == 0) ? bh->b_size : ih_location(ih - 1);
1275
1276
1277 last_loc = ih_location(&ih[nr - 1 - first]);
1278 last_removed_loc = ih_location(&ih[del_num - 1]);
1279
1280 memmove(bh->b_data + last_loc + j - last_removed_loc,
1281 bh->b_data + last_loc, last_removed_loc - last_loc);
1282
1283
1284 memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
1285
1286
1287 for (i = first; i < nr - del_num; i++)
1288 put_ih_location(&ih[i - first],
1289 ih_location(&ih[i - first]) + (j -
1290 last_removed_loc));
1291
1292
1293 set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
1294 set_blkh_free_space(blkh,
1295 blkh_free_space(blkh) + (j - last_removed_loc +
1296 IH_SIZE * del_num));
1297
1298 do_balance_mark_leaf_dirty(bi->tb, bh, 0);
1299
1300 if (bi->bi_parent) {
1301 struct disk_child *t_dc =
1302 B_N_CHILD(bi->bi_parent, bi->bi_position);
1303 put_dc_size(t_dc,
1304 dc_size(t_dc) - (j - last_removed_loc +
1305 IH_SIZE * del_num));
1306 do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
1307 }
1308 }
1309
1310
1311
1312
1313
1314 void leaf_paste_entries(struct buffer_info *bi,
1315 int item_num,
1316 int before,
1317 int new_entry_count,
1318 struct reiserfs_de_head *new_dehs,
1319 const char *records, int paste_size)
1320 {
1321 struct item_head *ih;
1322 char *item;
1323 struct reiserfs_de_head *deh;
1324 char *insert_point;
1325 int i;
1326 struct buffer_head *bh = bi->bi_bh;
1327
1328 if (new_entry_count == 0)
1329 return;
1330
1331 ih = item_head(bh, item_num);
1332
1333
1334
1335
1336
1337 RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
1338 RFALSE(ih_entry_count(ih) < before,
1339 "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
1340 ih_entry_count(ih), before);
1341
1342
1343 item = bh->b_data + ih_location(ih);
1344
1345
1346 deh = B_I_DEH(bh, ih);
1347
1348
1349 insert_point =
1350 item +
1351 (before ? deh_location(&deh[before - 1])
1352 : (ih_item_len(ih) - paste_size));
1353
1354
1355 for (i = ih_entry_count(ih) - 1; i >= before; i--)
1356 put_deh_location(&deh[i],
1357 deh_location(&deh[i]) +
1358 (DEH_SIZE * new_entry_count));
1359
1360
1361 for (i = 0; i < before; i++)
1362 put_deh_location(&deh[i],
1363 deh_location(&deh[i]) + paste_size);
1364
1365 put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
1366
1367
1368 memmove(insert_point + paste_size, insert_point,
1369 item + (ih_item_len(ih) - paste_size) - insert_point);
1370
1371
1372 memcpy(insert_point + DEH_SIZE * new_entry_count, records,
1373 paste_size - DEH_SIZE * new_entry_count);
1374
1375
1376 deh += before;
1377 memmove((char *)(deh + new_entry_count), deh,
1378 insert_point - (char *)deh);
1379
1380
1381 deh = (struct reiserfs_de_head *)((char *)deh);
1382 memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
1383
1384
1385 for (i = 0; i < new_entry_count; i++) {
1386 put_deh_location(&deh[i],
1387 deh_location(&deh[i]) +
1388 (-deh_location
1389 (&new_dehs[new_entry_count - 1]) +
1390 insert_point + DEH_SIZE * new_entry_count -
1391 item));
1392 }
1393
1394
1395 if (!before) {
1396 set_le_ih_k_offset(ih, deh_offset(new_dehs));
1397 }
1398 #ifdef CONFIG_REISERFS_CHECK
1399 {
1400 int prev, next;
1401
1402 deh = B_I_DEH(bh, ih);
1403 for (i = 0; i < ih_entry_count(ih); i++) {
1404 next =
1405 (i <
1406 ih_entry_count(ih) -
1407 1) ? deh_location(&deh[i + 1]) : 0;
1408 prev = (i != 0) ? deh_location(&deh[i - 1]) : 0;
1409
1410 if (prev && prev <= deh_location(&deh[i]))
1411 reiserfs_error(sb_from_bi(bi), "vs-10240",
1412 "directory item (%h) "
1413 "corrupted (prev %a, "
1414 "cur(%d) %a)",
1415 ih, deh + i - 1, i, deh + i);
1416 if (next && next >= deh_location(&deh[i]))
1417 reiserfs_error(sb_from_bi(bi), "vs-10250",
1418 "directory item (%h) "
1419 "corrupted (cur(%d) %a, "
1420 "next %a)",
1421 ih, i, deh + i, deh + i + 1);
1422 }
1423 }
1424 #endif
1425
1426 }