X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fclosefs.c;h=b39b15d219201cbac593a1e1dbf46860245c8128;hb=5be8dc2143c7b3b21a9b8fb56797dd855ee87560;hp=e24b6b6972644e72068d067b2cd66a5666eac826;hpb=21c84b71e205b5ab13f14343da5645dcc985856d;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c index e24b6b6..b39b15d 100644 --- a/lib/ext2fs/closefs.c +++ b/lib/ext2fs/closefs.c @@ -10,22 +10,52 @@ */ #include +#if HAVE_UNISTD_H #include -#include +#endif #include #include -#ifdef HAVE_ERRNO_H -#include -#endif #include #include "ext2fsP.h" +static int test_root(int a, int b) +{ + if (a == 0) + return 1; + while (1) { + if (a == 1) + return 1; + if (a % b) + return 0; + a = a / b; + } +} + +int ext2fs_bg_has_super(ext2_filsys fs, int group_block) +{ +#ifdef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER + struct ext2fs_sb *s; + + s = (struct ext2fs_sb *) fs->super; + if (!(s->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) + return 1; + + if (test_root(group_block, 3) || (test_root(group_block, 5)) || + test_root(group_block, 7)) + return 1; + + return 0; +#else + return 1; +#endif +} + errcode_t ext2fs_flush(ext2_filsys fs) { - int i,j,maxgroup; - int group_block; + dgrp_t i,j,maxgroup; + blk_t group_block; errcode_t retval; char *group_ptr; unsigned long fs_state; @@ -39,12 +69,18 @@ errcode_t ext2fs_flush(ext2_filsys fs) fs->super->s_wtime = time(NULL); if (fs->flags & EXT2_FLAG_SWAP_BYTES) { - retval = ENOMEM; - if (!(super_shadow = malloc(SUPERBLOCK_SIZE))) + retval = EXT2_ET_NO_MEMORY; + retval = ext2fs_get_mem(SUPERBLOCK_SIZE, + (void **) &super_shadow); + if (retval) goto errout; - if (!(group_shadow = malloc(fs->blocksize*fs->desc_blocks))) + retval = ext2fs_get_mem((size_t)(fs->blocksize * + fs->desc_blocks), + (void **) &group_shadow); + if (retval) goto errout; - memset(group_shadow, 0, fs->blocksize*fs->desc_blocks); + memset(group_shadow, 0, (size_t) fs->blocksize * + fs->desc_blocks); /* swap the superblock */ *super_shadow = *fs->super; @@ -92,6 +128,9 @@ errcode_t ext2fs_flush(ext2_filsys fs) maxgroup = (fs->flags & EXT2_FLAG_MASTER_SB_ONLY) ? 1 : fs->group_desc_count; for (i = 0; i < maxgroup; i++) { + if (!ext2fs_bg_has_super(fs, i)) + goto next_group; + if (i !=0 ) { retval = io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE, @@ -108,6 +147,7 @@ errcode_t ext2fs_flush(ext2_filsys fs) goto errout; group_ptr += fs->blocksize; } + next_group: group_block += EXT2_BLOCKS_PER_GROUP(fs->super); } @@ -127,9 +167,9 @@ errout: fs->super->s_state = fs_state; if (fs->flags & EXT2_FLAG_SWAP_BYTES) { if (super_shadow) - free(super_shadow); + ext2fs_free_mem((void **) &super_shadow); if (group_shadow) - free(group_shadow); + ext2fs_free_mem((void **) &group_shadow); } return retval; } @@ -154,33 +194,3 @@ errcode_t ext2fs_close(ext2_filsys fs) return 0; } -/* - * This procedure frees a badblocks list. - */ -void ext2fs_badblocks_list_free(ext2_badblocks_list bb) -{ - if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) - return; - - if (bb->list) - free(bb->list); - bb->list = 0; - free(bb); -} - -/* - * Close a directory block list - */ -void ext2fs_free_dblist(ext2_dblist dblist) -{ - if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST)) - return; - - if (dblist->list) - free(dblist->list); - dblist->list = 0; - if (dblist->fs && dblist->fs->dblist == dblist) - dblist->fs->dblist = 0; - dblist->magic = 0; - free(dblist); -}