13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * badblocks.c --- routines to manipulate the bad block structure
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *
621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header%
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header%
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h"
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
154cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
174cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
201d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_STAT_H
213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
221d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
231d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/types.h>
251d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
27b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
2821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include "ext2fsP.h"
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
31a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Helper function for making a badblocks list
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
33b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ostatic errcode_t make_u32_list(int size, int num, __u32 *list,
34b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o			       ext2_u32_list *ret)
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
36b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_list	bb;
37b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	errcode_t	retval;
38efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
39c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
407b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	if (retval)
417b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
42b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	memset(bb, 0, sizeof(struct ext2_struct_u32_list));
43f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->size = size ? size : 10;
45a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	bb->num = num;
46ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o	retval = ext2fs_get_array(bb->size, sizeof(blk_t), &bb->list);
472694f31946f0c168cc8d098f3970f0ae08d94e7bTheodore Ts'o	if (retval) {
48c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o		ext2fs_free_mem(&bb);
497b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
51a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (list)
52a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		memcpy(bb->list, list, bb->size * sizeof(blk_t));
53a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	else
54a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		memset(bb->list, 0, bb->size * sizeof(blk_t));
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = bb;
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
58efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
59a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
60a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/*
61b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o * This procedure creates an empty u32 list.
62b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o */
63b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
64b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
65b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return make_u32_list(size, 0, 0, ret);
66b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
67b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
68b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o/*
69a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * This procedure creates an empty badblocks list.
70a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */
71a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
72a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{
73b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
74a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o}
75a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
76b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
77a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/*
78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * This procedure copies a badblocks list
79a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */
80b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
81a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{
82a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	errcode_t	retval;
83efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
84b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	retval = make_u32_list(src->size, src->num, src->list, dest);
85a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (retval)
86a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		return retval;
87a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	(*dest)->badblocks_flags = src->badblocks_flags;
88a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	return 0;
89a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o}
90a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
91b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
92b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				ext2_badblocks_list *dest)
93b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
94b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_copy((ext2_u32_list) src,
95b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o			       (ext2_u32_list *) dest);
96b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure frees a badblocks list.
10021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *
10121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * (note: moved to closefs.c)
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
103f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure adds a block to a badblocks list.
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
108b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1107b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	errcode_t	retval;
1117b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	int		i, j;
11276f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o	unsigned long	old_size;
1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
114f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
115f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (bb->num >= bb->size) {
117b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o		old_size = bb->size * sizeof(__u32);
118f75c28de4731c2cd09f6ca1a23e25c968a1edc2fTheodore Ts'o		bb->size += 100;
119b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o		retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
120c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o					   &bb->list);
12176f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o		if (retval) {
122f75c28de4731c2cd09f6ca1a23e25c968a1edc2fTheodore Ts'o			bb->size -= 100;
1237b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o			return retval;
12476f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o		}
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1279b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	/*
1289b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	 * Add special case code for appending to the end of the list
1299b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	 */
1309b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	i = bb->num-1;
1319b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	if ((bb->num != 0) && (bb->list[i] == blk))
1329b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		return 0;
1339b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	if ((bb->num == 0) || (bb->list[i] < blk)) {
1349b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		bb->list[bb->num++] = blk;
1359b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		return 0;
1369b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	}
1379b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o
13821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	j = bb->num;
13921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	for (i=0; i < bb->num; i++) {
14021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (bb->list[i] == blk)
14121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			return 0;
14221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (bb->list[i] > blk) {
14321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			j = i;
14421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			break;
14521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		}
14621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	}
14721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	for (i=bb->num; i > j; i--)
14821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		bb->list[i] = bb->list[i-1];
14921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	bb->list[j] = blk;
15021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	bb->num++;
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
154b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
155b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
156b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
157b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
158b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
1593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
1607d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * This procedure finds a particular block is on a badblocks
1613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * list.
1623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
1637d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
1643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
16521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int	low, high, mid;
1663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
1687d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
169f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
170f635d7f65bd002984ce9a202d491d4f187b996b2Theodore Ts'o	if (bb->num == 0)
1717d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
172f635d7f65bd002984ce9a202d491d4f187b996b2Theodore Ts'o
17321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	low = 0;
17421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	high = bb->num-1;
17521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (blk == bb->list[low])
1767d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return low;
17721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (blk == bb->list[high])
1787d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return high;
1793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
18021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	while (low < high) {
181a4aff9ca5bcc3df76dcb3d49765674feba3d7654Theodore Ts'o		mid = ((unsigned)low + (unsigned)high)/2;
18221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (mid == low || mid == high)
18321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			break;
18421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (blk == bb->list[mid])
1857d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o			return mid;
18621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (blk < bb->list[mid])
18721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			high = mid;
18821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		else
18921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			low = mid;
19021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	}
1917d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	return -1;
1927d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
1937d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
1947d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o/*
1957d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * This procedure tests to see if a particular block is on a badblocks
1967d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * list.
1977d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o */
1987d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
1997d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
2007d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (ext2fs_u32_list_find(bb, blk) < 0)
2017d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return 0;
2027d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	else
2037d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return 1;
2043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
206b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
207b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
208b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
209b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
210b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
211b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
2127d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o/*
2137d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * Remove a block from the badblock list
2147d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o */
2157d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
2167d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
2177d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	int	remloc, i;
2187d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2197d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (bb->num == 0)
2207d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
2217d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2227d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	remloc = ext2fs_u32_list_find(bb, blk);
2237d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (remloc < 0)
2247d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
2257d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2267d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	for (i = remloc ; i < bb->num-1; i++)
2277d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		bb->list[i] = bb->list[i+1];
2287d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	bb->num--;
2297d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	return 0;
2307d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
2317d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2327d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'ovoid ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
2337d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
2347d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	ext2fs_u32_list_del(bb, blk);
2357d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
2367d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
237b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
238b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					ext2_u32_iterate *ret)
2393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
240b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_iterate iter;
2417b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	errcode_t		retval;
2423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
243f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
244f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
245c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
2467b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	if (retval)
2477b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
2483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
249f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
2503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = bb;
2513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->ptr = 0;
2523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = iter;
2533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
256b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
257b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					      ext2_badblocks_iterate *ret)
2583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
259b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
260b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					      (ext2_u32_iterate *) ret);
261b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
262b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
263b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
264b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
265b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
266b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_list	bb;
267f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
268f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
269f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return 0;
270f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
271f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	bb = iter->bb;
272f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
273f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
274f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return 0;
275efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (iter->ptr < bb->num) {
2773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*blk = bb->list[iter->ptr++];
2783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return 1;
279efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	}
2803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*blk = 0;
2813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
2823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
284b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
285b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
286b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
287b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				       (__u32 *) blk);
288b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
289b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
290b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
291b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ovoid ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
2923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
293f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
294f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return;
295f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
2963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = 0;
297c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	ext2fs_free_mem(&iter);
2983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
29957dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
300b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ovoid ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
301b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
302b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
303b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
304b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
305b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
306b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
30757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{
30857dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
30957dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
31057dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
31157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	if (bb1->num != bb2->num)
31257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		return 0;
31357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
31457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
31557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		return 0;
31657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	return 1;
31757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o}
318b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
319b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
320b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
321b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_equal((ext2_u32_list) bb1,
322b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				     (ext2_u32_list) bb2);
323b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
324220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o
325220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'oint ext2fs_u32_list_count(ext2_u32_list bb)
326220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o{
327220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o	return bb->num;
328220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o}
329