Whamcloud - gitweb
libext2fs: clean up generic handling of ext2fs_find_first_{set,zero}_*()
authorTheodore Ts'o <tytso@mit.edu>
Mon, 13 Jan 2014 00:45:43 +0000 (19:45 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 20 Jan 2014 00:19:17 +0000 (19:19 -0500)
Move the error checking into the the generic bitmap code, and add
support for bitmaps with cluster_bits set.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/blkmap64_ba.c
lib/ext2fs/gen_bitmap64.c

index 8eddde9..284236d 100644 (file)
@@ -328,12 +328,6 @@ static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
        const unsigned char *pos;
        unsigned long max_loop_count, i;
 
-       if (start < bitmap->start || end > bitmap->end || start > end)
-               return EINVAL;
-
-       if (bitmap->cluster_bits)
-               return EINVAL;
-
        /* scan bits until we hit a byte boundary */
        while ((bitpos & 0x7) != 0 && count > 0) {
                if (!ext2fs_test_bit64(bitpos, bp->bitarray)) {
index fcf63ad..9615f1e 100644 (file)
@@ -801,17 +801,14 @@ errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
                                              __u64 start, __u64 end, __u64 *out)
 {
        int b;
+       __u64 cstart, cend, cout;
+       errcode_t retval;
 
        if (!bitmap)
                return EINVAL;
 
-       if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
-               return bitmap->bitmap_ops->find_first_zero(bitmap, start,
-                                                          end, out);
-
        if (EXT2FS_IS_32_BITMAP(bitmap)) {
                blk_t blk = 0;
-               errcode_t retval;
 
                if (((start) & ~0xffffffffULL) ||
                    ((end) & ~0xffffffffULL)) {
@@ -829,23 +826,29 @@ errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
        if (!EXT2FS_IS_64_BITMAP(bitmap))
                return EINVAL;
 
-       start >>= bitmap->cluster_bits;
-       end >>= bitmap->cluster_bits;
+       cstart = start >> bitmap->cluster_bits;
+       cend = end >> bitmap->cluster_bits;
 
-       if (start < bitmap->start || end > bitmap->end || start > end) {
+       if (cstart < bitmap->start || cend > bitmap->end || start > end) {
                warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
                return EINVAL;
        }
 
-       while (start <= end) {
-               b = bitmap->bitmap_ops->test_bmap(bitmap, start);
-               if (!b) {
-                       *out = start << bitmap->cluster_bits;
-                       return 0;
-               }
-               start++;
+       if (bitmap->bitmap_ops->find_first_zero) {
+               retval = bitmap->bitmap_ops->find_first_zero(bitmap, cstart,
+                                                            cend, &cout);
+               if (retval)
+                       return retval;
+       found:
+               cout <<= bitmap->cluster_bits;
+               *out = (cout >= start) ? cout : start;
+               return 0;
        }
 
+       for (cout = cstart; cout <= cend; cout++)
+               if (!bitmap->bitmap_ops->test_bmap(bitmap, cout))
+                       goto found;
+
        return ENOENT;
 }
 
@@ -853,17 +856,14 @@ errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
                                             __u64 start, __u64 end, __u64 *out)
 {
        int b;
+       __u64 cstart, cend, cout;
+       errcode_t retval;
 
        if (!bitmap)
                return EINVAL;
 
-       if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_set)
-               return bitmap->bitmap_ops->find_first_set(bitmap, start,
-                                                         end, out);
-
        if (EXT2FS_IS_32_BITMAP(bitmap)) {
                blk_t blk = 0;
-               errcode_t retval;
 
                if (((start) & ~0xffffffffULL) ||
                    ((end) & ~0xffffffffULL)) {
@@ -881,22 +881,28 @@ errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
        if (!EXT2FS_IS_64_BITMAP(bitmap))
                return EINVAL;
 
-       start >>= bitmap->cluster_bits;
-       end >>= bitmap->cluster_bits;
+       cstart = start >> bitmap->cluster_bits;
+       cend = end >> bitmap->cluster_bits;
 
-       if (start < bitmap->start || end > bitmap->end || start > end) {
+       if (cstart < bitmap->start || cend > bitmap->end || start > end) {
                warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
                return EINVAL;
        }
 
-       while (start <= end) {
-               b = bitmap->bitmap_ops->test_bmap(bitmap, start);
-               if (b) {
-                       *out = start << bitmap->cluster_bits;
-                       return 0;
-               }
-               start++;
+       if (bitmap->bitmap_ops->find_first_set) {
+               retval = bitmap->bitmap_ops->find_first_set(bitmap, cstart,
+                                                           cend, &cout);
+               if (retval)
+                       return retval;
+       found:
+               cout <<= bitmap->cluster_bits;
+               *out = (cout >= start) ? cout : start;
+               return 0;
        }
 
+       for (cout = cstart; cout <= cend; cout++)
+               if (bitmap->bitmap_ops->test_bmap(bitmap, cout))
+                       goto found;
+
        return ENOENT;
 }