mirror of https://github.com/vitalif/e2fsprogs
Fix bug in resize2fs which caused it to fail on filesystems with a
non-empty bad block list. Resize2fs now discards any blocks on the badblock list which are no longer part of the filesystem as the result of a filesystem shrink. (Note: this means that shrinking and then enlarging a filesystem is no longer a reversible operation; information about bad blocks in the part of the filesystem which is to be chopped off will be lost.)bitmap-optimize
parent
23658ffa30
commit
7d7bdd578b
|
@ -1,3 +1,11 @@
|
||||||
|
2003-06-24 <tytso@snap.thunk.org>
|
||||||
|
|
||||||
|
* badblocks.c, ext2fs.h (ext2fs_u32_list_find,
|
||||||
|
ext2fs_u32_list_test, ext2fs_u32_list_del,
|
||||||
|
ext2fs_badblocks_list_del): Add functions to delete a
|
||||||
|
block from the badblocks list.
|
||||||
|
* tst_badblocks.c: Add test cases for ext2fs_badblocks_list_del().
|
||||||
|
|
||||||
2003-05-21 Theodore Ts'o <tytso@mit.edu>
|
2003-05-21 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
* getsectsize.c (ext2fs_get_device_sectsize): New function which
|
* getsectsize.c (ext2fs_get_device_sectsize): New function which
|
||||||
|
|
|
@ -156,7 +156,40 @@ errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
|
||||||
return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
|
return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This procedure finds a particular block is on a badblocks
|
||||||
|
* list.
|
||||||
|
*/
|
||||||
|
int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
|
||||||
|
{
|
||||||
|
int low, high, mid;
|
||||||
|
|
||||||
|
if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (bb->num == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
low = 0;
|
||||||
|
high = bb->num-1;
|
||||||
|
if (blk == bb->list[low])
|
||||||
|
return low;
|
||||||
|
if (blk == bb->list[high])
|
||||||
|
return high;
|
||||||
|
|
||||||
|
while (low < high) {
|
||||||
|
mid = (low+high)/2;
|
||||||
|
if (mid == low || mid == high)
|
||||||
|
break;
|
||||||
|
if (blk == bb->list[mid])
|
||||||
|
return mid;
|
||||||
|
if (blk < bb->list[mid])
|
||||||
|
high = mid;
|
||||||
|
else
|
||||||
|
low = mid;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This procedure tests to see if a particular block is on a badblocks
|
* This procedure tests to see if a particular block is on a badblocks
|
||||||
|
@ -164,33 +197,10 @@ errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
|
||||||
*/
|
*/
|
||||||
int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
|
int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
|
||||||
{
|
{
|
||||||
int low, high, mid;
|
if (ext2fs_u32_list_find(bb, blk) < 0)
|
||||||
|
|
||||||
if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
else
|
||||||
if (bb->num == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
low = 0;
|
|
||||||
high = bb->num-1;
|
|
||||||
if (blk == bb->list[low])
|
|
||||||
return 1;
|
return 1;
|
||||||
if (blk == bb->list[high])
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
while (low < high) {
|
|
||||||
mid = (low+high)/2;
|
|
||||||
if (mid == low || mid == high)
|
|
||||||
break;
|
|
||||||
if (blk == bb->list[mid])
|
|
||||||
return 1;
|
|
||||||
if (blk < bb->list[mid])
|
|
||||||
high = mid;
|
|
||||||
else
|
|
||||||
low = mid;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
|
int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
|
||||||
|
@ -199,6 +209,31 @@ 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,
|
errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
|
||||||
ext2_u32_iterate *ret)
|
ext2_u32_iterate *ret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -491,6 +491,8 @@ extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
|
||||||
blk_t blk);
|
blk_t blk);
|
||||||
extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
|
extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
|
||||||
blk_t blk);
|
blk_t blk);
|
||||||
|
extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
|
||||||
|
extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
|
||||||
extern errcode_t
|
extern errcode_t
|
||||||
ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
|
ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
|
||||||
ext2_badblocks_iterate *ret);
|
ext2_badblocks_iterate *ret);
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#include "ext2_fs.h"
|
#include "ext2_fs.h"
|
||||||
#include "ext2fs.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 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 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 };
|
blk_t test3[] = { 3, 1, 4, 5, 9, 2, 7, 10, 5, 6, 10, 8, 0 };
|
||||||
|
@ -44,6 +47,20 @@ blk_t test4a[] = {
|
||||||
45, 0,
|
45, 0,
|
||||||
66, 1,
|
66, 1,
|
||||||
0 };
|
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 int test_fail = 0;
|
||||||
|
|
||||||
|
@ -118,6 +135,38 @@ static void validate_test_seq(badblocks_list bb, blk_t *vec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
int file_test(badblocks_list bb)
|
||||||
{
|
{
|
||||||
badblocks_list new_bb = 0;
|
badblocks_list new_bb = 0;
|
||||||
|
@ -156,11 +205,11 @@ int file_test(badblocks_list bb)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
badblocks_list bb1, bb2, bb3, bb4;
|
badblocks_list bb1, bb2, bb3, bb4, bb5;
|
||||||
int equal;
|
int equal;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
|
|
||||||
bb1 = bb2 = bb3 = bb4 = 0;
|
bb1 = bb2 = bb3 = bb4 = bb5 = 0;
|
||||||
|
|
||||||
printf("test1: ");
|
printf("test1: ");
|
||||||
retval = create_test_list(test1, &bb1);
|
retval = create_test_list(test1, &bb1);
|
||||||
|
@ -189,7 +238,19 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
printf("\n");
|
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");
|
printf("Comparison tests:\n");
|
||||||
equal = ext2fs_badblocks_equal(bb1, bb2);
|
equal = ext2fs_badblocks_equal(bb1, bb2);
|
||||||
printf("bb1 and bb2 are %sequal.\n", equal ? "" : "NOT ");
|
printf("bb1 and bb2 are %sequal.\n", equal ? "" : "NOT ");
|
||||||
|
@ -205,14 +266,19 @@ int main(int argc, char **argv)
|
||||||
printf("bb1 and bb4 are %sequal.\n", equal ? "" : "NOT ");
|
printf("bb1 and bb4 are %sequal.\n", equal ? "" : "NOT ");
|
||||||
if (equal)
|
if (equal)
|
||||||
test_fail++;
|
test_fail++;
|
||||||
|
|
||||||
|
equal = ext2fs_badblocks_equal(bb4, bb5);
|
||||||
|
printf("bb4 and bb5 are %sequal.\n", equal ? "" : "NOT ");
|
||||||
|
if (!equal)
|
||||||
|
test_fail++;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_test(bb4);
|
||||||
|
|
||||||
if (test_fail == 0)
|
if (test_fail == 0)
|
||||||
printf("ext2fs library badblocks tests checks out OK!\n");
|
printf("ext2fs library badblocks tests checks out OK!\n");
|
||||||
|
|
||||||
file_test(bb4);
|
|
||||||
|
|
||||||
if (bb1)
|
if (bb1)
|
||||||
ext2fs_badblocks_list_free(bb1);
|
ext2fs_badblocks_list_free(bb1);
|
||||||
if (bb2)
|
if (bb2)
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2003-06-24 <tytso@snap.thunk.org>
|
||||||
|
|
||||||
|
* resize2fs.c (block_mover): Don't move blocks associated with the
|
||||||
|
bad blocks inode. Instead, just remove them from the
|
||||||
|
badblocks list. (Note this means that shrinking and then
|
||||||
|
enlarging a filesystem is not a reversible operation;
|
||||||
|
information about bad blocks in the part of the filesystem
|
||||||
|
which is to be chopped off is discarded.)
|
||||||
|
|
||||||
2003-06-08 Theodore Ts'o <tytso@mit.edu>
|
2003-06-08 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
* resize2fs.8.in: Make explicit that you need to run resize2fs
|
* resize2fs.8.in: Make explicit that you need to run resize2fs
|
||||||
|
|
|
@ -837,6 +837,12 @@ static errcode_t block_mover(ext2_resize_t rfs)
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
int size, c;
|
int size, c;
|
||||||
int to_move, moved;
|
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;
|
new_blk = fs->super->s_first_data_block;
|
||||||
if (!rfs->itable_buf) {
|
if (!rfs->itable_buf) {
|
||||||
|
@ -862,6 +868,11 @@ static errcode_t block_mover(ext2_resize_t rfs)
|
||||||
continue;
|
continue;
|
||||||
if (!ext2fs_test_block_bitmap(rfs->move_blocks, blk))
|
if (!ext2fs_test_block_bitmap(rfs->move_blocks, blk))
|
||||||
continue;
|
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);
|
new_blk = get_new_block(rfs);
|
||||||
if (!new_blk) {
|
if (!new_blk) {
|
||||||
|
@ -931,6 +942,12 @@ static errcode_t block_mover(ext2_resize_t rfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errout:
|
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;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue