Commit d40990537c9ea85dfe75dbe0ffba5e1002dfdf3f
1 parent
fe744fdb74
Exists in
master
and in
4 other branches
nilfs2: fix missing block address termination in btree node shrinking
nilfs_btree_delete function does not terminate part of virtual block addresses when shrinking the last remaining child node into the root node. The missing address termination causes that dead btree node blocks persist and chip away free disk space. This fixes the leak bug on the btree node deletion. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Showing 1 changed file with 14 additions and 7 deletions Side-by-side Diff
fs/nilfs2/btree.c
... | ... | @@ -1346,6 +1346,11 @@ |
1346 | 1346 | path[level].bp_bh = NULL; |
1347 | 1347 | } |
1348 | 1348 | |
1349 | +static void nilfs_btree_nop(struct nilfs_bmap *btree, | |
1350 | + struct nilfs_btree_path *path, | |
1351 | + int level, __u64 *keyp, __u64 *ptrp) | |
1352 | +{ | |
1353 | +} | |
1349 | 1354 | |
1350 | 1355 | static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, |
1351 | 1356 | struct nilfs_btree_path *path, |
1352 | 1357 | |
1353 | 1358 | |
1354 | 1359 | |
... | ... | @@ -1439,16 +1444,22 @@ |
1439 | 1444 | NILFS_BTREE_ROOT_NCHILDREN_MAX) { |
1440 | 1445 | path[level].bp_op = nilfs_btree_shrink; |
1441 | 1446 | stats->bs_nblocks += 2; |
1447 | + level++; | |
1448 | + path[level].bp_op = nilfs_btree_nop; | |
1449 | + goto shrink_root_child; | |
1442 | 1450 | } else { |
1443 | 1451 | path[level].bp_op = nilfs_btree_do_delete; |
1444 | 1452 | stats->bs_nblocks++; |
1453 | + goto out; | |
1445 | 1454 | } |
1446 | - | |
1447 | - goto out; | |
1448 | - | |
1449 | 1455 | } |
1450 | 1456 | } |
1451 | 1457 | |
1458 | + /* child of the root node is deleted */ | |
1459 | + path[level].bp_op = nilfs_btree_do_delete; | |
1460 | + stats->bs_nblocks++; | |
1461 | + | |
1462 | +shrink_root_child: | |
1452 | 1463 | node = nilfs_btree_get_root(btree); |
1453 | 1464 | path[level].bp_oldreq.bpr_ptr = |
1454 | 1465 | nilfs_btree_node_get_ptr(node, dindex, |
... | ... | @@ -1457,10 +1468,6 @@ |
1457 | 1468 | ret = nilfs_bmap_prepare_end_ptr(btree, &path[level].bp_oldreq, dat); |
1458 | 1469 | if (ret < 0) |
1459 | 1470 | goto err_out_child_node; |
1460 | - | |
1461 | - /* child of the root node is deleted */ | |
1462 | - path[level].bp_op = nilfs_btree_do_delete; | |
1463 | - stats->bs_nblocks++; | |
1464 | 1471 | |
1465 | 1472 | /* success */ |
1466 | 1473 | out: |