X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fbb_inode.c;h=268eecf8b7803d247394a58a14ad24d20e5ebc2b;hb=62f17f36031102a2a40fac338e063c556f73b94a;hp=a5dd3a965a8721e943a5a50bba5aa95b12fc7ad5;hpb=21c84b71e205b5ab13f14343da5645dcc985856d;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c index a5dd3a9..268eecf 100644 --- a/lib/ext2fs/bb_inode.c +++ b/lib/ext2fs/bb_inode.c @@ -1,32 +1,34 @@ /* * 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. + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. * %End-Header% */ +#include "config.h" #include #include +#if HAVE_UNISTD_H #include -#include +#endif #include #include +#if HAVE_SYS_STAT_H #include +#endif +#if HAVE_SYS_TYPES_H #include -#if HAVE_ERRNO_H -#include #endif -#include - +#include "ext2_fs.h" #include "ext2fs.h" struct set_badblock_record { @@ -40,12 +42,15 @@ struct set_badblock_record { errcode_t err; }; -static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, - blk_t ref_block, int ref_offset, void *private); -static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, +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 *private); - + void *priv_data); + /* * Given a bad blocks bitmap, update the bad blocks inode to reflect * the map. @@ -55,30 +60,27 @@ 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; - blk_t blk; - + 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; + + memset(&rec, 0, sizeof(rec)); rec.max_ind_blocks = 10; - rec.ind_blocks = malloc(rec.max_ind_blocks * sizeof(blk_t)); - if (!rec.ind_blocks) - return ENOMEM; + retval = ext2fs_get_array(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)); - rec.block_buf = malloc(fs->blocksize); - if (!rec.block_buf) { - retval = ENOMEM; + 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) + * First clear the old bad blocks (while saving the indirect blocks) */ retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, BLOCK_FLAG_DEPTH_TRAVERSE, 0, @@ -89,7 +91,7 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list) retval = rec.err; goto cleanup; } - + /* * Now set the bad blocks! * @@ -102,49 +104,39 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list) &rec.bb_iter); if (retval) goto cleanup; - while (ext2fs_badblocks_list_iterate(rec.bb_iter, &blk)) { - ext2fs_mark_block_bitmap(fs->block_map, blk); - } - ext2fs_badblocks_list_iterate_end(rec.bb_iter); - ext2fs_mark_bb_dirty(fs); - - retval = ext2fs_badblocks_list_iterate_begin(bb_list, - &rec.bb_iter); - if (retval) - goto cleanup; retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, BLOCK_FLAG_APPEND, 0, set_bad_block_proc, &rec); ext2fs_badblocks_list_iterate_end(rec.bb_iter); - if (retval) + if (retval) goto cleanup; if (rec.err) { retval = rec.err; goto cleanup; } } - + /* * Update the bad block inode's mod time and block count - * field. + * field. */ retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode); if (retval) goto cleanup; - - inode.i_atime = inode.i_mtime = time(0); + + inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0); if (!inode.i_ctime) - inode.i_ctime = time(0); - inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512); + inode.i_ctime = fs->now ? fs->now : time(0); + ext2fs_iblk_set(fs, &inode, rec.bad_block_count); inode.i_size = rec.bad_block_count * fs->blocksize; retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode); if (retval) goto cleanup; - + cleanup: - free(rec.ind_blocks); - free(rec.block_buf); + ext2fs_free_mem(&rec.ind_blocks); + ext2fs_free_mem(&rec.block_buf); return retval; } @@ -154,12 +146,19 @@ cleanup: * Clear the bad blocks in the bad block inode, while saving the * indirect blocks. */ -static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, - blk_t ref_block, int ref_offset, void *private) +#ifdef __TURBOC__ + #pragma argsused +#endif +static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, + blk_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) { struct set_badblock_record *rec = (struct set_badblock_record *) - private; - int group; + priv_data; + errcode_t retval; + unsigned long old_size; if (!*block_nr) return 0; @@ -167,7 +166,7 @@ static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, /* * If the block number is outrageous, clear it and ignore it. */ - if (*block_nr >= fs->super->s_blocks_count || + if (*block_nr >= ext2fs_blocks_count(fs->super) || *block_nr < fs->super->s_first_data_block) { *block_nr = 0; return BLOCK_CHANGED; @@ -175,12 +174,14 @@ static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, if (blockcnt < 0) { if (rec->ind_blocks_size >= rec->max_ind_blocks) { + old_size = rec->max_ind_blocks * sizeof(blk_t); rec->max_ind_blocks += 10; - rec->ind_blocks = realloc(rec->ind_blocks, - rec->max_ind_blocks * - sizeof(blk_t)); - if (!rec->ind_blocks) { - rec->err = ENOMEM; + retval = ext2fs_resize_mem(old_size, + rec->max_ind_blocks * sizeof(blk_t), + &rec->ind_blocks); + if (retval) { + rec->max_ind_blocks -= 10; + rec->err = retval; return BLOCK_ABORT; } } @@ -190,32 +191,31 @@ static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt, /* * Mark the block as unused, and update accounting information */ - ext2fs_unmark_block_bitmap(fs->block_map, *block_nr); - ext2fs_mark_bb_dirty(fs); - group = ext2fs_group_of_blk(fs, *block_nr); - fs->group_desc[group].bg_free_blocks_count++; - fs->super->s_free_blocks_count++; - ext2fs_mark_super_dirty(fs); - + ext2fs_block_alloc_stats2(fs, *block_nr, -1); + *block_nr = 0; return BLOCK_CHANGED; } - + /* * Helper function for update_bb_inode() * * Set the block list in the bad block inode, using the supplied bitmap. */ +#ifdef __TURBOC__ + #pragma argsused +#endif static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, - int blockcnt, blk_t ref_block, - int ref_offset, void *private) + e2_blkcnt_t blockcnt, + blk_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) { struct set_badblock_record *rec = (struct set_badblock_record *) - private; + priv_data; errcode_t retval; blk_t blk; - int group; if (blockcnt >= 0) { /* @@ -235,7 +235,7 @@ static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, retry: if (rec->ind_blocks_ptr < rec->ind_blocks_size) { blk = rec->ind_blocks[rec->ind_blocks_ptr++]; - if (ext2fs_test_block_bitmap(fs->block_map, blk)) + if (ext2fs_test_block_bitmap2(fs->block_map, blk)) goto retry; } else { retval = ext2fs_new_block(fs, 0, 0, &blk); @@ -244,23 +244,18 @@ static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, return BLOCK_ABORT; } } - retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf); + retval = io_channel_write_blk64(fs->io, blk, 1, rec->block_buf); if (retval) { rec->err = retval; return BLOCK_ABORT; } - ext2fs_mark_block_bitmap(fs->block_map, blk); - ext2fs_mark_bb_dirty(fs); } - + /* * Update block counts */ - group = ext2fs_group_of_blk(fs, blk); - fs->group_desc[group].bg_free_blocks_count--; - fs->super->s_free_blocks_count--; - ext2fs_mark_super_dirty(fs); - + ext2fs_block_alloc_stats2(fs, blk, +1); + *block_nr = blk; return BLOCK_CHANGED; }