blob: 722af8d09279411a8d1da1a925409b5b1be1baf8 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * badblocks.c --- routines to manipulate the bad block structure
3 *
Theodore Ts'o21c84b71997-04-29 16:15:03 +00004 * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
Theodore Ts'o3839e651997-04-26 13:21:57 +000010 */
11
12#include <stdio.h>
13#include <string.h>
14#include <unistd.h>
15#include <stdlib.h>
16#include <fcntl.h>
17#include <time.h>
18#include <sys/stat.h>
19#include <sys/types.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000020#if HAVE_ERRNO_H
21#include <errno.h>
22#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000023
Theodore Ts'o3839e651997-04-26 13:21:57 +000024#include <linux/ext2_fs.h>
25
Theodore Ts'o21c84b71997-04-29 16:15:03 +000026#include "ext2fsP.h"
Theodore Ts'o3839e651997-04-26 13:21:57 +000027
28/*
29 * This procedure create an empty badblocks list.
30 */
Theodore Ts'o21c84b71997-04-29 16:15:03 +000031errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
Theodore Ts'o3839e651997-04-26 13:21:57 +000032{
Theodore Ts'o21c84b71997-04-29 16:15:03 +000033 ext2_badblocks_list bb;
Theodore Ts'o3839e651997-04-26 13:21:57 +000034
Theodore Ts'o21c84b71997-04-29 16:15:03 +000035 bb = malloc(sizeof(struct ext2_struct_badblocks_list));
Theodore Ts'o3839e651997-04-26 13:21:57 +000036 if (!bb)
37 return ENOMEM;
Theodore Ts'o21c84b71997-04-29 16:15:03 +000038 memset(bb, 0, sizeof(struct ext2_struct_badblocks_list));
Theodore Ts'of3db3561997-04-26 13:34:30 +000039 bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
Theodore Ts'o3839e651997-04-26 13:21:57 +000040 bb->size = size ? size : 10;
41 bb->list = malloc(bb->size * sizeof(blk_t));
42 if (!bb->list) {
43 free(bb);
44 return ENOMEM;
45 }
46 *ret = bb;
47 return 0;
48}
49
50/*
51 * This procedure frees a badblocks list.
Theodore Ts'o21c84b71997-04-29 16:15:03 +000052 *
53 * (note: moved to closefs.c)
Theodore Ts'o3839e651997-04-26 13:21:57 +000054 */
Theodore Ts'of3db3561997-04-26 13:34:30 +000055
Theodore Ts'o3839e651997-04-26 13:21:57 +000056
57/*
58 * This procedure adds a block to a badblocks list.
59 */
Theodore Ts'o21c84b71997-04-29 16:15:03 +000060errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
Theodore Ts'o3839e651997-04-26 13:21:57 +000061{
Theodore Ts'o21c84b71997-04-29 16:15:03 +000062 int i, j;
63 blk_t *new_list;
Theodore Ts'o3839e651997-04-26 13:21:57 +000064
Theodore Ts'of3db3561997-04-26 13:34:30 +000065 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
66
Theodore Ts'o3839e651997-04-26 13:21:57 +000067 if (bb->num >= bb->size) {
68 bb->size += 10;
Theodore Ts'o21c84b71997-04-29 16:15:03 +000069 new_list = realloc(bb->list, bb->size * sizeof(blk_t));
70 if (!new_list)
Theodore Ts'o3839e651997-04-26 13:21:57 +000071 return ENOMEM;
Theodore Ts'o21c84b71997-04-29 16:15:03 +000072 bb->list = new_list;
Theodore Ts'o3839e651997-04-26 13:21:57 +000073 }
74
Theodore Ts'o21c84b71997-04-29 16:15:03 +000075 j = bb->num;
76 for (i=0; i < bb->num; i++) {
77 if (bb->list[i] == blk)
78 return 0;
79 if (bb->list[i] > blk) {
80 j = i;
81 break;
82 }
83 }
84 for (i=bb->num; i > j; i--)
85 bb->list[i] = bb->list[i-1];
86 bb->list[j] = blk;
87 bb->num++;
Theodore Ts'o3839e651997-04-26 13:21:57 +000088 return 0;
89}
90
91/*
92 * This procedure tests to see if a particular block is on a badblocks
93 * list.
94 */
Theodore Ts'o21c84b71997-04-29 16:15:03 +000095int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
Theodore Ts'o3839e651997-04-26 13:21:57 +000096{
Theodore Ts'o21c84b71997-04-29 16:15:03 +000097 int low, high, mid;
Theodore Ts'o3839e651997-04-26 13:21:57 +000098
Theodore Ts'o21c84b71997-04-29 16:15:03 +000099 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
100 return 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000101
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000102 low = 0;
103 high = bb->num-1;
104 if (blk == bb->list[low])
105 return 1;
106 if (blk == bb->list[high])
107 return 1;
108
109 while (low < high) {
110 mid = (low+high)/2;
111 if (mid == low || mid == high)
112 break;
113 if (blk == bb->list[mid])
Theodore Ts'o3839e651997-04-26 13:21:57 +0000114 return 1;
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000115 if (blk < bb->list[mid])
116 high = mid;
117 else
118 low = mid;
119 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000120 return 0;
121}
122
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000123errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
124 ext2_badblocks_iterate *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000125{
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000126 ext2_badblocks_iterate iter;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000127
Theodore Ts'of3db3561997-04-26 13:34:30 +0000128 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
129
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000130 iter = malloc(sizeof(struct ext2_struct_badblocks_iterate));
Theodore Ts'o3839e651997-04-26 13:21:57 +0000131 if (!iter)
132 return ENOMEM;
133
Theodore Ts'of3db3561997-04-26 13:34:30 +0000134 iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000135 iter->bb = bb;
136 iter->ptr = 0;
137 *ret = iter;
138 return 0;
139}
140
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000141int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000142{
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000143 ext2_badblocks_list bb;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000144
145 if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
146 return 0;
147
148 bb = iter->bb;
149
150 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
151 return 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000152
153 if (iter->ptr < bb->num) {
154 *blk = bb->list[iter->ptr++];
155 return 1;
156 }
157 *blk = 0;
158 return 0;
159}
160
Theodore Ts'o21c84b71997-04-29 16:15:03 +0000161void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000162{
Theodore Ts'of3db3561997-04-26 13:34:30 +0000163 if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
164 return;
165
Theodore Ts'o3839e651997-04-26 13:21:57 +0000166 iter->bb = 0;
167 free(iter);
168}
169
170
171
172
173