Whamcloud - gitweb
create_inode: remove backup definition of __func__
[tools/e2fsprogs.git] / misc / mke2fs.c
index 565389d..68fbb66 100644 (file)
@@ -16,7 +16,7 @@
  * enforced (but it's not much fun on a character device :-).
  */
 
-#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
+#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX */
 
 #include "config.h"
 #include <stdio.h>
@@ -26,7 +26,7 @@
 #include <time.h>
 #ifdef __linux__
 #include <sys/utsname.h>
-#include <linux/version.h>
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
 #endif
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
@@ -52,10 +52,12 @@ extern int optind;
 #include "ext2fs/ext2fsP.h"
 #include "uuid/uuid.h"
 #include "util.h"
-#include "profile.h"
-#include "prof_err.h"
+#include "support/nls-enable.h"
+#include "support/plausible.h"
+#include "support/profile.h"
+#include "support/prof_err.h"
 #include "../version.h"
-#include "quota/mkquota.h"
+#include "support/quotaio.h"
 #include "mke2fs.h"
 #include "create_inode.h"
 
@@ -108,11 +110,14 @@ char *journal_device;
 static int sync_kludge;        /* Set using the MKE2FS_SYNC env. option */
 char **fs_types;
 const char *root_dir;  /* Copy files from the specified directory */
+static char *undo_file;
 
 static profile_t       profile;
 
 static int sys_page_size = 4096;
 
+static int errors_behavior = 0;
+
 static void usage(void)
 {
        fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
@@ -124,8 +129,9 @@ static void usage(void)
        "\t[-g blocks-per-group] [-L volume-label] "
        "[-M last-mounted-directory]\n\t[-O feature[,...]] "
        "[-r fs-revision] [-E extended-option[,...]]\n"
-       "\t[-t fs-type] [-T usage-type ] [-U UUID] "
-       "[-jnqvDFKSV] device [blocks-count]\n"),
+       "\t[-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior]"
+       "[-z undo_file]\n"
+       "\t[-jnqvDFKSV] device [blocks-count]\n"),
                program_name);
        exit(1);
 }
@@ -174,7 +180,8 @@ static int parse_version_number(const char *s)
        return KERNEL_VERSION(major, minor, rev);
 }
 
-static int is_before_linux_ver(unsigned int major, unsigned int minor)
+static int is_before_linux_ver(unsigned int major, unsigned int minor,
+                              unsigned int rev)
 {
        struct          utsname ut;
        static int      linux_version_code = -1;
@@ -188,10 +195,11 @@ static int is_before_linux_ver(unsigned int major, unsigned int minor)
        if (linux_version_code == 0)
                return 0;
 
-       return linux_version_code < KERNEL_VERSION(major, minor, 0);
+       return linux_version_code < KERNEL_VERSION(major, minor, rev);
 }
 #else
-static int is_before_linux_ver(unsigned int major, unsigned int minor)
+static int is_before_linux_ver(unsigned int major, unsigned int minor,
+                              unsigned int rev)
 {
        return 0;
 }
@@ -339,13 +347,11 @@ static void write_reserved_inodes(ext2_filsys fs)
        ext2_ino_t      ino;
        struct ext2_inode *inode;
 
-       retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+       retval = ext2fs_get_memzero(EXT2_INODE_SIZE(fs->super), &inode);
        if (retval) {
-               com_err("inode_init", retval,
-                       "while allocating memory");
+               com_err("inode_init", retval, _("while allocating memory"));
                exit(1);
        }
-       bzero(inode, EXT2_INODE_SIZE(fs->super));
 
        for (ino = 1; ino < EXT2_FIRST_INO(fs->super); ino++)
                ext2fs_write_inode_full(fs, ino, inode,
@@ -384,6 +390,7 @@ static errcode_t packed_allocate_tables(ext2_filsys fs)
                ext2fs_block_alloc_stats_range(fs, goal,
                                               fs->inode_blocks_per_group, +1);
                ext2fs_inode_table_loc_set(fs, i, goal);
+               ext2fs_group_desc_csum_set(fs, i);
        }
        return 0;
 }
@@ -416,12 +423,14 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
                        ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_ZEROED);
                        ext2fs_group_desc_csum_set(fs, i);
                }
-               retval = ext2fs_zero_blocks2(fs, blk, num, &blk, &num);
-               if (retval) {
-                       fprintf(stderr, _("\nCould not write %d "
-                                 "blocks in inode table starting at %llu: %s\n"),
-                               num, blk, error_message(retval));
-                       exit(1);
+               if (!itable_zeroed) {
+                       retval = ext2fs_zero_blocks2(fs, blk, num, &blk, &num);
+                       if (retval) {
+                               fprintf(stderr, _("\nCould not write %d "
+                                         "blocks in inode table starting at %llu: %s\n"),
+                                       num, blk, error_message(retval));
+                               exit(1);
+                       }
                }
                if (sync_kludge) {
                        if (sync_kludge == 1)
@@ -430,7 +439,6 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
                                sync();
                }
        }
-       ext2fs_zero_blocks2(0, 0, 0, 0, 0);
        ext2fs_numeric_progress_close(fs, &progress,
                                      _("done                            \n"));
 
@@ -619,7 +627,6 @@ static void create_journal_dev(ext2_filsys fs)
                count -= c;
                ext2fs_numeric_progress_update(fs, &progress, blk);
        }
-       ext2fs_zero_blocks2(0, 0, 0, 0, 0);
 
        ext2fs_numeric_progress_close(fs, &progress, NULL);
 write_superblock:
@@ -861,7 +868,7 @@ static void parse_extended_opts(struct ext2_super_block *param,
                        if (*p || num_backups > 2) {
                                fprintf(stderr,
                                        _("Invalid # of backup "
-                                         "superbocks: %s\n"),
+                                         "superblocks: %s\n"),
                                        arg);
                                r_usage++;
                                continue;
@@ -1071,7 +1078,8 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_FLEX_BG|
                EXT4_FEATURE_INCOMPAT_MMP |
                EXT4_FEATURE_INCOMPAT_64BIT|
-               EXT4_FEATURE_INCOMPAT_INLINE_DATA,
+               EXT4_FEATURE_INCOMPAT_INLINE_DATA|
+               EXT4_FEATURE_INCOMPAT_ENCRYPT,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -1080,9 +1088,7 @@ static __u32 ok_features[3] = {
                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
                EXT4_FEATURE_RO_COMPAT_GDT_CSUM|
                EXT4_FEATURE_RO_COMPAT_BIGALLOC|
-#ifdef CONFIG_QUOTA
                EXT4_FEATURE_RO_COMPAT_QUOTA|
-#endif
                EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
 };
 
@@ -1344,6 +1350,18 @@ int get_int_from_profile(char **types, const char *opt, int def_val)
        return ret;
 }
 
+static unsigned int get_uint_from_profile(char **types, const char *opt,
+                                       unsigned int def_val)
+{
+       unsigned int ret;
+       char **cpp;
+
+       profile_get_uint(profile, "defaults", opt, 0, def_val, &ret);
+       for (cpp = types; *cpp; cpp++)
+               profile_get_uint(profile, "fs_types", *cpp, opt, ret, &ret);
+       return ret;
+}
+
 static double get_double_from_profile(char **types, const char *opt,
                                      double def_val)
 {
@@ -1521,7 +1539,7 @@ profile_error:
        memset(&fs_param, 0, sizeof(struct ext2_super_block));
        fs_param.s_rev_level = 1;  /* Create revision 1 filesystems now */
 
-       if (is_before_linux_ver(2, 2))
+       if (is_before_linux_ver(2, 2, 0))
                fs_param.s_rev_level = 0;
 
        if (argc && *argv) {
@@ -1534,7 +1552,7 @@ profile_error:
        }
 
        while ((c = getopt (argc, argv,
-                   "b:cg:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
+                   "b:ce:g:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:Vz:")) != EOF) {
                switch (c) {
                case 'b':
                        blocksize = parse_num_blocks2(optarg, -1);
@@ -1577,6 +1595,20 @@ profile_error:
                case 'E':
                        extended_opts = optarg;
                        break;
+               case 'e':
+                       if (strcmp(optarg, "continue") == 0)
+                               errors_behavior = EXT2_ERRORS_CONTINUE;
+                       else if (strcmp(optarg, "remount-ro") == 0)
+                               errors_behavior = EXT2_ERRORS_RO;
+                       else if (strcmp(optarg, "panic") == 0)
+                               errors_behavior = EXT2_ERRORS_PANIC;
+                       else {
+                               com_err(program_name, 0,
+                                       _("bad error behavior - %s"),
+                                       optarg);
+                               usage();
+                       }
+                       break;
                case 'F':
                        force++;
                        break;
@@ -1606,6 +1638,12 @@ profile_error:
                                        _("flex_bg size must be a power of 2"));
                                exit(1);
                        }
+                       if (flex_bg_size > MAX_32_NUM) {
+                               com_err(program_name, 0,
+                               _("flex_bg size (%lu) must be less than"
+                               " or equal to 2^31"), flex_bg_size);
+                               exit(1);
+                       }
                        break;
                case 'i':
                        inode_ratio = strtoul(optarg, &tmp, 0);
@@ -1695,6 +1733,11 @@ profile_error:
                                        _("bad revision level - %s"), optarg);
                                exit(1);
                        }
+                       if (r_opt > EXT2_MAX_SUPP_REV) {
+                               com_err(program_name, EXT2_ET_REV_TOO_HIGH,
+                                       _("while trying to create revision %d"), r_opt);
+                               exit(1);
+                       }
                        fs_param.s_rev_level = r_opt;
                        break;
                case 's':       /* deprecated */
@@ -1732,6 +1775,9 @@ profile_error:
                        /* Print version number and exit */
                        show_version_only++;
                        break;
+               case 'z':
+                       undo_file = optarg;
+                       break;
                default:
                        usage();
                }
@@ -1785,7 +1831,7 @@ profile_error:
                printf(_("Using journal device's blocksize: %d\n"), blocksize);
                fs_param.s_log_block_size =
                        int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
-               ext2fs_close(jfs);
+               ext2fs_close_free(&jfs);
        }
 
        if (optind < argc) {
@@ -1810,6 +1856,8 @@ profile_error:
                flags |= CHECK_FS_EXIST;
        if (!quiet)
                flags |= VERBOSE_CREATE;
+       if (fs_blocks_count == 0)
+               flags |= NO_SIZE;
        if (!check_plausibility(device_name, flags, &is_device) && !force)
                proceed_question(proceed_delay);
 
@@ -1885,7 +1933,7 @@ profile_error:
        tmp = NULL;
        if (fs_param.s_rev_level != EXT2_GOOD_OLD_REV) {
                tmp = get_string_from_profile(fs_types, "base_features",
-                     "sparse_super,filetype,resize_inode,dir_index");
+                     "sparse_super,large_file,filetype,resize_inode,dir_index");
                edit_feature(tmp, &fs_param.s_feature_compat);
                free(tmp);
 
@@ -1925,20 +1973,20 @@ profile_error:
        if (for_hurd(creator_os)) {
                if (fs_param.s_feature_incompat &
                    EXT2_FEATURE_INCOMPAT_FILETYPE) {
-                       fprintf(stderr, _("The HURD does not support the "
-                                         "filetype feature.\n"));
+                       fprintf(stderr, "%s", _("The HURD does not support the "
+                                               "filetype feature.\n"));
                        exit(1);
                }
                if (fs_param.s_feature_ro_compat &
                    EXT4_FEATURE_RO_COMPAT_HUGE_FILE) {
-                       fprintf(stderr, _("The HURD does not support the "
-                                         "huge_file feature.\n"));
+                       fprintf(stderr, "%s", _("The HURD does not support the "
+                                               "huge_file feature.\n"));
                        exit(1);
                }
                if (fs_param.s_feature_ro_compat &
                    EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
-                       fprintf(stderr, _("The HURD does not support the "
-                                         "metadata_csum feature.\n"));
+                       fprintf(stderr, "%s", _("The HURD does not support the "
+                                               "metadata_csum feature.\n"));
                        exit(1);
                }
        }
@@ -1973,7 +2021,7 @@ profile_error:
 
                if (use_bsize == -1) {
                        use_bsize = sys_page_size;
-                       if (is_before_linux_ver(2, 6) && use_bsize > 4096)
+                       if (is_before_linux_ver(2, 6, 0) && use_bsize > 4096)
                                use_bsize = 4096;
                }
                if (lsector_size && use_bsize < lsector_size)
@@ -2082,7 +2130,8 @@ profile_error:
                reserved_ratio = 0;
                fs_param.s_feature_incompat = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV;
                fs_param.s_feature_compat = 0;
-               fs_param.s_feature_ro_compat = 0;
+               fs_param.s_feature_ro_compat &=
+                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
        }
 
        /* Check the user's mkfs options for 64bit */
@@ -2168,7 +2217,23 @@ profile_error:
                        blocksize, sys_page_size);
        }
 
-       lazy_itable_init = 0;
+       /* Metadata checksumming wasn't totally stable before 3.18. */
+       if (is_before_linux_ver(3, 18, 0) &&
+           (fs_param.s_feature_ro_compat &
+                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+               fprintf(stderr, _("Suggestion: Use Linux kernel >= 3.18 for "
+                       "improved stability of the metadata and journal "
+                       "checksum features.\n"));
+
+       /*
+        * On newer kernels we do have lazy_itable_init support. So pick the
+        * right default in case ext4 module is not loaded.
+        */
+       if (is_before_linux_ver(2, 6, 37))
+               lazy_itable_init = 0;
+       else
+               lazy_itable_init = 1;
+
        if (access("/sys/fs/ext4/features/lazy_itable_init", R_OK) == 0)
                lazy_itable_init = 1;
 
@@ -2239,13 +2304,6 @@ profile_error:
                                  "See https://ext4.wiki.kernel.org/"
                                  "index.php/Bigalloc for more information\n\n"));
 
-       if (!quiet &&
-           (fs_param.s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA))
-               fprintf(stderr, "%s", _("\nWarning: the quota feature is "
-                                 "still under development\n"
-                                 "See https://ext4.wiki.kernel.org/"
-                                 "index.php/Quota for more information\n\n"));
-
        /*
         * Since sparse_super is the default, we would only have a problem
         * here if it was explicitly disabled.
@@ -2280,8 +2338,8 @@ profile_error:
                inode_size = get_int_from_profile(fs_types, "inode_size", 0);
        if (!flex_bg_size && (fs_param.s_feature_incompat &
                              EXT4_FEATURE_INCOMPAT_FLEX_BG))
-               flex_bg_size = get_int_from_profile(fs_types,
-                                                   "flex_bg_size", 16);
+               flex_bg_size = get_uint_from_profile(fs_types,
+                                                    "flex_bg_size", 16);
        if (flex_bg_size) {
                if (!(fs_param.s_feature_incompat &
                      EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
@@ -2314,7 +2372,8 @@ profile_error:
             EXT4_FEATURE_INCOMPAT_INLINE_DATA) &&
            fs_param.s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
                com_err(program_name, 0,
-                       _("inode size is %d, inline data is useless"),
+                       _("%d byte inodes are too small for inline data; "
+                         "specify larger size"),
                        fs_param.s_inode_size);
                exit(1);
        }
@@ -2437,6 +2496,21 @@ static int mke2fs_setup_tdb(const char *name, io_manager *io_ptr)
        char *dev_name, *tmp_name;
        int free_tdb_dir = 0;
 
+       /* (re)open a specific undo file */
+       if (undo_file && undo_file[0] != 0) {
+               retval = set_undo_io_backing_manager(*io_ptr);
+               if (retval)
+                       goto err;
+               *io_ptr = undo_io_manager;
+               retval = set_undo_io_backup_file(undo_file);
+               if (retval)
+                       goto err;
+               printf(_("Overwriting existing filesystem; this can be undone "
+                        "using the command:\n"
+                        "    e2undo %s %s\n\n"), undo_file, name);
+               return retval;
+       }
+
        /*
         * Configuration via a conf file would be
         * nice
@@ -2470,10 +2544,14 @@ static int mke2fs_setup_tdb(const char *name, io_manager *io_ptr)
 
        if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
                retval = errno;
+               com_err(program_name, retval,
+                       _("while trying to delete %s"), tdb_file);
                goto errout;
        }
 
-       set_undo_io_backing_manager(*io_ptr);
+       retval = set_undo_io_backing_manager(*io_ptr);
+       if (retval)
+               goto errout;
        *io_ptr = undo_io_manager;
        retval = set_undo_io_backup_file(tdb_file);
        if (retval)
@@ -2491,6 +2569,7 @@ errout:
        if (free_tdb_dir)
                free(tdb_dir);
        free(tdb_file);
+err:
        com_err(program_name, retval, "%s",
                _("while trying to setup undo file\n"));
        return retval;
@@ -2597,6 +2676,38 @@ static int create_quota_inodes(ext2_filsys fs)
        return 0;
 }
 
+static errcode_t set_error_behavior(ext2_filsys fs)
+{
+       char    *arg = NULL;
+       short   errors = fs->super->s_errors;
+
+       arg = get_string_from_profile(fs_types, "errors", NULL);
+       if (arg == NULL)
+               goto try_user;
+
+       if (strcmp(arg, "continue") == 0)
+               errors = EXT2_ERRORS_CONTINUE;
+       else if (strcmp(arg, "remount-ro") == 0)
+               errors = EXT2_ERRORS_RO;
+       else if (strcmp(arg, "panic") == 0)
+               errors = EXT2_ERRORS_PANIC;
+       else {
+               com_err(program_name, 0,
+                       _("bad error behavior in profile - %s"),
+                       arg);
+               free(arg);
+               return EXT2_ET_INVALID_ARGUMENT;
+       }
+       free(arg);
+
+try_user:
+       if (errors_behavior)
+               errors = errors_behavior;
+
+       fs->super->s_errors = errors;
+       return 0;
+}
+
 int main (int argc, char *argv[])
 {
        errcode_t       retval = 0;
@@ -2630,7 +2741,7 @@ int main (int argc, char *argv[])
 #endif
                io_ptr = unix_io_manager;
 
-       if (should_do_undo(device_name)) {
+       if (undo_file != NULL || should_do_undo(device_name)) {
                retval = mke2fs_setup_tdb(device_name, &io_ptr);
                if (retval)
                        exit(1);
@@ -2661,23 +2772,32 @@ int main (int argc, char *argv[])
        }
        fs->progress_ops = &ext2fs_numeric_progress_ops;
 
+       /* Set the error behavior */
+       retval = set_error_behavior(fs);
+       if (retval)
+               usage();
+
        /* Check the user's mkfs options for metadata checksumming */
        if (!quiet &&
+           !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+                                      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) &&
            EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
                if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
                                EXT3_FEATURE_INCOMPAT_EXTENTS))
-                       printf(_("Extents are not enabled.  The file extent "
+                       printf("%s",
+                              _("Extents are not enabled.  The file extent "
                                 "tree can be checksummed, whereas block maps "
                                 "cannot.  Not enabling extents reduces the "
                                 "coverage of metadata checksumming.  "
                                 "Pass -O extents to rectify.\n"));
                if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
                                EXT4_FEATURE_INCOMPAT_64BIT))
-                       printf(_("64-bit filesystem support is not "
-                                "enabled.  The larger fields afforded by "
-                                "this feature enable full-strength "
-                                "checksumming.  Pass -O 64bit to rectify.\n"));
+                       printf("%s",
+                              _("64-bit filesystem support is not enabled.  "
+                                "The larger fields afforded by this feature "
+                                "enable full-strength checksumming.  "
+                                "Pass -O 64bit to rectify.\n"));
        }
 
        /* Calculate journal blocks */
@@ -2814,6 +2934,15 @@ int main (int argc, char *argv[])
                        sizeof(fs->super->s_last_mounted));
        }
 
+       /* Set current default encryption algorithms for data and
+        * filename encryption */
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_ENCRYPT) {
+               fs->super->s_encrypt_algos[0] =
+                       EXT4_ENCRYPTION_MODE_AES_256_XTS;
+               fs->super->s_encrypt_algos[1] =
+                       EXT4_ENCRYPTION_MODE_AES_256_CTS;
+       }
+
        if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
                fs->super->s_checksum_type = EXT2_CRC32C_CHKSUM;
@@ -2827,7 +2956,8 @@ int main (int argc, char *argv[])
        if (fs->super->s_feature_incompat &
            EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
                create_journal_dev(fs);
-               exit(ext2fs_close(fs) ? 1 : 0);
+               printf("\n");
+               exit(ext2fs_close_free(&fs) ? 1 : 0);
        }
 
        if (bad_blocks_filename)
@@ -2860,9 +2990,14 @@ int main (int argc, char *argv[])
        }
 
        if (super_only) {
+               check_plausibility(device_name, CHECK_FS_EXIST, NULL);
+               printf(_("%s may be further corrupted by superblock rewrite\n"),
+                      device_name);
+               if (!force)
+                       proceed_question(proceed_delay);
                fs->super->s_state |= EXT2_ERROR_FS;
                fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY);
-               /* 
+               /*
                 * The command "mke2fs -S" is used to recover
                 * corrupted file systems, so do not mark any of the
                 * inodes as unused; we want e2fsck to consider all
@@ -2948,7 +3083,7 @@ int main (int argc, char *argv[])
                }
                if (!quiet)
                        printf("%s", _("done\n"));
-               ext2fs_close(jfs);
+               ext2fs_close_free(&jfs);
                free(journal_device);
        } else if ((journal_size) ||
                   (fs_param.s_feature_compat &
@@ -3003,7 +3138,7 @@ no_journal:
                                       EXT4_FEATURE_RO_COMPAT_QUOTA))
                create_quota_inodes(fs);
 
-       retval = mk_hugefiles(fs);
+       retval = mk_hugefiles(fs, device_name);
        if (retval)
                com_err(program_name, retval, "while creating huge files");
        /* Copy files from the specified directory */
@@ -3015,7 +3150,7 @@ no_journal:
                                     EXT2_ROOT_INO);
                if (retval) {
                        com_err(program_name, retval, "%s",
-                               _("\nError while populating file system\n"));
+                               _("while populating file system"));
                        exit(1);
                } else if (!quiet)
                        printf("%s", _("done\n"));
@@ -3026,7 +3161,7 @@ no_journal:
                       "filesystem accounting information: "));
        checkinterval = fs->super->s_checkinterval;
        max_mnt_count = fs->super->s_max_mnt_count;
-       retval = ext2fs_close(fs);
+       retval = ext2fs_close_free(&fs);
        if (retval) {
                fprintf(stderr, "%s",
                        _("\nWarning, had trouble writing out superblocks."));