diff options
author | Jeff Mahoney <jeffm@suse.com> | 2014-04-23 10:01:00 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2014-05-13 10:06:35 -0400 |
commit | b54b8c918415376c6cfca0e1ceed26cf62b92ae1 (patch) | |
tree | 703db277388d5819cb8cf31085d8349633abc8a3 | |
parent | 2369ecd8e81f7295b14f205ff49160fc5c1cfa93 (diff) |
reiserfs: balance_leaf refactor, format balance_leaf_new_nodes_paste
Break up balance_leaf_paste_new_nodes into:
balance_leaf_paste_new_nodes_shift
balance_leaf_paste_new_nodes_shift_dirent
balance_leaf_paste_new_nodes_whole
and keep balance_leaf_paste_new_nodes 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 | 476 |
1 files changed, 271 insertions, 205 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 793fab7b9f02..cffcb67a5436 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
@@ -714,7 +714,7 @@ static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb, | |||
714 | struct buffer_info bi; | 714 | struct buffer_info bi; |
715 | int entry_count; | 715 | int entry_count; |
716 | 716 | ||
717 | RFALSE(zeroes_num, | 717 | RFALSE(tb->zeroes_num, |
718 | "PAP-12145: invalid parameter in case of a directory"); | 718 | "PAP-12145: invalid parameter in case of a directory"); |
719 | entry_count = ih_entry_count(item_head(tbS0, tb->item_pos)); | 719 | entry_count = ih_entry_count(item_head(tbS0, tb->item_pos)); |
720 | 720 | ||
@@ -782,10 +782,10 @@ static void balance_leaf_paste_right_shift(struct tree_balance *tb, | |||
782 | if (n_shift < 0) | 782 | if (n_shift < 0) |
783 | n_shift = 0; | 783 | n_shift = 0; |
784 | 784 | ||
785 | RFALSE(pos_in_item != ih_item_len(item_head(tbS0, item_pos)), | 785 | RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)), |
786 | "PAP-12155: invalid position to paste. ih_item_len=%d, " | 786 | "PAP-12155: invalid position to paste. ih_item_len=%d, " |
787 | "pos_in_item=%d", pos_in_item, | 787 | "pos_in_item=%d", tb->pos_in_item, |
788 | ih_item_len(item_head(tbS0, item_pos))); | 788 | ih_item_len(item_head(tbS0, tb->item_pos))); |
789 | 789 | ||
790 | leaf_shift_right(tb, tb->rnum[0], n_shift); | 790 | leaf_shift_right(tb, tb->rnum[0], n_shift); |
791 | 791 | ||
@@ -924,68 +924,89 @@ static void balance_leaf_new_nodes_insert(struct tree_balance *tb, | |||
924 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 924 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); |
925 | int n = B_NR_ITEMS(tbS0); | 925 | int n = B_NR_ITEMS(tbS0); |
926 | struct buffer_info bi; | 926 | struct buffer_info bi; |
927 | if (n - tb->snum[i] < tb->item_pos) { /* new item or it's part falls to first new node S_new[i] */ | 927 | int shift; |
928 | if (tb->item_pos == n - tb->snum[i] + 1 && tb->sbytes[i] != -1) { /* part of new item falls into S_new[i] */ | ||
929 | int old_key_comp, old_len, r_zeroes_number; | ||
930 | const char *r_body; | ||
931 | int version; | ||
932 | |||
933 | /* Move snum[i]-1 items from S[0] to S_new[i] */ | ||
934 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | ||
935 | tb->snum[i] - 1, -1, | ||
936 | tb->S_new[i]); | ||
937 | /* Remember key component and item length */ | ||
938 | version = ih_version(ih); | ||
939 | old_key_comp = le_ih_k_offset(ih); | ||
940 | old_len = ih_item_len(ih); | ||
941 | |||
942 | /* Calculate key component and item length to insert into S_new[i] */ | ||
943 | set_le_ih_k_offset(ih, le_ih_k_offset(ih) + | ||
944 | ((old_len - tb->sbytes[i]) << (is_indirect_le_ih(ih) ? tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT : 0))); | ||
945 | |||
946 | put_ih_item_len(ih, tb->sbytes[i]); | ||
947 | |||
948 | /* Insert part of the item into S_new[i] before 0-th item */ | ||
949 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); | ||
950 | |||
951 | if ((old_len - tb->sbytes[i]) > tb->zeroes_num) { | ||
952 | r_zeroes_number = 0; | ||
953 | r_body = body + (old_len - tb->sbytes[i]) - tb->zeroes_num; | ||
954 | } else { | ||
955 | r_body = body; | ||
956 | r_zeroes_number = tb->zeroes_num - (old_len - tb->sbytes[i]); | ||
957 | tb->zeroes_num -= r_zeroes_number; | ||
958 | } | ||
959 | 928 | ||
960 | leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number); | 929 | /* new item or it part don't falls into S_new[i] */ |
930 | if (n - tb->snum[i] >= tb->item_pos) { | ||
931 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | ||
932 | tb->snum[i], tb->sbytes[i], tb->S_new[i]); | ||
933 | return; | ||
934 | } | ||
961 | 935 | ||
962 | /* Calculate key component and item length to insert into S[i] */ | 936 | /* new item or it's part falls to first new node S_new[i] */ |
963 | set_le_ih_k_offset(ih, old_key_comp); | ||
964 | put_ih_item_len(ih, old_len - tb->sbytes[i]); | ||
965 | tb->insert_size[0] -= tb->sbytes[i]; | ||
966 | } else { /* whole new item falls into S_new[i] */ | ||
967 | 937 | ||
968 | /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */ | 938 | /* part of new item falls into S_new[i] */ |
969 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | 939 | if (tb->item_pos == n - tb->snum[i] + 1 && tb->sbytes[i] != -1) { |
970 | tb->snum[i] - 1, tb->sbytes[i], tb->S_new[i]); | 940 | int old_key_comp, old_len, r_zeroes_number; |
941 | const char *r_body; | ||
942 | int version; | ||
971 | 943 | ||
972 | /* Insert new item into S_new[i] */ | 944 | /* Move snum[i]-1 items from S[0] to S_new[i] */ |
973 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); | 945 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i] - 1, -1, |
974 | leaf_insert_into_buf(&bi, tb->item_pos - n + tb->snum[i] - 1, | 946 | tb->S_new[i]); |
975 | ih, body, tb->zeroes_num); | ||
976 | 947 | ||
977 | tb->zeroes_num = tb->insert_size[0] = 0; | 948 | /* Remember key component and item length */ |
978 | } | 949 | version = ih_version(ih); |
979 | } | 950 | old_key_comp = le_ih_k_offset(ih); |
951 | old_len = ih_item_len(ih); | ||
952 | |||
953 | /* | ||
954 | * Calculate key component and item length to insert | ||
955 | * into S_new[i] | ||
956 | */ | ||
957 | shift = 0; | ||
958 | if (is_indirect_le_ih(ih)) | ||
959 | shift = tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT; | ||
960 | set_le_ih_k_offset(ih, | ||
961 | le_ih_k_offset(ih) + | ||
962 | ((old_len - tb->sbytes[i]) << shift)); | ||
980 | 963 | ||
981 | else { /* new item or it part don't falls into S_new[i] */ | 964 | put_ih_item_len(ih, tb->sbytes[i]); |
982 | 965 | ||
983 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | 966 | /* Insert part of the item into S_new[i] before 0-th item */ |
984 | tb->snum[i], tb->sbytes[i], tb->S_new[i]); | 967 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); |
985 | } | 968 | |
969 | if ((old_len - tb->sbytes[i]) > tb->zeroes_num) { | ||
970 | r_zeroes_number = 0; | ||
971 | r_body = body + (old_len - tb->sbytes[i]) - | ||
972 | tb->zeroes_num; | ||
973 | } else { | ||
974 | r_body = body; | ||
975 | r_zeroes_number = tb->zeroes_num - (old_len - | ||
976 | tb->sbytes[i]); | ||
977 | tb->zeroes_num -= r_zeroes_number; | ||
978 | } | ||
979 | |||
980 | leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeroes_number); | ||
981 | |||
982 | /* | ||
983 | * Calculate key component and item length to | ||
984 | * insert into S[i] | ||
985 | */ | ||
986 | set_le_ih_k_offset(ih, old_key_comp); | ||
987 | put_ih_item_len(ih, old_len - tb->sbytes[i]); | ||
988 | tb->insert_size[0] -= tb->sbytes[i]; | ||
989 | } else { | ||
990 | /* whole new item falls into S_new[i] */ | ||
991 | |||
992 | /* | ||
993 | * Shift snum[0] - 1 items to S_new[i] | ||
994 | * (sbytes[i] of split item) | ||
995 | */ | ||
996 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | ||
997 | tb->snum[i] - 1, tb->sbytes[i], tb->S_new[i]); | ||
998 | |||
999 | /* Insert new item into S_new[i] */ | ||
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 | } | ||
986 | } | 1006 | } |
987 | 1007 | ||
988 | static void balance_leaf_new_nodes_paste(struct tree_balance *tb, | 1008 | /* we append to directory item */ |
1009 | static void balance_leaf_new_nodes_paste_dirent(struct tree_balance *tb, | ||
989 | struct item_head *ih, | 1010 | struct item_head *ih, |
990 | const char *body, | 1011 | const char *body, |
991 | struct item_head *insert_key, | 1012 | struct item_head *insert_key, |
@@ -993,153 +1014,206 @@ static void balance_leaf_new_nodes_paste(struct tree_balance *tb, | |||
993 | int i) | 1014 | int i) |
994 | { | 1015 | { |
995 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 1016 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); |
996 | int n = B_NR_ITEMS(tbS0); | 1017 | struct item_head *aux_ih = item_head(tbS0, tb->item_pos); |
1018 | int entry_count = ih_entry_count(aux_ih); | ||
997 | struct buffer_info bi; | 1019 | struct buffer_info bi; |
998 | if (n - tb->snum[i] <= tb->item_pos) { /* pasted item or part if it falls to S_new[i] */ | ||
999 | if (tb->item_pos == n - tb->snum[i] && tb->sbytes[i] != -1) { /* we must shift part of the appended item */ | ||
1000 | struct item_head *aux_ih; | ||
1001 | |||
1002 | RFALSE(ih, "PAP-12210: ih must be 0"); | ||
1003 | |||
1004 | aux_ih = item_head(tbS0, tb->item_pos); | ||
1005 | if (is_direntry_le_ih(aux_ih)) { | ||
1006 | /* we append to directory item */ | ||
1007 | |||
1008 | int entry_count; | ||
1009 | |||
1010 | entry_count = ih_entry_count(aux_ih); | ||
1011 | |||
1012 | if (entry_count - tb->sbytes[i] < tb->pos_in_item && tb->pos_in_item <= entry_count) { | ||
1013 | /* new directory entry falls into S_new[i] */ | ||
1014 | |||
1015 | RFALSE(!tb->insert_size[0], "PAP-12215: insert_size is already 0"); | ||
1016 | RFALSE(tb->sbytes[i] - 1 >= entry_count, | ||
1017 | "PAP-12220: there are no so much entries (%d), only %d", | ||
1018 | tb->sbytes[i] - 1, entry_count); | ||
1019 | |||
1020 | /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */ | ||
1021 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i] - 1, tb->S_new[i]); | ||
1022 | /* Paste given directory entry to directory item */ | ||
1023 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); | ||
1024 | leaf_paste_in_buffer(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1, | ||
1025 | tb->insert_size[0], body, tb->zeroes_num); | ||
1026 | /* paste new directory entry */ | ||
1027 | leaf_paste_entries(&bi, 0, tb->pos_in_item - entry_count + tb->sbytes[i] - 1, 1, | ||
1028 | (struct reiserfs_de_head *) body, | ||
1029 | body + DEH_SIZE, tb->insert_size[0]); | ||
1030 | tb->insert_size[0] = 0; | ||
1031 | tb->pos_in_item++; | ||
1032 | } else { /* new directory entry doesn't fall into S_new[i] */ | ||
1033 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], tb->sbytes[i], tb->S_new[i]); | ||
1034 | } | ||
1035 | } else { /* regular object */ | ||
1036 | |||
1037 | int n_shift, n_rem, r_zeroes_number; | ||
1038 | const char *r_body; | ||
1039 | |||
1040 | RFALSE(tb->pos_in_item != ih_item_len(item_head(tbS0, tb->item_pos)) || tb->insert_size[0] <= 0, | ||
1041 | "PAP-12225: item too short or insert_size <= 0"); | ||
1042 | |||
1043 | /* Calculate number of bytes which must be shifted from appended item */ | ||
1044 | n_shift = tb->sbytes[i] - tb->insert_size[0]; | ||
1045 | if (n_shift < 0) | ||
1046 | n_shift = 0; | ||
1047 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], n_shift, tb->S_new[i]); | ||
1048 | |||
1049 | /* Calculate number of bytes which must remain in body after append to S_new[i] */ | ||
1050 | n_rem = tb->insert_size[0] - tb->sbytes[i]; | ||
1051 | if (n_rem < 0) | ||
1052 | n_rem = 0; | ||
1053 | /* Append part of body into S_new[0] */ | ||
1054 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); | ||
1055 | if (n_rem > tb->zeroes_num) { | ||
1056 | r_zeroes_number = 0; | ||
1057 | r_body = body + n_rem - tb->zeroes_num; | ||
1058 | } else { | ||
1059 | r_body = body; | ||
1060 | r_zeroes_number = tb->zeroes_num - n_rem; | ||
1061 | tb->zeroes_num -= r_zeroes_number; | ||
1062 | } | ||
1063 | 1020 | ||
1064 | leaf_paste_in_buffer(&bi, 0, n_shift, | 1021 | if (entry_count - tb->sbytes[i] < tb->pos_in_item && |
1065 | tb->insert_size[0] - n_rem, | 1022 | tb->pos_in_item <= entry_count) { |
1066 | r_body, r_zeroes_number); | 1023 | /* new directory entry falls into S_new[i] */ |
1067 | { | ||
1068 | struct item_head *tmp; | ||
1069 | |||
1070 | tmp = item_head(tb->S_new[i], 0); | ||
1071 | if (is_indirect_le_ih | ||
1072 | (tmp)) { | ||
1073 | set_ih_free_space(tmp, 0); | ||
1074 | set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT))); | ||
1075 | } else { | ||
1076 | set_le_ih_k_offset(tmp, le_ih_k_offset(tmp) + n_rem); | ||
1077 | } | ||
1078 | } | ||
1079 | 1024 | ||
1080 | tb->insert_size[0] = n_rem; | 1025 | RFALSE(!tb->insert_size[0], |
1081 | if (!n_rem) | 1026 | "PAP-12215: insert_size is already 0"); |
1082 | tb->pos_in_item++; | 1027 | RFALSE(tb->sbytes[i] - 1 >= entry_count, |
1083 | } | 1028 | "PAP-12220: there are no so much entries (%d), only %d", |
1084 | } else | 1029 | tb->sbytes[i] - 1, entry_count); |
1085 | /* item falls wholly into S_new[i] */ | 1030 | |
1086 | { | 1031 | /* |
1087 | int leaf_mi; | 1032 | * Shift snum[i]-1 items in whole. |
1088 | struct item_head *pasted; | 1033 | * Shift sbytes[i] directory entries |
1034 | * from directory item number snum[i] | ||
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 | * Paste given directory entry to | ||
1041 | * directory item | ||
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 | /* paste new directory entry */ | ||
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 | /* new directory entry doesn't fall into S_new[i] */ | ||
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 *ih, | ||
1066 | const char *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 | /* regular object */ | ||
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 | * Calculate number of bytes which must be shifted from appended item | ||
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 | * Calculate number of bytes which must remain in body after | ||
1104 | * append to S_new[i] | ||
1105 | */ | ||
1106 | n_rem = tb->insert_size[0] - tb->sbytes[i]; | ||
1107 | if (n_rem < 0) | ||
1108 | n_rem = 0; | ||
1109 | |||
1110 | /* Append part of body into S_new[0] */ | ||
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 *ih, | ||
1139 | const char *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; | ||
1089 | 1150 | ||
1090 | #ifdef CONFIG_REISERFS_CHECK | 1151 | #ifdef CONFIG_REISERFS_CHECK |
1091 | struct item_head *ih_check = item_head(tbS0, tb->item_pos); | 1152 | struct item_head *ih_check = item_head(tbS0, tb->item_pos); |
1092 | |||
1093 | if (!is_direntry_le_ih(ih_check) | ||
1094 | && (tb->pos_in_item != ih_item_len(ih_check) | ||
1095 | || tb->insert_size[0] <= 0)) | ||
1096 | reiserfs_panic(tb->tb_sb, | ||
1097 | "PAP-12235", | ||
1098 | "pos_in_item " | ||
1099 | "must be equal " | ||
1100 | "to ih_item_len"); | ||
1101 | #endif /* CONFIG_REISERFS_CHECK */ | ||
1102 | 1153 | ||
1103 | leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW, | 1154 | if (!is_direntry_le_ih(ih_check) && |
1104 | tb, tb->snum[i], | 1155 | (tb->pos_in_item != ih_item_len(ih_check) || |
1105 | tb->sbytes[i], | 1156 | tb->insert_size[0] <= 0)) |
1106 | tb->S_new[i]); | 1157 | reiserfs_panic(tb->tb_sb, |
1107 | 1158 | "PAP-12235", | |
1108 | RFALSE(leaf_mi, | 1159 | "pos_in_item must be equal to ih_item_len"); |
1109 | "PAP-12240: unexpected value returned by leaf_move_items (%d)", | 1160 | #endif |
1110 | leaf_mi); | ||
1111 | |||
1112 | /* paste into item */ | ||
1113 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); | ||
1114 | leaf_paste_in_buffer(&bi, | ||
1115 | tb->item_pos - n + tb->snum[i], | ||
1116 | tb->pos_in_item, | ||
1117 | tb->insert_size[0], | ||
1118 | body, tb->zeroes_num); | ||
1119 | |||
1120 | pasted = item_head(tb->S_new[i], tb->item_pos - n + tb->snum[i]); | ||
1121 | if (is_direntry_le_ih(pasted)) { | ||
1122 | leaf_paste_entries(&bi, | ||
1123 | tb->item_pos - n + tb->snum[i], | ||
1124 | tb->pos_in_item, 1, | ||
1125 | (struct reiserfs_de_head *)body, | ||
1126 | body + DEH_SIZE, | ||
1127 | tb->insert_size[0]); | ||
1128 | } | ||
1129 | 1161 | ||
1130 | /* if we paste to indirect item update ih_free_space */ | 1162 | leaf_mi = leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, tb->snum[i], |
1131 | if (is_indirect_le_ih(pasted)) | 1163 | tb->sbytes[i], tb->S_new[i]); |
1132 | set_ih_free_space(pasted, 0); | ||
1133 | tb->zeroes_num = tb->insert_size[0] = 0; | ||
1134 | } | ||
1135 | } | ||
1136 | 1164 | ||
1137 | else { /* pasted item doesn't fall into S_new[i] */ | 1165 | RFALSE(leaf_mi, |
1166 | "PAP-12240: unexpected value returned by leaf_move_items (%d)", | ||
1167 | leaf_mi); | ||
1138 | 1168 | ||
1139 | leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, | 1169 | /* paste into item */ |
1140 | tb->snum[i], tb->sbytes[i], tb->S_new[i]); | 1170 | buffer_info_init_bh(tb, &bi, tb->S_new[i]); |
1141 | } | 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 | /* if we paste to indirect item update ih_free_space */ | ||
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 *ih, | ||
1192 | const char *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 | /* pasted item doesn't fall into S_new[i] */ | ||
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 | /* pasted item or part if it falls to S_new[i] */ | ||
1142 | 1208 | ||
1209 | if (tb->item_pos == n - tb->snum[i] && tb->sbytes[i] != -1) | ||
1210 | /* we must shift part of the appended item */ | ||
1211 | balance_leaf_new_nodes_paste_shift(tb, ih, body, insert_key, | ||
1212 | insert_ptr, i); | ||
1213 | else | ||
1214 | /* item falls wholly into S_new[i] */ | ||
1215 | balance_leaf_new_nodes_paste_whole(tb, ih, body, insert_key, | ||
1216 | insert_ptr, i); | ||
1143 | } | 1217 | } |
1144 | 1218 | ||
1145 | /* Fill new nodes that appear in place of S[0] */ | 1219 | /* Fill new nodes that appear in place of S[0] */ |
@@ -1152,6 +1226,7 @@ static void balance_leaf_new_nodes(struct tree_balance *tb, | |||
1152 | { | 1226 | { |
1153 | int i; | 1227 | int i; |
1154 | for (i = tb->blknum[0] - 2; i >= 0; i--) { | 1228 | for (i = tb->blknum[0] - 2; i >= 0; i--) { |
1229 | BUG_ON(flag != M_INSERT && flag != M_PASTE); | ||
1155 | 1230 | ||
1156 | RFALSE(!tb->snum[i], | 1231 | RFALSE(!tb->snum[i], |
1157 | "PAP-12200: snum[%d] == %d. Must be > 0", i, | 1232 | "PAP-12200: snum[%d] == %d. Must be > 0", i, |
@@ -1164,21 +1239,12 @@ static void balance_leaf_new_nodes(struct tree_balance *tb, | |||
1164 | /* initialized block type and tree level */ | 1239 | /* initialized block type and tree level */ |
1165 | set_blkh_level(B_BLK_HEAD(tb->S_new[i]), DISK_LEAF_NODE_LEVEL); | 1240 | set_blkh_level(B_BLK_HEAD(tb->S_new[i]), DISK_LEAF_NODE_LEVEL); |
1166 | 1241 | ||
1167 | switch (flag) { | 1242 | if (flag == M_INSERT) |
1168 | case M_INSERT: /* insert item */ | ||
1169 | balance_leaf_new_nodes_insert(tb, ih, body, insert_key, | 1243 | balance_leaf_new_nodes_insert(tb, ih, body, insert_key, |
1170 | insert_ptr, i); | 1244 | insert_ptr, i); |
1171 | break; | 1245 | else /* M_PASTE */ |
1172 | |||
1173 | case M_PASTE: /* append item */ | ||
1174 | balance_leaf_new_nodes_paste(tb, ih, body, insert_key, | 1246 | balance_leaf_new_nodes_paste(tb, ih, body, insert_key, |
1175 | insert_ptr, i); | 1247 | insert_ptr, i); |
1176 | break; | ||
1177 | default: /* cases d and t */ | ||
1178 | reiserfs_panic(tb->tb_sb, "PAP-12245", | ||
1179 | "blknum > 2: unexpected mode: %s(%d)", | ||
1180 | (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag); | ||
1181 | } | ||
1182 | 1248 | ||
1183 | memcpy(insert_key + i, leaf_key(tb->S_new[i], 0), KEY_SIZE); | 1249 | memcpy(insert_key + i, leaf_key(tb->S_new[i], 0), KEY_SIZE); |
1184 | insert_ptr[i] = tb->S_new[i]; | 1250 | insert_ptr[i] = tb->S_new[i]; |