blob: f286747bc08dbcad91f522dcd2453ddb5bd05bb1 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * badblocks.c --- routines to manipulate the bad block structure
3 *
4 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
6 */
7
8#include <stdio.h>
9#include <string.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <fcntl.h>
13#include <time.h>
14#include <sys/stat.h>
15#include <sys/types.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +000016#if HAVE_ERRNO_H
17#include <errno.h>
18#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000019
Theodore Ts'o3839e651997-04-26 13:21:57 +000020#include <linux/ext2_fs.h>
21
22#include "ext2fs.h"
23
24/*
25 * This procedure create an empty badblocks list.
26 */
27errcode_t badblocks_list_create(badblocks_list *ret, int size)
28{
29 badblocks_list bb;
30
31 bb = malloc(sizeof(struct struct_badblocks_list));
32 if (!bb)
33 return ENOMEM;
34 memset(bb, 0, sizeof(struct struct_badblocks_list));
Theodore Ts'of3db3561997-04-26 13:34:30 +000035 bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
Theodore Ts'o3839e651997-04-26 13:21:57 +000036 bb->size = size ? size : 10;
37 bb->list = malloc(bb->size * sizeof(blk_t));
38 if (!bb->list) {
39 free(bb);
40 return ENOMEM;
41 }
42 *ret = bb;
43 return 0;
44}
45
46/*
47 * This procedure frees a badblocks list.
48 */
49void badblocks_list_free(badblocks_list bb)
50{
Theodore Ts'of3db3561997-04-26 13:34:30 +000051 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
52 return;
53
Theodore Ts'o3839e651997-04-26 13:21:57 +000054 if (bb->list)
55 free(bb->list);
56 bb->list = 0;
57 free(bb);
58}
59
60/*
61 * This procedure adds a block to a badblocks list.
62 */
63errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
64{
65 int i;
66
Theodore Ts'of3db3561997-04-26 13:34:30 +000067 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
68
Theodore Ts'o3839e651997-04-26 13:21:57 +000069 for (i=0; i < bb->num; i++)
70 if (bb->list[i] == blk)
71 return 0;
72
73 if (bb->num >= bb->size) {
74 bb->size += 10;
75 bb->list = realloc(bb->list, bb->size * sizeof(blk_t));
76 if (!bb->list) {
77 bb->size = 0;
78 bb->num = 0;
79 return ENOMEM;
80 }
81 }
82
83 bb->list[bb->num++] = blk;
84 return 0;
85}
86
87/*
88 * This procedure tests to see if a particular block is on a badblocks
89 * list.
90 */
91int badblocks_list_test(badblocks_list bb, blk_t blk)
92{
93 int i;
94
Theodore Ts'of3db3561997-04-26 13:34:30 +000095 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
96
Theodore Ts'o3839e651997-04-26 13:21:57 +000097 for (i=0; i < bb->num; i++)
98 if (bb->list[i] == blk)
99 return 1;
100
101 return 0;
102}
103
104errcode_t badblocks_list_iterate_begin(badblocks_list bb,
105 badblocks_iterate *ret)
106{
107 badblocks_iterate iter;
108
Theodore Ts'of3db3561997-04-26 13:34:30 +0000109 EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
110
Theodore Ts'o3839e651997-04-26 13:21:57 +0000111 iter = malloc(sizeof(struct struct_badblocks_iterate));
112 if (!iter)
113 return ENOMEM;
114
Theodore Ts'of3db3561997-04-26 13:34:30 +0000115 iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000116 iter->bb = bb;
117 iter->ptr = 0;
118 *ret = iter;
119 return 0;
120}
121
122int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
123{
Theodore Ts'of3db3561997-04-26 13:34:30 +0000124 badblocks_list bb;
125
126 if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
127 return 0;
128
129 bb = iter->bb;
130
131 if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
132 return 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000133
134 if (iter->ptr < bb->num) {
135 *blk = bb->list[iter->ptr++];
136 return 1;
137 }
138 *blk = 0;
139 return 0;
140}
141
142void badblocks_list_iterate_end(badblocks_iterate iter)
143{
Theodore Ts'of3db3561997-04-26 13:34:30 +0000144 if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
145 return;
146
Theodore Ts'o3839e651997-04-26 13:21:57 +0000147 iter->bb = 0;
148 free(iter);
149}
150
151
152
153
154