aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ext2fs/openfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext2fs/openfs.c')
-rw-r--r--lib/ext2fs/openfs.c139
1 files changed, 33 insertions, 106 deletions
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index 45b3627e..d638da03 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -22,9 +22,6 @@
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
#include "ext2_fs.h"
@@ -32,12 +29,11 @@
#include "ext2fs.h"
#include "e2image.h"
-blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block,
- dgrp_t i)
+blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
{
int bg;
int has_super = 0;
- blk64_t ret_blk;
+ int ret_blk;
if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
(i < fs->super->s_first_meta_bg))
@@ -46,7 +42,7 @@ blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block,
bg = EXT2_DESC_PER_BLOCK(fs->super) * i;
if (ext2fs_bg_has_super(fs, bg))
has_super = 1;
- ret_blk = ext2fs_group_first_block2(fs, bg) + has_super;
+ ret_blk = ext2fs_group_first_block(fs, bg) + has_super;
/*
* If group_block is not the normal value, we're trying to use
* the backup group descriptors and superblock --- so use the
@@ -57,16 +53,11 @@ blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block,
*/
if (group_block != fs->super->s_first_data_block &&
((ret_blk + fs->super->s_blocks_per_group) <
- ext2fs_blocks_count(fs->super)))
+ fs->super->s_blocks_count))
ret_blk += fs->super->s_blocks_per_group;
return ret_blk;
}
-blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
-{
- return ext2fs_descriptor_block_loc2(fs, group_block, i);
-}
-
errcode_t ext2fs_open(const char *name, int flags, int superblock,
unsigned int block_size, io_manager manager,
ext2_filsys *ret_fs)
@@ -85,9 +76,6 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
* EXT2_FLAG_FORCE - Open the filesystem even if some of the
* features aren't supported.
* EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
- * EXT2_FLAG_SKIP_MMP - Open without multi-mount protection check.
- * EXT2_FLAG_64BITS - Allow 64-bit bitfields (needed for large
- * filesystems)
*/
errcode_t ext2fs_open2(const char *name, const char *io_options,
int flags, int superblock,
@@ -98,11 +86,10 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
errcode_t retval;
unsigned long i, first_meta_bg;
__u32 features;
- unsigned int blocks_per_group, io_flags;
- blk64_t group_block, blk;
+ int groups_per_block, blocks_per_group, io_flags;
+ blk_t group_block, blk;
char *dest, *cp;
#ifdef WORDS_BIGENDIAN
- unsigned int groups_per_block;
struct ext2_group_desc *gdp;
int j;
#endif
@@ -144,7 +131,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
goto cleanup;
fs->image_io = fs->io;
fs->io->app_data = fs;
- retval = io_channel_alloc_buf(fs->io, -SUPERBLOCK_SIZE, &fs->super);
+ retval = ext2fs_get_memalign(SUPERBLOCK_SIZE, 512, &fs->super);
if (retval)
goto cleanup;
if (flags & EXT2_FLAG_IMAGE_FILE) {
@@ -221,7 +208,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
features = fs->super->s_feature_incompat;
#ifdef EXT2_LIB_SOFTSUPP_INCOMPAT
if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
- features &= ~EXT2_LIB_SOFTSUPP_INCOMPAT;
+ features &= !EXT2_LIB_SOFTSUPP_INCOMPAT;
#endif
if (features & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
retval = EXT2_ET_UNSUPP_FEATURE;
@@ -231,7 +218,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
features = fs->super->s_feature_ro_compat;
#ifdef EXT2_LIB_SOFTSUPP_RO_COMPAT
if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
- features &= ~EXT2_LIB_SOFTSUPP_RO_COMPAT;
+ features &= !EXT2_LIB_SOFTSUPP_RO_COMPAT;
#endif
if ((flags & EXT2_FLAG_RW) &&
(features & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
@@ -252,36 +239,12 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
-
- /*
- * bigalloc requires cluster-aware bitfield operations, which at the
- * moment means we need EXT2_FLAG_64BITS.
- */
- if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
- !(flags & EXT2_FLAG_64BITS)) {
- retval = EXT2_ET_CANT_USE_LEGACY_BITMAPS;
- goto cleanup;
- }
-
- if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
- (fs->super->s_log_block_size != fs->super->s_log_cluster_size)) {
- retval = EXT2_ET_CORRUPT_SUPERBLOCK;
- goto cleanup;
- }
- fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
+ fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
if (EXT2_INODE_SIZE(fs->super) < EXT2_GOOD_OLD_INODE_SIZE) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
- fs->cluster_ratio_bits = fs->super->s_log_cluster_size -
- fs->super->s_log_block_size;
- if (EXT2_BLOCKS_PER_GROUP(fs->super) !=
- EXT2_CLUSTERS_PER_GROUP(fs->super) << fs->cluster_ratio_bits) {
- retval = EXT2_ET_CORRUPT_SUPERBLOCK;
- goto cleanup;
- }
+ fs->fragsize = EXT2_FRAG_SIZE(fs->super);
fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) *
EXT2_INODE_SIZE(fs->super) +
EXT2_BLOCK_SIZE(fs->super) - 1) /
@@ -321,18 +284,18 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super) ||
EXT2_DESC_PER_BLOCK(fs->super) == 0 ||
- fs->super->s_first_data_block >= ext2fs_blocks_count(fs->super)) {
+ fs->super->s_first_data_block >= fs->super->s_blocks_count) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
- fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) -
- fs->super->s_first_data_block,
- blocks_per_group);
- if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) !=
- fs->super->s_inodes_count) {
- retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+ fs->group_desc_count = ext2fs_div_ceil(fs->super->s_blocks_count -
+ fs->super->s_first_data_block,
+ blocks_per_group);
+ if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) !=
+ fs->super->s_inodes_count) {
+ retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
- }
+ }
fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
EXT2_DESC_PER_BLOCK(fs->super));
retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
@@ -341,12 +304,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
goto cleanup;
if (!group_block)
group_block = fs->super->s_first_data_block;
- if (group_block == 0 && fs->blocksize == 1024)
- group_block = 1; /* Deal with 1024 blocksize && bigalloc */
dest = (char *) fs->group_desc;
-#ifdef WORDS_BIGENDIAN
groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
-#endif
if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
first_meta_bg = fs->super->s_first_meta_bg;
else
@@ -358,24 +317,20 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
goto cleanup;
#ifdef WORDS_BIGENDIAN
gdp = (struct ext2_group_desc *) dest;
- for (j=0; j < groups_per_block*first_meta_bg; j++) {
- gdp = ext2fs_group_desc(fs, fs->group_desc, j);
- ext2fs_swap_group_desc2(fs, gdp);
- }
+ for (j=0; j < groups_per_block*first_meta_bg; j++)
+ ext2fs_swap_group_desc(gdp++);
#endif
dest += fs->blocksize*first_meta_bg;
}
for (i=first_meta_bg ; i < fs->desc_blocks; i++) {
- blk = ext2fs_descriptor_block_loc2(fs, group_block, i);
- retval = io_channel_read_blk64(fs->io, blk, 1, dest);
+ blk = ext2fs_descriptor_block_loc(fs, group_block, i);
+ retval = io_channel_read_blk(fs->io, blk, 1, dest);
if (retval)
goto cleanup;
#ifdef WORDS_BIGENDIAN
- for (j=0; j < groups_per_block; j++) {
- gdp = ext2fs_group_desc(fs, fs->group_desc,
- i * groups_per_block + j);
- ext2fs_swap_group_desc2(fs, gdp);
- }
+ gdp = (struct ext2_group_desc *) dest;
+ for (j=0; j < groups_per_block; j++)
+ ext2fs_swap_group_desc(gdp++);
#endif
dest += fs->blocksize;
}
@@ -388,34 +343,18 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
*/
if (superblock > 1 && EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
- dgrp_t group;
-
- for (group = 0; group < fs->group_desc_count; group++) {
- ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
- ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
- ext2fs_bg_itable_unused_set(fs, group, 0);
- /* The checksum will be reset later, but fix it here
- * anyway to avoid printing a lot of spurious errors. */
- ext2fs_group_desc_csum_set(fs, group);
- }
- if (fs->flags & EXT2_FLAG_RW)
- ext2fs_mark_super_dirty(fs);
- }
-
- if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
- !(flags & EXT2_FLAG_SKIP_MMP) &&
- (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
- retval = ext2fs_mmp_start(fs);
- if (retval) {
- fs->flags |= EXT2_FLAG_SKIP_MMP; /* just do cleanup */
- ext2fs_mmp_stop(fs);
- goto cleanup;
+ struct ext2_group_desc *gd;
+ for (i = 0, gd = fs->group_desc; i < fs->group_desc_count;
+ i++, gd++) {
+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ gd->bg_flags &= ~EXT2_BG_INODE_UNINIT;
+ gd->bg_itable_unused = 0;
}
+ ext2fs_mark_super_dirty(fs);
}
fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs;
-
return 0;
cleanup:
if (flags & EXT2_FLAG_NOFREE_ON_ERROR)
@@ -450,20 +389,8 @@ errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io)
errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io)
{
- errcode_t err;
-
if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
return EXT2_ET_NOT_IMAGE_FILE;
- err = io_channel_set_blksize(new_io, fs->blocksize);
- if (err)
- return err;
- if ((new_io == fs->image_io) || (new_io == fs->io))
- return 0;
- if ((fs->image_io != fs->io) &&
- fs->image_io)
- io_channel_close(fs->image_io);
- if (fs->io)
- io_channel_close(fs->io);
fs->io = fs->image_io = new_io;
fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_RW |
EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;