103 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * read_bb --- read the bad blocks inode
 | |
|  *
 | |
|  * Copyright (C) 1994 Theodore Ts'o.
 | |
|  *
 | |
|  * %Begin-Header%
 | |
|  * This file may be redistributed under the terms of the GNU Library
 | |
|  * General Public License, version 2.
 | |
|  * %End-Header%
 | |
|  */
 | |
| 
 | |
| #include "config.h"
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #if HAVE_UNISTD_H
 | |
| #include <unistd.h>
 | |
| #endif
 | |
| #include <fcntl.h>
 | |
| #include <time.h>
 | |
| #if HAVE_SYS_STAT_H
 | |
| #include <sys/stat.h>
 | |
| #endif
 | |
| #if HAVE_SYS_TYPES_H
 | |
| #include <sys/types.h>
 | |
| #endif
 | |
| 
 | |
| #include "ext2_fs.h"
 | |
| #include "ext2fs.h"
 | |
| 
 | |
| struct read_bb_record {
 | |
| 	ext2_badblocks_list	bb_list;
 | |
| 	errcode_t	err;
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Helper function for ext2fs_read_bb_inode()
 | |
|  */
 | |
| #ifdef __TURBOC__
 | |
|  #pragma argsused
 | |
| #endif
 | |
| static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
 | |
| 			  e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
 | |
| 			  blk_t ref_block EXT2FS_ATTR((unused)),
 | |
| 			  int ref_offset EXT2FS_ATTR((unused)),
 | |
| 			  void *priv_data)
 | |
| {
 | |
| 	struct read_bb_record *rb = (struct read_bb_record *) priv_data;
 | |
| 
 | |
| 	if (blockcnt < 0)
 | |
| 		return 0;
 | |
| 
 | |
| 	if ((*block_nr < fs->super->s_first_data_block) ||
 | |
| 	    (*block_nr >= ext2fs_blocks_count(fs->super)))
 | |
| 		return 0;	/* Ignore illegal blocks */
 | |
| 
 | |
| 	rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
 | |
| 	if (rb->err)
 | |
| 		return BLOCK_ABORT;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Reads the current bad blocks from the bad blocks inode.
 | |
|  */
 | |
| errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
 | |
| {
 | |
| 	errcode_t	retval;
 | |
| 	struct read_bb_record rb;
 | |
| 	struct ext2_inode inode;
 | |
| 	blk_t	numblocks;
 | |
| 
 | |
| 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 | |
| 
 | |
| 	if (!*bb_list) {
 | |
| 		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
 | |
| 		if (retval)
 | |
| 			return retval;
 | |
| 		numblocks = inode.i_blocks;
 | |
| 		if (!(ext2fs_has_feature_huge_file(fs->super) &&
 | |
| 		      (inode.i_flags & EXT4_HUGE_FILE_FL)))
 | |
| 			numblocks = numblocks / (fs->blocksize / 512);
 | |
| 		numblocks += 20;
 | |
| 		if (numblocks < 50)
 | |
| 			numblocks = 50;
 | |
| 		if (numblocks > 50000)
 | |
| 			numblocks = 500;
 | |
| 		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
 | |
| 		if (retval)
 | |
| 			return retval;
 | |
| 	}
 | |
| 
 | |
| 	rb.bb_list = *bb_list;
 | |
| 	rb.err = 0;
 | |
| 	retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, BLOCK_FLAG_READ_ONLY,
 | |
| 				       0, mark_bad_block, &rb);
 | |
| 	if (retval)
 | |
| 		return retval;
 | |
| 
 | |
| 	return rb.err;
 | |
| }
 | |
| 
 | |
| 
 |