Whamcloud - gitweb
Many files:
[tools/e2fsprogs.git] / lib / ext2fs / closefs.c
index e24b6b6..b39b15d 100644 (file)
  */
 
 #include <stdio.h>
+#if HAVE_UNISTD_H
 #include <unistd.h>
-#include <stdlib.h>
+#endif
 #include <time.h>
 #include <string.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
 
 #include <linux/ext2_fs.h>
 
 #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);
-}