return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
}
-
-
/*
- * This procedure tests to see if a particular block is on a badblocks
+ * This procedure finds a particular block is on a badblocks
* list.
*/
-int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
+int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
{
int low, high, mid;
if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
- return 0;
+ return -1;
if (bb->num == 0)
- return 0;
+ return -1;
low = 0;
high = bb->num-1;
if (blk == bb->list[low])
- return 1;
+ return low;
if (blk == bb->list[high])
- return 1;
+ return high;
while (low < high) {
mid = (low+high)/2;
if (mid == low || mid == high)
break;
if (blk == bb->list[mid])
- return 1;
+ return mid;
if (blk < bb->list[mid])
high = mid;
else
low = mid;
}
- return 0;
+ return -1;
+}
+
+/*
+ * This procedure tests to see if a particular block is on a badblocks
+ * list.
+ */
+int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
+{
+ if (ext2fs_u32_list_find(bb, blk) < 0)
+ return 0;
+ else
+ return 1;
}
int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
}
+/*
+ * Remove a block from the badblock list
+ */
+int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
+{
+ int remloc, i;
+
+ if (bb->num == 0)
+ return -1;
+
+ remloc = ext2fs_u32_list_find(bb, blk);
+ if (remloc < 0)
+ return -1;
+
+ for (i = remloc ; i < bb->num-1; i++)
+ bb->list[i] = bb->list[i+1];
+ bb->num--;
+ return 0;
+}
+
+void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
+{
+ ext2fs_u32_list_del(bb, blk);
+}
+
errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
ext2_u32_iterate *ret)
{
#include "ext2_fs.h"
#include "ext2fs.h"
+#define ADD_BLK 0x0001
+#define DEL_BLK 0x0002
+
blk_t test1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
blk_t test2[] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 1 };
blk_t test3[] = { 3, 1, 4, 5, 9, 2, 7, 10, 5, 6, 10, 8, 0 };
45, 0,
66, 1,
0 };
+blk_t test5[] = { 31, 20, 17, 51, 23, 1, 56, 57, 0 };
+blk_t test5a[] = {
+ 50, ADD_BLK,
+ 51, DEL_BLK,
+ 57, DEL_BLK,
+ 66, ADD_BLK,
+ 31, DEL_BLK,
+ 12, ADD_BLK,
+ 2, ADD_BLK,
+ 13, ADD_BLK,
+ 1, DEL_BLK,
+ 0
+ };
+
static int test_fail = 0;
}
}
+static void do_test_seq(badblocks_list bb, blk_t *vec)
+{
+ int i, match;
+
+ for (i = 0; vec[i]; i += 2) {
+ switch (vec[i+1]) {
+ case ADD_BLK:
+ ext2fs_badblocks_list_add(bb, vec[i]);
+ match = ext2fs_badblocks_list_test(bb, vec[i]);
+ printf("Adding block %d --- now %s\n", vec[i],
+ match ? "present" : "absent");
+ if (!match) {
+ printf("FAILURE!\n");
+ test_fail++;
+ }
+ break;
+ case DEL_BLK:
+ ext2fs_badblocks_list_del(bb, vec[i]);
+ match = ext2fs_badblocks_list_test(bb, vec[i]);
+ printf("Removing block %d --- now %s\n", vec[i],
+ ext2fs_badblocks_list_test(bb, vec[i]) ?
+ "present" : "absent");
+ if (match) {
+ printf("FAILURE!\n");
+ test_fail++;
+ }
+ break;
+ }
+ }
+}
+
+
int file_test(badblocks_list bb)
{
badblocks_list new_bb = 0;
int main(int argc, char **argv)
{
- badblocks_list bb1, bb2, bb3, bb4;
+ badblocks_list bb1, bb2, bb3, bb4, bb5;
int equal;
errcode_t retval;
- bb1 = bb2 = bb3 = bb4 = 0;
+ bb1 = bb2 = bb3 = bb4 = bb5 = 0;
printf("test1: ");
retval = create_test_list(test1, &bb1);
}
printf("\n");
- if (bb1 && bb2 && bb3 && bb4) {
+ printf("test5: ");
+ retval = create_test_list(test5, &bb5);
+ if (retval == 0) {
+ print_list(bb5, 0);
+ printf("\n");
+ do_test_seq(bb5, test5a);
+ printf("After test5 sequence: ");
+ print_list(bb5, 0);
+ printf("\n");
+ }
+ printf("\n");
+
+ if (bb1 && bb2 && bb3 && bb4 && bb5) {
printf("Comparison tests:\n");
equal = ext2fs_badblocks_equal(bb1, bb2);
printf("bb1 and bb2 are %sequal.\n", equal ? "" : "NOT ");
printf("bb1 and bb4 are %sequal.\n", equal ? "" : "NOT ");
if (equal)
test_fail++;
+
+ equal = ext2fs_badblocks_equal(bb4, bb5);
+ printf("bb4 and bb5 are %sequal.\n", equal ? "" : "NOT ");
+ if (!equal)
+ test_fail++;
printf("\n");
}
+ file_test(bb4);
+
if (test_fail == 0)
printf("ext2fs library badblocks tests checks out OK!\n");
- file_test(bb4);
-
if (bb1)
ext2fs_badblocks_list_free(bb1);
if (bb2)
errcode_t retval;
int size, c;
int to_move, moved;
+ ext2_badblocks_list badblock_list = 0;
+ int bb_modified = 0;
+
+ retval = ext2fs_read_bb_inode(old_fs, &badblock_list);
+ if (retval)
+ return retval;
new_blk = fs->super->s_first_data_block;
if (!rfs->itable_buf) {
continue;
if (!ext2fs_test_block_bitmap(rfs->move_blocks, blk))
continue;
+ if (ext2fs_badblocks_list_test(badblock_list, blk)) {
+ ext2fs_badblocks_list_del(badblock_list, blk);
+ bb_modified++;
+ continue;
+ }
new_blk = get_new_block(rfs);
if (!new_blk) {
}
errout:
+ if (badblock_list) {
+ if (!retval && bb_modified)
+ retval = ext2fs_update_bb_inode(old_fs,
+ badblock_list);
+ ext2fs_badblocks_list_free(badblock_list);
+ }
return retval;
}