aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/btree.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2011-05-25 10:00:27 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2011-06-11 02:51:15 -0400
commitd40990537c9ea85dfe75dbe0ffba5e1002dfdf3f (patch)
tree3db27e3e911428502942c95b9f8f52e2a041bd54 /fs/nilfs2/btree.c
parentfe744fdb74f2417d8571faefa45f72b0ead25f89 (diff)
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>
Diffstat (limited to 'fs/nilfs2/btree.c')
-rw-r--r--fs/nilfs2/btree.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index fd4f05b91942..b2e3ff347620 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -1346,6 +1346,11 @@ static void nilfs_btree_shrink(struct nilfs_bmap *btree,
1346 path[level].bp_bh = NULL; 1346 path[level].bp_bh = NULL;
1347} 1347}
1348 1348
1349static 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
1350static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree, 1355static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree,
1351 struct nilfs_btree_path *path, 1356 struct nilfs_btree_path *path,
@@ -1439,16 +1444,22 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree,
1439 NILFS_BTREE_ROOT_NCHILDREN_MAX) { 1444 NILFS_BTREE_ROOT_NCHILDREN_MAX) {
1440 path[level].bp_op = nilfs_btree_shrink; 1445 path[level].bp_op = nilfs_btree_shrink;
1441 stats->bs_nblocks += 2; 1446 stats->bs_nblocks += 2;
1447 level++;
1448 path[level].bp_op = nilfs_btree_nop;
1449 goto shrink_root_child;
1442 } else { 1450 } else {
1443 path[level].bp_op = nilfs_btree_do_delete; 1451 path[level].bp_op = nilfs_btree_do_delete;
1444 stats->bs_nblocks++; 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
1462shrink_root_child:
1452 node = nilfs_btree_get_root(btree); 1463 node = nilfs_btree_get_root(btree);
1453 path[level].bp_oldreq.bpr_ptr = 1464 path[level].bp_oldreq.bpr_ptr =
1454 nilfs_btree_node_get_ptr(node, dindex, 1465 nilfs_btree_node_get_ptr(node, dindex,
@@ -1458,10 +1469,6 @@ static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree,
1458 if (ret < 0) 1469 if (ret < 0)
1459 goto err_out_child_node; 1470 goto err_out_child_node;
1460 1471
1461 /* child of the root node is deleted */
1462 path[level].bp_op = nilfs_btree_do_delete;
1463 stats->bs_nblocks++;
1464
1465 /* success */ 1472 /* success */
1466 out: 1473 out:
1467 *levelp = level; 1474 *levelp = level;