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
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
191d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_STAT_H
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
211d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
221d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/types.h>
241d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
26b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
2721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include "ext2fsP.h"
283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
30a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Helper function for making a badblocks list
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
32b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ostatic errcode_t make_u32_list(int size, int num, __u32 *list,
33b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o			       ext2_u32_list *ret)
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
35b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_list	bb;
36b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	errcode_t	retval;
37efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
38c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
397b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	if (retval)
407b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
41b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	memset(bb, 0, sizeof(struct ext2_struct_u32_list));
42f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->size = size ? size : 10;
44a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	bb->num = num;
45ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o	retval = ext2fs_get_array(bb->size, sizeof(blk_t), &bb->list);
462694f31946f0c168cc8d098f3970f0ae08d94e7bTheodore Ts'o	if (retval) {
47c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o		ext2fs_free_mem(&bb);
487b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
50a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (list)
51a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		memcpy(bb->list, list, bb->size * sizeof(blk_t));
52a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	else
53a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		memset(bb->list, 0, bb->size * sizeof(blk_t));
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = bb;
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
57efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
58a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
59a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/*
60b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o * This procedure creates an empty u32 list.
61b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o */
62b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
63b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
64b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return make_u32_list(size, 0, 0, ret);
65b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
66b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
67b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o/*
68a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * This procedure creates an empty badblocks list.
69a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */
70a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
71a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{
72b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
73a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o}
74a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
75b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
76a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/*
77a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * This procedure copies a badblocks list
78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */
79b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
80a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{
81a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	errcode_t	retval;
82efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
83b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	retval = make_u32_list(src->size, src->num, src->list, dest);
84a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (retval)
85a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		return retval;
86a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	(*dest)->badblocks_flags = src->badblocks_flags;
87a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	return 0;
88a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o}
89a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o
90b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
91b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				ext2_badblocks_list *dest)
92b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
93b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_copy((ext2_u32_list) src,
94b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o			       (ext2_u32_list *) dest);
95b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure frees a badblocks list.
9921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *
10021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * (note: moved to closefs.c)
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
102f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure adds a block to a badblocks list.
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
107b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1097b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	errcode_t	retval;
1107b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	int		i, j;
11176f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o	unsigned long	old_size;
1123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
113f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
114f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (bb->num >= bb->size) {
116b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o		old_size = bb->size * sizeof(__u32);
117f75c28de4731c2cd09f6ca1a23e25c968a1edc2fTheodore Ts'o		bb->size += 100;
118b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o		retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
119c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o					   &bb->list);
12076f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o		if (retval) {
121f75c28de4731c2cd09f6ca1a23e25c968a1edc2fTheodore Ts'o			bb->size -= 100;
1227b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o			return retval;
12376f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o		}
1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1269b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	/*
1279b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	 * Add special case code for appending to the end of the list
1289b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	 */
1299b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	i = bb->num-1;
1309b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	if ((bb->num != 0) && (bb->list[i] == blk))
1319b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		return 0;
1329b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	if ((bb->num == 0) || (bb->list[i] < blk)) {
1339b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		bb->list[bb->num++] = blk;
1349b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o		return 0;
1359b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o	}
1369b9fe8ac19db2bbd202bffd305ceee767a45f57aTheodore Ts'o
13721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	j = bb->num;
13821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	for (i=0; i < bb->num; i++) {
13921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (bb->list[i] == blk)
14021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			return 0;
14121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (bb->list[i] > blk) {
14221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			j = i;
14321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			break;
14421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		}
14521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	}
14621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	for (i=bb->num; i > j; i--)
14721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		bb->list[i] = bb->list[i-1];
14821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	bb->list[j] = blk;
14921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	bb->num++;
1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
153b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
154b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
155b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
156b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
157b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
1597d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * This procedure finds a particular block is on a badblocks
1603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * list.
1613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
1627d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
1633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
16421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int	low, high, mid;
1653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
16621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
1677d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
168f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
169f635d7f65bd002984ce9a202d491d4f187b996b2Theodore Ts'o	if (bb->num == 0)
1707d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
171f635d7f65bd002984ce9a202d491d4f187b996b2Theodore Ts'o
17221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	low = 0;
17321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	high = bb->num-1;
17421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (blk == bb->list[low])
1757d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return low;
17621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	if (blk == bb->list[high])
1777d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return high;
1783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
17921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	while (low < high) {
180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		mid = ((unsigned)low + (unsigned)high)/2;
18121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (mid == low || mid == high)
18221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			break;
18321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (blk == bb->list[mid])
1847d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o			return mid;
18521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		if (blk < bb->list[mid])
18621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			high = mid;
18721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		else
18821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			low = mid;
18921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	}
1907d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	return -1;
1917d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
1927d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
1937d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o/*
1947d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * This procedure tests to see if a particular block is on a badblocks
1957d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * list.
1967d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o */
1977d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
1987d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
1997d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (ext2fs_u32_list_find(bb, blk) < 0)
2007d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return 0;
2017d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	else
2027d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return 1;
2033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
205b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
206b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
207b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
208b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
209b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
210b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
2117d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o/*
2127d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o * Remove a block from the badblock list
2137d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o */
2147d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'oint ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
2157d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
2167d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	int	remloc, i;
2177d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2187d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (bb->num == 0)
2197d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
2207d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2217d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	remloc = ext2fs_u32_list_find(bb, blk);
2227d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	if (remloc < 0)
2237d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		return -1;
2247d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2257d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	for (i = remloc ; i < bb->num-1; i++)
2267d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o		bb->list[i] = bb->list[i+1];
2277d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	bb->num--;
2287d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	return 0;
2297d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
2307d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
2317d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'ovoid ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
2327d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o{
2337d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o	ext2fs_u32_list_del(bb, blk);
2347d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o}
2357d7bdd578b307cad1dc248310eb279c6fb73b682Theodore Ts'o
236b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
237b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					ext2_u32_iterate *ret)
2383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
239b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_iterate iter;
2407b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	errcode_t		retval;
2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
242f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
243f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
244c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
2457b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	if (retval)
2467b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
2473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
248f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
2493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = bb;
2503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->ptr = 0;
2513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = iter;
2523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
2533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
255b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oerrcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
256b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					      ext2_badblocks_iterate *ret)
2573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
258b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
259b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o					      (ext2_u32_iterate *) ret);
260b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
261b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
262b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
263b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
264b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
265b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2_u32_list	bb;
266f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
267f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
268f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return 0;
269f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
270f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	bb = iter->bb;
271f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
272f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
273f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return 0;
274efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (iter->ptr < bb->num) {
2763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*blk = bb->list[iter->ptr++];
2773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return 1;
278efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	}
2793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*blk = 0;
2803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
2813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
283b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
284b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
285b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
286b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				       (__u32 *) blk);
287b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
288b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
289b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
290b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ovoid ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
2913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
292f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
293f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return;
294f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
2953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = 0;
296c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	ext2fs_free_mem(&iter);
2973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
29857dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
299b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'ovoid ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
300b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
301b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
302b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
303b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
304b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
305b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
30657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{
30757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
30857dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
30957dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
31057dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	if (bb1->num != bb2->num)
31157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		return 0;
31257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
31357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
31457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		return 0;
31557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	return 1;
31657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o}
317b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o
318b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'oint ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
319b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o{
320b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o	return ext2fs_u32_list_equal((ext2_u32_list) bb1,
321b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o				     (ext2_u32_list) bb2);
322b7a00563b22b0ea47ddc7117508c0b8e0d65df43Theodore Ts'o}
323220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o
324220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'oint ext2fs_u32_list_count(ext2_u32_list bb)
325220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o{
326220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o	return bb->num;
327220c0040fb4a5e8a2a091a9e3a936bb8a85223d8Theodore Ts'o}
328