Coverage Report

Created: 2026-03-18 06:51

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