Home | History | Annotate | Download | only in ext2fs
      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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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