diff options
| -rw-r--r-- | fs/reiserfs/do_balan.c | 150 |
1 files changed, 79 insertions, 71 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 1c4b45993c79..18adf948aa80 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
| @@ -982,6 +982,82 @@ static void balance_leaf_finish_node_insert(struct tree_balance *tb, | |||
| 982 | } | 982 | } |
| 983 | } | 983 | } |
| 984 | 984 | ||
| 985 | static void balance_leaf_finish_node_paste(struct tree_balance *tb, | ||
| 986 | struct item_head *ih, | ||
| 987 | const char *body) | ||
| 988 | { | ||
| 989 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | ||
| 990 | struct buffer_info bi; | ||
| 991 | struct item_head *pasted; | ||
| 992 | |||
| 993 | pasted = item_head(tbS0, tb->item_pos); | ||
| 994 | /* when directory, may be new entry already pasted */ | ||
| 995 | if (is_direntry_le_ih(pasted)) { | ||
| 996 | if (tb->pos_in_item >= 0 && tb->pos_in_item <= ih_entry_count(pasted)) { | ||
| 997 | |||
| 998 | RFALSE(!tb->insert_size[0], | ||
| 999 | "PAP-12260: insert_size is 0 already"); | ||
| 1000 | |||
| 1001 | /* prepare space */ | ||
| 1002 | buffer_info_init_tbS0(tb, &bi); | ||
| 1003 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1004 | tb->insert_size[0], body, | ||
| 1005 | tb->zeroes_num); | ||
| 1006 | |||
| 1007 | /* paste entry */ | ||
| 1008 | leaf_paste_entries(&bi, tb->item_pos, tb->pos_in_item, 1, | ||
| 1009 | (struct reiserfs_de_head *)body, | ||
| 1010 | body + DEH_SIZE, | ||
| 1011 | tb->insert_size[0]); | ||
| 1012 | if (!tb->item_pos && !tb->pos_in_item) { | ||
| 1013 | RFALSE(!tb->CFL[0] || !tb->L[0], | ||
| 1014 | "PAP-12270: CFL[0]/L[0] must be specified"); | ||
| 1015 | if (tb->CFL[0]) | ||
| 1016 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); | ||
| 1017 | } | ||
| 1018 | tb->insert_size[0] = 0; | ||
| 1019 | } | ||
| 1020 | } else { /* regular object */ | ||
| 1021 | if (tb->pos_in_item == ih_item_len(pasted)) { | ||
| 1022 | |||
| 1023 | RFALSE(tb->insert_size[0] <= 0, | ||
| 1024 | "PAP-12275: insert size must not be %d", | ||
| 1025 | tb->insert_size[0]); | ||
| 1026 | buffer_info_init_tbS0(tb, &bi); | ||
| 1027 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1028 | tb->insert_size[0], body, tb->zeroes_num); | ||
| 1029 | |||
| 1030 | if (is_indirect_le_ih(pasted)) { | ||
| 1031 | #if 0 | ||
| 1032 | RFALSE(tb-> | ||
| 1033 | insert_size[0] != | ||
| 1034 | UNFM_P_SIZE, | ||
| 1035 | "PAP-12280: insert_size for indirect item must be %d, not %d", | ||
| 1036 | UNFM_P_SIZE, | ||
| 1037 | tb-> | ||
| 1038 | insert_size[0]); | ||
| 1039 | #endif | ||
| 1040 | set_ih_free_space(pasted, 0); | ||
| 1041 | } | ||
| 1042 | tb->insert_size[0] = 0; | ||
| 1043 | } | ||
| 1044 | #ifdef CONFIG_REISERFS_CHECK | ||
| 1045 | else { | ||
| 1046 | if (tb->insert_size[0]) { | ||
| 1047 | print_cur_tb("12285"); | ||
| 1048 | reiserfs_panic(tb->tb_sb, | ||
| 1049 | "PAP-12285", | ||
| 1050 | "insert_size " | ||
| 1051 | "must be 0 " | ||
| 1052 | "(%d)", | ||
| 1053 | tb->insert_size[0]); | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | #endif /* CONFIG_REISERFS_CHECK */ | ||
| 1057 | |||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | |||
| 985 | /** | 1061 | /** |
| 986 | * balance_leaf - reiserfs tree balancing algorithm | 1062 | * balance_leaf - reiserfs tree balancing algorithm |
| 987 | * @tb: tree balance state | 1063 | * @tb: tree balance state |
| @@ -1002,7 +1078,6 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, | |||
| 1002 | struct buffer_head **insert_ptr) | 1078 | struct buffer_head **insert_ptr) |
| 1003 | { | 1079 | { |
| 1004 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 1080 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); |
| 1005 | struct buffer_info bi; | ||
| 1006 | int n, i; | 1081 | int n, i; |
| 1007 | 1082 | ||
| 1008 | PROC_INFO_INC(tb->tb_sb, balance_at[0]); | 1083 | PROC_INFO_INC(tb->tb_sb, balance_at[0]); |
| @@ -1159,76 +1234,9 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, | |||
| 1159 | balance_leaf_finish_node_insert(tb, ih, body); | 1234 | balance_leaf_finish_node_insert(tb, ih, body); |
| 1160 | break; | 1235 | break; |
| 1161 | 1236 | ||
| 1162 | case M_PASTE:{ /* append item in S[0] */ | 1237 | case M_PASTE: /* append item in S[0] */ |
| 1163 | struct item_head *pasted; | 1238 | balance_leaf_finish_node_paste(tb, ih, body); |
| 1164 | 1239 | break; | |
| 1165 | pasted = item_head(tbS0, tb->item_pos); | ||
| 1166 | /* when directory, may be new entry already pasted */ | ||
| 1167 | if (is_direntry_le_ih(pasted)) { | ||
| 1168 | if (tb->pos_in_item >= 0 && tb->pos_in_item <= ih_entry_count(pasted)) { | ||
| 1169 | |||
| 1170 | RFALSE(!tb->insert_size[0], | ||
| 1171 | "PAP-12260: insert_size is 0 already"); | ||
| 1172 | |||
| 1173 | /* prepare space */ | ||
| 1174 | buffer_info_init_tbS0(tb, &bi); | ||
| 1175 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1176 | tb->insert_size[0], body, | ||
| 1177 | tb->zeroes_num); | ||
| 1178 | |||
| 1179 | /* paste entry */ | ||
| 1180 | leaf_paste_entries(&bi, tb->item_pos, tb->pos_in_item, 1, | ||
| 1181 | (struct reiserfs_de_head *)body, | ||
| 1182 | body + DEH_SIZE, | ||
| 1183 | tb->insert_size[0]); | ||
| 1184 | if (!tb->item_pos && !tb->pos_in_item) { | ||
| 1185 | RFALSE(!tb->CFL[0] || !tb->L[0], | ||
| 1186 | "PAP-12270: CFL[0]/L[0] must be specified"); | ||
| 1187 | if (tb->CFL[0]) | ||
| 1188 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); | ||
| 1189 | } | ||
| 1190 | tb->insert_size[0] = 0; | ||
| 1191 | } | ||
| 1192 | } else { /* regular object */ | ||
| 1193 | if (tb->pos_in_item == ih_item_len(pasted)) { | ||
| 1194 | |||
| 1195 | RFALSE(tb->insert_size[0] <= 0, | ||
| 1196 | "PAP-12275: insert size must not be %d", | ||
| 1197 | tb->insert_size[0]); | ||
| 1198 | buffer_info_init_tbS0(tb, &bi); | ||
| 1199 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1200 | tb->insert_size[0], body, tb->zeroes_num); | ||
| 1201 | |||
| 1202 | if (is_indirect_le_ih(pasted)) { | ||
| 1203 | #if 0 | ||
| 1204 | RFALSE(tb-> | ||
| 1205 | insert_size[0] != | ||
| 1206 | UNFM_P_SIZE, | ||
| 1207 | "PAP-12280: insert_size for indirect item must be %d, not %d", | ||
| 1208 | UNFM_P_SIZE, | ||
| 1209 | tb-> | ||
| 1210 | insert_size[0]); | ||
| 1211 | #endif | ||
| 1212 | set_ih_free_space(pasted, 0); | ||
| 1213 | } | ||
| 1214 | tb->insert_size[0] = 0; | ||
| 1215 | } | ||
| 1216 | #ifdef CONFIG_REISERFS_CHECK | ||
| 1217 | else { | ||
| 1218 | if (tb->insert_size[0]) { | ||
| 1219 | print_cur_tb("12285"); | ||
| 1220 | reiserfs_panic(tb->tb_sb, | ||
| 1221 | "PAP-12285", | ||
| 1222 | "insert_size " | ||
| 1223 | "must be 0 " | ||
| 1224 | "(%d)", | ||
| 1225 | tb->insert_size[0]); | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | #endif /* CONFIG_REISERFS_CHECK */ | ||
| 1229 | |||
| 1230 | } | ||
| 1231 | } /* case M_PASTE: */ | ||
| 1232 | } | 1240 | } |
| 1233 | } | 1241 | } |
| 1234 | #ifdef CONFIG_REISERFS_CHECK | 1242 | #ifdef CONFIG_REISERFS_CHECK |
