Mirror of git://git.busybox.net/busybox with our patches on top
Source
xxxxxxxxxx
/* vi: set sw=4 ts=4: */
/*
* bb_inode.c --- routines to update the bad block inode.
*
* WARNING: This routine modifies a lot of state in the filesystem; if
* this routine returns an error, the bad block inode may be in an
* inconsistent state.
*
* Copyright (C) 1994, 1995 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
struct set_badblock_record {
ext2_badblocks_iterate bb_iter;
int bad_block_count;
blk_t *ind_blocks;
int max_ind_blocks;
int ind_blocks_size;
int ind_blocks_ptr;
char *block_buf;
errcode_t err;
};
static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
e2_blkcnt_t blockcnt,
blk_t ref_block, int ref_offset,
void *priv_data);
static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
e2_blkcnt_t blockcnt,
blk_t ref_block, int ref_offset,
void *priv_data);
/*
* Given a bad blocks bitmap, update the bad blocks inode to reflect
* the map.
*/
errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
{
errcode_t retval;
struct set_badblock_record rec;
struct ext2_inode inode;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!fs->block_map)
return EXT2_ET_NO_BLOCK_BITMAP;
rec.bad_block_count = 0;
rec.ind_blocks_size = rec.ind_blocks_ptr = 0;
rec.max_ind_blocks = 10;
retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t),
&rec.ind_blocks);
if (retval)
return retval;
memset(rec.ind_blocks, 0, rec.max_ind_blocks * sizeof(blk_t));
retval = ext2fs_get_mem(fs->blocksize, &rec.block_buf);
if (retval)
goto cleanup;
memset(rec.block_buf, 0, fs->blocksize);
rec.err = 0;
/*
* First clear the old bad blocks (while saving the indirect blocks)
*/
retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
BLOCK_FLAG_DEPTH_TRAVERSE, 0,
clear_bad_block_proc, &rec);
if (retval)
goto cleanup;
if (rec.err) {
retval = rec.err;