struct opaque_ext2_group_desc *gdp,
dgrp_t group)
{
- int desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
-
- return (struct ext2_group_desc *)((char *)gdp + group * desc_size);
+ struct ext2_group_desc *ret_gdp;
+ errcode_t retval;
+ static char *buf = 0;
+ static int bufsize = 0;
+ blk64_t blk;
+ int desc_size = EXT2_DESC_SIZE(fs->super) & ~7;
+ int desc_per_blk = EXT2_DESC_PER_BLOCK(fs->super);
+
+ if (group > fs->group_desc_count)
+ return NULL;
+ if (gdp)
+ return (struct ext2_group_desc *)((char *)gdp +
+ group * desc_size);
+ /*
+ * If fs->group_desc wasn't read in when the file system was
+ * opened, then read it on demand here.
+ */
+ if (bufsize < fs->blocksize)
+ ext2fs_free_mem(&buf);
+ if (!buf) {
+ retval = ext2fs_get_mem(fs->blocksize, &buf);
+ if (retval)
+ return NULL;
+ bufsize = fs->blocksize;
+ }
+ blk = ext2fs_descriptor_block_loc2(fs, fs->super->s_first_data_block,
+ group / desc_per_blk);
+ retval = io_channel_read_blk(fs->io, blk, 1, buf);
+ if (retval)
+ return NULL;
+ ret_gdp = (struct ext2_group_desc *)
+ (buf + ((group % desc_per_blk) * desc_size));
+#ifdef WORDS_BIGENDIAN
+ ext2fs_swap_group_desc2(fs, ret_gdp);
+#endif
+ return ret_gdp;
}
/* Do the same but as an ext4 group desc for internal use here */
}
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)
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))) {
flags |= EXT2_FLAG_FORCE;
if (image_dump)
flags |= EXT2_FLAG_IMAGE_FILE;
+ if (header_only)
+ flags |= EXT2_FLAG_SUPER_ONLY;
try_open_again:
if (use_superblock && !use_blocksize) {
for (use_blocksize = EXT2_MIN_BLOCK_SIZE;