diff options
| -rw-r--r-- | fs/reiserfs/do_balan.c | 895 |
1 files changed, 195 insertions, 700 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 2b7882b508db..9a3c68cf6026 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
| @@ -324,23 +324,17 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
| 324 | switch (flag) { | 324 | switch (flag) { |
| 325 | case M_INSERT: /* insert item into L[0] */ | 325 | case M_INSERT: /* insert item into L[0] */ |
| 326 | 326 | ||
| 327 | if (item_pos == tb->lnum[0] - 1 | 327 | if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { |
| 328 | && tb->lbytes != -1) { | ||
| 329 | /* part of new item falls into L[0] */ | 328 | /* part of new item falls into L[0] */ |
| 330 | int new_item_len; | 329 | int new_item_len; |
| 331 | int version; | 330 | int version; |
| 332 | 331 | ||
| 333 | ret_val = | 332 | ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, -1); |
| 334 | leaf_shift_left(tb, tb->lnum[0] - 1, | ||
| 335 | -1); | ||
| 336 | 333 | ||
| 337 | /* Calculate item length to insert to S[0] */ | 334 | /* Calculate item length to insert to S[0] */ |
| 338 | new_item_len = | 335 | new_item_len = ih_item_len(ih) - tb->lbytes; |
| 339 | ih_item_len(ih) - tb->lbytes; | ||
| 340 | /* Calculate and check item length to insert to L[0] */ | 336 | /* Calculate and check item length to insert to L[0] */ |
| 341 | put_ih_item_len(ih, | 337 | put_ih_item_len(ih, ih_item_len(ih) - new_item_len); |
| 342 | ih_item_len(ih) - | ||
| 343 | new_item_len); | ||
| 344 | 338 | ||
| 345 | RFALSE(ih_item_len(ih) <= 0, | 339 | RFALSE(ih_item_len(ih) <= 0, |
| 346 | "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d", | 340 | "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d", |
| @@ -349,30 +343,18 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
| 349 | /* Insert new item into L[0] */ | 343 | /* Insert new item into L[0] */ |
| 350 | buffer_info_init_left(tb, &bi); | 344 | buffer_info_init_left(tb, &bi); |
| 351 | leaf_insert_into_buf(&bi, | 345 | leaf_insert_into_buf(&bi, |
| 352 | n + item_pos - | 346 | n + item_pos - ret_val, ih, body, |
| 353 | ret_val, ih, body, | 347 | zeros_num > ih_item_len(ih) ? ih_item_len(ih) : zeros_num); |
| 354 | zeros_num > | ||
| 355 | ih_item_len(ih) ? | ||
| 356 | ih_item_len(ih) : | ||
| 357 | zeros_num); | ||
| 358 | 348 | ||
| 359 | version = ih_version(ih); | 349 | version = ih_version(ih); |
| 360 | 350 | ||
| 361 | /* Calculate key component, item length and body to insert into S[0] */ | 351 | /* Calculate key component, item length and body to insert into S[0] */ |
| 362 | set_le_ih_k_offset(ih, | 352 | set_le_ih_k_offset(ih, le_ih_k_offset(ih) + |
| 363 | le_ih_k_offset(ih) + | 353 | (tb-> lbytes << (is_indirect_le_ih(ih) ? tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0))); |
| 364 | (tb-> | ||
| 365 | lbytes << | ||
| 366 | (is_indirect_le_ih | ||
| 367 | (ih) ? tb->tb_sb-> | ||
| 368 | s_blocksize_bits - | ||
| 369 | UNFM_P_SHIFT : | ||
| 370 | 0))); | ||
| 371 | 354 | ||
| 372 | put_ih_item_len(ih, new_item_len); | 355 | put_ih_item_len(ih, new_item_len); |
| 373 | if (tb->lbytes > zeros_num) { | 356 | if (tb->lbytes > zeros_num) { |
| 374 | body += | 357 | body += (tb->lbytes - zeros_num); |
| 375 | (tb->lbytes - zeros_num); | ||
| 376 | zeros_num = 0; | 358 | zeros_num = 0; |
| 377 | } else | 359 | } else |
| 378 | zeros_num -= tb->lbytes; | 360 | zeros_num -= tb->lbytes; |
| @@ -383,15 +365,10 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
| 383 | } else { | 365 | } else { |
| 384 | /* new item in whole falls into L[0] */ | 366 | /* new item in whole falls into L[0] */ |
| 385 | /* Shift lnum[0]-1 items to L[0] */ | 367 | /* Shift lnum[0]-1 items to L[0] */ |
| 386 | ret_val = | 368 | ret_val = leaf_shift_left(tb, tb->lnum[0] - 1, tb->lbytes); |
| 387 | leaf_shift_left(tb, tb->lnum[0] - 1, | ||
| 388 | tb->lbytes); | ||
| 389 | /* Insert new item into L[0] */ | 369 | /* Insert new item into L[0] */ |
| 390 | buffer_info_init_left(tb, &bi); | 370 | buffer_info_init_left(tb, &bi); |
| 391 | leaf_insert_into_buf(&bi, | 371 | leaf_insert_into_buf(&bi, n + item_pos - ret_val, ih, body, zeros_num); |
| 392 | n + item_pos - | ||
| 393 | ret_val, ih, body, | ||
| 394 | zeros_num); | ||
| 395 | tb->insert_size[0] = 0; | 372 | tb->insert_size[0] = 0; |
| 396 | zeros_num = 0; | 373 | zeros_num = 0; |
| 397 | } | 374 | } |
| @@ -399,264 +376,117 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
| 399 | 376 | ||
| 400 | case M_PASTE: /* append item in L[0] */ | 377 | case M_PASTE: /* append item in L[0] */ |
| 401 | 378 | ||
| 402 | if (item_pos == tb->lnum[0] - 1 | 379 | if (item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { |
| 403 | && tb->lbytes != -1) { | ||
| 404 | /* we must shift the part of the appended item */ | 380 | /* we must shift the part of the appended item */ |
| 405 | if (is_direntry_le_ih | 381 | if (is_direntry_le_ih(B_N_PITEM_HEAD(tbS0, item_pos))) { |
| 406 | (B_N_PITEM_HEAD(tbS0, item_pos))) { | ||
| 407 | 382 | ||
| 408 | RFALSE(zeros_num, | 383 | RFALSE(zeros_num, |
| 409 | "PAP-12090: invalid parameter in case of a directory"); | 384 | "PAP-12090: invalid parameter in case of a directory"); |
| 410 | /* directory item */ | 385 | /* directory item */ |
| 411 | if (tb->lbytes > pos_in_item) { | 386 | if (tb->lbytes > pos_in_item) { |
| 412 | /* new directory entry falls into L[0] */ | 387 | /* new directory entry falls into L[0] */ |
| 413 | struct item_head | 388 | struct item_head *pasted; |
| 414 | *pasted; | 389 | int l_pos_in_item = pos_in_item; |
| 415 | int l_pos_in_item = | ||
| 416 | pos_in_item; | ||
| 417 | 390 | ||
| 418 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */ | 391 | /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */ |
| 419 | ret_val = | 392 | ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes-1); |
| 420 | leaf_shift_left(tb, | 393 | if (ret_val && !item_pos) { |
| 421 | tb-> | 394 | pasted = B_N_PITEM_HEAD(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1); |
| 422 | lnum | 395 | l_pos_in_item += I_ENTRY_COUNT(pasted) - (tb->lbytes -1); |
| 423 | [0], | ||
| 424 | tb-> | ||
| 425 | lbytes | ||
| 426 | - | ||
| 427 | 1); | ||
| 428 | if (ret_val | ||
| 429 | && !item_pos) { | ||
| 430 | pasted = | ||
| 431 | B_N_PITEM_HEAD | ||
| 432 | (tb->L[0], | ||
| 433 | B_NR_ITEMS | ||
| 434 | (tb-> | ||
| 435 | L[0]) - | ||
| 436 | 1); | ||
| 437 | l_pos_in_item += | ||
| 438 | I_ENTRY_COUNT | ||
| 439 | (pasted) - | ||
| 440 | (tb-> | ||
| 441 | lbytes - | ||
| 442 | 1); | ||
| 443 | } | 396 | } |
| 444 | 397 | ||
| 445 | /* Append given directory entry to directory item */ | 398 | /* Append given directory entry to directory item */ |
| 446 | buffer_info_init_left(tb, &bi); | 399 | buffer_info_init_left(tb, &bi); |
| 447 | leaf_paste_in_buffer | 400 | leaf_paste_in_buffer(&bi, n + item_pos - ret_val, l_pos_in_item, tb->insert_size[0], body, zeros_num); |
| 448 | (&bi, | ||
| 449 | n + item_pos - | ||
| 450 | ret_val, | ||
| 451 | l_pos_in_item, | ||
| 452 | tb->insert_size[0], | ||
| 453 | body, zeros_num); | ||
| 454 | 401 | ||
| 455 | /* previous string prepared space for pasting new entry, following string pastes this entry */ | 402 | /* previous string prepared space for pasting new entry, following string pastes this entry */ |
| 456 | 403 | ||
| 457 | /* when we have merge directory item, pos_in_item has been changed too */ | 404 | /* when we have merge directory item, pos_in_item has been changed too */ |
| 458 | 405 | ||
| 459 | /* paste new directory entry. 1 is entry number */ | 406 | /* paste new directory entry. 1 is entry number */ |
| 460 | leaf_paste_entries(&bi, | 407 | |
