1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * read_bb --- read the bad blocks inode
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1994 Theodore Ts'o.
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Library
8*6a54128fSAndroid Build Coastguard Worker * General Public License, version 2.
9*6a54128fSAndroid Build Coastguard Worker * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker */
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #include <string.h>
15*6a54128fSAndroid Build Coastguard Worker #if HAVE_UNISTD_H
16*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
19*6a54128fSAndroid Build Coastguard Worker #include <time.h>
20*6a54128fSAndroid Build Coastguard Worker #if HAVE_SYS_STAT_H
21*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
22*6a54128fSAndroid Build Coastguard Worker #endif
23*6a54128fSAndroid Build Coastguard Worker #if HAVE_SYS_TYPES_H
24*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
25*6a54128fSAndroid Build Coastguard Worker #endif
26*6a54128fSAndroid Build Coastguard Worker
27*6a54128fSAndroid Build Coastguard Worker #include "ext2_fs.h"
28*6a54128fSAndroid Build Coastguard Worker #include "ext2fs.h"
29*6a54128fSAndroid Build Coastguard Worker
30*6a54128fSAndroid Build Coastguard Worker struct read_bb_record {
31*6a54128fSAndroid Build Coastguard Worker ext2_badblocks_list bb_list;
32*6a54128fSAndroid Build Coastguard Worker errcode_t err;
33*6a54128fSAndroid Build Coastguard Worker };
34*6a54128fSAndroid Build Coastguard Worker
35*6a54128fSAndroid Build Coastguard Worker /*
36*6a54128fSAndroid Build Coastguard Worker * Helper function for ext2fs_read_bb_inode()
37*6a54128fSAndroid Build Coastguard Worker */
38*6a54128fSAndroid Build Coastguard Worker #ifdef __TURBOC__
39*6a54128fSAndroid Build Coastguard Worker #pragma argsused
40*6a54128fSAndroid Build Coastguard Worker #endif
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)41*6a54128fSAndroid Build Coastguard Worker static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
42*6a54128fSAndroid Build Coastguard Worker e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
43*6a54128fSAndroid Build Coastguard Worker blk_t ref_block EXT2FS_ATTR((unused)),
44*6a54128fSAndroid Build Coastguard Worker int ref_offset EXT2FS_ATTR((unused)),
45*6a54128fSAndroid Build Coastguard Worker void *priv_data)
46*6a54128fSAndroid Build Coastguard Worker {
47*6a54128fSAndroid Build Coastguard Worker struct read_bb_record *rb = (struct read_bb_record *) priv_data;
48*6a54128fSAndroid Build Coastguard Worker
49*6a54128fSAndroid Build Coastguard Worker if (blockcnt < 0)
50*6a54128fSAndroid Build Coastguard Worker return 0;
51*6a54128fSAndroid Build Coastguard Worker
52*6a54128fSAndroid Build Coastguard Worker if ((*block_nr < fs->super->s_first_data_block) ||
53*6a54128fSAndroid Build Coastguard Worker (*block_nr >= ext2fs_blocks_count(fs->super)))
54*6a54128fSAndroid Build Coastguard Worker return 0; /* Ignore illegal blocks */
55*6a54128fSAndroid Build Coastguard Worker
56*6a54128fSAndroid Build Coastguard Worker rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
57*6a54128fSAndroid Build Coastguard Worker if (rb->err)
58*6a54128fSAndroid Build Coastguard Worker return BLOCK_ABORT;
59*6a54128fSAndroid Build Coastguard Worker return 0;
60*6a54128fSAndroid Build Coastguard Worker }
61*6a54128fSAndroid Build Coastguard Worker
62*6a54128fSAndroid Build Coastguard Worker /*
63*6a54128fSAndroid Build Coastguard Worker * Reads the current bad blocks from the bad blocks inode.
64*6a54128fSAndroid Build Coastguard Worker */
ext2fs_read_bb_inode(ext2_filsys fs,ext2_badblocks_list * bb_list)65*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
66*6a54128fSAndroid Build Coastguard Worker {
67*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
68*6a54128fSAndroid Build Coastguard Worker struct read_bb_record rb;
69*6a54128fSAndroid Build Coastguard Worker struct ext2_inode inode;
70*6a54128fSAndroid Build Coastguard Worker blk_t numblocks;
71*6a54128fSAndroid Build Coastguard Worker
72*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
73*6a54128fSAndroid Build Coastguard Worker
74*6a54128fSAndroid Build Coastguard Worker if (!*bb_list) {
75*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
76*6a54128fSAndroid Build Coastguard Worker if (retval)
77*6a54128fSAndroid Build Coastguard Worker return retval;
78*6a54128fSAndroid Build Coastguard Worker numblocks = inode.i_blocks;
79*6a54128fSAndroid Build Coastguard Worker if (!(ext2fs_has_feature_huge_file(fs->super) &&
80*6a54128fSAndroid Build Coastguard Worker (inode.i_flags & EXT4_HUGE_FILE_FL)))
81*6a54128fSAndroid Build Coastguard Worker numblocks = numblocks / (fs->blocksize / 512);
82*6a54128fSAndroid Build Coastguard Worker numblocks += 20;
83*6a54128fSAndroid Build Coastguard Worker if (numblocks < 50)
84*6a54128fSAndroid Build Coastguard Worker numblocks = 50;
85*6a54128fSAndroid Build Coastguard Worker if (numblocks > 50000)
86*6a54128fSAndroid Build Coastguard Worker numblocks = 500;
87*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_badblocks_list_create(bb_list, numblocks);
88*6a54128fSAndroid Build Coastguard Worker if (retval)
89*6a54128fSAndroid Build Coastguard Worker return retval;
90*6a54128fSAndroid Build Coastguard Worker }
91*6a54128fSAndroid Build Coastguard Worker
92*6a54128fSAndroid Build Coastguard Worker rb.bb_list = *bb_list;
93*6a54128fSAndroid Build Coastguard Worker rb.err = 0;
94*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, BLOCK_FLAG_READ_ONLY,
95*6a54128fSAndroid Build Coastguard Worker 0, mark_bad_block, &rb);
96*6a54128fSAndroid Build Coastguard Worker if (retval)
97*6a54128fSAndroid Build Coastguard Worker return retval;
98*6a54128fSAndroid Build Coastguard Worker
99*6a54128fSAndroid Build Coastguard Worker return rb.err;
100*6a54128fSAndroid Build Coastguard Worker }
101*6a54128fSAndroid Build Coastguard Worker
102*6a54128fSAndroid Build Coastguard Worker
103