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;