Coverage Report

Created: 2025-06-13 07:22

/src/libfsxfs/libfsxfs/libfsxfs_extent_list.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Extent list functions
3
 *
4
 * Copyright (C) 2020-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libfsxfs_definitions.h"
27
#include "libfsxfs_extent.h"
28
#include "libfsxfs_extent_list.h"
29
#include "libfsxfs_extents.h"
30
#include "libfsxfs_libcdata.h"
31
#include "libfsxfs_libcerror.h"
32
#include "libfsxfs_libcnotify.h"
33
34
/* Reads the extent list data
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libfsxfs_extent_list_read_data(
38
     libcdata_array_t *extents_array,
39
     uint64_t number_of_blocks,
40
     uint32_t number_of_extents,
41
     const uint8_t *data,
42
     size_t data_size,
43
     uint8_t add_sparse_extents,
44
     libcerror_error_t **error )
45
1.33k
{
46
1.33k
  libfsxfs_extent_t *last_extent   = NULL;
47
1.33k
  libfsxfs_extent_t *sparse_extent = NULL;
48
1.33k
  static char *function            = "libfsxfs_extent_list_read_data";
49
1.33k
  uint64_t logical_block_number    = 0;
50
1.33k
  int entry_index                  = 0;
51
52
1.33k
  if( libfsxfs_extents_read_data(
53
1.33k
       extents_array,
54
1.33k
       number_of_extents,
55
1.33k
       data,
56
1.33k
       data_size,
57
1.33k
       add_sparse_extents,
58
1.33k
       error ) != 1 )
59
68
  {
60
68
    libcerror_error_set(
61
68
     error,
62
68
     LIBCERROR_ERROR_DOMAIN_IO,
63
68
     LIBCERROR_IO_ERROR_READ_FAILED,
64
68
     "%s: unable to read data extents.",
65
68
     function );
66
67
68
    goto on_error;
68
68
  }
69
1.26k
  if( libfsxfs_extents_get_last_extent(
70
1.26k
       extents_array,
71
1.26k
       &last_extent,
72
1.26k
       error ) != 1 )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
77
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
78
0
     "%s: unable to retrieve last extent.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
1.26k
  if( last_extent != NULL )
84
1.22k
  {
85
1.22k
    logical_block_number = last_extent->logical_block_number + last_extent->number_of_blocks;
86
1.22k
  }
87
1.26k
  if( ( add_sparse_extents != 0 )
88
1.26k
   && ( logical_block_number < number_of_blocks ) )
89
146
  {
90
146
    if( ( last_extent == NULL )
91
146
     || ( ( last_extent->range_flags & LIBFSXFS_EXTENT_FLAG_IS_SPARSE ) == 0 ) )
92
117
    {
93
117
      if( libfsxfs_extent_initialize(
94
117
           &sparse_extent,
95
117
           error ) != 1 )
96
0
      {
97
0
        libcerror_error_set(
98
0
         error,
99
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
100
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
101
0
         "%s: unable to create sparse extent.",
102
0
         function );
103
104
0
        goto on_error;
105
0
      }
106
117
      sparse_extent->logical_block_number = logical_block_number;
107
117
      sparse_extent->range_flags          = LIBFSXFS_EXTENT_FLAG_IS_SPARSE;
108
109
117
      if( libcdata_array_append_entry(
110
117
           extents_array,
111
117
           &entry_index,
112
117
           (intptr_t *) sparse_extent,
113
117
           error ) != 1 )
114
0
      {
115
0
        libcerror_error_set(
116
0
         error,
117
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
118
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
119
0
         "%s: unable to append sparse extent to array.",
120
0
         function );
121
122
0
        goto on_error;
123
0
      }
124
117
      last_extent   = sparse_extent;
125
117
      sparse_extent = NULL;
126
117
    }
127
146
    last_extent->number_of_blocks += number_of_blocks - logical_block_number;
128
129
#if defined( HAVE_DEBUG_OUTPUT )
130
    if( libcnotify_verbose != 0 )
131
    {
132
      libcnotify_printf(
133
       "%s: logical block number\t\t\t: %" PRIu64 "\n",
134
       function,
135
       last_extent->logical_block_number );
136
137
      libcnotify_printf(
138
       "%s: physical block number\t\t\t: %" PRIu64 "\n",
139
       function,
140
       last_extent->physical_block_number );
141
142
      libcnotify_printf(
143
       "%s: number of blocks\t\t\t: %" PRIu64 "\n",
144
       function,
145
       last_extent->number_of_blocks );
146
147
      libcnotify_printf(
148
       "\n" );
149
    }
150
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
151
146
  }
152
1.26k
  return( 1 );
153
154
68
on_error:
155
68
  if( sparse_extent != NULL )
156
0
  {
157
0
    libfsxfs_extent_free(
158
0
     &sparse_extent,
159
0
     NULL );
160
0
  }
161
68
  libcdata_array_empty(
162
68
   extents_array,
163
68
   (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_extent_free,
164
68
   NULL );
165
166
68
  return( -1 );
167
1.26k
}
168