1e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall/*
2e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * gen_bitmap64.c --- routines to read, write, and manipulate the new qinode and
3e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * block bitmaps.
4e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
5e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * Copyright (C) 2007, 2008 Theodore Ts'o.
6e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
7e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * %Begin-Header%
8e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * This file may be redistributed under the terms of the GNU Public
9e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * License.
10e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * %End-Header%
11e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall */
12e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
13e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <stdio.h>
14e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <string.h>
15e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if HAVE_UNISTD_H
16e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <unistd.h>
17e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
18e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <fcntl.h>
19e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <time.h>
20e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <errno.h>
21e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if HAVE_SYS_STAT_H
22e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <sys/stat.h>
23e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
24e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if HAVE_SYS_TYPES_H
25e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <sys/types.h>
26e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
27e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef HAVE_SYS_TIME_H
28e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <sys/time.h>
29e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
30e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
31e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include "ext2_fs.h"
32e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include "ext2fsP.h"
33e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include "bmap64.h"
34e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
35e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall/*
36e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * Design of 64-bit bitmaps
37e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
38e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * In order maintain ABI compatibility with programs that don't
39e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * understand about 64-bit blocks/inodes,
40e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * ext2fs_allocate_inode_bitmap() and ext2fs_allocate_block_bitmap()
41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * will create old-style bitmaps unless the application passes the
42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * flag EXT2_FLAG_64BITS to ext2fs_open().  If this flag is
43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * passed, then we know the application has been recompiled, so we can
44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * use the new-style bitmaps.  If it is not passed, we have to return
45e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * an error if trying to open a filesystem which needs 64-bit bitmaps.
46e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * The new bitmaps use a new set of structure magic numbers, so that
48e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * both the old-style and new-style interfaces can identify which
49e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * version of the data structure was used.  Both the old-style and
50e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * new-style interfaces will support either type of bitmap, although
51e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * of course 64-bit operation will only be possible when both the
52e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * new-style interface and the new-style bitmap are used.
53e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
54e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * For example, the new bitmap interfaces will check the structure
55e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * magic numbers and so will be able to detect old-stype bitmap.  If
56e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * they see an old-style bitmap, they will pass it to the gen_bitmap.c
57e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * functions for handling.  The same will be true for the old
58e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * interfaces as well.
59e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *
60e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * The new-style interfaces will have several different back-end
61e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * implementations, so we can support different encodings that are
62e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * appropriate for different applications.  In general the default
63e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * should be whatever makes sense, and what the application/library
64e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * will use.  However, e2fsck may need specialized implementations for
65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * its own uses.  For example, when doing parent directory pointer
66e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * loop detections in pass 3, the bitmap will *always* be sparse, so
67e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * e2fsck can request an encoding which is optimized for that.
68e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall */
69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic void warn_bitmap(ext2fs_generic_bitmap bitmap,
71e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			int code, __u64 arg)
72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
73e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR
74e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (bitmap->description)
75e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(0, bitmap->base_error_code+code,
76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"#%llu for %s", arg, bitmap->description);
77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	else
78e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(0, bitmap->base_error_code + code, "#%llu", arg);
79e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
80e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
81e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
82e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
83e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define INC_STAT(map, name) map->stats.name
84e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#else
85e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define INC_STAT(map, name) ;;
86e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
87e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
88e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
89e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
90e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    int type, __u64 start, __u64 end,
91e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    __u64 real_end,
92e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    const char *descr,
93e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    ext2fs_generic_bitmap *ret)
94e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
95e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_generic_bitmap	bitmap;
96e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct ext2_bitmap_ops	*ops;
97e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2_ino_t num_dirs;
98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	errcode_t retval;
99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
100e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!type)
101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		type = EXT2FS_BMAP64_BITARRAY;
102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	switch (type) {
104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	case EXT2FS_BMAP64_BITARRAY:
105e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ops = &ext2fs_blkmap64_bitarray;
106e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		break;
107e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	case EXT2FS_BMAP64_RBTREE:
108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ops = &ext2fs_blkmap64_rbtree;
109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		break;
110e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	case EXT2FS_BMAP64_AUTODIR:
111e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_get_num_dirs(fs, &num_dirs);
112e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval || num_dirs > (fs->super->s_inodes_count / 320))
113e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ops = &ext2fs_blkmap64_bitarray;
114e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		else
115e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ops = &ext2fs_blkmap64_rbtree;
116e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		break;
117e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	default:
118e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
119e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
120e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
121e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
122e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    &bitmap);
123e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval)
124e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
125e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
126e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS
127e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (gettimeofday(&bitmap->stats.created,
128e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 (struct timezone *) NULL) == -1) {
129e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		perror("gettimeofday");
130e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&bitmap);
131e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
132e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
133e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->stats.type = type;
134e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
135e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
136e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* XXX factor out, repeated in copy_bmap */
137e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->magic = magic;
138e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->fs = fs;
139e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->start = start;
140e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->end = end;
141e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->real_end = real_end;
142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->bitmap_ops = ops;
143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->cluster_bits = 0;
144e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	switch (magic) {
145e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	case EXT2_ET_MAGIC_INODE_BITMAP64:
146e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
147e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		break;
148e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	case EXT2_ET_MAGIC_BLOCK_BITMAP64:
149e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->cluster_bits = fs->cluster_ratio_bits;
151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		break;
152e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	default:
153e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
154e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
155e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (descr) {
156e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
157e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval) {
158e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_free_mem(&bitmap);
159e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return retval;
160e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
161e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		strcpy(bitmap->description, descr);
162e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	} else
163e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->description = 0;
164e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
165e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = bitmap->bitmap_ops->new_bmap(fs, bitmap);
166e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval) {
167e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&bitmap->description);
168e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&bitmap);
169e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
171e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
172e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	*ret = bitmap;
173e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
174e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
175e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS
177e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct ext2_bmap_statistics *stats = &bitmap->stats;
180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
181e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	float mark_seq_perc = 0.0, test_seq_perc = 0.0;
182e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	float mark_back_perc = 0.0, test_back_perc = 0.0;
183e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
184e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	double inuse;
185e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct timeval now;
186e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
187e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
188e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (stats->test_count) {
189e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		test_seq_perc = ((float)stats->test_seq /
190e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				 stats->test_count) * 100;
191e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		test_back_perc = ((float)stats->test_back /
192e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  stats->test_count) * 100;
193e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
194e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
195e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (stats->mark_count) {
196e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		mark_seq_perc = ((float)stats->mark_seq /
197e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				 stats->mark_count) * 100;
198e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		mark_back_perc = ((float)stats->mark_back /
199e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				  stats->mark_count) * 100;
200e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
202e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (gettimeofday(&now, (struct timezone *) NULL) == -1) {
204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		perror("gettimeofday");
205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
207e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
208e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	inuse = (double) now.tv_sec + \
209e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		(((double) now.tv_usec) * 0.000001);
210e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	inuse -= (double) stats->created.tv_sec + \
211e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		(((double) stats->created.tv_usec) * 0.000001);
212e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
213e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "\n[+] %s bitmap (type %d)\n", bitmap->description,
214e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->type);
215e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "=================================================\n");
216e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
217e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16llu bits long\n",
218e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->real_end - bitmap->start);
219e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu copy_bmap\n%16lu resize_bmap\n",
220e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->copy_count, stats->resize_count);
221e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu mark bmap\n%16lu unmark_bmap\n",
222e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->mark_count, stats->unmark_count);
223e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu test_bmap\n%16lu mark_bmap_extent\n",
224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->test_count, stats->mark_ext_count);
225e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu unmark_bmap_extent\n"
226e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		"%16lu test_clear_bmap_extent\n",
227e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->unmark_ext_count, stats->test_ext_count);
228e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu set_bmap_range\n%16lu set_bmap_range\n",
229e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->set_range_count, stats->get_range_count);
230e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu clear_bmap\n%16lu contiguous bit test (%.2f%%)\n",
231e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->clear_count, stats->test_seq, test_seq_perc);
232e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16lu contiguous bit mark (%.2f%%)\n"
233e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		"%16llu bits tested backwards (%.2f%%)\n",
234e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->mark_seq, mark_seq_perc,
235e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->test_back, test_back_perc);
236e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	fprintf(stderr, "%16llu bits marked backwards (%.2f%%)\n"
237e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		"%16.2f seconds in use\n",
238e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		stats->mark_back, mark_back_perc, inuse);
239e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif /* BMAP_STATS_OPS */
240e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
241e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
242e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
243e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
244e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
245e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
246e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
247e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
248e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
249e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_generic_bitmap(bmap);
250e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
251e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
252e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
253e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
254e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
255e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
256e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS
257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (getenv("E2FSPROGS_BITMAP_STATS")) {
258e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_print_bmap_statistics(bmap);
259e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bmap->bitmap_ops->print_stats(bmap);
260e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
261e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
262e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
263e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->bitmap_ops->free_bmap(bmap);
264e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
265e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (bmap->description) {
266e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&bmap->description);
267e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bmap->description = 0;
268e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
269e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->magic = 0;
270e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_free_mem(&bmap);
271e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
272e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
273e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
274e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				   ext2fs_generic_bitmap *dest)
275e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
276e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	char *descr, *new_descr;
277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_generic_bitmap	new_bmap;
278e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	errcode_t retval;
279e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
280e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!src)
281e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
282e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
283e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(src))
284e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_copy_generic_bitmap(src, dest);
285e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
286e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(src))
287e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
288e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
289e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* Allocate a new bitmap struct */
290e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
291e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    &new_bmap);
292e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval)
293e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
294e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
295e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
296e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
297e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	src->stats.copy_count++;
298e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
299e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS
300e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (gettimeofday(&new_bmap->stats.created,
301e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 (struct timezone *) NULL) == -1) {
302e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		perror("gettimeofday");
303e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&new_bmap);
304e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 1;
305e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
306e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->stats.type = src->stats.type;
307e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
308e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
309e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* Copy all the high-level parts over */
310e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->magic = src->magic;
311e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->fs = src->fs;
312e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->start = src->start;
313e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->end = src->end;
314e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->real_end = src->real_end;
315e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->bitmap_ops = src->bitmap_ops;
316e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->base_error_code = src->base_error_code;
317e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	new_bmap->cluster_bits = src->cluster_bits;
318e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
319e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	descr = src->description;
320e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (descr) {
321e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_get_mem(strlen(descr)+10, &new_descr);
322e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval) {
323e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_free_mem(&new_bmap);
324e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return retval;
325e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
326e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		sprintf(new_descr, "copy of %s", descr);
327e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		new_bmap->description = new_descr;
328e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
329e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
330e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = src->bitmap_ops->copy_bmap(src, new_bmap);
331e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval) {
332e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&new_bmap->description);
333e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&new_bmap);
334e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
335e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
336e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
337e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	*dest = new_bmap;
338e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
339e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
340e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
341e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
342e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
343e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				     __u64 new_end,
344e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				     __u64 new_real_end)
345e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
346e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
347e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
348e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
349e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap))
350e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_resize_generic_bitmap(bmap->magic, new_end,
351e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						    new_real_end, bmap);
352e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
353e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
354e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
355e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
356e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, resize_count);
357e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
358e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end);
359e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
360e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
361e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
362e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					errcode_t neq,
363e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					__u64 end, __u64 *oend)
364e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
365e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
366e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
367e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
368e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap)) {
369e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2_ino_t tmp_oend;
370e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		int retval;
371e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
372e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_fudge_generic_bitmap_end(bitmap, bitmap->magic,
373e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							 neq, end, &tmp_oend);
374e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (oend)
375e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*oend = tmp_oend;
376e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
377e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
378e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
379e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
380e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
381e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
382e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (end > bitmap->real_end)
383e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return neq;
384e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (oend)
385e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*oend = bitmap->end;
386e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->end = end;
387e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
388e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
389e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
390e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
391e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
392e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
393e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
394e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
395e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap))
396e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_get_generic_bitmap_start(bitmap);
397e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
398e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
399e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
400e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
401e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bitmap->start;
402e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
403e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
404e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
405e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
406e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
407e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
408e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
409e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap))
410e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_get_generic_bitmap_end(bitmap);
411e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
412e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
413e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
414e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
415e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bitmap->end;
416e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
417e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
418e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap)
419e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
420e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap))
421e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_clear_generic_bitmap(bitmap);
422e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	else
423e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->bitmap_ops->clear_bmap (bitmap);
424e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
425e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
426e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
427e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			     __u64 arg)
428e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
429e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
430e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
431e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
432e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap)) {
433e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (arg & ~0xffffffffULL) {
434e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bitmap,
435e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    EXT2FS_MARK_ERROR, 0xffffffff);
436e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 0;
437e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
438e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_mark_generic_bitmap(bitmap, arg);
439e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
440e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
441e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
442e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
443e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
444e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	arg >>= bitmap->cluster_bits;
445e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
446e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
447e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (arg == bitmap->stats.last_marked + 1)
448e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->stats.mark_seq++;
449e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (arg < bitmap->stats.last_marked)
450e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->stats.mark_back++;
451e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->stats.last_marked = arg;
452e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->stats.mark_count++;
453e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
454e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
455e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((arg < bitmap->start) || (arg > bitmap->end)) {
456e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg);
457e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
458e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
459e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
460e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bitmap->bitmap_ops->mark_bmap(bitmap, arg);
461e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
462e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
463e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
464e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       __u64 arg)
465e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
468e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
469e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap)) {
470e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (arg & ~0xffffffffULL) {
471e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR,
472e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    0xffffffff);
473e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 0;
474e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
475e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_unmark_generic_bitmap(bitmap, arg);
476e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
477e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
478e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
479e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
480e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
481e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	arg >>= bitmap->cluster_bits;
482e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
483e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bitmap, unmark_count);
484e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
485e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((arg < bitmap->start) || (arg > bitmap->end)) {
486e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg);
487e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
488e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
489e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
490e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bitmap->bitmap_ops->unmark_bmap(bitmap, arg);
491e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
492e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
493e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
494e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			     __u64 arg)
495e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
496e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
497e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
498e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
499e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap)) {
500e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (arg & ~0xffffffffULL) {
501e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR,
502e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    0xffffffff);
503e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 0;
504e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
505e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_test_generic_bitmap(bitmap, arg);
506e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
507e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
508e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
509e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
510e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
511e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	arg >>= bitmap->cluster_bits;
512e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
513e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef BMAP_STATS_OPS
514e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->stats.test_count++;
515e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (arg == bitmap->stats.last_tested + 1)
516e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->stats.test_seq++;
517e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (arg < bitmap->stats.last_tested)
518e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		bitmap->stats.test_back++;
519e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bitmap->stats.last_tested = arg;
520e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
521e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
522e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((arg < bitmap->start) || (arg > bitmap->end)) {
523e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg);
524e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;
525e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
526e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
527e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bitmap->bitmap_ops->test_bmap(bitmap, arg);
528e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
529e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
530e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
531e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					__u64 start, unsigned int num,
532e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					void *in)
533e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
534e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
535e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
536e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
537e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
538e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((start+num-1) & ~0xffffffffULL) {
539e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR,
540e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    0xffffffff);
541e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return EINVAL;
542e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
543e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_set_generic_bitmap_range(bmap, bmap->magic,
544e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						       start, num, in);
545e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
546e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
547e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
548e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
549e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
550e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, set_range_count);
551e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
552e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in);
553e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
554e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
555e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
556e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					__u64 start, unsigned int num,
557e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					void *out)
558e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
559e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
560e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
561e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
562e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
563e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((start+num-1) & ~0xffffffffULL) {
564e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bmap,
565e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    EXT2FS_UNMARK_ERROR, 0xffffffff);
566e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return EINVAL;
567e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
568e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_get_generic_bitmap_range(bmap, bmap->magic,
569e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						       start, num, out);
570e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
571e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
572e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
573e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
574e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
575e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, get_range_count);
576e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
577e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bmap->bitmap_ops->get_bmap_range(bmap, start, num, out);
578e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
579e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
580e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_compare_generic_bmap(errcode_t neq,
581e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				      ext2fs_generic_bitmap bm1,
582e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				      ext2fs_generic_bitmap bm2)
583e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
584e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	i;
585e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
586e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bm1 || !bm2)
587e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
588e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (bm1->magic != bm2->magic)
589e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
590e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
591e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* Now we know both bitmaps have the same magic */
592e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bm1))
593e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_compare_generic_bitmap(bm1->magic, neq, bm1, bm2);
594e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
595e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bm1))
596e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
597e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
598e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((bm1->start != bm2->start) ||
599e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    (bm1->end != bm2->end))
600e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return neq;
601e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
602e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
603e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (ext2fs_test_generic_bmap(bm1, i) !=
604e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    ext2fs_test_generic_bmap(bm2, i))
605e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return neq;
606e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
607e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
608e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
609e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
610e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
611e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
612e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	__u64	start, num;
613e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
614e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
615e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_set_generic_bitmap_padding(bmap);
616e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
617e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
618e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
619e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	start = bmap->end + 1;
620e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	num = bmap->real_end - bmap->end;
621e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->bitmap_ops->mark_bmap_extent(bmap, start, num);
622e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* XXX ought to warn on error */
623e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
624e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
625e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
626e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				    blk64_t block, unsigned int num)
627e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
628e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	__u64	end = block + num;
629e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
630e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
631e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
632e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
633e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (num == 1)
634e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return !ext2fs_test_generic_bmap((ext2fs_generic_bitmap)
635e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						 bmap, block);
636e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
637e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
638e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((block+num-1) & ~0xffffffffULL) {
639e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
640e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    EXT2FS_UNMARK_ERROR, 0xffffffff);
641e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return EINVAL;
642e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
643e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return ext2fs_test_block_bitmap_range(
644e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			(ext2fs_generic_bitmap) bmap, block, num);
645e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
646e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
647e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
648e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
649e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
650e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, test_ext_count);
651e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
652e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* convert to clusters if necessary */
653e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	block >>= bmap->cluster_bits;
654e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end += (1 << bmap->cluster_bits) - 1;
655e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end >>= bmap->cluster_bits;
656e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	num = end - block;
657e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
658e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
659e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block,
660e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				   bmap->description);
661e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
662e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
663e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
664e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return bmap->bitmap_ops->test_clear_bmap_extent(bmap, block, num);
665e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
666e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
667e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
668e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				     blk64_t block, unsigned int num)
669e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
670e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	__u64	end = block + num;
671e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
672e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
673e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
674e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
675e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
676e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((block+num-1) & ~0xffffffffULL) {
677e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
678e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    EXT2FS_UNMARK_ERROR, 0xffffffff);
679e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return;
680e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
681e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_mark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
682e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					       block, num);
683e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
684e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
685e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
686e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
687e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
688e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, mark_ext_count);
689e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
690e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* convert to clusters if necessary */
691e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	block >>= bmap->cluster_bits;
692e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end += (1 << bmap->cluster_bits) - 1;
693e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end >>= bmap->cluster_bits;
694e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	num = end - block;
695e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
696e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
697e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
698e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				   bmap->description);
699e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
700e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
701e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
702e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->bitmap_ops->mark_bmap_extent(bmap, block, num);
703e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
704e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
705e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
706e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				       blk64_t block, unsigned int num)
707e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
708e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	__u64	end = block + num;
709e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
710e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bmap)
711e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
712e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
713e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bmap)) {
714e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if ((block+num-1) & ~0xffffffffULL) {
715e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
716e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    EXT2FS_UNMARK_ERROR, 0xffffffff);
717e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return;
718e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
719e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_unmark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
720e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						 block, num);
721e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
722e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
723e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bmap))
724e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
725e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
726e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	INC_STAT(bmap, unmark_ext_count);
727e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
728e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	/* convert to clusters if necessary */
729e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	block >>= bmap->cluster_bits;
730e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end += (1 << bmap->cluster_bits) - 1;
731e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end >>= bmap->cluster_bits;
732e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	num = end - block;
733e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
734e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
735e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
736e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				   bmap->description);
737e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return;
738e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
739e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
740e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num);
741e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
742e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
743e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
744e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
745e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR
746e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (bitmap && bitmap->description)
747e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
748e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"called %s with 64-bit bitmap for %s", func,
749e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			bitmap->description);
750e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	else
751e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
752e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			"called %s with 64-bit bitmap", func);
753e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
754e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
755e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
756e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
757e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					   ext2fs_block_bitmap *bitmap)
758e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
759e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_block_bitmap	cmap, bmap;
760e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	errcode_t		retval;
761e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t			i, b_end, c_end;
762e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int			n, ratio;
763e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
764e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap = *bitmap;
765e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
766e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap))
767e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return 0;	/* Nothing to do */
768e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
769e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap",
770e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					      &cmap);
771e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval)
772e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
773e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
774e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	i = bmap->start;
775e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	b_end = bmap->end;
776e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->end = bmap->real_end;
777e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	c_end = cmap->end;
778e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	cmap->end = cmap->real_end;
779e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	n = 0;
780e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ratio = 1 << fs->cluster_ratio_bits;
781e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	while (i < bmap->real_end) {
782e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (ext2fs_test_block_bitmap2(bmap, i)) {
783e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_mark_block_bitmap2(cmap, i);
784e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			i += ratio - n;
785e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			n = 0;
786e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			continue;
787e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
788e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		i++; n++;
789e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (n >= ratio)
790e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			n = 0;
791e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
792e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	bmap->end = b_end;
793e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	cmap->end = c_end;
794e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ext2fs_free_block_bitmap(bmap);
795e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	*bitmap = cmap;
796e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return 0;
797e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
798e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
799e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
800e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					      __u64 start, __u64 end, __u64 *out)
801e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
802e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int b;
803e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
804e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!bitmap)
805e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
806e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
807e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
808e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return bitmap->bitmap_ops->find_first_zero(bitmap, start,
809e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							   end, out);
810e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
811e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (EXT2FS_IS_32_BITMAP(bitmap)) {
812e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk_t blk = 0;
813e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		errcode_t retval;
814e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
815e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (((start) & ~0xffffffffULL) ||
816e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    ((end) & ~0xffffffffULL)) {
817e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
818e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return EINVAL;
819e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
820e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
821e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		retval = ext2fs_find_first_zero_generic_bitmap(bitmap, start,
822e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							       end, &blk);
823e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval == 0)
824e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*out = blk;
825e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return retval;
826e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
827e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
828e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (!EXT2FS_IS_64_BITMAP(bitmap))
829e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
830e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
831e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	start >>= bitmap->cluster_bits;
832e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	end >>= bitmap->cluster_bits;
833e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
834e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (start < bitmap->start || end > bitmap->end || start > end) {
835e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
836e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		return EINVAL;
837e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
838e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
839e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	while (start <= end) {
840e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		b = bitmap->bitmap_ops->test_bmap(bitmap, start);
841e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (!b) {
842e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*out = start << bitmap->cluster_bits;
843e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return 0;
844e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
845e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		start++;
846e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
847e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
848e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return ENOENT;
849e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
850