Many files:
  Checkin of e2fsprogs 1.03.

diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index ba77b93..eba0b9f 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,40 @@
+Wed Mar 27 00:33:40 1996    <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.03
+
+Tue Mar 26 12:06:32 1996    <tytso@rsts-11.mit.edu>
+
+	* bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit):
+		Change the m68k bit numbering for bitmasks to match with
+		the bit numbering used by all other ext2 implementations.
+
+Thu Mar  7 03:37:00 1996    <tytso@rsts-11.mit.edu>
+
+	* inode.c (ext2fs_get_next_inode, ext2fs_close_inode_scan, 
+	ext2fs_open_inode_scan): Support dynamically-sized inodes.
+
+Wed Mar  6 12:26:29 1996    <tytso@rsts-11.mit.edu>
+
+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Support
+		dynamically-sized inodes.
+
+	* openfs.c (ext2fs_open): Allow dynamic revision filesystem to be
+	        loaded.
+
+Tue Mar  5 03:49:37 1996    <tytso@rsts-11.mit.edu>
+
+	* initialize.c (ext2fs_initialize): Catch an error condition where
+		the passed in size is *really* too small.
+
+	* alloc.c (ext2fs_new_inode): 
+	* ext2fs.h (EXT2_FIRST_INODE): Add support for dynamic revision to
+		get first inode.
+
+Wed Feb 21 15:56:17 1996    <tytso@rsts-11.mit.edu>
+
+	* getsize.c (ext2fs_get_device_size): Open the device read-only
+		when trying to determine its size.
+
 Wed Jan 31 11:06:08 1996    <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.02
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index 5465e80..c048879 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -43,8 +43,8 @@
 		dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
 
 	start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
-	if (start_inode < EXT2_FIRST_INO)
-		start_inode = EXT2_FIRST_INO;
+	if (start_inode < EXT2_FIRST_INODE(fs->super))
+		start_inode = EXT2_FIRST_INODE(fs->super);
 	i = start_inode;
 
 	do {
@@ -52,7 +52,7 @@
 			break;
 		i++;
 		if (i > fs->super->s_inodes_count)
-			i = EXT2_FIRST_INO;
+			i = EXT2_FIRST_INODE(fs->super);
 	} while (i != start_inode);
 	
 	if (ext2fs_test_inode_bitmap(map, i))
diff --git a/lib/ext2fs/bitops.h b/lib/ext2fs/bitops.h
index 1703872..e98e2d2 100644
--- a/lib/ext2fs/bitops.h
+++ b/lib/ext2fs/bitops.h
@@ -141,7 +141,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (addr));
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
 
 	return retval;
 }
@@ -151,7 +151,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (addr));
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
 
 	return retval;
 }
@@ -161,7 +161,7 @@
 	char retval;
 
 	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
-	     : "=d" (retval) : "d" (nr), "a" (addr));
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
 
 	return retval;
 }
diff --git a/lib/ext2fs/check_desc.c b/lib/ext2fs/check_desc.c
index a8d5d95..7d3f3d4 100644
--- a/lib/ext2fs/check_desc.c
+++ b/lib/ext2fs/check_desc.c
@@ -25,13 +25,10 @@
 {
 	int i;
 	int block = fs->super->s_first_data_block;
-	int next, inode_blocks_per_group;
+	int next;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
-	inode_blocks_per_group = fs->super->s_inodes_per_group /
-		EXT2_INODES_PER_BLOCK (fs->super);
-
 	for (i = 0; i < fs->group_desc_count; i++) {
 		next = block + fs->super->s_blocks_per_group;
 		/*
@@ -53,8 +50,8 @@
 		 * within the group
 		 */
 		if (fs->group_desc[i].bg_inode_table < block ||
-		    fs->group_desc[i].bg_inode_table+inode_blocks_per_group >=
-		    next)
+		    ((fs->group_desc[i].bg_inode_table +
+		      fs->inode_blocks_per_group) >= next))
 			return EXT2_ET_GDESC_BAD_INODE_TABLE;
 		
 		block = next;
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 09dfd47..71153ce 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -190,5 +190,8 @@
 ec	EXT2_ET_BAD_DEVICE_NAME,
 	"Illegal or malformed device name"
 
+ec	EXT2_ET_MISSING_INODE_TABLE,
+	"A block group is missing an inode table."
+
 	end
 
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 140c126..73194c0 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -56,6 +56,13 @@
 
 typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
 
+#ifdef EXT2_DYNAMIC_REV
+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
+#else
+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO
+#define EXT2_INODE_SIZE(s)	sizeof(struct ext2_inode)
+#endif
+
 /*
  * Flags for the ext2_filsys structure
  */
@@ -68,6 +75,12 @@
 #define EXT2_FLAG_BB_DIRTY	0x20
 #define EXT2_SWAP_BYTES		0x40
 
+/*
+ * Special flag in the ext2 inode i_flag field that means that this is
+ * a new inode.  (So that ext2_write_inode() can clear extra fields.)
+ */
+#define EXT2_NEW_INODE_FL	0x80000000
+
 struct struct_ext2_filsys {
 	int				magic;
 	io_channel			io;
@@ -175,7 +188,10 @@
 	int			inodes_left, blocks_left, groups_left;
 	int			inode_buffer_blocks;
 	char *			inode_buffer;
-	struct ext2_inode *	inode_scan_ptr;
+	int			inode_size;
+	char *			ptr;
+	int			bytes_left;
+	char			*temp_buffer;
 	errcode_t		(*done_group)(ext2_filsys fs,
 					      ext2_inode_scan scan,
 					      dgrp_t group,
diff --git a/lib/ext2fs/getsize.c b/lib/ext2fs/getsize.c
index 7918624..86b12d1 100644
--- a/lib/ext2fs/getsize.c
+++ b/lib/ext2fs/getsize.c
@@ -60,7 +60,7 @@
 	char ch;
 #endif /* HAVE_SYS_DISKLABEL_H */
 
-	fd = open(file, O_RDWR);
+	fd = open(file, O_RDONLY);
 	if (fd < 0)
 		return errno;
 
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 7428b0d..cc7abd0 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -84,6 +84,15 @@
 	set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
 	set_field(s_errors, EXT2_ERRORS_DEFAULT);
 
+
+#ifdef EXT2_DYNAMIC_REV
+	set_field(s_rev_level, EXT2_GOOD_OLD_REV);
+	if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
+		set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
+		set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
+	}
+#endif
+
 	set_field(s_checkinterval, EXT2_DFL_CHECKINTERVAL);
 	super->s_lastcheck = time(NULL);
 
@@ -108,6 +117,8 @@
 				super->s_first_data_block +
 				EXT2_BLOCKS_PER_GROUP(super) - 1)
 		/ EXT2_BLOCKS_PER_GROUP(super);
+	if (fs->group_desc_count == 0)
+		return EXT2_ET_TOOSMALL;
 	fs->desc_blocks = (fs->group_desc_count +
 			   EXT2_DESC_PER_BLOCK(super) - 1)
 		/ EXT2_DESC_PER_BLOCK(super);
@@ -131,12 +142,24 @@
 	 * the inode table blocks in the descriptor.  If not, add some
 	 * additional inodes/group.  Waste not, want not...
 	 */
-	fs->inode_blocks_per_group = (super->s_inodes_per_group +
-				      EXT2_INODES_PER_BLOCK(super) - 1) /
-					      EXT2_INODES_PER_BLOCK(super);
-	super->s_inodes_per_group = fs->inode_blocks_per_group *
-		EXT2_INODES_PER_BLOCK(super);
-		
+	fs->inode_blocks_per_group = (((super->s_inodes_per_group *
+					EXT2_INODE_SIZE(super)) +
+				       EXT2_BLOCK_SIZE(super) - 1) /
+				      EXT2_BLOCK_SIZE(super));
+	super->s_inodes_per_group = ((fs->inode_blocks_per_group *
+				      EXT2_BLOCK_SIZE(super)) /
+				     EXT2_INODE_SIZE(super));
+	/*
+	 * Finally, make sure the number of inodes per group is a
+	 * multiple of 8.  This is needed to simplify the bitmap
+	 * splicing code.
+	 */
+	super->s_inodes_per_group &= ~7;
+	fs->inode_blocks_per_group = (((super->s_inodes_per_group *
+					EXT2_INODE_SIZE(super)) +
+				       EXT2_BLOCK_SIZE(super) - 1) /
+				      EXT2_BLOCK_SIZE(super));
+
 	/*
 	 * adjust inode count to reflect the adjusted inodes_per_group
 	 */
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index ae69bc2..04c5e4d 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -35,6 +35,8 @@
 
 	scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
 	scan->fs = fs;
+	scan->inode_size = EXT2_INODE_SIZE(fs->super);
+	scan->bytes_left = 0;
 	scan->current_group = -1;
 	scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
 	scan->groups_left = fs->group_desc_count;
@@ -45,6 +47,12 @@
 		free(scan);
 		return ENOMEM;
 	}
+	scan->temp_buffer = malloc(scan->inode_size);
+	if (!scan->temp_buffer) {
+		free(scan->inode_buffer);
+		free(scan);
+		return ENOMEM;
+	}
 	*ret_scan = scan;
 	return 0;
 }
@@ -56,6 +64,8 @@
 	
 	free(scan->inode_buffer);
 	scan->inode_buffer = NULL;
+	free(scan->temp_buffer);
+	scan->temp_buffer = NULL;
 	free(scan);
 	return;
 }
@@ -79,53 +89,82 @@
 {
 	errcode_t	retval;
 	int		num_blocks;
+	int		extra_bytes = 0;
 	
 	EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
 
+	/*
+	 * Do we need to start reading a new block group?
+	 */
 	if (scan->inodes_left <= 0) {
-		if (scan->blocks_left <= 0) {
-			if (scan->done_group) {
-				retval = (scan->done_group)
-					(scan->fs, scan,
-					 scan->current_group,
-					 scan->done_group_data);
-				if (retval)
-					return retval;
-			}
-			do {
-				if (scan->groups_left <= 0) {
-					*ino = 0;
-					return 0;
-				}
-				scan->current_group++;
-				scan->groups_left--;
-			
-				scan->current_block =
-		scan->fs->group_desc[scan->current_group].bg_inode_table;
-				scan->blocks_left = (EXT2_INODES_PER_GROUP(scan->fs->super) /
-						     EXT2_INODES_PER_BLOCK(scan->fs->super));
-			} while (scan->current_block == 0);
-		} else {
-			scan->current_block += scan->inode_buffer_blocks;
+		if (scan->done_group) {
+			retval = (scan->done_group)
+				(scan->fs, scan,
+				 scan->current_group,
+				 scan->done_group_data);
+			if (retval)
+				return retval;
 		}
+		if (scan->groups_left <= 0) {
+			*ino = 0;
+			return 0;
+		}
+		scan->current_group++;
+		scan->groups_left--;
+			
+		scan->current_block = scan->fs->
+			group_desc[scan->current_group].bg_inode_table;
+
+		if (scan->current_block == 0)
+			return EXT2_ET_MISSING_INODE_TABLE;
+		scan->bytes_left = 0;
+		scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
+		scan->blocks_left = scan->fs->inode_blocks_per_group;
+	}
+
+	/*
+	 * Have we run out of space in the inode buffer?  If so, we
+	 * need to read in more blocks.
+	 */
+	if (scan->bytes_left < scan->inode_size) {
+		memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
+		extra_bytes = scan->bytes_left;
+		
 		scan->blocks_left -= scan->inode_buffer_blocks;
 		num_blocks = scan->inode_buffer_blocks;
 		if (scan->blocks_left < 0)
 			num_blocks += scan->blocks_left;
 		
-		scan->inodes_left = EXT2_INODES_PER_BLOCK(scan->fs->super) *
-			num_blocks;
-
 		retval = io_channel_read_blk(scan->fs->io, scan->current_block,
 					     num_blocks, scan->inode_buffer);
 		if (retval)
 			return EXT2_ET_NEXT_INODE_READ;
-		scan->inode_scan_ptr = (struct ext2_inode *) scan->inode_buffer;
+		scan->ptr = scan->inode_buffer;
+		scan->bytes_left = num_blocks * scan->fs->blocksize;
+	
+		scan->current_block += scan->inode_buffer_blocks;
 	}
-	if (scan->fs->flags & EXT2_SWAP_BYTES)
-		inocpy_with_swap(inode, scan->inode_scan_ptr++);
-	else
-		*inode = *scan->inode_scan_ptr++;
+
+	if (extra_bytes) {
+		memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
+		       scan->inode_size - extra_bytes);
+		scan->ptr += scan->inode_size - extra_bytes;
+		scan->bytes_left -= scan->inode_size - extra_bytes;
+
+		if (scan->fs->flags & EXT2_SWAP_BYTES)
+			inocpy_with_swap(inode, (struct ext2_inode *)
+					 scan->temp_buffer);
+		else
+			*inode = *((struct ext2_inode *) scan->temp_buffer);
+	} else {
+		if (scan->fs->flags & EXT2_SWAP_BYTES)
+			inocpy_with_swap(inode, (struct ext2_inode *)
+					 scan->ptr);
+		else
+			*inode = *((struct ext2_inode *) scan->ptr);
+		scan->ptr += scan->inode_size;
+		scan->bytes_left -= scan->inode_size;
+	}
 
 	scan->inodes_left--;
 	scan->current_inode++;
@@ -137,17 +176,16 @@
  * Functions to read and write a single inode.
  */
 static char *inode_buffer = 0;
-static blk_t inode_buffer_block;
+static blk_t inode_buffer_block = 0;
 static int inode_buffer_size = 0;
 
 errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
 			     struct ext2_inode * inode)
 {
-	unsigned long group;
-	unsigned long block;
-	unsigned long block_nr;
+	unsigned long 	group, block, block_nr, offset;
+	char 		*ptr;
 	errcode_t	retval;
-	int i;
+	int 		clen, length;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -165,10 +203,9 @@
 	}
 		
 	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-	block = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) /
-		EXT2_INODES_PER_BLOCK(fs->super);
-	i = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) %
-		EXT2_INODES_PER_BLOCK(fs->super);
+	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+		EXT2_INODE_SIZE(fs->super);
+	block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
 	block_nr = fs->group_desc[group].bg_inode_table + block;
 	if (block_nr != inode_buffer_block) {
 		retval = io_channel_read_blk(fs->io, block_nr, 1,
@@ -177,23 +214,44 @@
 			return retval;
 		inode_buffer_block = block_nr;
 	}
+	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
+	ptr = ((char *) inode_buffer) + offset;
+
+	memset(inode, 0, sizeof(struct ext2_inode));
+	length = EXT2_INODE_SIZE(fs->super);
+	if (length > sizeof(struct ext2_inode))
+		length = sizeof(struct ext2_inode);
+	
+	if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
+		clen = EXT2_BLOCK_SIZE(fs->super) - offset;
+		memcpy((char *) inode, ptr, clen);
+		length -= clen;
+		
+		retval = io_channel_read_blk(fs->io, block_nr+1, 1,
+					     inode_buffer);
+		if (retval)
+			return retval;
+		inode_buffer_block = block_nr+1;
+		
+		memcpy(((char *) inode) + clen,
+		       inode_buffer, length);
+	} else
+		memcpy((char *) inode, ptr, length);
+	
 	if (fs->flags & EXT2_SWAP_BYTES)
-		inocpy_with_swap(inode,
-				 (struct ext2_inode *) inode_buffer + i);
-	else
-		memcpy (inode, (struct ext2_inode *) inode_buffer + i,
-			sizeof (struct ext2_inode));
+		inocpy_with_swap(inode, inode);
+
 	return 0;
 }
 
 errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
 		     struct ext2_inode * inode)
 {
-	unsigned long group;
-	unsigned long block;
-	unsigned long block_nr;
+	unsigned long group, block, block_nr, offset;
 	errcode_t	retval;
-	int i;
+	struct ext2_inode temp_inode;
+	char *ptr;
+	int i, clen, length;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -213,13 +271,23 @@
 		inode_buffer_size = fs->blocksize;
 		inode_buffer_block = 0;
 	}
-		
+	if (fs->flags & EXT2_SWAP_BYTES)
+		inocpy_with_swap(&temp_inode, inode);
+	else
+		memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
+	
 	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-	block = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) /
-		EXT2_INODES_PER_BLOCK(fs->super);
-	i = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) %
-		EXT2_INODES_PER_BLOCK(fs->super);
+	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+		EXT2_INODE_SIZE(fs->super);
+	block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
 	block_nr = fs->group_desc[group].bg_inode_table + block;
+	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
+	ptr = (char *) inode_buffer + offset;
+
+	length = EXT2_INODE_SIZE(fs->super);
+	if (length > sizeof(struct ext2_inode))
+		length = sizeof(struct ext2_inode);
+	
 	if (inode_buffer_block != block_nr) {
 		retval = io_channel_read_blk(fs->io, block_nr, 1,
 					     inode_buffer);
@@ -227,15 +295,35 @@
 			return retval;
 		inode_buffer_block = block_nr;
 	}
-	if (fs->flags & EXT2_SWAP_BYTES)
-		inocpy_with_swap((struct ext2_inode *) inode_buffer + i,
-				 inode);
-	else
-		memcpy ((struct ext2_inode *) inode_buffer + i, inode,
-			sizeof (struct ext2_inode));
+	
+	if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
+		clen = EXT2_BLOCK_SIZE(fs->super) - offset;
+		memcpy(ptr, &temp_inode, clen);
+		length -= clen;
+	} else {
+		memcpy(ptr, &temp_inode, length);
+		length = 0;
+	}
 	retval = io_channel_write_blk(fs->io, block_nr, 1, inode_buffer);
 	if (retval)
 		return retval;
+
+	if (length) {
+		retval = io_channel_read_blk(fs->io, ++block_nr, 1,
+					     inode_buffer);
+		if (retval) {
+			inode_buffer_block = 0;
+			return retval;
+		}
+		inode_buffer_block = block_nr;
+		memcpy(inode_buffer, ((char *) &temp_inode) + clen, length);
+
+		retval = io_channel_write_blk(fs->io, block_nr, 1,
+					      inode_buffer);
+		if (retval)
+			return retval;
+	}
+	
 	fs->flags |= EXT2_FLAG_CHANGED;
 	return 0;
 }
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index b674ace..e8b01e2 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -99,16 +99,25 @@
 		retval = EXT2_ET_BAD_MAGIC;
 		goto cleanup;
 	}
+#ifdef EXT2_DYNAMIC_REV
+	if (fs->super->s_rev_level > EXT2_DYNAMIC_REV) {
+		retval = EXT2_ET_REV_TOO_HIGH;
+		goto cleanup;
+	}
+#else
 #ifdef	EXT2_CURRENT_REV
 	if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
 		retval = EXT2_ET_REV_TOO_HIGH;
 		goto cleanup;
 	}
 #endif
+#endif
 	fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
 	fs->fragsize = EXT2_FRAG_SIZE(fs->super);
-	fs->inode_blocks_per_group = (fs->super->s_inodes_per_group /
-				      EXT2_INODES_PER_BLOCK(fs->super));
+	fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
+				       EXT2_INODE_SIZE(fs->super) +
+				       EXT2_BLOCK_SIZE(fs->super) - 1) /
+				      EXT2_BLOCK_SIZE(fs->super));
 	if (block_size) {
 		if (block_size != fs->blocksize) {
 			retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index 1854839..3a3f51f 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -35,7 +35,8 @@
 		return EXT2_ET_RO_FILSYS;
 	if (!inode_bitmap)
 		return 0;
-	nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+	nbytes = (EXT2_INODES_PER_GROUP(fs->super)+7) / 8;
+	
 	bitmap_block = malloc(fs->blocksize);
 	if (!bitmap_block)
 		return ENOMEM;