]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: handle fragmented multiblock dir2 in process_leaf_node_dir2()
authorEric Sandeen <sandeen@redhat.com>
Tue, 5 Jun 2012 18:25:57 +0000 (13:25 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Tue, 5 Jun 2012 18:25:57 +0000 (13:25 -0500)
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 <sandeen@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
repair/dir2.c

index f9562d79f8e7dba37c9e87360a821a94b248c1e8..7a614a8d6ec2b07085c3de622bda99b445b4031e 100644 (file)
@@ -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"),