diff options
| -rw-r--r-- | fs/reiserfs/do_balan.c | 165 |
1 files changed, 73 insertions, 92 deletions
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index cffcb67a5436..959b7b578f9d 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
| @@ -72,19 +72,6 @@ inline void do_balance_mark_leaf_dirty(struct tree_balance *tb, | |||
| 72 | * if snum1 is larger than 0 we put items into the new node s1 | 72 | * if snum1 is larger than 0 we put items into the new node s1 |
| 73 | * if snum2 is larger than 0 we put items into the new node s2 | 73 | * if snum2 is larger than 0 we put items into the new node s2 |
| 74 | * Note that all *num* count new items being created. | 74 | * Note that all *num* count new items being created. |
| 75 | * | ||
| 76 | * It would be easier to read balance_leaf() if each of these summary | ||
| 77 | * lines was a separate procedure rather than being inlined. I think | ||
| 78 | * that there are many passages here and in balance_leaf_when_delete() in | ||
| 79 | * which two calls to one procedure can replace two passages, and it | ||
| 80 | * might save cache space and improve software maintenance costs to do so. | ||
| 81 | * | ||
| 82 | * Vladimir made the perceptive comment that we should offload most of | ||
| 83 | * the decision making in this function into fix_nodes/check_balance, and | ||
| 84 | * then create some sort of structure in tb that says what actions should | ||
| 85 | * be performed by do_balance. | ||
| 86 | * | ||
| 87 | * -Hans | ||
| 88 | */ | 75 | */ |
| 89 | 76 | ||
| 90 | /* | 77 | /* |
| @@ -1263,18 +1250,49 @@ static void balance_leaf_finish_node_insert(struct tree_balance *tb, | |||
| 1263 | { | 1250 | { |
| 1264 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 1251 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); |
| 1265 | struct buffer_info bi; | 1252 | struct buffer_info bi; |
| 1266 | buffer_info_init_tbS0(tb, &bi); | 1253 | buffer_info_init_tbS0(tb, &bi); |
| 1267 | leaf_insert_into_buf(&bi, tb->item_pos, ih, | 1254 | leaf_insert_into_buf(&bi, tb->item_pos, ih, body, tb->zeroes_num); |
| 1268 | body, tb->zeroes_num); | 1255 | |
| 1269 | 1256 | /* If we insert the first key change the delimiting key */ | |
| 1270 | /* | 1257 | if (tb->item_pos == 0) { |
| 1271 | * If we insert the first key | 1258 | if (tb->CFL[0]) /* can be 0 in reiserfsck */ |
| 1272 | * change the delimiting key | 1259 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); |
| 1273 | */ | 1260 | |
| 1274 | if (tb->item_pos == 0) { | 1261 | } |
| 1275 | if (tb->CFL[0]) /* can be 0 in reiserfsck */ | 1262 | } |
| 1276 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); | 1263 | |
| 1277 | } | 1264 | static void balance_leaf_finish_node_paste_dirent(struct tree_balance *tb, |
| 1265 | struct item_head *ih, | ||
| 1266 | const char *body) | ||
| 1267 | { | ||
| 1268 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | ||
| 1269 | struct item_head *pasted = item_head(tbS0, tb->item_pos); | ||
| 1270 | struct buffer_info bi; | ||
| 1271 | |||
| 1272 | if (tb->pos_in_item >= 0 && tb->pos_in_item <= ih_entry_count(pasted)) { | ||
| 1273 | RFALSE(!tb->insert_size[0], | ||
| 1274 | "PAP-12260: insert_size is 0 already"); | ||
| 1275 | |||
| 1276 | /* prepare space */ | ||
| 1277 | buffer_info_init_tbS0(tb, &bi); | ||
| 1278 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1279 | tb->insert_size[0], body, tb->zeroes_num); | ||
| 1280 | |||
| 1281 | /* paste entry */ | ||
| 1282 | leaf_paste_entries(&bi, tb->item_pos, tb->pos_in_item, 1, | ||
| 1283 | (struct reiserfs_de_head *)body, | ||
| 1284 | body + DEH_SIZE, tb->insert_size[0]); | ||
| 1285 | |||
| 1286 | if (!tb->item_pos && !tb->pos_in_item) { | ||
| 1287 | RFALSE(!tb->CFL[0] || !tb->L[0], | ||
| 1288 | "PAP-12270: CFL[0]/L[0] must be specified"); | ||
| 1289 | if (tb->CFL[0]) | ||
| 1290 | replace_key(tb, tb->CFL[0], tb->lkey[0], | ||
| 1291 | tbS0, 0); | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | tb->insert_size[0] = 0; | ||
| 1295 | } | ||
| 1278 | } | 1296 | } |
| 1279 | 1297 | ||
| 1280 | static void balance_leaf_finish_node_paste(struct tree_balance *tb, | 1298 | static void balance_leaf_finish_node_paste(struct tree_balance *tb, |
| @@ -1283,74 +1301,37 @@ static void balance_leaf_finish_node_paste(struct tree_balance *tb, | |||
| 1283 | { | 1301 | { |
| 1284 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); | 1302 | struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); |
| 1285 | struct buffer_info bi; | 1303 | struct buffer_info bi; |
| 1286 | struct item_head *pasted; | 1304 | struct item_head *pasted = item_head(tbS0, tb->item_pos); |
| 1287 | |||
| 1288 | pasted = item_head(tbS0, tb->item_pos); | ||
| 1289 | /* when directory, may be new entry already pasted */ | ||
| 1290 | if (is_direntry_le_ih(pasted)) { | ||
| 1291 | if (tb->pos_in_item >= 0 && tb->pos_in_item <= ih_entry_count(pasted)) { | ||
| 1292 | |||
| 1293 | RFALSE(!tb->insert_size[0], | ||
| 1294 | "PAP-12260: insert_size is 0 already"); | ||
| 1295 | |||
| 1296 | /* prepare space */ | ||
| 1297 | buffer_info_init_tbS0(tb, &bi); | ||
| 1298 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1299 | tb->insert_size[0], body, | ||
| 1300 | tb->zeroes_num); | ||
| 1301 | |||
| 1302 | /* paste entry */ | ||
| 1303 | leaf_paste_entries(&bi, tb->item_pos, tb->pos_in_item, 1, | ||
| 1304 | (struct reiserfs_de_head *)body, | ||
| 1305 | body + DEH_SIZE, | ||
| 1306 | tb->insert_size[0]); | ||
| 1307 | if (!tb->item_pos && !tb->pos_in_item) { | ||
| 1308 | RFALSE(!tb->CFL[0] || !tb->L[0], | ||
| 1309 | "PAP-12270: CFL[0]/L[0] must be specified"); | ||
| 1310 | if (tb->CFL[0]) | ||
| 1311 | replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0); | ||
| 1312 | } | ||
| 1313 | tb->insert_size[0] = 0; | ||
| 1314 | } | ||
| 1315 | } else { /* regular object */ | ||
| 1316 | if (tb->pos_in_item == ih_item_len(pasted)) { | ||
| 1317 | |||
| 1318 | RFALSE(tb->insert_size[0] <= 0, | ||
| 1319 | "PAP-12275: insert size must not be %d", | ||
| 1320 | tb->insert_size[0]); | ||
| 1321 | buffer_info_init_tbS0(tb, &bi); | ||
| 1322 | leaf_paste_in_buffer(&bi, tb->item_pos, tb->pos_in_item, | ||
| 1323 | tb->insert_size[0], body, tb->zeroes_num); | ||
| 1324 | |||
| 1325 | if (is_indirect_le_ih(pasted)) { | ||
| 1326 | #if 0 | ||
| 1327 | RFALSE(tb-> | ||
| 1328 | insert_size[0] != | ||
| 1329 | UNFM_P_SIZE, | ||
| 1330 | "PAP-12280: insert_size for indirect item must be %d, not %d", | ||
| 1331 | UNFM_P_SIZE, | ||
| 1332 | tb-> | ||
| 1333 | insert_size[0]); | ||
| 1334 | #endif | ||
| 1335 | set_ih_free_space(pasted, 0); | ||
| 1336 | } | ||
| 1337 | tb->insert_size[0] = 0; | ||
| 1338 | } | ||
| 1339 | #ifdef CONFIG_REISERFS_CHECK | ||
| 1340 | else { | ||
| 1341 | if (tb->insert_size[0]) { | ||
| 1342 | print_cur_tb("12285"); | ||
| 1343 | reiserfs_panic(tb->tb_sb, | ||
| 1344 | "PAP-12285", | ||
| 1345 | "insert_size " | ||
| 1346 | "must be 0 " | ||
| 1347 | "(%d)", | ||
| 1348 | tb->insert_size[0]); | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | #endif /* CONFIG_REISERFS_CHECK */ | ||
| 1352 | 1305 | ||
| 1353 | } | 1306 | /* when directory, may be new entry already pasted */ |
| 1307 | if (is_direntry_le_ih(pasted)) { | ||
| 1308 | balance_leaf_finish_node_paste_dirent(tb, ih, body); | ||
| 1309 | return; | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | /* regular object */ | ||
| 1313 | |||
| 1314 | if (tb->pos_in_item == ih_item_len(pasted)) { | ||
| 1315 | RFALSE(tb->insert_size[0] <= 0, | ||
| 1316 | "PAP-12275: insert size must not be %d", | ||
| 1317 | tb->insert_size[0]); | ||
| 1318 | buffer_info_init_tbS0(tb, &bi); | ||
| 1319 | leaf_paste_in_buffer(&bi, tb->item_pos, | ||
| 1320 | tb->pos_in_item, tb->insert_size[0], body, | ||
| 1321 | tb->zeroes_num); | ||
| 1322 | |||
| 1323 | if (is_indirect_le_ih(pasted)) | ||
| 1324 | set_ih_free_space(pasted, 0); | ||
| 1325 | |||
| 1326 | tb->insert_size[0] = 0; | ||
| 1327 | } | ||
| 1328 | #ifdef CONFIG_REISERFS_CHECK | ||
| 1329 | else if (tb->insert_size[0]) { | ||
| 1330 | print_cur_tb("12285"); | ||
| 1331 | reiserfs_panic(tb->tb_sb, "PAP-12285", | ||
| 1332 | "insert_size must be 0 (%d)", tb->insert_size[0]); | ||
| 1333 | } | ||
| 1334 | #endif | ||
| 1354 | } | 1335 | } |
| 1355 | 1336 | ||
| 1356 | /* | 1337 | /* |
