blob: e50560c57ac3691c54455969ad09b7f8fb970041 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * bitmaps.c --- routines to read, write, and manipulate the inode and
3 * block bitmaps.
4 *
Theodore Ts'o21c84b71997-04-29 16:15:03 +00005 * 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%
Theodore Ts'o3839e651997-04-26 13:21:57 +000011 */
12
13#include <stdio.h>
14#include <string.h>
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000015#if HAVE_UNISTD_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000016#include <unistd.h>
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000017#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000018#include <fcntl.h>
19#include <time.h>
Theodore Ts'o1d2ff461997-10-19 23:00:21 +000020#if HAVE_SYS_STAT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000021#include <sys/stat.h>
Theodore Ts'o1d2ff461997-10-19 23:00:21 +000022#endif
23#if HAVE_SYS_TYPES_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000024#include <sys/types.h>
Theodore Ts'o1d2ff461997-10-19 23:00:21 +000025#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000026
Theodore Ts'o3839e651997-04-26 13:21:57 +000027#include <linux/ext2_fs.h>
28
29#include "ext2fs.h"
30
Theodore Ts'oa29f4d31997-04-29 21:26:48 +000031static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
32 const char *descr, char *init_map,
33 ext2fs_generic_bitmap *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +000034{
Theodore Ts'o7b4e4531997-10-26 03:41:24 +000035 ext2fs_generic_bitmap bitmap;
36 errcode_t retval;
37 size_t size;
Theodore Ts'o3839e651997-04-26 13:21:57 +000038
Theodore Ts'o7b4e4531997-10-26 03:41:24 +000039 retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
40 (void **) &bitmap);
41 if (retval)
42 return retval;
Theodore Ts'of3db3561997-04-26 13:34:30 +000043
Theodore Ts'o1e3472c1997-04-29 14:53:37 +000044 bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
45 bitmap->fs = NULL;
46 bitmap->start = start;
47 bitmap->end = end;
48 bitmap->real_end = real_end;
49 bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
Theodore Ts'of3db3561997-04-26 13:34:30 +000050 if (descr) {
Theodore Ts'o7b4e4531997-10-26 03:41:24 +000051 retval = ext2fs_get_mem(strlen(descr)+1,
52 (void **) &bitmap->description);
53 if (retval) {
54 ext2fs_free_mem((void **) &bitmap);
55 return retval;
Theodore Ts'of3db3561997-04-26 13:34:30 +000056 }
57 strcpy(bitmap->description, descr);
58 } else
59 bitmap->description = 0;
60
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000061 size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
Theodore Ts'o7b4e4531997-10-26 03:41:24 +000062 retval = ext2fs_get_mem(size, (void **) &bitmap->bitmap);
63 if (retval) {
64 ext2fs_free_mem((void **) &bitmap->description);
65 ext2fs_free_mem((void **) &bitmap);
66 return retval;
Theodore Ts'of3db3561997-04-26 13:34:30 +000067 }
68
Theodore Ts'oa29f4d31997-04-29 21:26:48 +000069 if (init_map)
70 memcpy(bitmap->bitmap, init_map, size);
71 else
72 memset(bitmap->bitmap, 0, size);
Theodore Ts'of3db3561997-04-26 13:34:30 +000073 *ret = bitmap;
Theodore Ts'o3839e651997-04-26 13:21:57 +000074 return 0;
75}
76
Theodore Ts'oa29f4d31997-04-29 21:26:48 +000077errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
78 __u32 end,
79 __u32 real_end,
80 const char *descr,
81 ext2fs_generic_bitmap *ret)
82{
83 return make_bitmap(start, end, real_end, descr, 0, ret);
84}
85
86errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
87 ext2fs_generic_bitmap *dest)
88{
89 errcode_t retval;
90 ext2fs_generic_bitmap new;
91
92 retval = make_bitmap(src->start, src->end, src->real_end,
93 src->description, src->bitmap, &new);
94 if (retval)
95 return retval;
96 new->magic = src->magic;
97 new->fs = src->fs;
98 new->base_error_code = src->base_error_code;
Theodore Ts'o1e1da291997-06-09 14:51:29 +000099 *dest = new;
Theodore Ts'oa29f4d31997-04-29 21:26:48 +0000100 return 0;
101}
102
Theodore Ts'offf876b1997-09-13 00:32:29 +0000103void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
104{
105 __u32 i, j;
106
107 for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
108 ext2fs_set_bit(j, map->bitmap);
109
110 return;
111}
Theodore Ts'oa29f4d31997-04-29 21:26:48 +0000112
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000113errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
Theodore Ts'of3db3561997-04-26 13:34:30 +0000114 const char *descr,
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000115 ext2fs_inode_bitmap *ret)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000116{
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000117 ext2fs_inode_bitmap bitmap;
118 errcode_t retval;
119 __u32 start, end, real_end;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000120
121 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000122
123 fs->write_bitmaps = ext2fs_write_bitmaps;
124
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000125 start = 1;
126 end = fs->super->s_inodes_count;
127 real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
128
129 retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
130 descr, &bitmap);
131 if (retval)
132 return retval;
133
134 bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
135 bitmap->fs = fs;
136 bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
137
138 *ret = bitmap;
139 return 0;
140}
141
142errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
143 const char *descr,
144 ext2fs_block_bitmap *ret)
145{
146 ext2fs_block_bitmap bitmap;
147 errcode_t retval;
148 __u32 start, end, real_end;
149
150 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
151
152 fs->write_bitmaps = ext2fs_write_bitmaps;
153
154 start = fs->super->s_first_data_block;
155 end = fs->super->s_blocks_count-1;
156 real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
157 * fs->group_desc_count)-1 + start;
158
159 retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
160 descr, &bitmap);
161 if (retval)
162 return retval;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000163
164 bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
165 bitmap->fs = fs;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000166 bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
167
Theodore Ts'of3db3561997-04-26 13:34:30 +0000168 *ret = bitmap;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000169 return 0;
170}
171
Theodore Ts'of3db3561997-04-26 13:34:30 +0000172errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
173 ino_t end, ino_t *oend)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000174{
Theodore Ts'of3db3561997-04-26 13:34:30 +0000175 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
176
177 if (end > bitmap->real_end)
178 return EXT2_ET_FUDGE_INODE_BITMAP_END;
179 if (oend)
180 *oend = bitmap->end;
181 bitmap->end = end;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000182 return 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000183}
Theodore Ts'o3839e651997-04-26 13:21:57 +0000184
Theodore Ts'of3db3561997-04-26 13:34:30 +0000185errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
186 blk_t end, blk_t *oend)
187{
188 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
189
190 if (end > bitmap->real_end)
191 return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
192 if (oend)
193 *oend = bitmap->end;
194 bitmap->end = end;
195 return 0;
196}
Theodore Ts'o3839e651997-04-26 13:21:57 +0000197
Theodore Ts'of3db3561997-04-26 13:34:30 +0000198void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
199{
200 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
201 return;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000202
Theodore Ts'of3db3561997-04-26 13:34:30 +0000203 memset(bitmap->bitmap, 0,
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +0000204 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
Theodore Ts'of3db3561997-04-26 13:34:30 +0000205}
Theodore Ts'o3839e651997-04-26 13:21:57 +0000206
Theodore Ts'of3db3561997-04-26 13:34:30 +0000207void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
208{
209 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
210 return;
211
212 memset(bitmap->bitmap, 0,
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +0000213 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
Theodore Ts'of3db3561997-04-26 13:34:30 +0000214}