Whamcloud - gitweb
libext2fs: ext2fs_new_block2() should call alloc_block hook
authorDarrick J. Wong <darrick.wong@oracle.com>
Sun, 29 Mar 2015 03:58:20 +0000 (23:58 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 29 Mar 2015 03:58:20 +0000 (23:58 -0400)
If ext2fs_new_block2() is called without a specific block map, we
should call the alloc_block hook before checking fs->block_map.  This
helps us to avoid a bug in e2fsck where we need to allocate a block
but instead of consulting block_found_map, we use the FS bitmaps,
which (prior to pass 5) could be wrong.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
lib/ext2fs/alloc.c

index 319d23b..f3c134e 100644 (file)
@@ -3823,7 +3823,7 @@ static errcode_t e2fsck_get_alloc_block(ext2_filsys fs, blk64_t goal,
                                return retval;
                }
 
-               retval = ext2fs_new_block2(fs, goal, 0, &new_block);
+               retval = ext2fs_new_block2(fs, goal, fs->block_map, &new_block);
                if (retval)
                        return retval;
        }
index 62b36fe..9901ca5 100644 (file)
@@ -137,9 +137,23 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
 {
        errcode_t retval;
        blk64_t b = 0;
+       errcode_t (*gab)(ext2_filsys fs, blk64_t goal, blk64_t *ret);
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
+       if (!map && fs->get_alloc_block) {
+               /*
+                * In case there are clients out there whose get_alloc_block
+                * handlers call ext2fs_new_block2 with a NULL block map,
+                * temporarily swap out the function pointer so that we don't
+                * end up in an infinite loop.
+                */
+               gab = fs->get_alloc_block;
+               fs->get_alloc_block = NULL;
+               retval = gab(fs, goal, &b);
+               fs->get_alloc_block = gab;
+               goto allocated;
+       }
        if (!map)
                map = fs->block_map;
        if (!map)
@@ -153,6 +167,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
        if ((retval == ENOENT) && (goal != fs->super->s_first_data_block))
                retval = ext2fs_find_first_zero_block_bitmap2(map,
                        fs->super->s_first_data_block, goal - 1, &b);
+allocated:
        if (retval == ENOENT)
                return EXT2_ET_BLOCK_ALLOC_FAIL;
        if (retval)