diff options
author | Jeff Mahoney <jeffm@suse.com> | 2014-04-23 10:00:57 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2014-05-07 13:13:34 -0400 |
commit | 3fade9377f44586845e82d542368cbf78471653c (patch) | |
tree | c07606f7771703b09f26b78622efcebbc950f371 | |
parent | 4bf4de6bc45a6b1cfa6af6cf235480287c8784fb (diff) |
reiserfs: balance_leaf refactor, format balance_leaf_paste_left
Break up balance_leaf_paste_left into:
balance_leaf_paste_left_shift
balance_leaf_paste_left_shift_dirent
balance_leaf_paste_left_whole
and keep balance_leaf_paste_left as a handler to select which is appropriate.
Also reformat to adhere to CodingStyle.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | fs/reiserfs/do_balan.c | 361 |
1 files changed, 222 insertions, 139 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index cca685daf26d..843c4023ad36 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
@@ -355,164 +355,247 @@ static void balance_leaf_insert_left(struct tree_balance *tb, | |||
355 | } | 355 | } |
356 | } | 356 | } |
357 | 357 | ||
358 | static void balance_leaf_paste_left(struct tree_balance *tb, | 358 | static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb, |
359 | struct item_head *ih, const char *body) | 359 | struct item_head *ih, |
360 | const char *body) | ||
360 | { | 361 | { |
361 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 362 | int n = B_NR_ITEMS(tb->L[0]); |
362 | int ret_val; | ||
363 | struct buffer_info bi; | 363 | struct buffer_info bi; |
364 | |||
365 | RFALSE(tb->zeroes_num, | ||
366 | "PAP-12090: invalid parameter in case of a directory"); | ||
367 | |||
368 | /* directory item */ | ||
369 | if (tb->lbytes > tb->pos_in_item) { | ||
370 | /* new directory entry falls into L[0] */ | ||
371 | struct item_head *pasted; | ||
372 | int ret, l_pos_in_item = tb->pos_in_item; | ||
373 | |||
374 | /* | ||
375 | * Shift lnum[0] - 1 items in whole. | ||
376 | * Shift lbytes - 1 entries from given directory item | ||
377 | */ | ||
378 | ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes - 1); | ||
379 | if (ret && !tb->item_pos) { | ||
380 | pasted = item_head(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1); | ||
381 | l_pos_in_item += ih_entry_count(pasted) - | ||
382 | (tb->lbytes - 1); | ||
383 | } | ||
384 | |||
385 | /* Append given directory entry to directory item */ | ||
386 | buffer_info_init_left(tb, &bi); | ||
387 | leaf_paste_in_buffer(&bi, n + tb->item_pos - ret, | ||
388 | l_pos_in_item, tb->insert_size[0], | ||
389 | body, tb->zeroes_num); | ||
390 | |||
391 | /* | ||
392 | * previous string prepared space for pasting new entry, | ||
393 | * following string pastes this entry | ||
394 | */ | ||
395 | |||
396 | /* | ||
397 | * when we have merge directory item, pos_in_item | ||
398 | * has been changed too | ||
399 | */ | ||
400 | |||
401 | /* paste new directory entry. 1 is entry number */ | ||
402 | leaf_paste_entries(&bi, n + tb->item_pos - ret, | ||
403 | l_pos_in_item, 1, | ||
404 | (struct reiserfs_de_head *) body, | ||
405 | body + DEH_SIZE, tb->insert_size[0]); | ||
406 | tb->insert_size[0] = 0; | ||
407 | } else { | ||
408 | /* new directory item doesn't fall into L[0] */ | ||
409 | /* | ||
410 | * Shift lnum[0]-1 items in whole. Shift lbytes | ||
411 | * directory entries from directory item number lnum[0] | ||
412 | */ | ||
413 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | ||
414 | } | ||
415 | |||
416 | /* Calculate new position to append in item body */ | ||
417 | tb->pos_in_item -= tb->lbytes; | ||
418 | } | ||
419 | |||
420 | static void balance_leaf_paste_left_shift(struct tree_balance *tb, | ||
421 | struct item_head *ih, | ||
422 | const char *body) | ||
423 | { | ||
424 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | ||
364 | int n = B_NR_ITEMS(tb->L[0]); | 425 | int n = B_NR_ITEMS(tb->L[0]); |
426 | struct buffer_info bi; | ||
365 | 427 | ||
366 | if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { | 428 | if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) { |
367 | /* we must shift the part of the appended item */ | 429 | balance_leaf_paste_left_shift_dirent(tb, ih, body); |
368 | if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) { | 430 | return; |
431 | } | ||
369 | 432 | ||
370 | RFALSE(tb->zeroes_num, | 433 | RFALSE(tb->lbytes <= 0, |
371 | "PAP-12090: invalid parameter in case of a directory"); | 434 | "PAP-12095: there is nothing to shift to L[0]. " |
372 | /* directory item */ | 435 | "lbytes=%d", tb->lbytes); |
373 | if (tb->lbytes > tb->pos_in_item) { | 436 | RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)), |
374 | /* new directory entry falls into L[0] */ | 437 | "PAP-12100: incorrect position to paste: " |
375 | struct item_head *pasted; | 438 | "item_len=%d, pos_in_item=%d", |
376 | int l_pos_in_item = tb->pos_in_item; | 439 | ih_item_len(item_head(tbS0, tb->item_pos)), tb->pos_in_item); |
377 | |||
378 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */ | ||
379 | ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes-1); | ||
380 | if (ret_val && !tb->item_pos) { | ||
381 | pasted = item_head(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1); | ||
382 | l_pos_in_item += ih_entry_count(pasted) - (tb->lbytes -1); | ||
383 | } | ||
384 | 440 | ||
385 | /* Append given directory entry to directory item */ | 441 | /* appended item will be in L[0] in whole */ |
386 | buffer_info_init_left(tb, &bi); | 442 | if (tb->lbytes >= tb->pos_in_item) { |
387 | leaf_paste_in_buffer(&bi, n + tb->item_pos - ret_val, l_pos_in_item, tb->insert_size[0], body, tb->zeroes_num); | 443 | struct item_head *tbS0_pos_ih, *tbL0_ih; |
444 | struct item_head *tbS0_0_ih; | ||
445 | struct reiserfs_key *left_delim_key; | ||
446 | int ret, l_n, version, temp_l; | ||
388 | 447 | ||
389 | /* previous string prepared space for pasting new entry, following string pastes this entry */ | 448 | tbS0_pos_ih = item_head(tbS0, tb->item_pos); |
449 | tbS0_0_ih = item_head(tbS0, 0); | ||
390 | 450 | ||
391 | /* when we have merge directory item, pos_in_item has been changed too */ | 451 | /* |
452 | * this bytes number must be appended | ||
453 | * to the last item of L[h] | ||
454 | */ | ||
455 | l_n = tb->lbytes - tb->pos_in_item; | ||
392 | 456 | ||
393 | /* paste new directory entry. 1 is entry number */ | 457 | /* Calculate new insert_size[0] */ |
394 | leaf_paste_entries(&bi, n + tb->item_pos - ret_val, l_pos_in_item, | 458 | tb->insert_size[0] -= l_n; |
395 | 1, (struct reiserfs_de_head *) body, | ||
396 | body + DEH_SIZE, tb->insert_size[0]); | ||
397 | tb->insert_size[0] = 0; | ||
398 | } else { | ||
399 | /* new directory item doesn't fall into L[0] */ | ||
400 | /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */ | ||
401 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | ||
402 | } | ||
403 | /* Calculate new position to append in item body */ | ||
404 | tb->pos_in_item -= tb->lbytes; | ||
405 | } else { | ||
406 | /* regular object */ | ||
407 | RFALSE(tb->lbytes <= 0, "PAP-12095: there is nothing to shift to L[0]. lbytes=%d", tb->lbytes); | ||
408 | RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)), | ||
409 | "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d", | ||
410 | ih_item_len(item_head(tbS0, tb->item_pos)), tb->pos_in_item); | ||
411 | |||
412 | if (tb->lbytes >= tb->pos_in_item) { | ||
413 | /* appended item will be in L[0] in whole */ | ||
414 | int l_n; | ||
415 | |||
416 | /* this bytes number must be appended to the last item of L[h] */ | ||
417 | l_n = tb->lbytes - tb->pos_in_item; | ||
418 | |||
419 | /* Calculate new insert_size[0] */ | ||
420 | tb->insert_size[0] -= l_n; | ||
421 | |||
422 | RFALSE(tb->insert_size[0] <= 0, | ||
423 | "PAP-12105: there is nothing to paste into L[0]. insert_size=%d", | ||
424 | tb->insert_size[0]); | ||
425 | ret_val = leaf_shift_left(tb, tb->lnum[0], ih_item_len | ||
426 | (item_head(tbS0, tb->item_pos))); | ||
427 | /* Append to body of item in L[0] */ | ||
428 | buffer_info_init_left(tb, &bi); | ||
429 | leaf_paste_in_buffer | ||
430 | (&bi, n + tb->item_pos - ret_val, ih_item_len | ||
431 | (item_head(tb->L[0], n + tb->item_pos - ret_val)), | ||
432 | l_n, body, | ||
433 | tb->zeroes_num > l_n ? l_n : tb->zeroes_num); | ||
434 | /* 0-th item in S0 can be only of DIRECT type when l_n != 0 */ | ||
435 | { | ||
436 | int version; | ||
437 | int temp_l = l_n; | ||
438 | |||
439 | RFALSE(ih_item_len(item_head(tbS0, 0)), | ||
440 | "PAP-12106: item length must be 0"); | ||
441 | RFALSE(comp_short_le_keys(leaf_key(tbS0, 0), leaf_key | ||
442 | (tb->L[0], n + tb->item_pos - ret_val)), | ||
443 | "PAP-12107: items must be of the same file"); | ||
444 | if (is_indirect_le_ih(item_head(tb->L[0], n + tb->item_pos - ret_val))) { | ||
445 | temp_l = l_n << (tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT); | ||
446 | } | ||
447 | /* update key of first item in S0 */ | ||
448 | version = ih_version(item_head(tbS0, 0)); | ||
449 | set_le_key_k_offset(version, leaf_key(tbS0, 0), | ||
450 | le_key_k_offset(version,leaf_key(tbS0, 0)) + temp_l); | ||
451 | /* update left delimiting key */ | ||
452 | set_le_key_k_offset(version, internal_key(tb->CFL[0], tb->lkey[0]), | ||
453 | le_key_k_offset(version, internal_key(tb->CFL[0], tb->lkey[0])) + temp_l); | ||
454 | } | ||
455 | 459 | ||
456 | /* Calculate new body, position in item and insert_size[0] */ | 460 | RFALSE(tb->insert_size[0] <= 0, |
457 | if (l_n > tb->zeroes_num) { | 461 | "PAP-12105: there is nothing to paste into " |
458 | body += (l_n - tb->zeroes_num); | 462 | "L[0]. insert_size=%d", tb->insert_size[0]); |
459 | tb->zeroes_num = 0; | ||
460 | } else | ||
461 | tb->zeroes_num -= l_n; | ||
462 | tb->pos_in_item = 0; | ||
463 | 463 | ||
464 | RFALSE(comp_short_le_keys(leaf_key(tbS0, 0), leaf_key(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1)) | 464 | ret = leaf_shift_left(tb, tb->lnum[0], |
465 | || !op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size) | 465 | ih_item_len(tbS0_pos_ih)); |
466 | || !op_is_left_mergeable(internal_key(tb->CFL[0], tb->lkey[0]), tbS0->b_size), | ||
467 | "PAP-12120: item must be merge-able with left neighboring item"); | ||
468 | } else { /* only part of the appended item will be in L[0] */ | ||
469 | 466 | ||
470 | /* Calculate position in item for append in S[0] */ | 467 | tbL0_ih = item_head(tb->L[0], n + tb->item_pos - ret); |
471 | tb->pos_in_item -= tb->lbytes; | ||
472 | 468 | ||
473 | RFALSE(tb->pos_in_item <= 0, "PAP-12125: no place for paste. pos_in_item=%d", tb->pos_in_item); | 469 | /* Append to body of item in L[0] */ |
470 | buffer_info_init_left(tb, &bi); | ||
471 | leaf_paste_in_buffer(&bi, n + tb->item_pos - ret, | ||
472 | ih_item_len(tbL0_ih), l_n, body, | ||
473 | min_t(int, l_n, tb->zeroes_num)); | ||
474 | 474 | ||
475 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ | 475 | /* |
476 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | 476 | * 0-th item in S0 can be only of DIRECT type |
477 | } | 477 | * when l_n != 0 |
478 | } | 478 | */ |
479 | } else { /* appended item will be in L[0] in whole */ | 479 | temp_l = l_n; |
480 | 480 | ||
481 | struct item_head *pasted; | 481 | RFALSE(ih_item_len(tbS0_0_ih), |
482 | "PAP-12106: item length must be 0"); | ||
483 | RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key, | ||
484 | leaf_key(tb->L[0], n + tb->item_pos - ret)), | ||
485 | "PAP-12107: items must be of the same file"); | ||
482 | 486 | ||
483 | if (!tb->item_pos && op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)) { /* if we paste into first item of S[0] and it is left mergable */ | 487 | if (is_indirect_le_ih(tbL0_ih)) { |
484 | /* then increment pos_in_item by the size of the last item in L[0] */ | 488 | int shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT; |
485 | pasted = item_head(tb->L[0], n - 1); | 489 | temp_l = l_n << shift; |
486 | if (is_direntry_le_ih(pasted)) | 490 | } |
487 | tb->pos_in_item += ih_entry_count(pasted); | 491 | /* update key of first item in S0 */ |
488 | else | 492 | version = ih_version(tbS0_0_ih); |
489 | tb->pos_in_item += ih_item_len(pasted); | 493 | add_le_key_k_offset(version, &tbS0_0_ih->ih_key, temp_l); |
490 | } | ||
491 | 494 | ||
492 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */ | 495 | /* update left delimiting key */ |
493 | ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | 496 | left_delim_key = internal_key(tb->CFL[0], tb->lkey[0]); |
494 | /* Append to body of item in L[0] */ | 497 | add_le_key_k_offset(version, left_delim_key, temp_l); |
495 | buffer_info_init_left(tb, &bi); | ||
496 | leaf_paste_in_buffer(&bi, n + tb->item_pos - ret_val, | ||
497 | tb->pos_in_item, | ||
498 | tb->insert_size[0], | ||
499 | body, tb->zeroes_num); | ||
500 | 498 | ||
501 | /* if appended item is directory, paste entry */ | 499 | /* |
502 | pasted = item_head(tb->L[0], n + tb->item_pos - ret_val); | 500 | * Calculate new body, position in item and |
503 | if (is_direntry_le_ih(pasted)) | 501 | * insert_size[0] |
504 | leaf_paste_entries(&bi, n + tb->item_pos - ret_val, | 502 | */ |
505 | tb->pos_in_item, 1, | 503 | if (l_n > tb->zeroes_num) { |
506 | (struct reiserfs_de_head *) body, | 504 | body += (l_n - tb->zeroes_num); |
507 | body + DEH_SIZE, | 505 | tb->zeroes_num = 0; |
508 | tb->insert_size[0]); | 506 | } else |
509 | /* if appended item is indirect item, put unformatted node into un list */ | 507 | tb->zeroes_num -= l_n; |
510 | if (is_indirect_le_ih(pasted)) | 508 | tb->pos_in_item = 0; |
511 | set_ih_free_space(pasted, 0); | 509 | |
512 | tb->insert_size[0] = 0; | 510 | RFALSE(comp_short_le_keys(&tbS0_0_ih->ih_key, |
513 | tb->zeroes_num = 0; | 511 | leaf_key(tb->L[0], |
514 | } | 512 | B_NR_ITEMS(tb->L[0]) - 1)) || |
513 | !op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size) || | ||
514 | !op_is_left_mergeable(left_delim_key, tbS0->b_size), | ||
515 | "PAP-12120: item must be merge-able with left " | ||
516 | "neighboring item"); | ||
517 | } else { | ||
518 | /* only part of the appended item will be in L[0] */ | ||
519 | |||
520 | /* Calculate position in item for append in S[0] */ | ||
521 | tb->pos_in_item -= tb->lbytes; | ||
515 | 522 | ||
523 | RFALSE(tb->pos_in_item <= 0, | ||
524 | "PAP-12125: no place for paste. pos_in_item=%d", | ||
525 | tb->pos_in_item); | ||
526 | |||
527 | /* | ||
528 | * Shift lnum[0] - 1 items in whole. | ||
529 | * Shift lbytes - 1 byte from item number lnum[0] | ||
530 | */ | ||
531 | leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | |||
536 | /* appended item will be in L[0] in whole */ | ||
537 | static void balance_leaf_paste_left_whole(struct tree_balance *tb, | ||
538 | struct item_head *ih, | ||
539 | const char *body) | ||
540 | { | ||
541 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | ||
542 | int n = B_NR_ITEMS(tb->L[0]); | ||
543 | struct buffer_info bi; | ||
544 | struct item_head *pasted; | ||
545 | int ret; | ||
546 | |||
547 | /* if we paste into first item of S[0] and it is left mergable */ | ||
548 | if (!tb->item_pos && | ||
549 | op_is_left_mergeable(leaf_key(tbS0, 0), tbS0->b_size)) { | ||
550 | /* | ||
551 | * then increment pos_in_item by the size of the | ||
552 | * last item in L[0] | ||
553 | */ | ||
554 | pasted = item_head(tb->L[0], n - 1); | ||
555 | if (is_direntry_le_ih(pasted)) | ||
556 | tb->pos_in_item += ih_entry_count(pasted); | ||
557 | else | ||
558 | tb->pos_in_item += ih_item_len(pasted); | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Shift lnum[0] - 1 items in whole. | ||
563 | * Shift lbytes - 1 byte from item number lnum[0] | ||
564 | */ | ||
565 | ret = leaf_shift_left(tb, tb->lnum[0], tb->lbytes); | ||
566 | |||
567 | /* Append to body of item in L[0] */ | ||
568 | buffer_info_init_left(tb, &bi); | ||
569 | leaf_paste_in_buffer(&bi, n + tb->item_pos - ret, tb->pos_in_item, | ||
570 | tb->insert_size[0], body, tb->zeroes_num); | ||
571 | |||
572 | /* if appended item is directory, paste entry */ | ||
573 | pasted = item_head(tb->L[0], n + tb->item_pos - ret); | ||
574 | if (is_direntry_le_ih(pasted)) | ||
575 | leaf_paste_entries(&bi, n + tb->item_pos - ret, | ||
576 | tb->pos_in_item, 1, | ||
577 | (struct reiserfs_de_head *)body, | ||
578 | body + DEH_SIZE, tb->insert_size[0]); | ||
579 | |||
580 | /* | ||
581 | * if appended item is indirect item, put unformatted node | ||
582 | * into un list | ||
583 | */ | ||
584 | if (is_indirect_le_ih(pasted)) | ||
585 | set_ih_free_space(pasted, 0); | ||
586 | |||
587 | tb->insert_size[0] = 0; | ||
588 | tb->zeroes_num = 0; | ||
589 | } | ||
590 | |||
591 | static void balance_leaf_paste_left(struct tree_balance *tb, | ||
592 | struct item_head *ih, const char *body) | ||
593 | { | ||
594 | /* we must shift the part of the appended item */ | ||
595 | if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) | ||
596 | balance_leaf_paste_left_shift(tb, ih, body); | ||
597 | else | ||
598 | balance_leaf_paste_left_whole(tb, ih, body); | ||
516 | } | 599 | } |
517 | 600 | ||
518 | /* Shift lnum[0] items from S[0] to the left neighbor L[0] */ | 601 | /* Shift lnum[0] items from S[0] to the left neighbor L[0] */ |