From: Eric Sandeen Date: Tue, 5 Jun 2012 18:25:57 +0000 (-0500) Subject: xfs_repair: handle fragmented multiblock dir2 in process_leaf_node_dir2() X-Git-Tag: v3.1.9-rc1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9fe1cc862159b50651baa68a6b60ae0819d4f871;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: handle fragmented multiblock dir2 in process_leaf_node_dir2() process_leaf_node_dir2() had the following loop: while ((dbno = blkmap_next_off(blkmap, ndbno, &t)) < mp->m_dirleafblk) { ... ndbno = dbno + mp->m_dirblkfsbs - 1; ... } which does not account for fragmented multiblock dir2. ndbno was blindly being advanced by m_dirblkfsbs, but then blkmap_next_off() would return the logical block of the next mapped extent in blkmap, which may be within the current (fragmented) dir2 multi-block, not the next multi-block, because the extent index t hadn't been advanced. Fix this by calling blkmap_next_off() until ndbno has advanced into the next multiblock dir2 block, thereby keeping the extent index t straight while properly advancing ndbno. Signed-off-by: Eric Sandeen Reviewed-by: Ben Myers --- diff --git a/repair/dir2.c b/repair/dir2.c index f9562d79f..7a614a8d6 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -2003,7 +2003,11 @@ process_leaf_node_dir2( ndbno = NULLDFILOFF; while ((dbno = blkmap_next_off(blkmap, ndbno, &t)) < mp->m_dirleafblk) { nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp, &lbmp); - ndbno = dbno + mp->m_dirblkfsbs - 1; + /* Advance through map to last dfs block in this dir block */ + ndbno = dbno; + while (ndbno < dbno + mp->m_dirblkfsbs - 1) { + ndbno = blkmap_next_off(blkmap, ndbno, &t); + } if (nex == 0) { do_warn( _("block %" PRIu64 " for directory inode %" PRIu64 " is missing\n"),