Coverage Report

Created: 2026-04-12 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/e2fsprogs/lib/ext2fs/gen_bitmap.c
Line
Count
Source
1
/*
2
 * gen_bitmap.c --- Generic (32-bit) bitmap routines
3
 *
4
 * Copyright (C) 2001 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
13
#include "config.h"
14
#include <stdio.h>
15
#include <string.h>
16
#if HAVE_UNISTD_H
17
#include <unistd.h>
18
#endif
19
#include <fcntl.h>
20
#include <time.h>
21
#if HAVE_SYS_STAT_H
22
#include <sys/stat.h>
23
#endif
24
#if HAVE_SYS_TYPES_H
25
#include <sys/types.h>
26
#endif
27
28
#include "ext2_fs.h"
29
#include "ext2fsP.h"
30
31
struct ext2fs_struct_generic_bitmap_32 {
32
  errcode_t magic;
33
  ext2_filsys   fs;
34
  __u32   start, end;
35
  __u32   real_end;
36
  char  * description;
37
  char  * bitmap;
38
  errcode_t base_error_code;
39
  __u32   reserved[7];
40
};
41
42
typedef struct ext2fs_struct_generic_bitmap_32 *ext2fs_generic_bitmap_32;
43
44
#define EXT2FS_IS_32_BITMAP(bmap) \
45
43.4k
  (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
46
43.4k
   ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
47
43.4k
   ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
48
49
#define EXT2FS_IS_64_BITMAP(bmap) \
50
0
  (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
51
0
   ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
52
0
   ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
53
54
/*
55
 * Used by previously inlined function, so we have to export this and
56
 * not change the function signature
57
 */
58
void ext2fs_warn_bitmap2(ext2fs_generic_bitmap gen_bitmap,
59
          int code, unsigned long arg)
60
16.2k
{
61
16.2k
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
62
63
16.2k
#ifndef OMIT_COM_ERR
64
16.2k
  if (bitmap->description)
65
16.2k
    com_err(0, bitmap->base_error_code+code,
66
16.2k
      "#%lu for %s", arg, bitmap->description);
67
0
  else
68
0
    com_err(0, bitmap->base_error_code + code, "#%lu", arg);
69
16.2k
#endif
70
16.2k
}
71
72
static errcode_t check_magic(ext2fs_generic_bitmap bitmap)
73
273
{
74
273
  if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) ||
75
273
       (bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) ||
76
251
       (bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP)))
77
0
    return EXT2_ET_MAGIC_GENERIC_BITMAP;
78
273
  return 0;
79
273
}
80
81
errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
82
             __u32 start, __u32 end, __u32 real_end,
83
             const char *descr, char *init_map,
84
             ext2fs_generic_bitmap *ret)
85
273
{
86
273
  ext2fs_generic_bitmap_32 bitmap;
87
273
  errcode_t   retval;
88
273
  size_t      size;
89
90
273
  retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap_32),
91
273
        &bitmap);
92
273
  if (retval)
93
0
    return retval;
94
95
273
  bitmap->magic = magic;
96
273
  bitmap->fs = fs;
97
273
  bitmap->start = start;
98
273
  bitmap->end = end;
99
273
  bitmap->real_end = real_end;
100
273
  switch (magic) {
101
22
  case EXT2_ET_MAGIC_INODE_BITMAP:
102
22
    bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
103
22
    break;
104
251
  case EXT2_ET_MAGIC_BLOCK_BITMAP:
105
251
    bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
106
251
    break;
107
0
  default:
108
0
    bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
109
273
  }
110
273
  if (descr) {
111
273
    retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
112
273
    if (retval) {
113
0
      ext2fs_free_mem(&bitmap);
114
0
      return retval;
115
0
    }
116
273
    strcpy(bitmap->description, descr);
117
273
  } else
118
0
    bitmap->description = 0;
119
120
273
  size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
121
  /* Round up to allow for the BT x86 instruction */
122
273
  size = (size + 7) & ~3;
123
273
  retval = ext2fs_get_mem(size, &bitmap->bitmap);
124
273
  if (retval) {
125
0
    ext2fs_free_mem(&bitmap->description);
126
0
    ext2fs_free_mem(&bitmap);
127
0
    return retval;
128
0
  }
129
130
273
  if (init_map)
131
0
    memcpy(bitmap->bitmap, init_map, size);
132
273
  else
133
273
    memset(bitmap->bitmap, 0, size);
134
273
  *ret = (ext2fs_generic_bitmap) bitmap;
135
273
  return 0;
136
273
}
137
138
errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
139
           __u32 end,
140
           __u32 real_end,
141
           const char *descr,
142
           ext2fs_generic_bitmap *ret)
143
0
{
144
0
  return ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_GENERIC_BITMAP, 0,
145
0
            start, end, real_end, descr, 0, ret);
146
0
}
147
148
errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap gen_src,
149
             ext2fs_generic_bitmap *dest)
150
0
{
151
0
  ext2fs_generic_bitmap_32 src = (ext2fs_generic_bitmap_32) gen_src;
152
153
0
  return (ext2fs_make_generic_bitmap(src->magic, src->fs,
154
0
             src->start, src->end,
155
0
             src->real_end,
156
0
             src->description, src->bitmap,
157
0
             dest));
158
0
}
159
160
void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap gen_bitmap)
161
273
{
162
273
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
163
164
273
  if (check_magic(gen_bitmap))
165
0
    return;
166
167
273
  bitmap->magic = 0;
168
273
  if (bitmap->description) {
169
273
    ext2fs_free_mem(&bitmap->description);
170
273
    bitmap->description = 0;
171
273
  }
172
273
  if (bitmap->bitmap) {
173
273
    ext2fs_free_mem(&bitmap->bitmap);
174
273
    bitmap->bitmap = 0;
175
273
  }
176
273
  ext2fs_free_mem(&bitmap);
177
273
}
178
179
int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
180
          blk_t bitno)
181
0
{
182
0
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
183
184
0
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
185
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
186
0
      ext2fs_warn_bitmap32(bitmap, __func__);
187
0
      return ext2fs_test_generic_bmap(bitmap, bitno);
188
0
    }
189
0
#ifndef OMIT_COM_ERR
190
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
191
0
      "test_bitmap(%lu)", (unsigned long) bitno);
192
0
#endif
193
0
    return 0;
194
0
  }
195
196
0
  if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
197
0
    ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
198
0
    return 0;
199
0
  }
200
0
  return ext2fs_test_bit(bitno - bitmap32->start, bitmap32->bitmap);
201
0
}
202
203
int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
204
           __u32 bitno)
205
43.4k
{
206
43.4k
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
207
208
43.4k
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
209
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
210
0
      ext2fs_warn_bitmap32(bitmap, __func__);
211
0
      return ext2fs_mark_generic_bmap(bitmap, bitno);
212
0
    }
213
0
#ifndef OMIT_COM_ERR
214
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
215
0
      "mark_bitmap(%lu)", (unsigned long) bitno);
216
0
#endif
217
0
    return 0;
218
0
  }
219
220
43.4k
  if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
221
2.69k
    ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
222
2.69k
    return 0;
223
2.69k
  }
224
40.7k
  return ext2fs_set_bit(bitno - bitmap32->start, bitmap32->bitmap);
225
43.4k
}
226
227
int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
228
             blk_t bitno)
229
0
{
230
0
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
231
232
0
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
233
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
234
0
      ext2fs_warn_bitmap32(bitmap, __func__);
235
0
      return ext2fs_unmark_generic_bmap(bitmap, bitno);
236
0
    }
237
0
#ifndef OMIT_COM_ERR
238
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
239
0
      "mark_bitmap(%lu)", (unsigned long) bitno);
240
0
#endif
241
0
    return 0;
242
0
  }
243
244
0
  if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
245
0
    ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
246
0
    return 0;
247
0
  }
248
0
  return ext2fs_clear_bit(bitno - bitmap32->start, bitmap32->bitmap);
249
0
}
250
251
__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
252
0
{
253
0
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
254
255
0
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
256
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
257
0
      ext2fs_warn_bitmap32(bitmap, __func__);
258
0
      return ext2fs_get_generic_bmap_start(bitmap);
259
0
    }
260
0
#ifndef OMIT_COM_ERR
261
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
262
0
      "get_bitmap_start");
263
0
#endif
264
0
    return 0;
265
0
  }
266
267
0
  return bitmap32->start;
268
0
}
269
270
__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
271
0
{
272
0
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
273
274
0
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
275
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
276
0
      ext2fs_warn_bitmap32(bitmap, __func__);
277
0
      return ext2fs_get_generic_bmap_end(bitmap);
278
0
    }
279
0
#ifndef OMIT_COM_ERR
280
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
281
0
      "get_bitmap_end");
282
0
#endif
283
0
    return 0;
284
0
  }
285
0
  return bitmap32->end;
286
0
}
287
288
void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
289
0
{
290
0
  ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
291
292
0
  if (!EXT2FS_IS_32_BITMAP(bitmap)) {
293
0
    if (EXT2FS_IS_64_BITMAP(bitmap)) {
294
0
      ext2fs_warn_bitmap32(bitmap, __func__);
295
0
      ext2fs_clear_generic_bmap(bitmap);
296
0
      return;
297
0
    }
298
0
#ifndef OMIT_COM_ERR
299
0
    com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
300
0
      "clear_generic_bitmap");
301
0
#endif
302
0
    return;
303
0
  }
304
305
0
  memset(bitmap32->bitmap, 0,
306
0
         (size_t) (((bitmap32->real_end - bitmap32->start) / 8) + 1));
307
0
}
308
309
errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap gen_bitmap,
310
            errcode_t magic, errcode_t neq,
311
            ext2_ino_t end, ext2_ino_t *oend)
312
0
{
313
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
314
315
0
  EXT2_CHECK_MAGIC(bitmap, magic);
316
317
0
  if (end > bitmap->real_end)
318
0
    return neq;
319
0
  if (oend)
320
0
    *oend = bitmap->end;
321
0
  bitmap->end = end;
322
0
  return 0;
323
0
}
324
325
errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
326
               __u32 new_end, __u32 new_real_end,
327
               ext2fs_generic_bitmap gen_bmap)
328
0
{
329
0
  ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
330
0
  errcode_t retval;
331
0
  size_t    size, new_size;
332
0
  __u32   bitno;
333
334
0
  if (!bmap || (bmap->magic != magic))
335
0
    return magic;
336
337
  /*
338
   * If we're expanding the bitmap, make sure all of the new
339
   * parts of the bitmap are zero.
340
   */
341
0
  if (new_end > bmap->end) {
342
0
    bitno = bmap->real_end;
343
0
    if (bitno > new_end)
344
0
      bitno = new_end;
345
0
    for (; bitno > bmap->end; bitno--)
346
0
      ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
347
0
  }
348
0
  if (new_real_end == bmap->real_end) {
349
0
    bmap->end = new_end;
350
0
    return 0;
351
0
  }
352
353
0
  size = ((bmap->real_end - bmap->start) / 8) + 1;
354
0
  new_size = ((new_real_end - bmap->start) / 8) + 1;
355
356
0
  if (size != new_size) {
357
0
    retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
358
0
    if (retval)
359
0
      return retval;
360
0
  }
361
0
  if (new_size > size)
362
0
    memset(bmap->bitmap + size, 0, new_size - size);
363
364
0
  bmap->end = new_end;
365
0
  bmap->real_end = new_real_end;
366
0
  return 0;
367
0
}
368
369
errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
370
          ext2fs_generic_bitmap gen_bm1,
371
          ext2fs_generic_bitmap gen_bm2)
372
0
{
373
0
  ext2fs_generic_bitmap_32 bm1 = (ext2fs_generic_bitmap_32) gen_bm1;
374
0
  ext2fs_generic_bitmap_32 bm2 = (ext2fs_generic_bitmap_32) gen_bm2;
375
0
  blk_t i;
376
377
0
  if (!bm1 || bm1->magic != magic)
378
0
    return magic;
379
0
  if (!bm2 || bm2->magic != magic)
380
0
    return magic;
381
382
0
  if ((bm1->start != bm2->start) ||
383
0
      (bm1->end != bm2->end) ||
384
0
      (memcmp(bm1->bitmap, bm2->bitmap,
385
0
        (size_t) (bm1->end - bm1->start)/8)))
386
0
    return neq;
387
388
0
  for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
389
0
    if (ext2fs_fast_test_block_bitmap(gen_bm1, i) !=
390
0
        ext2fs_fast_test_block_bitmap(gen_bm2, i))
391
0
      return neq;
392
393
0
  return 0;
394
0
}
395
396
void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap gen_map)
397
0
{
398
0
  ext2fs_generic_bitmap_32 map = (ext2fs_generic_bitmap_32) gen_map;
399
0
  __u32 i, j;
400
401
  /* Protect loop from wrap-around if map->real_end is maxed */
402
0
  for (i=map->end+1, j = i - map->start;
403
0
       i <= map->real_end && i > map->end;
404
0
       i++, j++)
405
0
    ext2fs_set_bit(j, map->bitmap);
406
0
}
407
408
errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
409
            errcode_t magic,
410
            __u32 start, __u32 num,
411
            void *out)
412
16.1k
{
413
16.1k
  ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
414
415
16.1k
  if (!bmap || (bmap->magic != magic))
416
0
    return magic;
417
418
16.1k
  if ((start < bmap->start) || (start+num-1 > bmap->real_end))
419
0
    return EXT2_ET_INVALID_ARGUMENT;
420
421
16.1k
  memcpy(out, bmap->bitmap + ((start - bmap->start) >> 3), (num+7) >> 3);
422
16.1k
  return 0;
423
16.1k
}
424
425
errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
426
            errcode_t magic,
427
            __u32 start, __u32 num,
428
            void *in)
429
272k
{
430
272k
  ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
431
432
272k
  if (!bmap || (bmap->magic != magic))
433
0
    return magic;
434
435
272k
  if ((start < bmap->start) || (start+num-1 > bmap->real_end))
436
0
    return EXT2_ET_INVALID_ARGUMENT;
437
438
272k
  memcpy(bmap->bitmap + ((start - bmap->start) >> 3), in, (num+7) >> 3);
439
272k
  return 0;
440
272k
}
441
442
/*
443
 * Compare @mem to zero buffer by 256 bytes.
444
 * Return 1 if @mem is zeroed memory, otherwise return 0.
445
 */
446
int ext2fs_mem_is_zero(const char *mem, size_t len)
447
0
{
448
0
  static const char zero_buf[256];
449
450
0
  while (len >= sizeof(zero_buf)) {
451
0
    if (memcmp(mem, zero_buf, sizeof(zero_buf)))
452
0
      return 0;
453
0
    len -= sizeof(zero_buf);
454
0
    mem += sizeof(zero_buf);
455
0
  }
456
  /* Deal with leftover bytes. */
457
0
  if (len)
458
0
    return !memcmp(mem, zero_buf, len);
459
0
  return 1;
460
0
}
461
462
/*
463
 * Return true if all of the bits in a specified range are clear
464
 */
465
static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap gen_bitmap,
466
              unsigned int start,
467
              unsigned int len)
468
0
{
469
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
470
0
  size_t start_byte, len_byte = len >> 3;
471
0
  unsigned int start_bit, len_bit = len % 8;
472
0
  int first_bit = 0;
473
0
  int last_bit  = 0;
474
0
  int mark_count = 0;
475
0
  int mark_bit = 0;
476
0
  int i;
477
0
  const char *ADDR = bitmap->bitmap;
478
479
0
  start -= bitmap->start;
480
0
  start_byte = start >> 3;
481
0
  start_bit = start % 8;
482
483
0
  if (start_bit != 0) {
484
    /*
485
     * The compared start block number or start inode number
486
     * is not the first bit in a byte.
487
     */
488
0
    mark_count = 8 - start_bit;
489
0
    if (len < 8 - start_bit) {
490
0
      mark_count = (int)len;
491
0
      mark_bit = len + start_bit - 1;
492
0
    } else
493
0
      mark_bit = 7;
494
495
0
    for (i = mark_count; i > 0; i--, mark_bit--)
496
0
      first_bit |= 1 << mark_bit;
497
498
    /*
499
     * Compare blocks or inodes in the first byte.
500
     * If there is any marked bit, this function returns 0.
501
     */
502
0
    if (first_bit & ADDR[start_byte])
503
0
      return 0;
504
0
    else if (len <= 8 - start_bit)
505
0
      return 1;
506
507
0
    start_byte++;
508
0
    len_bit = (len - mark_count) % 8;
509
0
    len_byte = (len - mark_count) >> 3;
510
0
  }
511
512
  /*
513
   * The compared start block number or start inode number is
514
   * the first bit in a byte.
515
   */
516
0
  if (len_bit != 0) {
517
    /*
518
     * The compared end block number or end inode number is
519
     * not the last bit in a byte.
520
     */
521
0
    for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--)
522
0
      last_bit |= 1 << mark_bit;
523
524
    /*
525
     * Compare blocks or inodes in the last byte.
526
     * If there is any marked bit, this function returns 0.
527
     */
528
0
    if (last_bit & ADDR[start_byte + len_byte])
529
0
      return 0;
530
0
    else if (len_byte == 0)
531
0
      return 1;
532
0
  }
533
534
  /* Check whether all bytes are 0 */
535
0
  return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
536
0
}
537
538
errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
539
            __u32 start, __u32 end,
540
            __u32 *out)
541
0
{
542
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
543
0
  blk_t b;
544
545
0
  if (start < bitmap->start || end > bitmap->end || start > end) {
546
0
    ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
547
0
    return EINVAL;
548
0
  }
549
550
0
  while (start <= end) {
551
0
    b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
552
0
    if (!b) {
553
0
      *out = start;
554
0
      return 0;
555
0
    }
556
0
    start++;
557
0
  }
558
559
0
  return ENOENT;
560
0
}
561
562
errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
563
                 __u32 start, __u32 end,
564
                 __u32 *out)
565
0
{
566
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
567
0
  blk_t b;
568
569
0
  if (start < bitmap->start || end > bitmap->end || start > end) {
570
0
    ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
571
0
    return EINVAL;
572
0
  }
573
574
0
  while (start <= end) {
575
0
    b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
576
0
    if (b) {
577
0
      *out = start;
578
0
      return 0;
579
0
    }
580
0
    start++;
581
0
  }
582
583
0
  return ENOENT;
584
0
}
585
586
int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
587
           blk_t block, int num)
588
0
{
589
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
590
591
0
  EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
592
0
  if ((block < bitmap->start) || (block > bitmap->real_end) ||
593
0
      (block+num-1 > bitmap->real_end)) {
594
0
    ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
595
0
           block, bitmap->description);
596
0
    return 0;
597
0
  }
598
0
  return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
599
0
                  bitmap, block, num);
600
0
}
601
602
int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap gen_bitmap,
603
           ext2_ino_t inode, int num)
604
0
{
605
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
606
607
0
  EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
608
0
  if ((inode < bitmap->start) || (inode > bitmap->real_end) ||
609
0
      (inode+num-1 > bitmap->real_end)) {
610
0
    ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
611
0
           inode, bitmap->description);
612
0
    return 0;
613
0
  }
614
0
  return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
615
0
                  bitmap, inode, num);
616
0
}
617
618
void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
619
            blk_t block, int num)
620
148k
{
621
148k
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
622
148k
  int i;
623
624
148k
  if ((block < bitmap->start) || (block > bitmap->end) ||
625
109k
      (block+num-1 > bitmap->end)) {
626
109k
    ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
627
109k
           bitmap->description);
628
109k
    return;
629
109k
  }
630
329M
  for (i=0; i < num; i++)
631
329M
    ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
632
38.6k
}
633
634
void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
635
              blk_t block, int num)
636
0
{
637
0
  ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
638
0
  int i;
639
640
0
  if ((block < bitmap->start) || (block > bitmap->end) ||
641
0
      (block+num-1 > bitmap->end)) {
642
0
    ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
643
0
           bitmap->description);
644
0
    return;
645
0
  }
646
0
  for (i=0; i < num; i++)
647
0
    ext2fs_fast_clear_bit(block + i - bitmap->start,
648
0
              bitmap->bitmap);
649
0
}
650