]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blobdiff - lib/ext2fs/openfs.c
Merge branch 'maint' into next
[thirdparty/e2fsprogs.git] / lib / ext2fs / openfs.c
index 21729574ffc6acf041f080593793d1cf595768aa..3331452df910c86183a1301c95569f47632da27c 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "ext2_fs.h"
 
-
 #include "ext2fs.h"
 #include "e2image.h"
 
@@ -94,6 +93,12 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
                            manager, ret_fs);
 }
 
+static void block_sha_map_free_entry(void *data)
+{
+       free(data);
+       return;
+}
+
 /*
  *  Note: if superblock is non-zero, block-size must also be non-zero.
  *     Superblock and block_size can be zero to use the default size.
@@ -121,7 +126,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
        blk64_t         group_block, blk;
        char            *dest, *cp;
        int             group_zero_adjust = 0;
-       int             inode_size;
+       unsigned int    inode_size;
        __u64           groups_cnt;
 #ifdef WORDS_BIGENDIAN
        unsigned int    groups_per_block;
@@ -380,13 +385,16 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                goto cleanup;
        }
        fs->group_desc_count =  groups_cnt;
-       if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) !=
+       if (!(flags & EXT2_FLAG_IGNORE_SB_ERRORS) &&
+           (__u64)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));
+       if (flags & EXT2_FLAG_SUPER_ONLY)
+               goto skip_read_bg;
        retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
                                &fs->group_desc);
        if (retval)
@@ -427,7 +435,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                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);
+                       if (gdp)
+                               ext2fs_swap_group_desc2(fs, gdp);
                }
 #endif
                dest += fs->blocksize*first_meta_bg;
@@ -447,7 +456,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                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);
+                       if (gdp)
+                               ext2fs_swap_group_desc2(fs, gdp);
                }
 #endif
                dest += fs->blocksize;
@@ -473,7 +483,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                if (fs->flags & EXT2_FLAG_RW)
                        ext2fs_mark_super_dirty(fs);
        }
-
+skip_read_bg:
        if (ext2fs_has_feature_mmp(fs->super) &&
            !(flags & EXT2_FLAG_SKIP_MMP) &&
            (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
@@ -485,6 +495,19 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                }
        }
 
+       if (fs->flags & EXT2_FLAG_SHARE_DUP) {
+               fs->block_sha_map = ext2fs_hashmap_create(ext2fs_djb2_hash,
+                                       block_sha_map_free_entry, 4096);
+               if (!fs->block_sha_map) {
+                       retval = EXT2_ET_NO_MEMORY;
+                       goto cleanup;
+               }
+               ext2fs_set_feature_shared_blocks(fs->super);
+       }
+
+       if (ext2fs_has_feature_casefold(fs->super))
+               fs->encoding = ext2fs_load_nls_table(fs->super->s_encoding);
+
        fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
        *ret_fs = fs;