• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * bitmaps.c --- routines to read, write, and manipulate the inode and
3  * block bitmaps.
4  *
5  * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6  *
7  * %Begin-Header%
8  * This file may be redistributed under the terms of the GNU Public
9  * License.
10  * %End-Header%
11  */
12 
13 #include <stdio.h>
14 #include <string.h>
15 #if HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <fcntl.h>
19 #include <time.h>
20 #if HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 #if HAVE_SYS_TYPES_H
24 #include <sys/types.h>
25 #endif
26 
27 #include "ext2_fs.h"
28 #include "ext2fs.h"
29 
make_bitmap(__u32 start,__u32 end,__u32 real_end,const char * descr,char * init_map,ext2fs_generic_bitmap * ret)30 static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
31 			     const char *descr, char *init_map,
32 			     ext2fs_generic_bitmap *ret)
33 {
34 	ext2fs_generic_bitmap	bitmap;
35 	errcode_t		retval;
36 	size_t			size;
37 
38 	retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
39 				&bitmap);
40 	if (retval)
41 		return retval;
42 
43 	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
44 	bitmap->fs = NULL;
45 	bitmap->start = start;
46 	bitmap->end = end;
47 	bitmap->real_end = real_end;
48 	bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
49 	if (descr) {
50 		retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
51 		if (retval) {
52 			ext2fs_free_mem(&bitmap);
53 			return retval;
54 		}
55 		strcpy(bitmap->description, descr);
56 	} else
57 		bitmap->description = 0;
58 
59 	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
60 	retval = ext2fs_get_mem(size, &bitmap->bitmap);
61 	if (retval) {
62 		ext2fs_free_mem(&bitmap->description);
63 		ext2fs_free_mem(&bitmap);
64 		return retval;
65 	}
66 
67 	if (init_map)
68 		memcpy(bitmap->bitmap, init_map, size);
69 	else
70 		memset(bitmap->bitmap, 0, size);
71 	*ret = bitmap;
72 	return 0;
73 }
74 
ext2fs_allocate_generic_bitmap(__u32 start,__u32 end,__u32 real_end,const char * descr,ext2fs_generic_bitmap * ret)75 errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
76 					 __u32 end,
77 					 __u32 real_end,
78 					 const char *descr,
79 					 ext2fs_generic_bitmap *ret)
80 {
81 	return make_bitmap(start, end, real_end, descr, 0, ret);
82 }
83 
ext2fs_copy_bitmap(ext2fs_generic_bitmap src,ext2fs_generic_bitmap * dest)84 errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
85 			     ext2fs_generic_bitmap *dest)
86 {
87 	errcode_t		retval;
88 	ext2fs_generic_bitmap	new_map;
89 
90 	retval = make_bitmap(src->start, src->end, src->real_end,
91 			     src->description, src->bitmap, &new_map);
92 	if (retval)
93 		return retval;
94 	new_map->magic = src->magic;
95 	new_map->fs = src->fs;
96 	new_map->base_error_code = src->base_error_code;
97 	*dest = new_map;
98 	return 0;
99 }
100 
ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)101 void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
102 {
103 	__u32	i, j;
104 
105 	/* Protect loop from wrap-around if map->real_end is maxed */
106 	for (i=map->end+1, j = i - map->start;
107 	     i <= map->real_end && i > map->end;
108 	     i++, j++)
109 		ext2fs_set_bit(j, map->bitmap);
110 
111 	return;
112 }
113 
ext2fs_allocate_inode_bitmap(ext2_filsys fs,const char * descr,ext2fs_inode_bitmap * ret)114 errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
115 				       const char *descr,
116 				       ext2fs_inode_bitmap *ret)
117 {
118 	ext2fs_inode_bitmap bitmap;
119 	errcode_t	retval;
120 	__u32		start, end, real_end;
121 
122 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
123 
124 	fs->write_bitmaps = ext2fs_write_bitmaps;
125 
126 	start = 1;
127 	end = fs->super->s_inodes_count;
128 	real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
129 
130 	retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
131 						descr, &bitmap);
132 	if (retval)
133 		return retval;
134 
135 	bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
136 	bitmap->fs = fs;
137 	bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
138 
139 	*ret = bitmap;
140 	return 0;
141 }
142 
ext2fs_allocate_block_bitmap(ext2_filsys fs,const char * descr,ext2fs_block_bitmap * ret)143 errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
144 				       const char *descr,
145 				       ext2fs_block_bitmap *ret)
146 {
147 	ext2fs_block_bitmap bitmap;
148 	errcode_t	retval;
149 	__u32		start, end, real_end;
150 
151 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
152 
153 	fs->write_bitmaps = ext2fs_write_bitmaps;
154 
155 	start = fs->super->s_first_data_block;
156 	end = fs->super->s_blocks_count-1;
157 	real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
158 		    * fs->group_desc_count)-1 + start;
159 
160 	retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
161 						descr, &bitmap);
162 	if (retval)
163 		return retval;
164 
165 	bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
166 	bitmap->fs = fs;
167 	bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
168 
169 	*ret = bitmap;
170 	return 0;
171 }
172 
ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,ext2_ino_t end,ext2_ino_t * oend)173 errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
174 					ext2_ino_t end, ext2_ino_t *oend)
175 {
176 	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
177 
178 	if (end > bitmap->real_end)
179 		return EXT2_ET_FUDGE_INODE_BITMAP_END;
180 	if (oend)
181 		*oend = bitmap->end;
182 	bitmap->end = end;
183 	return 0;
184 }
185 
ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,blk_t end,blk_t * oend)186 errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
187 					blk_t end, blk_t *oend)
188 {
189 	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
190 
191 	if (end > bitmap->real_end)
192 		return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
193 	if (oend)
194 		*oend = bitmap->end;
195 	bitmap->end = end;
196 	return 0;
197 }
198 
ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)199 void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
200 {
201 	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
202 		return;
203 
204 	memset(bitmap->bitmap, 0,
205 	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
206 }
207 
ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)208 void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
209 {
210 	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
211 		return;
212 
213 	memset(bitmap->bitmap, 0,
214 	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
215 }
216