1 /* vi: set sw=4 ts=4: */
3 * badblocks.c --- routines to manipulate the bad block structure
5 * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
24 #include <sys/types.h>
31 * Helper function for making a badblocks list
33 static errcode_t
make_u32_list(int size
, int num
, __u32
*list
,
39 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_u32_list
), &bb
);
42 memset(bb
, 0, sizeof(struct ext2_struct_u32_list
));
43 bb
->magic
= EXT2_ET_MAGIC_BADBLOCKS_LIST
;
44 bb
->size
= size
? size
: 10;
46 retval
= ext2fs_get_mem(bb
->size
* sizeof(blk_t
), &bb
->list
);
52 memcpy(bb
->list
, list
, bb
->size
* sizeof(blk_t
));
54 memset(bb
->list
, 0, bb
->size
* sizeof(blk_t
));
61 * This procedure creates an empty u32 list.
63 errcode_t
ext2fs_u32_list_create(ext2_u32_list
*ret
, int size
)
65 return make_u32_list(size
, 0, 0, ret
);
69 * This procedure creates an empty badblocks list.
71 errcode_t
ext2fs_badblocks_list_create(ext2_badblocks_list
*ret
, int size
)
73 return make_u32_list(size
, 0, 0, (ext2_badblocks_list
*) ret
);
78 * This procedure copies a badblocks list
80 errcode_t
ext2fs_u32_copy(ext2_u32_list src
, ext2_u32_list
*dest
)
84 retval
= make_u32_list(src
->size
, src
->num
, src
->list
, dest
);
87 (*dest
)->badblocks_flags
= src
->badblocks_flags
;
91 errcode_t
ext2fs_badblocks_copy(ext2_badblocks_list src
,
92 ext2_badblocks_list
*dest
)
94 return ext2fs_u32_copy((ext2_u32_list
) src
,
95 (ext2_u32_list
*) dest
);
99 * This procedure frees a badblocks list.
101 * (note: moved to closefs.c)
106 * This procedure adds a block to a badblocks list.
108 errcode_t
ext2fs_u32_list_add(ext2_u32_list bb
, __u32 blk
)
112 unsigned long old_size
;
114 EXT2_CHECK_MAGIC(bb
, EXT2_ET_MAGIC_BADBLOCKS_LIST
);
116 if (bb
->num
>= bb
->size
) {
117 old_size
= bb
->size
* sizeof(__u32
);
119 retval
= ext2fs_resize_mem(old_size
, bb
->size
* sizeof(__u32
),
128 * Add special case code for appending to the end of the list
131 if ((bb
->num
!= 0) && (bb
->list
[i
] == blk
))
133 if ((bb
->num
== 0) || (bb
->list
[i
] < blk
)) {
134 bb
->list
[bb
->num
++] = blk
;
139 for (i
=0; i
< bb
->num
; i
++) {
140 if (bb
->list
[i
] == blk
)
142 if (bb
->list
[i
] > blk
) {
147 for (i
=bb
->num
; i
> j
; i
--)
148 bb
->list
[i
] = bb
->list
[i
-1];
154 errcode_t
ext2fs_badblocks_list_add(ext2_badblocks_list bb
, blk_t blk
)
156 return ext2fs_u32_list_add((ext2_u32_list
) bb
, (__u32
) blk
);
160 * This procedure finds a particular block is on a badblocks
163 int ext2fs_u32_list_find(ext2_u32_list bb
, __u32 blk
)
167 if (bb
->magic
!= EXT2_ET_MAGIC_BADBLOCKS_LIST
)
175 if (blk
== bb
->list
[low
])
177 if (blk
== bb
->list
[high
])
182 if (mid
== low
|| mid
== high
)
184 if (blk
== bb
->list
[mid
])
186 if (blk
< bb
->list
[mid
])
195 * This procedure tests to see if a particular block is on a badblocks
198 int ext2fs_u32_list_test(ext2_u32_list bb
, __u32 blk
)
200 if (ext2fs_u32_list_find(bb
, blk
) < 0)
206 int ext2fs_badblocks_list_test(ext2_badblocks_list bb
, blk_t blk
)
208 return ext2fs_u32_list_test((ext2_u32_list
) bb
, (__u32
) blk
);
213 * Remove a block from the badblock list
215 int ext2fs_u32_list_del(ext2_u32_list bb
, __u32 blk
)
222 remloc
= ext2fs_u32_list_find(bb
, blk
);
226 for (i
= remloc
; i
< bb
->num
- 1; i
++)
227 bb
->list
[i
] = bb
->list
[i
+1];
232 void ext2fs_badblocks_list_del(ext2_u32_list bb
, __u32 blk
)
234 ext2fs_u32_list_del(bb
, blk
);
237 errcode_t
ext2fs_u32_list_iterate_begin(ext2_u32_list bb
,
238 ext2_u32_iterate
*ret
)
240 ext2_u32_iterate iter
;
243 EXT2_CHECK_MAGIC(bb
, EXT2_ET_MAGIC_BADBLOCKS_LIST
);
245 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate
), &iter
);
249 iter
->magic
= EXT2_ET_MAGIC_BADBLOCKS_ITERATE
;
256 errcode_t
ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb
,
257 ext2_badblocks_iterate
*ret
)
259 return ext2fs_u32_list_iterate_begin((ext2_u32_list
) bb
,
260 (ext2_u32_iterate
*) ret
);
264 int ext2fs_u32_list_iterate(ext2_u32_iterate iter
, __u32
*blk
)
268 if (iter
->magic
!= EXT2_ET_MAGIC_BADBLOCKS_ITERATE
)
273 if (bb
->magic
!= EXT2_ET_MAGIC_BADBLOCKS_LIST
)
276 if (iter
->ptr
< bb
->num
) {
277 *blk
= bb
->list
[iter
->ptr
++];
284 int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter
, blk_t
*blk
)
286 return ext2fs_u32_list_iterate((ext2_u32_iterate
) iter
,
291 void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter
)
293 if (!iter
|| (iter
->magic
!= EXT2_ET_MAGIC_BADBLOCKS_ITERATE
))
297 ext2fs_free_mem(&iter
);
300 void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter
)
302 ext2fs_u32_list_iterate_end((ext2_u32_iterate
) iter
);
306 int ext2fs_u32_list_equal(ext2_u32_list bb1
, ext2_u32_list bb2
)
308 EXT2_CHECK_MAGIC(bb1
, EXT2_ET_MAGIC_BADBLOCKS_LIST
);
309 EXT2_CHECK_MAGIC(bb2
, EXT2_ET_MAGIC_BADBLOCKS_LIST
);
311 if (bb1
->num
!= bb2
->num
)
314 if (memcmp(bb1
->list
, bb2
->list
, bb1
->num
* sizeof(blk_t
)) != 0)
319 int ext2fs_badblocks_equal(ext2_badblocks_list bb1
, ext2_badblocks_list bb2
)
321 return ext2fs_u32_list_equal((ext2_u32_list
) bb1
,
322 (ext2_u32_list
) bb2
);
325 int ext2fs_u32_list_count(ext2_u32_list bb
)