badblocks.c revision 3839e65723771b85975f4263102dd3ceec4523c
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * badblocks.c --- routines to manipulate the bad block structure
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * under the terms of the GNU Public License.
63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h>
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/types.h>
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/fs.h>
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/ext2_fs.h>
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h"
213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure create an empty badblocks list.
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t badblocks_list_create(badblocks_list *ret, int size)
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	badblocks_list	bb;
283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb = malloc(sizeof(struct struct_badblocks_list));
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!bb)
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ENOMEM;
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	memset(bb, 0, sizeof(struct struct_badblocks_list));
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->size = size ? size : 10;
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->list = malloc(bb->size * sizeof(blk_t));
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!bb->list) {
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		free(bb);
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ENOMEM;
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = bb;
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure frees a badblocks list.
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid badblocks_list_free(badblocks_list bb)
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (bb->list)
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		free(bb->list);
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->list = 0;
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	free(bb);
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure adds a block to a badblocks list.
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	i;
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	for (i=0; i < bb->num; i++)
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (bb->list[i] == blk)
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return 0;
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (bb->num >= bb->size) {
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		bb->size += 10;
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		bb->list = realloc(bb->list, bb->size * sizeof(blk_t));
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (!bb->list) {
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			bb->size = 0;
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			bb->num = 0;
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return ENOMEM;
723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	bb->list[bb->num++] = blk;
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This procedure tests to see if a particular block is on a badblocks
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * list.
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint badblocks_list_test(badblocks_list bb, blk_t blk)
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	i;
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	for (i=0; i < bb->num; i++)
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (bb->list[i] == blk)
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return 1;
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t badblocks_list_iterate_begin(badblocks_list bb,
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				       badblocks_iterate *ret)
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	badblocks_iterate iter;
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter = malloc(sizeof(struct struct_badblocks_iterate));
1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!iter)
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ENOMEM;
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = bb;
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->ptr = 0;
1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*ret = iter;
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	badblocks_list	bb = iter->bb;
1123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (iter->ptr < bb->num) {
1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		*blk = bb->list[iter->ptr++];
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return 1;
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*blk = 0;
1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid badblocks_list_iterate_end(badblocks_iterate iter)
1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	iter->bb = 0;
1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	free(iter);
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
131