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