]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Merge branch 'maint' into next
authorTheodore Ts'o <tytso@mit.edu>
Thu, 7 Dec 2023 16:02:53 +0000 (11:02 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 7 Dec 2023 16:02:53 +0000 (11:02 -0500)
50 files changed:
README
RELEASE-NOTES
debian/changelog
debian/control
debian/libext2fs2.symbols
debugfs/debugfs.8.in
debugfs/htree.c
debugfs/journal.c
debugfs/logdump.c
debugfs/set_fields.c
doc/RelNotes/v1.47.0.txt [new file with mode: 0644]
doc/libext2fs.texinfo
e2fsck/e2fsck.h
e2fsck/journal.c
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/pass4.c
e2fsck/problem.c
e2fsck/problem.h
e2fsck/rehash.c
e2fsck/super.c
e2fsck/unix.c
e2fsprogs.lsm
e2fsprogs.spec
lib/e2p/feature.c
lib/e2p/ls.c
lib/ext2fs/Makefile.in
lib/ext2fs/badblocks.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2_io.h
lib/ext2fs/ext2fs.h
lib/ext2fs/ext_attr.c
lib/ext2fs/ismounted.c
lib/ext2fs/orphan.c [new file with mode: 0644]
lib/ext2fs/swapfs.c
lib/ext2fs/tst_super_size.c
lib/ext2fs/unix_io.c
lib/support/mkquota.c
misc/e2image.c
misc/e2label.8.in
misc/mke2fs.8.in
misc/mke2fs.c
misc/mke2fs.conf.in
misc/tune2fs.8.in
misc/tune2fs.c
po/e2fsprogs.pot
tests/filter.sed
tests/m_assume_storage_prezeroed/expect [new file with mode: 0644]
tests/m_assume_storage_prezeroed/script [new file with mode: 0644]
version.h

diff --git a/README b/README
index 31398541f4773dcb68f3eaefc7857afee79ad4eb..0970deb754ccf3ae43f68ff2233252d3a19d1c39 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-       This is the new version (1.46.6) of the second extended file
+       This is the new version (1.47.0) of the second extended file
 system management programs.
 
        From time to time, I release new versions of e2fsprogs, to fix
index 0e61bc7fcbe008ae66128ca04213638309702fe4..5fc5f475677aadae8bb4d2235b21f387c70073d5 120000 (symlink)
@@ -1 +1 @@
-doc/RelNotes/v1.46.5.txt
\ No newline at end of file
+doc/RelNotes/v1.47.0.txt
\ No newline at end of file
index 5305242816fccff34ca0e49ca068304e7e154fb3..60a0a9b89b7cffdf2e5e5e63182de5e08ef7cc09 100644 (file)
@@ -1,6 +1,25 @@
+e2fsprogs (1.47.0-1) unstable; urgency=medium
+
+  * New upstream version
+  * Add support for the new orphan_file feature, which speeds up workloads
+    that are deleting or truncating a large number files in parallel.
+  * Mke2fs now enables the orphan_file and metadata_csum_seed feature.
+  * Mke2fs now supports the extended option "assume_storage_prezeroed"
+    which causes mke2fs to skip zeroing the journal and inode tables and
+    to mark the inode tables as zeroed.
+  * Tune2fs and e2label will more reliably modify the label and UUID for a
+    mounted file system using new kernel ioctls.
+  * Tune2fs can now disable the casefold feature after scanning all of the
+    directories do not have the casefold flag set.
+  * Fix a potential unbalanced mutex unlock when there is a short read
+    while using the bounce buffer when using direct I/O.
+  * Update to standards 4.6.2
+
+ -- Theodore Y. Ts'o <tytso@mit.edu>  Mon, 06 Feb 2023 22:07:49 -0500
+
 e2fsprogs (1.46.6-1) unstable; urgency=medium
 
-  * Upstream version
+  * New upstream version
   * NMU acknowledge (Closes: #1022096)
   * In line with v6.2 and later Linux kernel, the extended xattribute hash
     may be calculated using either the signed or unsigned char variant,
index 671a60119681fd7aa74b911d36c2891a46f0b2bb..770198708aa9a43d75a4f1ba6f4c35f0aed632e6 100644 (file)
@@ -4,7 +4,7 @@ Priority: required
 Maintainer: Theodore Y. Ts'o <tytso@mit.edu>
 Build-Depends: gettext, texinfo, pkg-config, libfuse-dev [linux-any kfreebsd-any] <!pkg.e2fsprogs.no-fuse2fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], cron [linux-any]
 Rules-Requires-Root: no
-Standards-Version: 4.6.1
+Standards-Version: 4.6.2
 Homepage: http://e2fsprogs.sourceforge.net
 Vcs-Browser: https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
 Vcs-Git: https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git -b debian/master
index 46c48adf05c165012f735c4e59a3ac2bd741aaf6..6a97cf1e072e09bb057ba44b70c1873b42a19139 100644 (file)
@@ -159,6 +159,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_create_inode_cache@Base 1.43
  ext2fs_create_journal_superblock2@Base 1.46.0
  ext2fs_create_journal_superblock@Base 1.37
+ ext2fs_create_orphan_file@Base 1.47.0
  ext2fs_create_resize_inode@Base 1.37
  ext2fs_dblist_count2@Base 1.42
  ext2fs_dblist_count@Base 1.37
@@ -173,6 +174,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_dblist_sort@Base 1.37
  ext2fs_decode_extent@Base 1.46.0
  ext2fs_default_journal_size@Base 1.40
+ ext2fs_default_orphan_file_blocks@Base 1.47.0
  ext2fs_descriptor_block_loc2@Base 1.42
  ext2fs_descriptor_block_loc@Base 1.37
  ext2fs_dir_block_csum_set@Base 1.43
@@ -194,6 +196,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_div64_ceil@Base 1.42
  ext2fs_div_ceil@Base 1.40
  ext2fs_djb2_hash@Base 1.44.3~rc1
+ ext2fs_do_orphan_file_block_csum@Base 1.47.0
  ext2fs_dup_handle@Base 1.37
  ext2fs_dx_csum@Base 1.46~WIP.2019.10.09
  ext2fs_expand_dir@Base 1.37
@@ -406,6 +409,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_inode_size_set@Base 1.42.12
  ext2fs_inode_table_loc@Base 1.42
  ext2fs_inode_table_loc_set@Base 1.42
+ ext2fs_inodes_per_orphan_block@Base 1.47.0
  ext2fs_is_fast_symlink@Base 1.44.0~rc1
  ext2fs_journal_sb_start@Base 1.42.12
  ext2fs_link@Base 1.37
@@ -458,6 +462,9 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_open@Base 1.37
  ext2fs_open_file@Base 1.42
  ext2fs_open_inode_scan@Base 1.37
+ ext2fs_orphan_block_tail@Base 1.47.0
+ ext2fs_orphan_file_block_csum_set@Base 1.47.0
+ ext2fs_orphan_file_block_csum_verify@Base 1.47.0
  ext2fs_parse_version_string@Base 1.37
  ext2fs_process_dir_block@Base 1.37
  ext2fs_punch@Base 1.42
@@ -611,6 +618,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_test_inode_bitmap@Base 1.37
  ext2fs_test_inode_bitmap_range@Base 1.41.8
  ext2fs_test_valid@Base 1.37
+ ext2fs_truncate_orphan_file@Base 1.47.0
  ext2fs_u32_copy@Base 1.37
  ext2fs_u32_list_add@Base 1.37
  ext2fs_u32_list_count@Base 1.37
@@ -665,6 +673,7 @@ libext2fs.so.2 libext2fs2 #MINVER#
  ext2fs_xattrs_iterate@Base 1.43
  ext2fs_xattrs_open@Base 1.43
  ext2fs_xattrs_read@Base 1.43
+ ext2fs_xattrs_read_inode@Base 1.47.0
  ext2fs_xattrs_write@Base 1.43
  ext2fs_zero_blocks2@Base 1.42
  ext2fs_zero_blocks@Base 1.41.0
index 637d22b3f23467e344527134bbcbd78ae5da73c0..5b5329c38d6e70ebb1a90c27956d1dbef42d3018 100644 (file)
@@ -505,7 +505,7 @@ which is a hard link to
 .IR filespec .
 Note this does not adjust the inode reference counts.
 .TP
-.BI logdump " [-acsOS] [-b block] [-i filespec] [-f journal_file] [output_file]"
+.BI logdump " [-acsOS] [-b block] [-n num_trans ] [-i filespec] [-f journal_file] [output_file]"
 Dump the contents of the ext3 journal.  By default, dump the journal inode as
 specified in the superblock.  However, this can be overridden with the
 .I \-i
@@ -528,7 +528,7 @@ The
 .I \-a
 option causes the
 .B logdump
-program to print the contents of all of the descriptor blocks.
+to print the contents of all of the descriptor blocks.
 The
 .I \-b
 option causes
@@ -548,6 +548,15 @@ The
 option causes logdump to display old (checkpointed) journal entries.
 This can be used to try to track down journal problems even after the
 journal has been replayed.
+.IP
+The
+.I \-n
+option causes
+.B logdump
+to continue past a journal block which is missing a magic number.
+Instead, it will stop only when the entire log is printed or after
+.I num_trans
+transactions.
 .TP
 .BI ls " [-l] [-c] [-d] [-p] [-r] filespec"
 Print a listing of the files in the directory
index a9f9211ba563108a9e2d04946004a1d277328bce..a3e95ddb091c91f554d841ba4c9fb806d4f1589b 100644 (file)
@@ -336,11 +336,18 @@ void do_dx_hash(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
        errcode_t       err;
        int             c;
        int             hash_version = 0;
-       __u32           hash_seed[4];
+       __u32           hash_seed[4] = { 0, };
        int             hash_flags = 0;
        const struct ext2fs_nls_table *encoding = NULL;
 
-       hash_seed[0] = hash_seed[1] = hash_seed[2] = hash_seed[3] = 0;
+       if (current_fs) {
+               hash_seed[0] = current_fs->super->s_hash_seed[0];
+               hash_seed[1] = current_fs->super->s_hash_seed[1];
+               hash_seed[2] = current_fs->super->s_hash_seed[2];
+               hash_seed[3] = current_fs->super->s_hash_seed[3];
+
+               hash_version = current_fs->super->s_def_hash_version;
+       }
 
        reset_getopt();
        while ((c = getopt(argc, argv, "h:s:ce:")) != EOF) {
index 5bac0d3b0f16901539be011718098dca885de3cd..79e3fff86ba1dd4ed76fb6997368137531730a30 100644 (file)
@@ -789,6 +789,8 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fsp)
        char *fsname;
        int fsflags;
        int fsblocksize;
+       char *save;
+       __u16 s_error_state;
 
        if (!(fs->flags & EXT2_FLAG_RW))
                return EXT2_ET_FILE_RO;
@@ -808,6 +810,12 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fsp)
        if (stats && stats->bytes_written)
                kbytes_written = stats->bytes_written >> 10;
 
+       save = malloc(EXT4_S_ERR_LEN);
+       if (save)
+               memcpy(save, ((char *) fs->super) + EXT4_S_ERR_START,
+                      EXT4_S_ERR_LEN);
+       s_error_state = fs->super->s_state & EXT2_ERROR_FS;
+
        ext2fs_mmp_stop(fs);
        fsname = fs->device_name;
        fs->device_name = NULL;
@@ -818,11 +826,15 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fsp)
        retval = ext2fs_open(fsname, fsflags, 0, fsblocksize, io_ptr, fsp);
        ext2fs_free_mem(&fsname);
        if (retval)
-               return retval;
+               goto outfree;
 
        fs = *fsp;
        fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
        fs->super->s_kbytes_written += kbytes_written;
+       fs->super->s_state |= s_error_state;
+       if (save)
+               memcpy(((char *) fs->super) + EXT4_S_ERR_START, save,
+                      EXT4_S_ERR_LEN);
 
        /* Set the superblock flags */
        ext2fs_clear_recover(fs, recover_retval != 0);
@@ -832,6 +844,9 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fsp)
         * the EXT2_ERROR_FS flag in the fs superblock if needed.
         */
        retval = ext2fs_check_ext3_journal(fs);
+
+outfree:
+       free(save);
        return retval ? retval : recover_retval;
 }
 
index 6b0133e06619832c5f8cd9d42014dad0d689c8b1..b600228ed0c957dc0927401ce5f16e0acfc4fb8d 100644 (file)
@@ -48,6 +48,7 @@ enum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL};
 #define ANY_BLOCK ((blk64_t) -1)
 
 static int             dump_all, dump_super, dump_old, dump_contents, dump_descriptors;
+static int64_t         dump_counts;
 static blk64_t         block_to_dump, bitmap_to_dump, inode_block_to_dump;
 static unsigned int    group_to_dump, inode_offset_to_dump;
 static ext2_ino_t      inode_to_dump;
@@ -113,9 +114,10 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
        bitmap_to_dump = -1;
        inode_block_to_dump = ANY_BLOCK;
        inode_to_dump = -1;
+       dump_counts = -1;
 
        reset_getopt();
-       while ((c = getopt (argc, argv, "ab:ci:f:OsS")) != EOF) {
+       while ((c = getopt (argc, argv, "ab:ci:f:OsSn:")) != EOF) {
                switch (c) {
                case 'a':
                        dump_all++;
@@ -148,6 +150,14 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
                case 'S':
                        dump_super++;
                        break;
+               case 'n':
+                       dump_counts = strtol(optarg, &tmp, 10);
+                       if (*tmp) {
+                               com_err(argv[0], 0,
+                                       "Bad log counts number - %s", optarg);
+                               return;
+                       }
+                       break;
                default:
                        goto print_usage;
                }
@@ -289,7 +299,7 @@ cleanup:
        return;
 
 print_usage:
-       fprintf(stderr, "%s: Usage: logdump [-acsOS] [-b<block>] [-i<filespec>]\n\t"
+       fprintf(stderr, "%s: Usage: logdump [-acsOS] [-n<num_trans>] [-b<block>] [-i<filespec>]\n\t"
                "[-f<journal_file>] [output_file]\n", argv[0]);
 }
 
@@ -366,9 +376,12 @@ static void dump_journal(char *cmdname, FILE *out_file,
        journal_header_t        *header;
        tid_t                   transaction;
        unsigned int            blocknr = 0;
+       unsigned int            first_transaction_blocknr;
        int                     fc_done;
        __u64                   total_len;
        __u32                   maxlen;
+       int64_t                 cur_counts = 0;
+       bool                    exist_no_magic = false;
 
        /* First, check to see if there's an ext2 superblock header */
        retval = read_journal_block(cmdname, source, 0, buf, 2048);
@@ -458,7 +471,19 @@ static void dump_journal(char *cmdname, FILE *out_file,
                        blocknr = 1;
        }
 
+       first_transaction_blocknr = blocknr;
+
        while (1) {
+               if (dump_old && (dump_counts != -1) && (cur_counts >= dump_counts))
+                       break;
+
+               if ((blocknr == first_transaction_blocknr) &&
+                   (cur_counts != 0) && dump_old && (dump_counts != -1)) {
+                       fprintf(out_file, "Dump all %lld journal records.\n",
+                               (long long) cur_counts);
+                       break;
+               }
+
                retval = read_journal_block(cmdname, source,
                                ((ext2_loff_t) blocknr) * blocksize,
                                buf, blocksize);
@@ -472,8 +497,16 @@ static void dump_journal(char *cmdname, FILE *out_file,
                blocktype = be32_to_cpu(header->h_blocktype);
 
                if (magic != JBD2_MAGIC_NUMBER) {
-                       fprintf (out_file, "No magic number at block %u: "
-                                "end of journal.\n", blocknr);
+                       if (exist_no_magic == false) {
+                               exist_no_magic = true;
+                               fprintf(out_file, "No magic number at block %u: "
+                                       "end of journal.\n", blocknr);
+                       }
+                       if (dump_old && (dump_counts != -1)) {
+                               blocknr++;
+                               WRAP(jsb, blocknr, maxlen);
+                               continue;
+                       }
                        break;
                }
 
@@ -500,6 +533,7 @@ static void dump_journal(char *cmdname, FILE *out_file,
                        continue;
 
                case JBD2_COMMIT_BLOCK:
+                       cur_counts++;
                        transaction++;
                        blocknr++;
                        WRAP(jsb, blocknr, maxlen);
index b00157940774bc8c61e86565df0deea85c32be16..f916deab8cea90e2f7c05e6373c53247900cd7c0 100644 (file)
@@ -183,6 +183,7 @@ static struct field_set_info super_fields[] = {
        { "lpf_ino", &set_sb.s_lpf_ino, NULL, 4, parse_uint },
        { "checksum_seed", &set_sb.s_checksum_seed, NULL, 4, parse_uint },
        { "encoding", &set_sb.s_encoding, NULL, 2, parse_encoding },
+       { "orphan_file_inum", &set_sb.s_orphan_file_inum, NULL, 4, parse_uint },
        { 0, 0, 0, 0 }
 };
 
diff --git a/doc/RelNotes/v1.47.0.txt b/doc/RelNotes/v1.47.0.txt
new file mode 100644 (file)
index 0000000..8af28b9
--- /dev/null
@@ -0,0 +1,53 @@
+E2fsprogs 1.47.0 (February 5, 2023)
+===================================
+
+Updates/Fixes since v1.46.6:
+
+UI and Features
+---------------
+
+Add support for the orphan_file feature, which speeds up workloads that
+are deleting or truncating a large number files in parallel.  This
+compat feature was first supported in the v5.15 Linux kernel.
+
+The mke2fs program (via the mke2fs.conf file) now enables the
+metadata_csum_seed and orphan_file features by default.  The
+metadata_csum_seed feature is an incompat feature which is first
+supported in the Linux kernel starting in the 4.4 kernel and e2fsprogs
+1.43.
+
+Mke2fs now supports the extended option "assume_storage_prezeroed" which
+causes mke2fs to skip zeroing the journal and inode tables and to mark
+the inode tables as zeroed.
+
+Add support to tune2fs and e2label to set the label and UUID for a
+mounted file system using a ioctl, which is more reliable than modifying
+the superblock via writing to the block device.  The kernel support for
+setting the label landed in v5.17, while the support for adding the UUID
+landed in v6.0.  If the ioctls are not supported, tune2fs and e2label
+will fall back old strategy of directly modifying the superblock.
+
+Allow tune2fs to disable the casefold feature after scanning all of the
+directories do not have the Casefold flag set.
+
+
+Fixes
+-----
+
+Fix a potential unbalanced mutex unlock when there is a short read while
+using the bounce buffer when using direct I/O.
+
+
+Performance, Internal Implementation, Development Support etc.
+--------------------------------------------------------------
+
+Fix various Coverity and compiler warnings.
+
+Add the new function ext2fs_xattrs_read_inode() which takes an in-memory
+inode to avoid needing to reread an inode that was already read into
+memory.
+
+Teach debugfs logdump command the -n option which forces printing a
+specified number of transactions, even when a block missing a magic
+number would have stopped the logdump.  (This is for debugging
+journalling problems.)
index 5300604aee4260d986216e6271e810fcd577e3dc..5d4b0537ca6278582f7eec0767fcb73b260523d0 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo    @c -*-texinfo-*-
 @c %**start of header
 @setfilename libext2fs.info
-@settitle The EXT2FS Library (version 1.46.6)
+@settitle The EXT2FS Library (version 1.47.0)
 @synindex tp fn
 @comment %**end of header
 
@@ -60,7 +60,7 @@ by the author.
 
 @title The EXT2FS Library
 @subtitle The EXT2FS Library
-@subtitle Version 1.46.6
+@subtitle Version 1.47.0
 @subtitle February 2023
 
 @author by Theodore Ts'o
@@ -101,7 +101,7 @@ by the Foundation.
 
 @top The EXT2FS Library
 
-This manual documents the EXT2FS Library, version 1.46.6.
+This manual documents the EXT2FS Library, version 1.47.0.
 
 @menu
 * Introduction to the EXT2FS Library::  
index b8caa43b79726a2b8a7e30971ed4b20de90cb51d..3f2dc3084c40c95fd314d2d50d32b373d31dc42a 100644 (file)
@@ -656,6 +656,7 @@ void sigcatcher_setup(void);
 void check_super_block(e2fsck_t ctx);
 int check_backup_super_block(e2fsck_t ctx);
 void check_resize_inode(e2fsck_t ctx);
+int check_init_orphan_file(e2fsck_t ctx);
 
 /* util.c */
 extern void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size,
index 8ae89bf7bd16c177f41ceda8133c56e5c5ad0852..0144aa45aa90ddb50cfaf6801131675038bc1901 100644 (file)
@@ -610,10 +610,10 @@ static void ext4_fc_flush_extents(e2fsck_t ctx, ext2_ino_t ino)
 
 /* Helper struct for dentry replay routines */
 struct dentry_info_args {
-       ext2_ino_t parent_ino;
-       int dname_len;
-       ext2_ino_t ino;
-       char *dname;
+       ext2_ino_t      parent_ino;
+       ext2_ino_t      ino;
+       int             dname_len;
+       char            *dname;
 };
 
 static inline int tl_to_darg(struct dentry_info_args *darg,
@@ -1683,6 +1683,7 @@ errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
        errcode_t       retval, recover_retval;
        io_stats        stats = 0;
        unsigned long long kbytes_written = 0;
+       __u16 s_error_state;
 
        printf(_("%s: recovering journal\n"), ctx->device_name);
        if (ctx->options & E2F_OPT_READONLY) {
@@ -1705,6 +1706,7 @@ errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
                ctx->fs->io->manager->get_stats(ctx->fs->io, &stats);
        if (stats && stats->bytes_written)
                kbytes_written = stats->bytes_written >> 10;
+       s_error_state = ctx->fs->super->s_state & EXT2_ERROR_FS;
 
        ext2fs_mmp_stop(ctx->fs);
        ext2fs_free(ctx->fs);
@@ -1721,6 +1723,7 @@ errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
        ctx->fs->now = ctx->now;
        ctx->fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
        ctx->fs->super->s_kbytes_written += kbytes_written;
+       ctx->fs->super->s_state |= s_error_state;
 
        /* Set the superblock flags */
        e2fsck_clear_recover(ctx, recover_retval != 0);
index 78540119db463bbb13465cc7f92e26302748b491..a341c72ac56e51bd061a6871d354781efcfc08c6 100644 (file)
@@ -918,6 +918,7 @@ static void reserve_block_for_lnf_repair(e2fsck_t ctx)
 }
 
 static errcode_t get_inline_data_ea_size(ext2_filsys fs, ext2_ino_t ino,
+                                        struct ext2_inode *inode,
                                         size_t *sz)
 {
        void *p;
@@ -928,7 +929,8 @@ static errcode_t get_inline_data_ea_size(ext2_filsys fs, ext2_ino_t ino,
        if (retval)
                return retval;
 
-       retval = ext2fs_xattrs_read(handle);
+       retval = ext2fs_xattrs_read_inode(handle,
+                                         (struct ext2_inode_large *)inode);
        if (retval)
                goto err;
 
@@ -1515,7 +1517,8 @@ void e2fsck_pass1(e2fsck_t ctx)
                    (ino >= EXT2_FIRST_INODE(fs->super))) {
                        size_t size = 0;
 
-                       pctx.errcode = get_inline_data_ea_size(fs, ino, &size);
+                       pctx.errcode = get_inline_data_ea_size(fs, ino, inode,
+                                                              &size);
                        if (!pctx.errcode &&
                            fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
                                ext2fs_set_feature_inline_data(sb);
@@ -1538,7 +1541,7 @@ void e2fsck_pass1(e2fsck_t ctx)
                        flags = fs->flags;
                        if (failed_csum)
                                fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
-                       err = get_inline_data_ea_size(fs, ino, &size);
+                       err = get_inline_data_ea_size(fs, ino, inode, &size);
                        fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
                                    (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
 
@@ -1785,6 +1788,32 @@ void e2fsck_pass1(e2fsck_t ctx)
                                                        inode_size, "pass1");
                                failed_csum = 0;
                        }
+               } else if (ino == fs->super->s_orphan_file_inum) {
+                       ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
+                       if (ext2fs_has_feature_orphan_file(fs->super)) {
+                               if (!LINUX_S_ISREG(inode->i_mode) &&
+                                   fix_problem(ctx, PR_1_ORPHAN_FILE_BAD_MODE,
+                                               &pctx)) {
+                                       inode->i_mode = LINUX_S_IFREG;
+                                       e2fsck_write_inode(ctx, ino, inode,
+                                                          "pass1");
+                                       failed_csum = 0;
+                               }
+                               check_blocks(ctx, &pctx, block_buf, NULL);
+                               FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
+                               continue;
+                       }
+                       if ((inode->i_links_count ||
+                            inode->i_blocks || inode->i_block[0]) &&
+                           fix_problem(ctx, PR_1_ORPHAN_FILE_NOT_CLEAR,
+                                       &pctx)) {
+                               memset(inode, 0, inode_size);
+                               ext2fs_icount_store(ctx->inode_link_info, ino,
+                                                   0);
+                               e2fsck_write_inode_full(ctx, ino, inode,
+                                                       inode_size, "pass1");
+                               failed_csum = 0;
+                       }
                } else if (ino < EXT2_FIRST_INODE(fs->super)) {
                        problem_t problem = 0;
 
@@ -3494,6 +3523,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
        }
 
        if (ino != quota_type2inum(PRJQUOTA, fs->super) &&
+           ino != fs->super->s_orphan_file_inum &&
            (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) &&
            !(inode->i_flags & EXT4_EA_INODE_FL)) {
                quota_data_add(ctx->qctx, (struct ext2_inode_large *) inode,
index 42f3e5efbd09b0786d41cc588aa83feefcaf9e82..b91628567a7fabac040bb512eae39e649938cfca 100644 (file)
@@ -1457,7 +1457,8 @@ skip_checksum:
                    (dirent->inode > fs->super->s_inodes_count) ||
                    (dirent->inode == fs->super->s_usr_quota_inum) ||
                    (dirent->inode == fs->super->s_grp_quota_inum) ||
-                   (dirent->inode == fs->super->s_prj_quota_inum)) {
+                   (dirent->inode == fs->super->s_prj_quota_inum) ||
+                   (dirent->inode == fs->super->s_orphan_file_inum)) {
                        problem = PR_2_BAD_INO;
                } else if (ctx->inode_bb_map &&
                           (ext2fs_test_inode_bitmap2(ctx->inode_bb_map,
index 8c2d2f1fca1234320fd28ffe65882a53aa168504..d2dda02a94b8d8e342460559c87c1578b4807497 100644 (file)
@@ -26,7 +26,7 @@
  * This subroutine returns 1 then the caller shouldn't bother with the
  * rest of the pass 4 tests.
  */
-static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i,
+static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
                            struct ext2_inode_large *inode)
 {
        ext2_filsys fs = ctx->fs;
@@ -34,9 +34,12 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i,
        __u32 eamagic = 0;
        int extra_size = 0;
 
-       e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
-                              EXT2_INODE_SIZE(fs->super),
-                              "pass4: disconnect_inode");
+       if (*last_ino != i) {
+               e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
+                                      EXT2_INODE_SIZE(fs->super),
+                                      "pass4: disconnect_inode");
+               *last_ino = i;
+       }
        if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
                extra_size = inode->i_extra_isize;
 
@@ -75,6 +78,7 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i,
        if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
                if (e2fsck_reconnect_file(ctx, i))
                        ext2fs_unmark_valid(fs);
+               *last_ino = 0;
        } else {
                /*
                 * If we don't attach the inode, then skip the
@@ -87,20 +91,22 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i,
        return 0;
 }
 
-static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i,
+/*
+ * This function is called when link_counted is zero. So this may not be
+ * an xattr inode at all. Return immediately if EA_INODE flag is not set.
+ */
+static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
                           struct ext2_inode_large *inode, __u16 *link_counted)
 {
        __u64 actual_refs = 0;
        __u64 ref_count;
 
-       /*
-        * This function is called when link_counted is zero. So this may not
-        * be an xattr inode at all. Return immediately if EA_INODE flag is not
-        * set.
-        */
-       e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
-                              EXT2_INODE_SIZE(ctx->fs->super),
-                              "pass4: check_ea_inode");
+       if (*last_ino != i) {
+               e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
+                                      EXT2_INODE_SIZE(ctx->fs->super),
+                                      "pass4: check_ea_inode");
+               *last_ino = i;
+       }
        if (!(inode->i_flags & EXT4_EA_INODE_FL))
                return;
 
@@ -180,7 +186,8 @@ void e2fsck_pass4(e2fsck_t ctx)
        inode = e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
 
        /* Protect loop from wrap-around if s_inodes_count maxed */
-       for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) {
+       for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
+               ext2_ino_t last_ino = 0;
                int isdir;
 
                if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
@@ -192,7 +199,7 @@ void e2fsck_pass4(e2fsck_t ctx)
                                        goto errout;
                }
                if (i == quota_type2inum(PRJQUOTA, ctx->fs->super) ||
-                   i == EXT2_BAD_INO ||
+                   i == fs->super->s_orphan_file_inum || i == EXT2_BAD_INO ||
                    (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
                        continue;
                if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) ||
@@ -210,7 +217,7 @@ void e2fsck_pass4(e2fsck_t ctx)
                         * check_ea_inode() will update link_counted if
                         * necessary.
                         */
-                       check_ea_inode(ctx, i, inode, &link_counted);
+                       check_ea_inode(ctx, i, &last_ino, inode, &link_counted);
                }
 
                if (link_counted == 0) {
@@ -219,7 +226,7 @@ void e2fsck_pass4(e2fsck_t ctx)
                                     fs->blocksize, "bad_inode buffer");
                        if (e2fsck_process_bad_inode(ctx, 0, i, buf))
                                continue;
-                       if (disconnect_inode(ctx, i, inode))
+                       if (disconnect_inode(ctx, i, &last_ino, inode))
                                continue;
                        ext2fs_icount_fetch(ctx->inode_link_info, i,
                                            &link_count);
@@ -239,8 +246,12 @@ void e2fsck_pass4(e2fsck_t ctx)
                if (link_counted != link_count) {
                        int fix_nlink = 0;
 
-                       e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
-                                              inode_size, "pass4");
+                       if (last_ino != i) {
+                               e2fsck_read_inode_full(ctx, i,
+                                                      EXT2_INODE(inode),
+                                                      inode_size, "pass4");
+                               last_ino = i;
+                       }
                        pctx.ino = i;
                        pctx.inode = EXT2_INODE(inode);
                        if ((link_count != inode->i_links_count) && !isdir &&
index e2572f5952f8457e447e56465004c68b25e5a82f..013ace24965be15aa00b5366752ec213f73a56d0 100644 (file)
@@ -526,6 +526,26 @@ static struct e2fsck_problem problem_table[] = {
             "not compatible. Resize @i should be disabled.  "),
          PROMPT_FIX, 0, 0, 0, 0 },
 
+       /* Orphan file contains holes */
+       { PR_0_ORPHAN_FILE_HOLE,
+         N_("Orphan file (@i %i) contains hole at @b %b. Terminating orphan file recovery.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file block has wrong magic */
+       { PR_0_ORPHAN_FILE_BAD_MAGIC,
+         N_("Orphan file (@i %i) @b %b contains wrong magic. Terminating orphan file recovery.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file block has wrong checksum */
+       { PR_0_ORPHAN_FILE_BAD_CHECKSUM,
+         N_("Orphan file (@i %i) @b %b contains wrong checksum. Terminating orphan file recovery.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file size isn't multiple of blocks size */
+       { PR_0_ORPHAN_FILE_WRONG_SIZE,
+         N_("Orphan file (@i %i) size is not multiple of block size. Terminating orphan file recovery.\n"),
+         PROMPT_NONE, 0 },
+
        /* Pass 1 errors */
 
        /* Pass 1: Checking inodes, blocks, and sizes */
@@ -1279,6 +1299,15 @@ static struct e2fsck_problem problem_table[] = {
          N_("@h %i uses SipHash, but should not.  "),
          PROMPT_CLEAR_HTREE, PR_PREEN_OK, 0, 0, 0 },
 
+       /* Orphan file has bad mode */
+       { PR_1_ORPHAN_FILE_BAD_MODE,
+         N_("Orphan file @i %i is not regular file.  "),
+         PROMPT_CLEAR, PR_PREEN_OK },
+
+       /* Orphan file inode is not in use, but contains data */
+       { PR_1_ORPHAN_FILE_NOT_CLEAR,
+         N_("Orphan file @i %i is not in use, but contains data.  "),
+         PROMPT_CLEAR, PR_PREEN_OK },
 
        /* Pass 1b errors */
 
@@ -2265,6 +2294,56 @@ static struct e2fsck_problem problem_table[] = {
          N_("Error writing quota info for quota type %N: %m\n"),
          PROMPT_NULL, 0, 0, 0, 0 },
 
+       /* Orphan file without a journal */
+       { PR_6_ORPHAN_FILE_WITHOUT_JOURNAL,
+         N_("@S has orphan file without @j.\n"),
+         PROMPT_CLEAR, PR_PREEN_OK },
+
+       /* Orphan file truncation failed */
+       { PR_6_ORPHAN_FILE_TRUNC_FAILED,
+         N_("Failed to truncate orphan file.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Failed to initialize orphan file */
+       { PR_6_ORPHAN_FILE_CORRUPTED,
+         N_("Failed to initialize orphan file.\n"),
+         PROMPT_RECREATE, PR_PREEN_OK },
+
+       /* Cannot fix corrupted orphan file with invalid bitmaps */
+       { PR_6_ORPHAN_FILE_BITMAP_INVALID,
+         N_("Cannot fix corrupted orphan file with invalid bitmaps.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file creation failed */
+       { PR_6_ORPHAN_FILE_CREATE_FAILED,
+         N_("Failed to truncate orphan file (@i %i).\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file block contains data */
+       { PR_6_ORPHAN_BLOCK_DIRTY,
+         N_("Orphan file (@i %i) @b %b is not clean.\n"),
+         PROMPT_CLEAR, PR_PREEN_OK },
+
+       /* orphan_present set but orphan file is empty */
+       { PR_6_ORPHAN_PRESENT_CLEAN_FILE,
+         N_("Feature orphan_present is set but orphan file is clean.\n"),
+         PROMPT_CLEAR, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
+
+       /* orphan_present set but orphan_file is not */
+       { PR_6_ORPHAN_PRESENT_NO_FILE,
+         N_("Feature orphan_present is set but feature orphan_file is not.\n"),
+         PROMPT_CLEAR, PR_PREEN_OK },
+
+       /* Orphan file size isn't multiple of blocks size */
+       { PR_6_ORPHAN_FILE_WRONG_SIZE,
+         N_("Orphan file (@i %i) size is not multiple of block size.\n"),
+         PROMPT_NONE, 0 },
+
+       /* Orphan file contains holes */
+       { PR_6_ORPHAN_FILE_HOLE,
+         N_("Orphan file (@i %i) contains hole at @b %b.\n"),
+         PROMPT_NONE, 0 },
+
        { 0 }
 };
 
index e86bc889d35ed801dcf84ed53c40b75a6f85e065..b47b0c630c67bbb96f66b9730ad6851cb39e827b 100644 (file)
@@ -288,6 +288,18 @@ struct problem_context {
 /* Meta_bg and resize_inode are not compatible, remove resize_inode*/
 #define PR_0_DISABLE_RESIZE_INODE              0x000051
 
+/* Orphan file contains holes */
+#define PR_0_ORPHAN_FILE_HOLE                  0x000052
+
+/* Orphan file block has wrong magic */
+#define PR_0_ORPHAN_FILE_BAD_MAGIC             0x000053
+
+/* Orphan file block has wrong checksum */
+#define PR_0_ORPHAN_FILE_BAD_CHECKSUM          0x000054
+
+/* Orphan file size isn't multiple of blocks size */
+#define PR_0_ORPHAN_FILE_WRONG_SIZE            0x000055
+
 /*
  * Pass 1 errors
  */
@@ -716,6 +728,11 @@ struct problem_context {
 /* Htree directory uses SipHash but should not */
 #define PR_1_HTREE_CANNOT_SIPHASH              0x01008E
 
+/* Orphan file inode is not a regular file */
+#define PR_1_ORPHAN_FILE_BAD_MODE              0x01008F
+
+/* Orphan file inode is not in use, but contains data */
+#define PR_1_ORPHAN_FILE_NOT_CLEAR             0x010090
 
 /*
  * Pass 1b errors
@@ -1296,6 +1313,35 @@ struct problem_context {
 /* Error updating quota information */
 #define PR_6_WRITE_QUOTAS              0x060006
 
+/* Orphan file without a journal */
+#define PR_6_ORPHAN_FILE_WITHOUT_JOURNAL       0x060007
+
+/* Orphan file truncation failed */
+#define PR_6_ORPHAN_FILE_TRUNC_FAILED  0x060008
+
+/* Failed to initialize orphan file */
+#define PR_6_ORPHAN_FILE_CORRUPTED     0x060009
+
+/* Cannot fix corrupted orphan file with invalid bitmaps */
+#define PR_6_ORPHAN_FILE_BITMAP_INVALID        0x06000A
+
+/* Orphan file creation failed */
+#define PR_6_ORPHAN_FILE_CREATE_FAILED 0x06000B
+
+/* Orphan file block contains data */
+#define PR_6_ORPHAN_BLOCK_DIRTY                0x06000C
+
+/* orphan_present set but orphan file is empty */
+#define PR_6_ORPHAN_PRESENT_CLEAN_FILE 0x06000D
+
+/* orphan_present set but orphan_file is not */
+#define PR_6_ORPHAN_PRESENT_NO_FILE    0x06000E
+
+/* Orphan file size isn't multiple of blocks size */
+#define PR_6_ORPHAN_FILE_WRONG_SIZE    0x06000F
+
+/* Orphan file contains holes */
+#define PR_6_ORPHAN_FILE_HOLE          0x060010
 
 /*
  * Function declarations
index 8235e468eb35585050c8b1330f1ccad4d93a30d4..c1da7d52724e9644a9e7ac45fc469868eb93f376 100644 (file)
@@ -89,9 +89,9 @@ struct fill_dir_struct {
 };
 
 struct hash_entry {
-       ext2_dirhash_t  hash;
-       ext2_dirhash_t  minor_hash;
-       ext2_ino_t      ino;
+       ext2_dirhash_t          hash;
+       ext2_dirhash_t          minor_hash;
+       ext2_ino_t              ino;
        struct ext2_dir_entry   *dir;
 };
 
index 123813be718394b17b3579f3879ddaa23bfbff25..be40dd8fb64d86af4e119ad3efe5c0a3aa380568 100644 (file)
@@ -314,6 +314,180 @@ static errcode_t e2fsck_write_all_quotas(e2fsck_t ctx)
        return pctx.errcode;
 }
 
+static int release_orphan_inode(e2fsck_t ctx, ext2_ino_t *ino, char *block_buf)
+{
+       ext2_filsys fs = ctx->fs;
+       struct problem_context pctx;
+       struct ext2_inode_large inode;
+       ext2_ino_t next_ino;
+
+       e2fsck_read_inode_full(ctx, *ino, EXT2_INODE(&inode),
+                               sizeof(inode), "release_orphan_inode");
+       clear_problem_context(&pctx);
+       pctx.ino = *ino;
+       pctx.inode = EXT2_INODE(&inode);
+       pctx.str = inode.i_links_count ? _("Truncating") : _("Clearing");
+
+       fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
+
+       next_ino = inode.i_dtime;
+       if (next_ino &&
+           ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
+            (next_ino > fs->super->s_inodes_count))) {
+               pctx.ino = next_ino;
+               fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
+               return 1;
+       }
+
+       if (release_inode_blocks(ctx, *ino, &inode, block_buf, &pctx))
+               return 1;
+
+       if (!inode.i_links_count) {
+               if (ctx->qctx)
+                       quota_data_inodes(ctx->qctx, &inode, *ino, -1);
+               ext2fs_inode_alloc_stats2(fs, *ino, -1,
+                                         LINUX_S_ISDIR(inode.i_mode));
+               ctx->free_inodes++;
+               inode.i_dtime = ctx->now;
+       } else {
+               inode.i_dtime = 0;
+       }
+       e2fsck_write_inode_full(ctx, *ino, EXT2_INODE(&inode),
+                               sizeof(inode), "delete_file");
+       *ino = next_ino;
+       return 0;
+}
+
+struct process_orphan_block_data {
+       e2fsck_t        ctx;
+       char            *buf;
+       char            *block_buf;
+       e2_blkcnt_t     blocks;
+       int             abort;
+       int             clear;
+       errcode_t       errcode;
+       ext2_ino_t      ino;
+       __u32           generation;
+};
+
+static int process_orphan_block(ext2_filsys fs,
+                              blk64_t  *block_nr,
+                              e2_blkcnt_t blockcnt,
+                              blk64_t  ref_blk EXT2FS_ATTR((unused)),
+                              int      ref_offset EXT2FS_ATTR((unused)),
+                              void *priv_data)
+{
+       struct process_orphan_block_data *pd;
+       e2fsck_t                ctx;
+       struct problem_context  pctx;
+       blk64_t                 blk = *block_nr;
+       struct ext4_orphan_block_tail *tail;
+       int                     j;
+       int                     inodes_per_ob;
+       __u32                   *bdata;
+       ext2_ino_t              ino;
+
+       pd = priv_data;
+       ctx = pd->ctx;
+       clear_problem_context(&pctx);
+       pctx.ino = fs->super->s_orphan_file_inum;
+       pctx.blk = blockcnt;
+
+       /* Orphan file must not have holes */
+       if (!blk) {
+               if (blockcnt == pd->blocks)
+                       return BLOCK_ABORT;
+               fix_problem(ctx, PR_0_ORPHAN_FILE_HOLE, &pctx);
+return_abort:
+               pd->abort = 1;
+               return BLOCK_ABORT;
+       }
+       inodes_per_ob = ext2fs_inodes_per_orphan_block(fs);
+       pd->errcode = io_channel_read_blk64(fs->io, blk, 1, pd->buf);
+       if (pd->errcode)
+               goto return_abort;
+       tail = ext2fs_orphan_block_tail(fs, pd->buf);
+       if (ext2fs_le32_to_cpu(tail->ob_magic) !=
+           EXT4_ORPHAN_BLOCK_MAGIC) {
+               fix_problem(ctx, PR_0_ORPHAN_FILE_BAD_MAGIC, &pctx);
+               goto return_abort;
+       }
+       if (!ext2fs_orphan_file_block_csum_verify(fs,
+                       fs->super->s_orphan_file_inum, blk, pd->buf)) {
+               fix_problem(ctx, PR_0_ORPHAN_FILE_BAD_CHECKSUM, &pctx);
+               goto return_abort;
+       }
+       bdata = (__u32 *)pd->buf;
+       for (j = 0; j < inodes_per_ob; j++) {
+               if (!bdata[j])
+                       continue;
+               ino = ext2fs_le32_to_cpu(bdata[j]);
+               if (release_orphan_inode(ctx, &ino, pd->block_buf))
+                       goto return_abort;
+       }
+       return 0;
+}
+
+static int process_orphan_file(e2fsck_t ctx, char *block_buf)
+{
+       ext2_filsys fs = ctx->fs;
+       char *orphan_buf;
+       struct process_orphan_block_data pd;
+       int ret = 0;
+       ext2_ino_t orphan_inum = fs->super->s_orphan_file_inum;
+       struct ext2_inode orphan_inode;
+       struct problem_context  pctx;
+       errcode_t retval;
+
+       if (!ext2fs_has_feature_orphan_file(fs->super))
+               return 0;
+
+       clear_problem_context(&pctx);
+       pctx.ino = orphan_inum;
+
+       orphan_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
+                                                   "orphan block buffer");
+       retval = ext2fs_read_inode(fs, orphan_inum, &orphan_inode);
+       if (retval < 0) {
+               com_err("process_orphan_file", retval,
+                       _("while reading inode %d"), orphan_inum);
+               ret = 1;
+               goto out;
+       }
+       if (EXT2_I_SIZE(&orphan_inode) & (fs->blocksize - 1)) {
+               fix_problem(ctx, PR_0_ORPHAN_FILE_WRONG_SIZE, &pctx);
+               ret = 1;
+               goto out;
+       }
+       pd.buf = orphan_buf + 3 * fs->blocksize;
+       pd.block_buf = block_buf;
+       pd.blocks = EXT2_I_SIZE(&orphan_inode) / fs->blocksize;
+       pd.ctx = ctx;
+       pd.abort = 0;
+       pd.errcode = 0;
+       retval = ext2fs_block_iterate3(fs, orphan_inum,
+                                      BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE,
+                                      orphan_buf, process_orphan_block, &pd);
+       if (retval) {
+               com_err("process_orphan_block", retval,
+                       _("while calling ext2fs_block_iterate for inode %d"),
+                       orphan_inum);
+               ret = 1;
+               goto out;
+       }
+       if (pd.abort) {
+               if (pd.errcode) {
+                       com_err("process_orphan_block", pd.errcode,
+                               _("while reading blocks of inode %d"),
+                               orphan_inum);
+               }
+               ret = 1;
+       }
+out:
+       ext2fs_free_mem(&orphan_buf);
+       return ret;
+}
+
 /*
  * This function releases all of the orphan inodes.  It returns 1 if
  * it hit some error, and 0 on success.
@@ -321,15 +495,17 @@ static errcode_t e2fsck_write_all_quotas(e2fsck_t ctx)
 static int release_orphan_inodes(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
-       ext2_ino_t      ino, next_ino;
-       struct ext2_inode_large inode;
+       ext2_ino_t ino;
        struct problem_context pctx;
        char *block_buf;
 
-       if ((ino = fs->super->s_last_orphan) == 0)
+       if (fs->super->s_last_orphan == 0 &&
+           !ext2fs_has_feature_orphan_present(fs->super))
                return 0;
 
        clear_problem_context(&pctx);
+       ino = fs->super->s_last_orphan;
+       pctx.ino = ino;
        pctx.errcode = e2fsck_read_all_quotas(ctx);
        if (pctx.errcode) {
                fix_problem(ctx, PR_0_QUOTA_INIT_CTX, &pctx);
@@ -344,9 +520,10 @@ static int release_orphan_inodes(e2fsck_t ctx)
        ext2fs_mark_super_dirty(fs);
 
        /*
-        * If the filesystem contains errors, don't run the orphan
-        * list, since the orphan list can't be trusted; and we're
-        * going to be running a full e2fsck run anyway...
+        * If the filesystem contains errors, don't process the orphan list
+        * or orphan file, since neither can be trusted; and we're going to
+        * be running a full e2fsck run anyway... We clear orphan file contents
+        * after filesystem is checked to avoid clearing someone else's data.
         */
        if (fs->super->s_state & EXT2_ERROR_FS) {
                if (ctx->qctx)
@@ -354,10 +531,8 @@ static int release_orphan_inodes(e2fsck_t ctx)
                return 0;
        }
 
-       if ((ino < EXT2_FIRST_INODE(fs->super)) ||
-           (ino > fs->super->s_inodes_count)) {
-               clear_problem_context(&pctx);
-               pctx.ino = ino;
+       if (ino && ((ino < EXT2_FIRST_INODE(fs->super)) ||
+           (ino > fs->super->s_inodes_count))) {
                fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
                goto err_qctx;
        }
@@ -366,43 +541,19 @@ static int release_orphan_inodes(e2fsck_t ctx)
                                                    "block iterate buffer");
        e2fsck_read_bitmaps(ctx);
 
+       /* First process orphan list */
        while (ino) {
-               e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode),
-                               sizeof(inode), "release_orphan_inodes");
-               clear_problem_context(&pctx);
-               pctx.ino = ino;
-               pctx.inode = EXT2_INODE(&inode);
-               pctx.str = inode.i_links_count ? _("Truncating") :
-                       _("Clearing");
-
-               fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
-
-               next_ino = inode.i_dtime;
-               if (next_ino &&
-                   ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
-                    (next_ino > fs->super->s_inodes_count))) {
-                       pctx.ino = next_ino;
-                       fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
+               if (release_orphan_inode(ctx, &ino, block_buf))
                        goto err_buf;
-               }
+       }
 
-               if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
-                       goto err_buf;
+       /* Next process orphan file */
+       if (ext2fs_has_feature_orphan_present(fs->super) &&
+           !ext2fs_has_feature_orphan_file(fs->super))
+               goto err_buf;
+       if (process_orphan_file(ctx, block_buf))
+               goto err_buf;
 
-               if (!inode.i_links_count) {
-                       if (ctx->qctx)
-                               quota_data_inodes(ctx->qctx, &inode, ino, -1);
-                       ext2fs_inode_alloc_stats2(fs, ino, -1,
-                                                 LINUX_S_ISDIR(inode.i_mode));
-                       ctx->free_inodes++;
-                       inode.i_dtime = ctx->now;
-               } else {
-                       inode.i_dtime = 0;
-               }
-               e2fsck_write_inode_full(ctx, ino, EXT2_INODE(&inode),
-                               sizeof(inode), "delete_file");
-               ino = next_ino;
-       }
        ext2fs_free_mem(&block_buf);
        pctx.errcode = e2fsck_write_all_quotas(ctx);
        if (pctx.errcode)
@@ -417,6 +568,134 @@ err:
        return 1;
 }
 
+static int reinit_orphan_block(ext2_filsys fs,
+                              blk64_t  *block_nr,
+                              e2_blkcnt_t blockcnt,
+                              blk64_t  ref_blk EXT2FS_ATTR((unused)),
+                              int      ref_offset EXT2FS_ATTR((unused)),
+                              void *priv_data)
+{
+       struct process_orphan_block_data *pd;
+       e2fsck_t                ctx;
+       blk64_t                 blk = *block_nr;
+       struct problem_context  pctx;
+
+       pd = priv_data;
+       ctx = pd->ctx;
+
+       /* Orphan file must not have holes */
+       if (!blk) {
+               if (blockcnt == pd->blocks)
+                       return BLOCK_ABORT;
+
+               clear_problem_context(&pctx);
+               pctx.ino = fs->super->s_orphan_file_inum;
+               pctx.blk = blockcnt;
+               fix_problem(ctx, PR_6_ORPHAN_FILE_HOLE, &pctx);
+return_abort:
+               pd->abort = 1;
+               return BLOCK_ABORT;
+       }
+
+       if (ext2fs_has_feature_metadata_csum(fs->super)) {
+               struct ext4_orphan_block_tail *tail;
+
+               tail = ext2fs_orphan_block_tail(fs, pd->buf);
+               /*
+                * Update checksum to match expected buffer contents with
+                * appropriate block number.
+                */
+               tail->ob_checksum = ext2fs_do_orphan_file_block_csum(fs,
+                               pd->ino, pd->generation, blk, pd->buf);
+       }
+       if (!pd->clear) {
+               pd->errcode = io_channel_read_blk64(fs->io, blk, 1,
+                                                   pd->block_buf);
+               /* Block is already cleanly initialized? */
+               if (!memcmp(pd->block_buf, pd->buf, fs->blocksize))
+                       return 0;
+
+               clear_problem_context(&pctx);
+               pctx.ino = fs->super->s_orphan_file_inum;
+               pctx.blk = blockcnt;
+               if (!fix_problem(ctx, PR_6_ORPHAN_BLOCK_DIRTY, &pctx))
+                       goto return_abort;
+               pd->clear = 1;
+       }
+       pd->errcode = io_channel_write_blk64(fs->io, blk, 1, pd->buf);
+       if (pd->errcode)
+               goto return_abort;
+       return 0;
+}
+
+/*
+ * Check and clear orphan file. We just return non-zero if we hit some
+ * inconsistency. Caller will truncate & recreate new orphan file.
+ */
+int check_init_orphan_file(e2fsck_t ctx)
+{
+       ext2_filsys fs = ctx->fs;
+       char *orphan_buf;
+       struct process_orphan_block_data pd;
+       struct ext4_orphan_block_tail *tail;
+       ext2_ino_t orphan_inum = fs->super->s_orphan_file_inum;
+       struct ext2_inode orphan_inode;
+       int ret = 0;
+       errcode_t retval;
+
+       orphan_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 5,
+                                                   "orphan block buffer");
+       e2fsck_read_inode(ctx, orphan_inum, &orphan_inode, "orphan inode");
+       if (EXT2_I_SIZE(&orphan_inode) & (fs->blocksize - 1)) {
+               struct problem_context  pctx;
+
+               clear_problem_context(&pctx);
+               pctx.ino = orphan_inum;
+               fix_problem(ctx, PR_6_ORPHAN_FILE_WRONG_SIZE, &pctx);
+               ret = 1;
+               goto out;
+       }
+       pd.buf = orphan_buf + 3 * fs->blocksize;
+       pd.block_buf = orphan_buf + 4 * fs->blocksize;
+       pd.blocks = EXT2_I_SIZE(&orphan_inode) / fs->blocksize;
+       pd.ctx = ctx;
+       pd.abort = 0;
+       pd.clear = 0;
+       pd.errcode = 0;
+       pd.ino = orphan_inum;
+       pd.generation = orphan_inode.i_generation;
+       /* Initialize buffer to write */
+       memset(pd.buf, 0, fs->blocksize);
+       tail = ext2fs_orphan_block_tail(fs, pd.buf);
+       tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC);
+
+       retval = ext2fs_block_iterate3(fs, orphan_inum,
+                                      BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE,
+                                      orphan_buf, reinit_orphan_block, &pd);
+       if (retval) {
+               com_err("reinit_orphan_block", retval,
+                       _("while calling ext2fs_block_iterate for inode %d"),
+                       orphan_inum);
+               ret = 1;
+               goto out;
+       }
+       if (pd.abort) {
+               if (pd.errcode) {
+                       com_err("process_orphan_block", pd.errcode,
+                               _("while reading blocks of inode %d"),
+                               orphan_inum);
+               }
+               ret = 1;
+       }
+
+       /* We had to clear some blocks. Report it up. */
+       if (ret == 0 && pd.clear)
+               ret = 2;
+out:
+       ext2fs_free_mem(&orphan_buf);
+       return ret;
+}
+
 /*
  * Check the resize inode to make sure it is sane.  We check both for
  * the case where on-line resizing is not enabled (in which case the
@@ -1109,7 +1388,8 @@ void check_super_block(e2fsck_t ctx)
  * away.
  */
 #define FEATURE_RO_COMPAT_IGNORE       (EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-                                        EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
+                                        EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
+                                        EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT)
 #define FEATURE_INCOMPAT_IGNORE                (EXT3_FEATURE_INCOMPAT_EXTENTS| \
                                         EXT3_FEATURE_INCOMPAT_RECOVER)
 
index 853eb29644ad6c9622d4c95805f344770e82b88b..e5b672a2e58acb7167376ead6a63a3349ccd65a3 100644 (file)
@@ -1954,15 +1954,82 @@ print_unsupp_features:
                                _("\n*** journal has been regenerated ***\n"));
                }
        }
-no_journal:
 
+no_journal:
        if (run_result & E2F_FLAG_ABORT) {
                fatal_error(ctx, _("aborted"));
        } else if (run_result & E2F_FLAG_CANCEL) {
                log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ?
                        ctx->device_name : ctx->filesystem_name);
                exit_value |= FSCK_CANCELED;
-       } else if (ctx->qctx && !ctx->invalid_bitmaps) {
+               goto cleanup;
+       }
+
+       if (ext2fs_has_feature_orphan_file(fs->super)) {
+               int ret;
+
+               /* No point in orphan file without a journal... */
+               if (!ext2fs_has_feature_journal(fs->super) &&
+                   fix_problem(ctx, PR_6_ORPHAN_FILE_WITHOUT_JOURNAL, &pctx)) {
+                       retval = ext2fs_truncate_orphan_file(fs);
+                       if (retval) {
+                               /* Huh, failed to delete file */
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+                       ext2fs_clear_feature_orphan_file(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+                       goto check_quotas;
+               }
+               ret = check_init_orphan_file(ctx);
+               if (ret == 2 ||
+                   (ret == 0 && ext2fs_has_feature_orphan_present(fs->super) &&
+                    fix_problem(ctx, PR_6_ORPHAN_PRESENT_CLEAN_FILE, &pctx))) {
+                       ext2fs_clear_feature_orphan_present(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+               } else if (ret == 1 &&
+                   fix_problem(ctx, PR_6_ORPHAN_FILE_CORRUPTED, &pctx)) {
+                       int orphan_file_blocks;
+
+                       if (ctx->invalid_bitmaps) {
+                               fix_problem(ctx,
+                                           PR_6_ORPHAN_FILE_BITMAP_INVALID,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+
+                       retval = ext2fs_truncate_orphan_file(fs);
+                       if (retval) {
+                               /* Huh, failed to truncate file */
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+
+                       orphan_file_blocks =
+                               ext2fs_default_orphan_file_blocks(fs);
+                       log_out(ctx, _("Creating orphan file (%d blocks): "),
+                               orphan_file_blocks);
+                       fflush(stdout);
+                       retval = ext2fs_create_orphan_file(fs,
+                                                          orphan_file_blocks);
+                       if (retval) {
+                               log_out(ctx, "%s: while trying to create "
+                                       "orphan file\n", error_message(retval));
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_CREATE_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+                       log_out(ctx, "%s", _(" Done.\n"));
+               }
+       } else if (ext2fs_has_feature_orphan_present(fs->super) &&
+                  fix_problem(ctx, PR_6_ORPHAN_PRESENT_NO_FILE, &pctx)) {
+                       ext2fs_clear_feature_orphan_present(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+       }
+check_quotas:
+       if (ctx->qctx && !ctx->invalid_bitmaps) {
                int needs_writeout;
 
                for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
@@ -1997,6 +2064,7 @@ no_journal:
                goto restart;
        }
 
+cleanup:
 #ifdef MTRACE
        mtrace_print("Cleanup");
 #endif
index 72ee4c81506c2a58545e8a811aba73892e54bd9c..3dec8c9e16295cc1b8e2f00f64b836c4140279f9 100644 (file)
@@ -1,15 +1,15 @@
 Begin3
 Title:          EXT2 Filesystem utilities
-Version:        1.46.6
-Entered-date:   2023-02-01
+Version:        1.47.0
+Entered-date:   2023-02-05
 Description:    The filesystem utilities for the EXT2, EXT3, and EXT4
                filesystems, including e2fsck, mke2fs, dumpe2fs, and others.
 Keywords:       utilities, filesystem, Ext2fs, ext3, ext4
 Author:         tytso@mit.edu (Theodore Tso)
 Maintained-by:  tytso@mit.edu (Theodore Tso)
 Primary-site:   ftp.kernel.org /pub/linux/kernel/people/tytso/e2fsprogs
-                9400kB e2fsprogs-1.46.6.tar.gz
-                1kB    e2fsprogs-1.46.6.lsm
+                9400kB e2fsprogs-1.46.7.tar.gz
+                1kB    e2fsprogs-1.46.7.lsm
 pAlternate-site: download.sourceforge.net /pub/sourceforge/e2fsprogs
 Platforms:     linux 1.2.x/1.3.x/2.0.x/2.1.x/2.2.x/2.3.x/2.4.x/2.5.x/2.6.x/3.x/4.x/5.x/6.x
 Copying-policy: GPL-2/LGPL-2
index 417be49012af419062afce6ab174fe69c0a21c87..bdcf76138d63e87b0844eca53e90ad39ca42833e 100644 (file)
@@ -5,7 +5,7 @@
 
 Summary: Utilities for managing ext2/ext3/ext4 filesystems
 Name: e2fsprogs
-Version: 1.46.6
+Version: 1.47.0
 Release: 0
 License: GPLv2
 Group: System Environment/Base
index 2291060214ff98e77bd59bdabfc927470726c5c5..29b7b1512400a1c7705f04d791ae3c0aad406684 100644 (file)
@@ -49,6 +49,8 @@ static struct feature feature_list[] = {
                        "fast_commit" },
        {       E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_STABLE_INODES,
                        "stable_inodes" },
+       {       E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE,
+                       "orphan_file" },
 
        {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
                        "sparse_super" },
@@ -80,6 +82,8 @@ static struct feature feature_list[] = {
                        "shared_blocks"},
        {       E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_VERITY,
                        "verity"},
+       {       E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT,
+                       "orphan_present" },
 
        {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
                        "compression" },
index 9511d2c7a51df59ab25f4468ecc10a1321809e2f..0b74aea2b452ee0c6d501aa3cfa9abe386e942d7 100644 (file)
@@ -482,6 +482,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
        if (ext2fs_has_feature_casefold(sb))
                fprintf(f, "Character encoding:       %s\n",
                        e2p_encoding2str(sb->s_encoding));
+       if (ext2fs_has_feature_orphan_file(sb))
+               fprintf(f, "Orphan file inode:        %u\n",
+                       sb->s_orphan_file_inum);
 }
 
 void list_super (struct ext2_super_block * s)
index 1b6a74b8f8c005da38b9657917e43b84c1fc373b..798ff60981a9987009d645a35d5b81f544155598 100644 (file)
@@ -115,6 +115,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
        newdir.o \
        nls_utf8.o \
        openfs.o \
+       orphan.o \
        progress.o \
        punch.o \
        qcow2.o \
@@ -198,6 +199,7 @@ SRCS= ext2_err.c \
        $(srcdir)/newdir.c \
        $(srcdir)/nls_utf8.c \
        $(srcdir)/openfs.c \
+       $(srcdir)/orphan.c \
        $(srcdir)/progress.c \
        $(srcdir)/punch.c \
        $(srcdir)/qcow2.c \
index 0f23983bffcba46d81cab4c19ba1278197914849..a306bc06e27147ba961d38e3eeeb99da970a8e4d 100644 (file)
@@ -103,7 +103,7 @@ errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
 
 
 /*
- * This procedure adds a block to a badblocks list.
+ * This procedure adds an item to a tracking list (e.g. badblocks or casefold).
  */
 errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
 {
index 01d2573b6b30d4f1afebd3545129b80dd4e6bf7c..0fc9c09a592551cf8e4ec0c7d89fe998eb8e9373 100644 (file)
@@ -773,7 +773,8 @@ struct ext2_super_block {
        __u8    s_last_error_errcode;
 /*27c*/ __le16 s_encoding;             /* Filename charset encoding */
        __le16  s_encoding_flags;       /* Filename charset encoding flags */
-       __le32  s_reserved[95];         /* Padding to the end of the block */
+       __le32  s_orphan_file_inum;     /* Inode for tracking orphan inodes */
+       __le32  s_reserved[94];         /* Padding to the end of the block */
 /*3fc*/        __u32   s_checksum;             /* crc32c(superblock) */
 };
 
@@ -828,7 +829,7 @@ struct ext2_super_block {
 #define EXT4_FEATURE_COMPAT_SPARSE_SUPER2      0x0200
 #define EXT4_FEATURE_COMPAT_FAST_COMMIT                0x0400
 #define EXT4_FEATURE_COMPAT_STABLE_INODES      0x0800
-
+#define EXT4_FEATURE_COMPAT_ORPHAN_FILE                0x1000
 
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
@@ -851,6 +852,7 @@ struct ext2_super_block {
 #define EXT4_FEATURE_RO_COMPAT_PROJECT         0x2000 /* Project quota */
 #define EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS   0x4000
 #define EXT4_FEATURE_RO_COMPAT_VERITY          0x8000
+#define EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT  0x10000
 
 #define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
 #define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
@@ -931,6 +933,7 @@ EXT4_FEATURE_COMPAT_FUNCS(exclude_bitmap,   2, EXCLUDE_BITMAP)
 EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,       4, SPARSE_SUPER2)
 EXT4_FEATURE_COMPAT_FUNCS(fast_commit,         4, FAST_COMMIT)
 EXT4_FEATURE_COMPAT_FUNCS(stable_inodes,       4, STABLE_INODES)
+EXT4_FEATURE_COMPAT_FUNCS(orphan_file,         4, ORPHAN_FILE)
 
 EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,     2, SPARSE_SUPER)
 EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,       2, LARGE_FILE)
@@ -947,6 +950,7 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(readonly,              4, READONLY)
 EXT4_FEATURE_RO_COMPAT_FUNCS(project,          4, PROJECT)
 EXT4_FEATURE_RO_COMPAT_FUNCS(shared_blocks,    4, SHARED_BLOCKS)
 EXT4_FEATURE_RO_COMPAT_FUNCS(verity,           4, VERITY)
+EXT4_FEATURE_RO_COMPAT_FUNCS(orphan_present,   4, ORPHAN_PRESENT)
 
 EXT4_FEATURE_INCOMPAT_FUNCS(compression,       2, COMPRESSION)
 EXT4_FEATURE_INCOMPAT_FUNCS(filetype,          2, FILETYPE)
@@ -1114,6 +1118,14 @@ static inline unsigned int ext2fs_dir_rec_len(__u8 name_len,
        return rec_len;
 }
 
+#define EXT4_ORPHAN_BLOCK_MAGIC 0x0b10ca04
+
+/* Structure at the tail of orphan block */
+struct ext4_orphan_block_tail {
+       __u32 ob_magic;
+       __u32 ob_checksum;
+};
+
 /*
  * Constants for ext4's extended time encoding
  */
index 679184e393f187bd215cfbd0f4f034d4e20da506..27eaaf1be35442660a9ac6c23b4b554b2c2f693d 100644 (file)
@@ -34,6 +34,8 @@ typedef struct struct_io_stats *io_stats;
 #define CHANNEL_FLAGS_DISCARD_ZEROES   0x02
 #define CHANNEL_FLAGS_BLOCK_DEVICE     0x04
 #define CHANNEL_FLAGS_THREADS          0x08
+#define CHANNEL_FLAGS_NODISCARD                0x10
+#define CHANNEL_FLAGS_NOZEROOUT                0x20
 
 #define io_channel_discard_zeroes_data(i) (i->flags & CHANNEL_FLAGS_DISCARD_ZEROES)
 
@@ -57,7 +59,7 @@ struct struct_io_channel {
                                       int actual_bytes_written,
                                       errcode_t error);
        int             refcount;
-       int             flags;
+       unsigned int    flags;
        long            reserved[14];
        void            *private_data;
        void            *app_data;
index b5477c1062edadc6f015d3601478b4e4acad5293..72c60d2b54d57adb3147eb09e9a8628f19a48776 100644 (file)
@@ -532,6 +532,7 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan;
 #define EXT2_MF_READONLY       4
 #define EXT2_MF_SWAP           8
 #define EXT2_MF_BUSY           16
+#define EXT2_MF_EXTFS          32
 
 /*
  * Ext2/linux mode flags.  We define them here so that we don't need
@@ -633,7 +634,8 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT2_FEATURE_COMPAT_EXT_ATTR|\
                                         EXT4_FEATURE_COMPAT_SPARSE_SUPER2|\
                                         EXT4_FEATURE_COMPAT_FAST_COMMIT|\
-                                        EXT4_FEATURE_COMPAT_STABLE_INODES)
+                                        EXT4_FEATURE_COMPAT_STABLE_INODES|\
+                                        EXT4_FEATURE_COMPAT_ORPHAN_FILE)
 
 #ifdef CONFIG_MMP
 #define EXT4_LIB_INCOMPAT_MMP          EXT4_FEATURE_INCOMPAT_MMP
@@ -668,7 +670,8 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT4_FEATURE_RO_COMPAT_READONLY |\
                                         EXT4_FEATURE_RO_COMPAT_PROJECT |\
                                         EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS |\
-                                        EXT4_FEATURE_RO_COMPAT_VERITY)
+                                        EXT4_FEATURE_RO_COMPAT_VERITY |\
+                                        EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT)
 
 /*
  * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
@@ -1295,6 +1298,8 @@ extern errcode_t ext2fs_adjust_ea_refcount3(ext2_filsys fs, blk64_t blk,
                                           ext2_ino_t inum);
 errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle);
 errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle);
+errcode_t ext2fs_xattrs_read_inode(struct ext2_xattr_handle *handle,
+                                  struct ext2_inode_large *inode);
 errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h,
                                int (*func)(char *name, char *value,
                                            size_t value_len, void *data),
@@ -1706,6 +1711,19 @@ errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
 errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
 errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
 
+/* orphan.c */
+extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks);
+extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs);
+extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs);
+extern __u32 ext2fs_do_orphan_file_block_csum(ext2_filsys fs, ext2_ino_t ino,
+                                             __u32 gen, blk64_t blk,
+                                             char *buf);
+extern errcode_t ext2fs_orphan_file_block_csum_set(ext2_filsys fs,
+                                                  ext2_ino_t ino, blk64_t blk,
+                                                  char *buf);
+extern int ext2fs_orphan_file_block_csum_verify(ext2_filsys fs, ext2_ino_t ino,
+                                               blk64_t blk, char *buf);
+
 /* get_pathname.c */
 extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
                               char **name);
@@ -1859,7 +1877,9 @@ extern int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry);
 extern void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type);
 extern struct ext2_inode *ext2fs_inode(struct ext2_inode_large * large_inode);
 extern const struct ext2_inode *ext2fs_const_inode(const struct ext2_inode_large * large_inode);
-
+extern int ext2fs_inodes_per_orphan_block(ext2_filsys fs);
+extern struct ext4_orphan_block_tail *ext2fs_orphan_block_tail(ext2_filsys fs,
+                                                              char *buf);
 #endif
 
 /*
@@ -2169,6 +2189,19 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode)
        return (const struct ext2_inode *) large_inode;
 }
 
+_INLINE_ int ext2fs_inodes_per_orphan_block(ext2_filsys fs)
+{
+       return (fs->blocksize - sizeof(struct ext4_orphan_block_tail)) /
+               sizeof(__u32);
+}
+
+_INLINE_ struct ext4_orphan_block_tail *
+ext2fs_orphan_block_tail(ext2_filsys fs, char *buf)
+{
+       return (struct ext4_orphan_block_tail *)(buf + fs->blocksize -
+               sizeof(struct ext4_orphan_block_tail));
+}
+
 #undef _INLINE_
 #endif
 
index 5525045c2a3bcb3e74910fbd98a5575bf86728fa..349404639f6f24eec591ffa5d7decb4ab89854e1 100644 (file)
@@ -1043,30 +1043,18 @@ static void xattrs_free_keys(struct ext2_xattr_handle *h)
        h->ibody_count = 0;
 }
 
-errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
+/* fetch xattrs from an already-loaded inode */
+errcode_t ext2fs_xattrs_read_inode(struct ext2_xattr_handle *handle,
+                                  struct ext2_inode_large *inode)
 {
-       struct ext2_inode_large *inode;
        struct ext2_ext_attr_header *header;
        __u32 ea_inode_magic;
        unsigned int storage_size;
        char *start, *block_buf = NULL;
        blk64_t blk;
-       size_t i;
-       errcode_t err;
+       errcode_t err = 0;
 
        EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
-       i = EXT2_INODE_SIZE(handle->fs->super);
-       if (i < sizeof(*inode))
-               i = sizeof(*inode);
-       err = ext2fs_get_memzero(i, &inode);
-       if (err)
-               return err;
-
-       err = ext2fs_read_inode_full(handle->fs, handle->ino,
-                                    (struct ext2_inode *)inode,
-                                    EXT2_INODE_SIZE(handle->fs->super));
-       if (err)
-               goto out;
 
        xattrs_free_keys(handle);
 
@@ -1102,7 +1090,7 @@ errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
 
 read_ea_block:
        /* Look for EA in a separate EA block */
-       blk = ext2fs_file_acl_block(handle->fs, (struct ext2_inode *)inode);
+       blk = ext2fs_file_acl_block(handle->fs, EXT2_INODE(inode));
        if (blk != 0) {
                if ((blk < handle->fs->super->s_first_data_block) ||
                    (blk >= ext2fs_blocks_count(handle->fs->super))) {
@@ -1133,20 +1121,39 @@ read_ea_block:
                err = read_xattrs_from_buffer(handle, inode,
                                        (struct ext2_ext_attr_entry *) start,
                                        storage_size, block_buf);
-               if (err)
-                       goto out3;
+       }
 
+out3:
+       if (block_buf)
                ext2fs_free_mem(&block_buf);
-       }
+out:
+       return err;
+}
 
-       ext2fs_free_mem(&block_buf);
-       ext2fs_free_mem(&inode);
-       return 0;
+errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
+{
+       struct ext2_inode_large *inode;
+       size_t inode_size = EXT2_INODE_SIZE(handle->fs->super);
+       errcode_t err;
+
+       EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
+
+       if (inode_size < sizeof(*inode))
+               inode_size = sizeof(*inode);
+       err = ext2fs_get_memzero(inode_size, &inode);
+       if (err)
+               return err;
+
+       err = ext2fs_read_inode_full(handle->fs, handle->ino, EXT2_INODE(inode),
+                                    EXT2_INODE_SIZE(handle->fs->super));
+       if (err)
+               goto out;
+
+       err = ext2fs_xattrs_read_inode(handle, inode);
 
-out3:
-       ext2fs_free_mem(&block_buf);
 out:
        ext2fs_free_mem(&inode);
+
        return err;
 }
 
index 8fc0b99da4b80cd7cb45de85da98e29f4414accc..a7db1a5c4ca1260512aaf83c4e99941a2b35bdd5 100644 (file)
@@ -213,6 +213,12 @@ is_root:
                        close(fd);
                (void) unlink(TEST_FILE);
        }
+
+       if (mnt && mnt->mnt_type &&
+           (!strcmp(mnt->mnt_type, "ext4") ||
+            !strcmp(mnt->mnt_type, "ext3") ||
+            !strcmp(mnt->mnt_type, "ext2")))
+               *mount_flags |= EXT2_MF_EXTFS;
        retval = 0;
 errout:
        endmntent (f);
diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c
new file mode 100644 (file)
index 0000000..c2f8356
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * orphan.c --- utility function to handle orphan file
+ *
+ * Copyright (C) 2015 Jan Kara.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <string.h>
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs)
+{
+       struct ext2_inode inode;
+       errcode_t err;
+       ext2_ino_t ino = fs->super->s_orphan_file_inum;
+
+       err = ext2fs_read_inode(fs, ino, &inode);
+       if (err)
+               return err;
+
+       err = ext2fs_punch(fs, ino, &inode, NULL, 0, ~0ULL);
+       if (err)
+               return err;
+
+       fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+       memset(&inode, 0, sizeof(struct ext2_inode));
+       err = ext2fs_write_inode(fs, ino, &inode);
+
+       ext2fs_clear_feature_orphan_file(fs->super);
+       ext2fs_clear_feature_orphan_present(fs->super);
+       ext2fs_mark_super_dirty(fs);
+       /* Need to update group descriptors as well */
+       fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+
+       return err;
+}
+
+__u32 ext2fs_do_orphan_file_block_csum(ext2_filsys fs, ext2_ino_t ino,
+                                      __u32 gen, blk64_t blk, char *buf)
+{
+       int inodes_per_ob = ext2fs_inodes_per_orphan_block(fs);
+       __u32 crc;
+
+       ino = ext2fs_cpu_to_le32(ino);
+       gen = ext2fs_cpu_to_le32(gen);
+       blk = ext2fs_cpu_to_le64(blk);
+       crc = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)&ino,
+                              sizeof(ino));
+       crc = ext2fs_crc32c_le(crc, (unsigned char *)&gen, sizeof(gen));
+       crc = ext2fs_crc32c_le(crc, (unsigned char *)&blk, sizeof(blk));
+       crc = ext2fs_crc32c_le(crc, (unsigned char *)buf,
+                               inodes_per_ob * sizeof(__u32));
+
+       return ext2fs_cpu_to_le32(crc);
+}
+
+struct mkorphan_info {
+       char *buf;
+       char *zerobuf;
+       blk_t num_blocks;
+       blk_t alloc_blocks;
+       blk64_t last_blk;
+       errcode_t err;
+       ext2_ino_t ino;
+       __u32 generation;
+};
+
+static int mkorphan_proc(ext2_filsys   fs,
+                        blk64_t        *blocknr,
+                        e2_blkcnt_t    blockcnt,
+                        blk64_t        ref_block EXT2FS_ATTR((unused)),
+                        int            ref_offset EXT2FS_ATTR((unused)),
+                        void           *priv_data)
+{
+       struct mkorphan_info *oi = (struct mkorphan_info *)priv_data;
+       blk64_t new_blk;
+       errcode_t err;
+
+       /* Can we just continue in currently allocated cluster? */
+       if (blockcnt &&
+           EXT2FS_B2C(fs, oi->last_blk) == EXT2FS_B2C(fs, oi->last_blk + 1)) {
+               new_blk = oi->last_blk + 1;
+       } else {
+               err = ext2fs_new_block2(fs, oi->last_blk, 0, &new_blk);
+               if (err) {
+                       oi->err = err;
+                       return BLOCK_ABORT;
+               }
+               ext2fs_block_alloc_stats2(fs, new_blk, +1);
+               oi->alloc_blocks++;
+       }
+       if (blockcnt >= 0) {
+               if (ext2fs_has_feature_metadata_csum(fs->super)) {
+                       struct ext4_orphan_block_tail *tail;
+
+                       tail = ext2fs_orphan_block_tail(fs, oi->buf);
+                       tail->ob_checksum = ext2fs_do_orphan_file_block_csum(fs,
+                               oi->ino, oi->generation, new_blk, oi->buf);
+               }
+               err = io_channel_write_blk64(fs->io, new_blk, 1, oi->buf);
+       } else  /* zerobuf is used to initialize new indirect blocks... */
+               err = io_channel_write_blk64(fs->io, new_blk, 1, oi->zerobuf);
+       if (err) {
+               oi->err = err;
+               return BLOCK_ABORT;
+       }
+       oi->last_blk = new_blk;
+       *blocknr = new_blk;
+       if (blockcnt >= 0 && --oi->num_blocks == 0)
+               return BLOCK_CHANGED | BLOCK_ABORT;
+       return BLOCK_CHANGED;
+}
+
+errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks)
+{
+       struct ext2_inode inode;
+       ext2_ino_t ino = fs->super->s_orphan_file_inum;
+       errcode_t err;
+       char *buf = NULL, *zerobuf = NULL;
+       struct mkorphan_info oi;
+       struct ext4_orphan_block_tail *ob_tail;
+
+       if (ino) {
+               err = ext2fs_read_inode(fs, ino, &inode);
+               if (err)
+                       return err;
+               if (EXT2_I_SIZE(&inode)) {
+                       err = ext2fs_truncate_orphan_file(fs);
+                       if (err)
+                               return err;
+               }
+       } else {
+               err = ext2fs_new_inode(fs, EXT2_ROOT_INO, LINUX_S_IFREG | 0600,
+                                      0, &ino);
+               if (err)
+                       return err;
+               ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
+       }
+
+       memset(&inode, 0, sizeof(struct ext2_inode));
+       if (ext2fs_has_feature_extents(fs->super)) {
+               inode.i_flags |= EXT4_EXTENTS_FL;
+               err = ext2fs_write_inode(fs, ino, &inode);
+               if (err)
+                       return err;
+       }
+
+       err = ext2fs_get_mem(fs->blocksize, &buf);
+       if (err)
+               return err;
+       err = ext2fs_get_mem(fs->blocksize, &zerobuf);
+       if (err)
+               goto out;
+       memset(buf, 0, fs->blocksize);
+       memset(zerobuf, 0, fs->blocksize);
+       ob_tail = ext2fs_orphan_block_tail(fs, buf);
+       ob_tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC);
+       oi.num_blocks = num_blocks;
+       oi.alloc_blocks = 0;
+       oi.last_blk = 0;
+       oi.generation = inode.i_generation;
+       oi.ino = ino;
+       oi.buf = buf;
+       oi.zerobuf = zerobuf;
+       oi.err = 0;
+       err = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_APPEND,
+                                   0, mkorphan_proc, &oi);
+       if (err)
+               goto out;
+       if (oi.err) {
+               err = oi.err;
+               goto out;
+       }
+
+       /* Reread inode after blocks were allocated */
+       err = ext2fs_read_inode(fs, ino, &inode);
+       if (err)
+               goto out;
+       ext2fs_iblk_set(fs, &inode, 0);
+       inode.i_atime = inode.i_mtime =
+               inode.i_ctime = fs->now ? fs->now : time(0);
+       inode.i_links_count = 1;
+       inode.i_mode = LINUX_S_IFREG | 0600;
+       ext2fs_iblk_add_blocks(fs, &inode, oi.alloc_blocks);
+       err = ext2fs_inode_size_set(fs, &inode,
+                       (unsigned long long)fs->blocksize * num_blocks);
+       if (err)
+               goto out;
+       err = ext2fs_write_new_inode(fs, ino, &inode);
+       if (err)
+               goto out;
+
+       fs->super->s_orphan_file_inum = ino;
+       ext2fs_set_feature_orphan_file(fs->super);
+       ext2fs_mark_super_dirty(fs);
+       /* Need to update group descriptors as well */
+       fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+out:
+       if (buf)
+               ext2fs_free_mem(&buf);
+       if (zerobuf)
+               ext2fs_free_mem(&zerobuf);
+       return err;
+}
+
+/*
+ * Find reasonable size for orphan file. We choose orphan file size to be
+ * between 32 and 512 filesystem blocks and not more than 1/4096 of the
+ * filesystem unless it is really small.
+ */
+e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs)
+{
+       __u64 num_blocks = ext2fs_blocks_count(fs->super);
+       e2_blkcnt_t blks = 512;
+
+       if (num_blocks < 128 * 1024)
+               blks = 32;
+       else if (num_blocks < 2 * 1024 * 1024)
+               blks = num_blocks / 4096;
+       return (blks + EXT2FS_CLUSTER_MASK(fs)) & ~EXT2FS_CLUSTER_MASK(fs);
+}
+
+static errcode_t ext2fs_orphan_file_block_csum(ext2_filsys fs, ext2_ino_t ino,
+                                              blk64_t blk, char *buf,
+                                              __u32 *crcp)
+{
+       struct ext2_inode inode;
+       errcode_t retval;
+
+       retval = ext2fs_read_inode(fs, ino, &inode);
+       if (retval)
+               return retval;
+       *crcp = ext2fs_do_orphan_file_block_csum(fs, ino, inode.i_generation,
+                                                blk, buf);
+       return 0;
+}
+
+errcode_t ext2fs_orphan_file_block_csum_set(ext2_filsys fs, ext2_ino_t ino,
+                                           blk64_t blk, char *buf)
+{
+       struct ext4_orphan_block_tail *tail;
+
+       if (!ext2fs_has_feature_metadata_csum(fs->super))
+               return 0;
+
+       tail = ext2fs_orphan_block_tail(fs, buf);
+       return ext2fs_orphan_file_block_csum(fs, ino, blk, buf,
+                                            &tail->ob_checksum);
+}
+
+int ext2fs_orphan_file_block_csum_verify(ext2_filsys fs, ext2_ino_t ino,
+                                        blk64_t blk, char *buf)
+{
+       struct ext4_orphan_block_tail *tail;
+       __u32 crc;
+       errcode_t retval;
+
+       if (!ext2fs_has_feature_metadata_csum(fs->super))
+               return 1;
+       retval = ext2fs_orphan_file_block_csum(fs, ino, blk, buf, &crc);
+       if (retval)
+               return 0;
+       tail = ext2fs_orphan_block_tail(fs, buf);
+       return ext2fs_le32_to_cpu(tail->ob_checksum) == crc;
+}
index 5e6b22f46f9508cd86b8da2af8170860dfb8750e..fe764b9e0528a96bec88fb6f379a016448892094 100644 (file)
@@ -131,8 +131,9 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
        /* s_*_time_hi are __u8 and does not need swabbing */
        sb->s_encoding = ext2fs_swab16(sb->s_encoding);
        sb->s_encoding_flags = ext2fs_swab16(sb->s_encoding_flags);
+       sb->s_orphan_file_inum = ext2fs_swab32(sb->s_orphan_file_inum);
        /* catch when new fields are used from s_reserved */
-       EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 95 * sizeof(__le32));
+       EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 94 * sizeof(__le32));
        sb->s_checksum = ext2fs_swab32(sb->s_checksum);
 }
 
index 80a5269bceb7cfe5658aacb9664278241638e780..ad452dee8eb3b44364f3a78667bc88de63980c8e 100644 (file)
@@ -152,7 +152,8 @@ int main(int argc, char **argv)
        check_field(s_last_error_errcode, 1);
        check_field(s_encoding, 2);
        check_field(s_encoding_flags, 2);
-       check_field(s_reserved, 95 * 4);
+       check_field(s_orphan_file_inum, 4);
+       check_field(s_reserved, 94 * 4);
        check_field(s_checksum, 4);
        do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
index 3171c7368feb342ec312f3270ece2128f4b197db..33c5d568656c8c6725d54cfff6070550ec4e1dd2 100644 (file)
@@ -761,6 +761,9 @@ static errcode_t unix_open_channel(const char *name, int fd,
        io->refcount = 1;
        io->flags = 0;
 
+       if (safe_getenv("UNIX_IO_NOZEROOUT"))
+               io->flags |= CHANNEL_FLAGS_NOZEROOUT;
+
        memset(data, 0, sizeof(struct unix_private_data));
        data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
        data->io_stats.num_fields = 2;
@@ -783,21 +786,20 @@ static errcode_t unix_open_channel(const char *name, int fd,
         * zero.
         */
        if (ext2fs_fstat(data->dev, &st) == 0) {
-               if (ext2fsP_is_disk_device(st.st_mode))
+               if (ext2fsP_is_disk_device(st.st_mode)) {
+#ifdef BLKDISCARDZEROES
+                       int zeroes = 0;
+
+                       if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 &&
+                           zeroes)
+                               io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+#endif
                        io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE;
-               else
+               } else {
                        io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+               }
        }
 
-#ifdef BLKDISCARDZEROES
-       {
-               int zeroes = 0;
-               if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 &&
-                   zeroes)
-                       io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
-       }
-#endif
-
 #if defined(__CYGWIN__)
        /*
         * Some operating systems require that the buffers be aligned,
@@ -1344,12 +1346,15 @@ static errcode_t unix_discard(io_channel channel, unsigned long long block,
                              unsigned long long count)
 {
        struct unix_private_data *data;
-       int             ret;
+       int             ret = EOPNOTSUPP;
 
        EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
        data = (struct unix_private_data *) channel->private_data;
        EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
 
+       if (channel->flags & CHANNEL_FLAGS_NODISCARD)
+               goto unimplemented;
+
        if (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE) {
 #ifdef BLKDISCARD
                __u64 range[2];
@@ -1376,8 +1381,10 @@ static errcode_t unix_discard(io_channel channel, unsigned long long block,
 #endif
        }
        if (ret < 0) {
-               if (errno == EOPNOTSUPP)
+               if (errno == EOPNOTSUPP) {
+                       channel->flags |= CHANNEL_FLAGS_NODISCARD;
                        goto unimplemented;
+               }
                return errno;
        }
        return 0;
@@ -1425,9 +1432,6 @@ static errcode_t unix_zeroout(io_channel channel, unsigned long long block,
        data = (struct unix_private_data *) channel->private_data;
        EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
 
-       if (safe_getenv("UNIX_IO_NOZEROOUT"))
-               goto unimplemented;
-
        if (!(channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE)) {
                /* Regular file, try to use truncate/punch/zero. */
                struct stat statbuf;
@@ -1450,13 +1454,18 @@ static errcode_t unix_zeroout(io_channel channel, unsigned long long block,
                }
        }
 
+       if (channel->flags & CHANNEL_FLAGS_NOZEROOUT)
+               goto unimplemented;
+
        ret = __unix_zeroout(data->dev,
                        (off_t)(block) * channel->block_size + data->offset,
                        (off_t)(count) * channel->block_size);
 err:
        if (ret < 0) {
-               if (errno == EOPNOTSUPP)
+               if (errno == EOPNOTSUPP) {
+                       channel->flags |= CHANNEL_FLAGS_NOZEROOUT;
                        goto unimplemented;
+               }
                return errno;
        }
        return 0;
index c89f895907f1d5d47222a7c72d24d21f40aa55b1..9339c9943f49192908d76951d1d511f7d9389b26 100644 (file)
@@ -509,7 +509,8 @@ errcode_t quota_compute_usage(quota_ctx_t qctx)
                        continue;
                if (ino == EXT2_ROOT_INO ||
                    (ino >= EXT2_FIRST_INODE(fs->super) &&
-                    ino != quota_type2inum(PRJQUOTA, fs->super))) {
+                    ino != quota_type2inum(PRJQUOTA, fs->super) &&
+                    ino != fs->super->s_orphan_file_inum)) {
                        space = ext2fs_get_stat_i_blocks(fs,
                                                EXT2_INODE(inode)) << 9;
                        quota_data_add(qctx, inode, ino, space);
index 8b4c0677a9c9be0d05ffcfe5ba441f0af6289f82..1ae03001fe9f9a976c3ec5591dee0324ff733c28 100644 (file)
@@ -1370,7 +1370,8 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
                    ino == fs->super->s_journal_inum ||
                    ino == quota_type2inum(USRQUOTA, fs->super) ||
                    ino == quota_type2inum(GRPQUOTA, fs->super) ||
-                   ino == quota_type2inum(PRJQUOTA, fs->super)) {
+                   ino == quota_type2inum(PRJQUOTA, fs->super) ||
+                   ino == fs->super->s_orphan_file_inum) {
                        retval = ext2fs_block_iterate3(fs, ino,
                                        BLOCK_FLAG_READ_ONLY, block_buf,
                                        process_dir_block, &pb);
index 1dc961994102dcaa0ab7240ee2d4980f6b9a7e99..fa5294c4677cdccc2e348595a8d95ffbe2955528 100644 (file)
@@ -33,7 +33,12 @@ Ext2 volume labels can be at most 16 characters long; if
 .I volume-label
 is longer than 16 characters,
 .B e2label
-will truncate it and print a warning message.
+will truncate it and print a warning message.  For other file systems that
+support online label manipulation and are mounted
+.B e2label
+will work as well, but it will not attempt to truncate the
+.I volume-label
+at all.
 .PP
 It is also possible to set the volume label using the
 .B \-L
index c0b5324569a186bafe6e6d39f04a2e73c3c194d2..30f97bb5c590ca98dad48fa8a993d4d4dc266a5e 100644 (file)
@@ -365,6 +365,13 @@ small risk if the system crashes before the journal has been overwritten
 entirely one time.  If the option value is omitted, it defaults to 1 to
 enable lazy journal inode zeroing.
 .TP
+.B assume_storage_prezeroed\fR[\fB= \fI<0 to disable, 1 to enable>\fR]
+If enabled,
+.BR mke2fs
+assumes that the storage device has been prezeroed, skips zeroing the journal
+and inode tables, and annotates the block group flags to signal that the inode
+table has been zeroed.
+.TP
 .B no_copy_xattrs
 Normally
 .B mke2fs
@@ -403,6 +410,11 @@ file system to change based on the user running \fBmke2fs\fR.
 Set a flag in the file system superblock indicating that it may be
 mounted using experimental kernel code, such as the ext4dev file system.
 .TP
+.BI orphan_file_size= size
+Set size of the file for tracking unlinked but still open inodes and inodes
+with truncate in progress. Larger file allows for better scalability, reserving
+a few blocks per cpu is ideal.
+.TP
 .B discard
 Attempt to discard blocks at mkfs time (discarding blocks initially is useful
 on solid state devices and sparse / thin-provisioned storage). When the device
index ba5f179a2539941bd9b5a3697e48f567712763ea..4a9c1b0924a9b09151a11995f82d22323a846ed7 100644 (file)
@@ -94,7 +94,9 @@ static gid_t  root_gid;
 int    journal_size;
 int    journal_flags;
 int    journal_fc_size;
+static e2_blkcnt_t     orphan_file_blocks;
 static int     lazy_itable_init;
+static int     assume_storage_prezeroed;
 static int     packed_meta_blocks;
 int            no_copy_xattrs;
 static char    *bad_blocks_filename = NULL;
@@ -1012,6 +1014,11 @@ static void parse_extended_opts(struct ext2_super_block *param,
                                lazy_itable_init = strtoul(arg, &p, 0);
                        else
                                lazy_itable_init = 1;
+               } else if (!strcmp(token, "assume_storage_prezeroed")) {
+                       if (arg)
+                               assume_storage_prezeroed = strtoul(arg, &p, 0);
+                       else
+                               assume_storage_prezeroed = 1;
                } else if (!strcmp(token, "lazy_journal_init")) {
                        if (arg)
                                journal_flags |= strtoul(arg, &p, 0) ?
@@ -1089,6 +1096,21 @@ static void parse_extended_opts(struct ext2_super_block *param,
                                continue;
                        }
                        encoding_flags = arg;
+               } else if (!strcmp(token, "orphan_file_size")) {
+                       if (!arg) {
+                               r_usage++;
+                               badopt = token;
+                               continue;
+                       }
+                       orphan_file_blocks = parse_num_blocks2(arg,
+                                               fs_param.s_log_block_size);
+                       if (orphan_file_blocks == 0) {
+                               fprintf(stderr,
+                                       _("Invalid size of orphan file %s\n"),
+                                       arg);
+                               r_usage++;
+                               continue;
+                       }
                } else {
                        r_usage++;
                        badopt = token;
@@ -1115,7 +1137,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
                        "\tnodiscard\n"
                        "\tencoding=<encoding>\n"
                        "\tencoding_flags=<flags>\n"
-                       "\tquotatype=<quota type(s) to be enabled>\n\n"),
+                       "\tquotatype=<quota type(s) to be enabled>\n"
+                       "\tassume_storage_prezeroed=<0 to disable, 1 to enable>\n\n"),
                        badopt ? badopt : "");
                free(buf);
                exit(1);
@@ -1156,7 +1179,8 @@ static __u32 ok_features[3] = {
                EXT2_FEATURE_COMPAT_EXT_ATTR |
                EXT4_FEATURE_COMPAT_SPARSE_SUPER2 |
                EXT4_FEATURE_COMPAT_FAST_COMMIT |
-               EXT4_FEATURE_COMPAT_STABLE_INODES,
+               EXT4_FEATURE_COMPAT_STABLE_INODES |
+               EXT4_FEATURE_COMPAT_ORPHAN_FILE,
        /* Incompat */
        EXT2_FEATURE_INCOMPAT_FILETYPE|
                EXT3_FEATURE_INCOMPAT_EXTENTS|
@@ -1551,6 +1575,8 @@ static void PRS(int argc, char *argv[])
        int             lsector_size = 0, psector_size = 0;
        int             show_version_only = 0, is_device = 0;
        unsigned long long num_inodes = 0; /* unsigned long long to catch too-large input */
+       int             default_orphan_file = 0;
+       int             default_csum_seed = 0;
        errcode_t       retval;
        char *          oldpath = getenv("PATH");
        char *          extended_opts = 0;
@@ -2103,8 +2129,24 @@ profile_error:
                ext2fs_clear_feature_ea_inode(&fs_param);
                ext2fs_clear_feature_casefold(&fs_param);
        }
-       edit_feature(fs_features ? fs_features : tmp,
-                    &fs_param.s_feature_compat);
+       if (!fs_features && tmp)
+               edit_feature(tmp, &fs_param.s_feature_compat);
+       /*
+        * Now all the defaults are incorporated in fs_param. Check the state
+        * of orphan_file feature so that we know whether we should silently
+        * disabled in case journal gets disabled.
+        */
+       if (ext2fs_has_feature_orphan_file(&fs_param))
+               default_orphan_file = 1;
+       if (ext2fs_has_feature_csum_seed(&fs_param))
+               default_csum_seed = 1;
+       if (fs_features)
+               edit_feature(fs_features, &fs_param.s_feature_compat);
+       /* Silently disable orphan_file if user chose fs without journal */
+       if (default_orphan_file && !ext2fs_has_feature_journal(&fs_param))
+               ext2fs_clear_feature_orphan_file(&fs_param);
+       if (default_csum_seed && !ext2fs_has_feature_metadata_csum(&fs_param))
+               ext2fs_clear_feature_csum_seed(&fs_param);
        if (tmp)
                free(tmp);
        (void) ext2fs_free_mem(&fs_features);
@@ -3097,6 +3139,18 @@ int main (int argc, char *argv[])
                io_channel_set_options(fs->io, opt_string);
        }
 
+       if (assume_storage_prezeroed) {
+               if (verbose)
+                       printf("%s",
+                              _("Assuming the storage device is prezeroed "
+                              "- skipping inode table and journal wipe\n"));
+
+               lazy_itable_init = 1;
+               itable_zeroed = 1;
+               zero_hugefile = 0;
+               journal_flags |= EXT2_MKJOURNAL_LAZYINIT;
+       }
+
        /* Can't undo discard ... */
        if (!noaction && discard && dev_size && (io_ptr != undo_io_manager)) {
                retval = mke2fs_discard_device(fs);
@@ -3431,6 +3485,9 @@ int main (int argc, char *argv[])
 
                if (!jparams.num_journal_blocks) {
                        ext2fs_clear_feature_journal(fs->super);
+                       ext2fs_clear_feature_orphan_file(fs->super);
+                       ext2fs_clear_feature_journal(&fs_param);
+                       ext2fs_clear_feature_orphan_file(&fs_param);
                        goto no_journal;
                }
                if (!quiet) {
@@ -3473,6 +3530,23 @@ no_journal:
                fix_cluster_bg_counts(fs);
        if (ext2fs_has_feature_quota(&fs_param))
                create_quota_inodes(fs);
+       if (ext2fs_has_feature_orphan_file(&fs_param)) {
+               if (!ext2fs_has_feature_journal(&fs_param)) {
+                       com_err(program_name, 0, _("cannot set orphan_file "
+                               "feature without a journal."));
+                       exit(1);
+               }
+               if (!orphan_file_blocks) {
+                       orphan_file_blocks =
+                               ext2fs_default_orphan_file_blocks(fs);
+               }
+               retval = ext2fs_create_orphan_file(fs, orphan_file_blocks);
+               if (retval) {
+                       com_err(program_name, retval,
+                               _("while creating orphan file"));
+                       exit(1);
+               }
+       }
 
        retval = mk_hugefiles(fs, device_name);
        if (retval)
index 056809927f3624173d7e303ec59e940cf74b18a9..b7fc95df7acfc49ba0395fde4a8afc566cd7e9e5 100644 (file)
@@ -11,7 +11,7 @@
                features = has_journal
        }
        ext4 = {
-               features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize
+               features = has_journal,extent,huge_file,flex_bg,metadata_csum,metadata_csum_seed,64bit,dir_nlink,extra_isize,orphan_file
        }
        small = {
                blocksize = 1024
index 979f6c5f258f7d6789078b591b7ec2a87034ec72..dcf108c1f026cf3fc375fcced02c2ecfa1e22337 100644 (file)
@@ -257,6 +257,11 @@ program.
 This superblock setting is only honored in 2.6.35+ kernels;
 and not at all by the ext2 and ext3 file system drivers.
 .TP
+.BI orphan_file_size= size
+Set size of the file for tracking unlinked but still open inodes and inodes
+with truncate in progress. Larger file allows for better scalability, reserving
+a few blocks per cpu is ideal.
+.TP
 .B force_fsck
 Set a flag in the file system superblock indicating that errors have been found.
 This will force fsck to run at the next mount.
@@ -452,8 +457,12 @@ Ext2 file system labels can be at most 16 characters long; if
 .I volume-label
 is longer than 16 characters,
 .B tune2fs
-will truncate it and print a warning.  The volume label can be used
-by
+will truncate it and print a warning.  For other file systems that
+support online label manipulation and are mounted
+.B tune2fs
+will work as well, but it will not attempt to truncate the
+.I volume-label
+at all.  The volume label can be used by
 .BR mount (8),
 .BR fsck (8),
 and
@@ -584,8 +593,10 @@ Enable the file system to be larger than 2^32 blocks.
 .TP
 .B casefold
 Enable support for file system level casefolding.
-.B Tune2fs
-currently only supports setting this file system feature.
+The option can be cleared only if filesystem has no
+directories with
+.B F
+attribute.
 .TP
 .B dir_index
 Use hashed b-trees to speed up lookups for large directories.
index cb5f575a3b5c236d4109244da5e8af7e084ab741..78b58347f3fa5af6eaee9a0e7555802fa0fecd16 100644 (file)
@@ -51,7 +51,14 @@ extern int optind;
 #include <unistd.h>
 #include <sys/types.h>
 #include <libgen.h>
-#include <limits.h>
+#include <limits.h>    /* for PATH_MAX */
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
 
 #include "ext2fs/ext2_fs.h"
 #include "ext2fs/ext2fs.h"
@@ -71,11 +78,34 @@ extern int optind;
 #define QOPT_ENABLE    (1)
 #define QOPT_DISABLE   (-1)
 
+#ifndef FS_IOC_SETFSLABEL
+#define FSLABEL_MAX 256
+#define FS_IOC_SETFSLABEL      _IOW(0x94, 50, char[FSLABEL_MAX])
+#endif
+
+#ifndef FS_IOC_GETFSLABEL
+#define FS_IOC_GETFSLABEL      _IOR(0x94, 49, char[FSLABEL_MAX])
+#endif
+
+struct fsuuid {
+       __u32   fsu_len;
+       __u32   fsu_flags;
+       __u8    fsu_uuid[];
+};
+
+#ifndef EXT4_IOC_GETFSUUID
+#define EXT4_IOC_GETFSUUID     _IOR('f', 44, struct fsuuid)
+#endif
+
+#ifndef EXT4_IOC_SETFSUUID
+#define EXT4_IOC_SETFSUUID     _IOW('f', 44, struct fsuuid)
+#endif
+
 extern int ask_yn(const char *string, int def);
 
 const char *program_name = "tune2fs";
 char *device_name;
-char *new_label, *new_last_mounted, *new_UUID;
+char *new_label, *new_last_mounted, *requested_uuid;
 char *io_options;
 static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
 static int m_flag, M_flag, Q_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
@@ -107,6 +137,7 @@ int enabling_casefold;
 int journal_size, journal_fc_size, journal_flags;
 char *journal_device;
 static blk64_t journal_location = ~0LL;
+static e2_blkcnt_t orphan_file_blocks;
 
 static struct list_head blk_move_list;
 
@@ -153,7 +184,8 @@ static __u32 ok_features[3] = {
        EXT3_FEATURE_COMPAT_HAS_JOURNAL |
                EXT2_FEATURE_COMPAT_DIR_INDEX |
                EXT4_FEATURE_COMPAT_FAST_COMMIT |
-               EXT4_FEATURE_COMPAT_STABLE_INODES,
+               EXT4_FEATURE_COMPAT_STABLE_INODES |
+               EXT4_FEATURE_COMPAT_ORPHAN_FILE,
        /* Incompat */
        EXT2_FEATURE_INCOMPAT_FILETYPE |
                EXT3_FEATURE_INCOMPAT_EXTENTS |
@@ -184,13 +216,15 @@ static __u32 clear_ok_features[3] = {
        EXT3_FEATURE_COMPAT_HAS_JOURNAL |
                EXT2_FEATURE_COMPAT_RESIZE_INODE |
                EXT2_FEATURE_COMPAT_DIR_INDEX |
-               EXT4_FEATURE_COMPAT_FAST_COMMIT,
+               EXT4_FEATURE_COMPAT_FAST_COMMIT |
+               EXT4_FEATURE_COMPAT_ORPHAN_FILE,
        /* Incompat */
        EXT2_FEATURE_INCOMPAT_FILETYPE |
                EXT4_FEATURE_INCOMPAT_FLEX_BG |
                EXT4_FEATURE_INCOMPAT_MMP |
                EXT4_FEATURE_INCOMPAT_64BIT |
-               EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+               EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+               EXT4_FEATURE_INCOMPAT_CASEFOLD,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -1009,6 +1043,41 @@ out:
        return retval;
 }
 
+static int has_casefold_inode(ext2_filsys fs)
+{
+       int length = EXT2_INODE_SIZE(fs->super);
+       struct ext2_inode *inode = NULL;
+       ext2_inode_scan scan;
+       errcode_t       retval;
+       ext2_ino_t      ino;
+       int found_casefold = 0;
+
+       retval = ext2fs_get_mem(length, &inode);
+       if (retval)
+               fatal_err(retval, "while allocating memory");
+
+       retval = ext2fs_open_inode_scan(fs, 0, &scan);
+       if (retval)
+               fatal_err(retval, "while opening inode scan");
+
+       do {
+               retval = ext2fs_get_next_inode_full(scan, &ino, inode, length);
+               if (retval)
+                       fatal_err(retval, "while getting next inode");
+               if (!ino)
+                       break;
+
+               if(inode->i_flags & EXT4_CASEFOLD_FL) {
+                       found_casefold = 1;
+                       break;
+               }
+       } while(1);
+
+       ext2fs_free_mem(&inode);
+       ext2fs_close_inode_scan(scan);
+       return found_casefold;
+}
+
 static errcode_t disable_uninit_bg(ext2_filsys fs, __u32 csum_feature_flag)
 {
        struct ext2_group_desc *gd;
@@ -1149,6 +1218,56 @@ static int update_feature_set(ext2_filsys fs, char *features)
                }
        }
 
+       if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) {
+               ext2_ino_t ino;
+
+               if (mount_flags & EXT2_MF_MOUNTED) {
+                       fputs(_("The orphan_file feature may only be cleared "
+                               "when the filesystem is unmounted.\n"), stderr);
+                       return 1;
+               }
+               if (ext2fs_has_feature_orphan_present(sb) && f_flag < 2) {
+                       fputs(_("The orphan_present feature is set. Please "
+                               "run e2fsck before clearing orphan_file "
+                               "feature.\n"),
+                             stderr);
+                       return 1;
+               }
+               err = ext2fs_read_bitmaps(fs);
+               if (err) {
+                       com_err(program_name, err, "%s",
+                               _("while loading bitmaps"));
+                       return 1;
+               }
+               err = ext2fs_truncate_orphan_file(fs);
+               if (err) {
+                       com_err(program_name, err,
+                               _("\n\twhile trying to delete orphan file\n"));
+                       return 1;
+               }
+               ino = sb->s_orphan_file_inum;
+               sb->s_orphan_file_inum = 0;
+               ext2fs_inode_alloc_stats2(fs, ino, -1, 0);
+               ext2fs_clear_feature_orphan_file(sb);
+               ext2fs_clear_feature_orphan_present(sb);
+               ext2fs_mark_super_dirty(fs);
+       }
+
+       if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) {
+               if (!ext2fs_has_feature_journal(sb)) {
+                       fputs(_("orphan_file feature can be set only for "
+                               "filesystems with journal.\n"), stderr);
+                       return 1;
+               }
+               /*
+                * If adding an orphan file, let the create orphan file
+                * code below handle setting the flag and creating it.
+                * We supply a default size if necessary.
+                */
+               orphan_file_blocks = ext2fs_default_orphan_file_blocks(fs);
+               ext2fs_set_feature_orphan_file(sb);
+       }
+
        if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
                EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
                if (ext2fs_has_feature_meta_bg(sb)) {
@@ -1493,6 +1612,22 @@ mmp_error:
                enabling_casefold = 1;
        }
 
+       if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD)) {
+               if (mount_flags & EXT2_MF_MOUNTED) {
+                       fputs(_("The casefold feature may only be disabled when "
+                               "the filesystem is unmounted.\n"), stderr);
+                       return 1;
+               }
+               if (has_casefold_inode(fs)) {
+                       fputs(_("The casefold feature can't be cleared when "
+                                       "there are inodes with +F flag.\n"), stderr);
+                       return 1;
+               }
+               fs->super->s_encoding = 0;
+               fs->super->s_encoding_flags = 0;
+               enabling_casefold = 0;
+       }
+
        if (FEATURE_ON(E2P_FEATURE_INCOMPAT,
                EXT4_FEATURE_INCOMPAT_CSUM_SEED)) {
                if (!ext2fs_has_feature_metadata_csum(sb)) {
@@ -2041,7 +2176,7 @@ static void parse_tune2fs_options(int argc, char **argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                case 'U':
-                       new_UUID = optarg;
+                       requested_uuid = optarg;
                        U_flag = 1;
                        open_flag = EXT2_FLAG_RW |
                                EXT2_FLAG_JOURNAL_DEV_OK;
@@ -2273,6 +2408,21 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
                                continue;
                        }
                        encoding_flags = arg;
+               } else if (!strcmp(token, "orphan_file_size")) {
+                       if (!arg) {
+                               r_usage++;
+                               continue;
+                       }
+                       orphan_file_blocks = parse_num_blocks2(arg,
+                                                fs->super->s_log_block_size);
+
+                       if (orphan_file_blocks < 1) {
+                               fprintf(stderr,
+                                       _("Invalid size of orphan file %s\n"),
+                                       arg);
+                               r_usage++;
+                               continue;
+                       }
                } else
                        r_usage++;
        }
@@ -2933,6 +3083,75 @@ fs_update_journal_user(struct ext2_super_block *sb, __u8 old_uuid[UUID_SIZE])
        return 0;
 }
 
+/*
+ * Use FS_IOC_SETFSLABEL or FS_IOC_GETFSLABEL to set/get file system label
+ * Return:     0 on success
+ *             1 on error
+ *             -1 when the old method should be used
+ */
+static int handle_fslabel(int setlabel)
+{
+#ifdef __linux__
+       errcode_t ret;
+       int mnt_flags, fd;
+       char label[FSLABEL_MAX];
+       int maxlen = FSLABEL_MAX - 1;
+       char mntpt[PATH_MAX + 1];
+
+       ret = ext2fs_check_mount_point(device_name, &mnt_flags,
+                                         mntpt, sizeof(mntpt));
+       if (ret)
+               return -1;
+
+       if (!(mnt_flags & EXT2_MF_MOUNTED) ||
+           (setlabel && (mnt_flags & EXT2_MF_READONLY)))
+               return -1;
+
+       if (!mntpt[0])
+               return -1;
+
+       fd = open(mntpt, O_RDONLY);
+       if (fd < 0)
+               return -1;
+
+       /* Get fs label */
+       if (!setlabel) {
+               if (ioctl(fd, FS_IOC_GETFSLABEL, &label)) {
+                       close(fd);
+                       if (errno == ENOTTY)
+                               return -1;
+                       com_err(mntpt, errno, _("while trying to get fs label"));
+                       return 1;
+               }
+               close(fd);
+               printf("%.*s\n", EXT2_LEN_STR(label));
+               return 0;
+       }
+
+       /* If it's extN file system, truncate the label to appropriate size */
+       if (mnt_flags & EXT2_MF_EXTFS)
+               maxlen = EXT2_LABEL_LEN;
+       if (strlen(new_label) > maxlen) {
+               fputs(_("Warning: label too long, truncating.\n"),
+                     stderr);
+               new_label[maxlen] = '\0';
+       }
+
+       /* Set fs label */
+       if (ioctl(fd, FS_IOC_SETFSLABEL, new_label)) {
+               close(fd);
+               if (errno == ENOTTY)
+                       return -1;
+               com_err(mntpt, errno, _("while trying to set fs label"));
+               return 1;
+       }
+       close(fd);
+       return 0;
+#else
+       return -1;
+#endif
+}
+
 #ifndef BUILD_AS_LIB
 int main(int argc, char **argv)
 #else
@@ -2945,6 +3164,9 @@ int tune2fs_main(int argc, char **argv)
        io_manager io_ptr, io_ptr_orig = NULL;
        int rc = 0;
        char default_undo_file[1] = { 0 };
+       char mntpt[PATH_MAX + 1] = { 0 };
+       int fd = -1;
+       struct fsuuid *fsuuid = NULL;
 
 #ifdef ENABLE_NLS
        setlocale(LC_MESSAGES, "");
@@ -2976,6 +3198,21 @@ int tune2fs_main(int argc, char **argv)
 #endif
                io_ptr = unix_io_manager;
 
+       /*
+        * Try the get/set fs label using ioctls before we even attempt
+        * to open the file system.
+        */
+       if (L_flag || print_label) {
+               rc = handle_fslabel(L_flag);
+               if (rc != -1) {
+#ifndef BUILD_AS_LIB
+                       exit(rc);
+#endif
+                       return rc;
+               }
+               rc = 0;
+       }
+
 retry_open:
        if ((open_flag & EXT2_FLAG_RW) == 0 || f_flag)
                open_flag |= EXT2_FLAG_SKIP_MMP;
@@ -3079,9 +3316,10 @@ retry_open:
                goto closefs;
        }
 
-       retval = ext2fs_check_if_mounted(device_name, &mount_flags);
+       retval = ext2fs_check_mount_point(device_name, &mount_flags,
+                                       mntpt, sizeof(mntpt));
        if (retval) {
-               com_err("ext2fs_check_if_mount", retval,
+               com_err("ext2fs_check_mount_point", retval,
                        _("while determining whether %s is mounted."),
                        device_name);
                rc = 1;
@@ -3261,6 +3499,24 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                if (rc)
                        goto closefs;
        }
+       if (orphan_file_blocks) {
+               errcode_t err;
+
+               err = ext2fs_read_bitmaps(fs);
+               if (err) {
+                       com_err(program_name, err, "%s",
+                               _("while loading bitmaps"));
+                       rc = 1;
+                       goto closefs;
+               }
+               err = ext2fs_create_orphan_file(fs, orphan_file_blocks);
+               if (err) {
+                       com_err(program_name, err, "%s",
+                               _("while creating orphan file"));
+                       rc = 1;
+                       goto closefs;
+               }
+       }
 
        if (Q_flag) {
                if (mount_flags & EXT2_MF_MOUNTED) {
@@ -3279,6 +3535,8 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                dgrp_t i;
                char buf[SUPERBLOCK_SIZE] __attribute__ ((aligned(8)));
                __u8 old_uuid[UUID_SIZE];
+               uuid_t new_uuid;
+               errcode_t ret = -1;
 
                if (ext2fs_has_feature_stable_inodes(fs->super)) {
                        fputs(_("Cannot change the UUID of this filesystem "
@@ -3332,25 +3590,62 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                                set_csum = 1;
                }
 
-               memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
-               if ((strcasecmp(new_UUID, "null") == 0) ||
-                   (strcasecmp(new_UUID, "clear") == 0)) {
-                       uuid_clear(sb->s_uuid);
-               } else if (strcasecmp(new_UUID, "time") == 0) {
-                       uuid_generate_time(sb->s_uuid);
-               } else if (strcasecmp(new_UUID, "random") == 0) {
-                       uuid_generate(sb->s_uuid);
-               } else if (uuid_parse(new_UUID, sb->s_uuid)) {
+#ifdef __linux__
+               if ((mount_flags & EXT2_MF_MOUNTED) &&
+                   !(mount_flags & EXT2_MF_READONLY) && mntpt[0]) {
+                       fd = open(mntpt, O_RDONLY);
+                       if (fd >= 0)
+                               fsuuid = malloc(sizeof(*fsuuid) + UUID_SIZE);
+                       if (fsuuid) {
+                               fsuuid->fsu_len = UUID_SIZE;
+                               fsuuid->fsu_flags = 0;
+                               ret = ioctl(fd, EXT4_IOC_GETFSUUID, fsuuid);
+                               if (ret || fsuuid->fsu_len != UUID_SIZE) {
+                                       free(fsuuid);
+                                       fsuuid = NULL;
+                               }
+                       }
+               }
+#endif
+
+               memcpy(old_uuid, fsuuid ? fsuuid->fsu_uuid : sb->s_uuid,
+                      UUID_SIZE);
+               if ((strcasecmp(requested_uuid, "null") == 0) ||
+                   (strcasecmp(requested_uuid, "clear") == 0)) {
+                       uuid_clear(new_uuid);
+               } else if (strcasecmp(requested_uuid, "time") == 0) {
+                       uuid_generate_time(new_uuid);
+               } else if (strcasecmp(requested_uuid, "random") == 0) {
+                       uuid_generate(new_uuid);
+               } else if (uuid_parse(requested_uuid, new_uuid)) {
                        com_err(program_name, 0, "%s",
                                _("Invalid UUID format\n"));
                        rc = 1;
                        goto closefs;
                }
-               ext2fs_init_csum_seed(fs);
-               if (set_csum) {
-                       for (i = 0; i < fs->group_desc_count; i++)
-                               ext2fs_group_desc_csum_set(fs, i);
-                       fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+
+               ret = -1;
+#ifdef __linux__
+               if (fsuuid) {
+                       fsuuid->fsu_len = UUID_SIZE;
+                       fsuuid->fsu_flags = 0;
+                       memcpy(&fsuuid->fsu_uuid, new_uuid, UUID_SIZE);
+                       ret = ioctl(fd, EXT4_IOC_SETFSUUID, fsuuid);
+               }
+#endif
+               /*
+                * If we can't set the UUID via the ioctl, fall
+                * back to directly modifying the superblock
+                .*/
+               if (ret) {
+                       memcpy(sb->s_uuid, new_uuid, UUID_SIZE);
+                       ext2fs_init_csum_seed(fs);
+                       if (set_csum) {
+                               for (i = 0; i < fs->group_desc_count; i++)
+                                       ext2fs_group_desc_csum_set(fs, i);
+                               fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+                       }
+                       ext2fs_mark_super_dirty(fs);
                }
 
                /* If this is a journal dev, we need to copy UUID into jsb */
@@ -3374,8 +3669,6 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                        if ((rc = fs_update_journal_user(sb, old_uuid)))
                                goto closefs;
                }
-
-               ext2fs_mark_super_dirty(fs);
        }
 
        if (I_flag) {
@@ -3450,6 +3743,10 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
        remove_error_table(&et_ext2_error_table);
 
 closefs:
+       if (fd >= 0)
+               close(fd);
+       if (fsuuid)
+               free(fsuuid);
        if (rc) {
                ext2fs_mmp_stop(fs);
 #ifndef BUILD_AS_LIB
index 013ee52c41fd51ca60552e6bb035dd51682eed67..6e03e97153f746fb9a9ba3ba70c91cb15a97830e 100644 (file)
@@ -78,9 +78,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: e2fsprogs 1.46.6\n"
+"Project-Id-Version: e2fsprogs 1.47.0\n"
 "Report-Msgid-Bugs-To: tytso@alum.mit.edu\n"
-"POT-Creation-Date: 2023-02-01 15:29-0500\n"
+"POT-Creation-Date: 2023-02-05 15:05-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -90,7 +90,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: e2fsck/badblocks.c:23 misc/mke2fs.c:221
+#: e2fsck/badblocks.c:23 misc/mke2fs.c:223
 #, c-format
 msgid "Bad block %u out of range; ignored.\n"
 msgstr ""
@@ -106,9 +106,9 @@ msgstr ""
 #: e2fsck/badblocks.c:72 e2fsck/scantest.c:107 e2fsck/unix.c:1592
 #: e2fsck/unix.c:1707 misc/badblocks.c:1273 misc/badblocks.c:1281
 #: misc/badblocks.c:1295 misc/badblocks.c:1307 misc/dumpe2fs.c:438
-#: misc/dumpe2fs.c:704 misc/dumpe2fs.c:708 misc/e2image.c:1440
-#: misc/e2image.c:1640 misc/e2image.c:1661 misc/mke2fs.c:237
-#: misc/tune2fs.c:2891 misc/tune2fs.c:2993 resize/main.c:422
+#: misc/dumpe2fs.c:704 misc/dumpe2fs.c:708 misc/e2image.c:1441
+#: misc/e2image.c:1641 misc/e2image.c:1662 misc/mke2fs.c:239
+#: misc/tune2fs.c:3037 misc/tune2fs.c:3231 resize/main.c:422
 #, c-format
 msgid "while trying to open %s"
 msgstr ""
@@ -118,7 +118,7 @@ msgstr ""
 msgid "while trying popen '%s'"
 msgstr ""
 
-#: e2fsck/badblocks.c:95 misc/mke2fs.c:244
+#: e2fsck/badblocks.c:95 misc/mke2fs.c:246
 msgid "while reading in list of bad blocks from file"
 msgstr ""
 
@@ -504,81 +504,81 @@ msgstr ""
 msgid "reading directory block"
 msgstr ""
 
-#: e2fsck/pass1.c:1173
+#: e2fsck/pass1.c:1175
 msgid "getting next inode from scan"
 msgstr ""
 
-#: e2fsck/pass1.c:1225
+#: e2fsck/pass1.c:1227
 msgid "in-use inode map"
 msgstr ""
 
-#: e2fsck/pass1.c:1236
+#: e2fsck/pass1.c:1238
 msgid "directory inode map"
 msgstr ""
 
-#: e2fsck/pass1.c:1246
+#: e2fsck/pass1.c:1248
 msgid "regular file inode map"
 msgstr ""
 
-#: e2fsck/pass1.c:1255 misc/e2image.c:1290
+#: e2fsck/pass1.c:1257 misc/e2image.c:1290
 msgid "in-use block map"
 msgstr ""
 
-#: e2fsck/pass1.c:1264
+#: e2fsck/pass1.c:1266
 msgid "metadata block map"
 msgstr ""
 
-#: e2fsck/pass1.c:1275
+#: e2fsck/pass1.c:1277
 msgid "inode casefold map"
 msgstr ""
 
-#: e2fsck/pass1.c:1340
+#: e2fsck/pass1.c:1342
 msgid "opening inode scan"
 msgstr ""
 
-#: e2fsck/pass1.c:2108
+#: e2fsck/pass1.c:2137
 msgid "Pass 1"
 msgstr ""
 
-#: e2fsck/pass1.c:2169
+#: e2fsck/pass1.c:2198
 #, c-format
 msgid "reading indirect blocks of inode %u"
 msgstr ""
 
-#: e2fsck/pass1.c:2220
+#: e2fsck/pass1.c:2249
 msgid "bad inode map"
 msgstr ""
 
-#: e2fsck/pass1.c:2260
+#: e2fsck/pass1.c:2289
 msgid "inode in bad block map"
 msgstr ""
 
-#: e2fsck/pass1.c:2280
+#: e2fsck/pass1.c:2309
 msgid "imagic inode map"
 msgstr ""
 
-#: e2fsck/pass1.c:2311
+#: e2fsck/pass1.c:2340
 msgid "multiply claimed block map"
 msgstr ""
 
-#: e2fsck/pass1.c:2436
+#: e2fsck/pass1.c:2465
 msgid "ext attr block map"
 msgstr ""
 
-#: e2fsck/pass1.c:3736
+#: e2fsck/pass1.c:3766
 #, c-format
 msgid "%6lu(%c): expecting %6lu got phys %6lu (blkcnt %lld)\n"
 msgstr ""
 
-#: e2fsck/pass1.c:4157
+#: e2fsck/pass1.c:4187
 msgid "block bitmap"
 msgstr ""
 
-#: e2fsck/pass1.c:4163
+#: e2fsck/pass1.c:4193
 msgid "inode bitmap"
 msgstr ""
 
-#: e2fsck/pass1.c:4169
+#: e2fsck/pass1.c:4199
 msgid "inode table"
 msgstr ""
 
@@ -610,7 +610,7 @@ msgstr ""
 msgid "inode loop detection bitmap"
 msgstr ""
 
-#: e2fsck/pass4.c:289
+#: e2fsck/pass4.c:300
 msgid "Pass 4"
 msgstr ""
 
@@ -974,7 +974,7 @@ msgstr ""
 msgid "Clear @j"
 msgstr ""
 
-#: e2fsck/problem.c:263 e2fsck/problem.c:799
+#: e2fsck/problem.c:263 e2fsck/problem.c:819
 #. @-expanded: filesystem has feature flag(s) set, but is a revision 0 filesystem.  
 msgid "@f has feature flag(s) set, but is a revision 0 @f.  "
 msgstr ""
@@ -1270,122 +1270,155 @@ msgid ""
 "not compatible. Resize @i should be disabled.  "
 msgstr ""
 
-#: e2fsck/problem.c:533
+#: e2fsck/problem.c:531
+#. @-expanded: Orphan file (inode %i) contains hole at block %b. Terminating orphan file 
+#. @-expanded: recovery.\n
+msgid ""
+"Orphan file (@i %i) contains hole at @b %b. Terminating orphan file "
+"recovery.\n"
+msgstr ""
+
+#: e2fsck/problem.c:536
+#. @-expanded: Orphan file (inode %i) block %b contains wrong magic. Terminating orphan file 
+#. @-expanded: recovery.\n
+msgid ""
+"Orphan file (@i %i) @b %b contains wrong magic. Terminating orphan file "
+"recovery.\n"
+msgstr ""
+
+#: e2fsck/problem.c:541
+#. @-expanded: Orphan file (inode %i) block %b contains wrong checksum. Terminating orphan file 
+#. @-expanded: recovery.\n
+msgid ""
+"Orphan file (@i %i) @b %b contains wrong checksum. Terminating orphan file "
+"recovery.\n"
+msgstr ""
+
+#: e2fsck/problem.c:546
+#, c-format
+#. @-expanded: Orphan file (inode %i) size is not multiple of block size. Terminating orphan 
+#. @-expanded: file recovery.\n
+msgid ""
+"Orphan file (@i %i) size is not multiple of block size. Terminating orphan "
+"file recovery.\n"
+msgstr ""
+
+#: e2fsck/problem.c:553
 #. @-expanded: Pass 1: Checking inodes, blocks, and sizes\n
 msgid "Pass 1: Checking @is, @bs, and sizes\n"
 msgstr ""
 
-#: e2fsck/problem.c:537
+#: e2fsck/problem.c:557
 #. @-expanded: root inode is not a directory.  
 msgid "@r is not a @d.  "
 msgstr ""
 
-#: e2fsck/problem.c:542
+#: e2fsck/problem.c:562
 #. @-expanded: root inode has dtime set (probably due to old mke2fs).  
 msgid "@r has dtime set (probably due to old mke2fs).  "
 msgstr ""
 
-#: e2fsck/problem.c:547
+#: e2fsck/problem.c:567
 #. @-expanded: Reserved inode %i (%Q) has invalid mode.  
 msgid "Reserved @i %i (%Q) has @n mode.  "
 msgstr ""
 
-#: e2fsck/problem.c:553
+#: e2fsck/problem.c:573
 #, no-c-format
 #. @-expanded: deleted inode %i has zero dtime.  
 msgid "@D @i %i has zero dtime.  "
 msgstr ""
 
-#: e2fsck/problem.c:559
+#: e2fsck/problem.c:579
 #, no-c-format
 #. @-expanded: inode %i is in use, but has dtime set.  
 msgid "@i %i is in use, but has dtime set.  "
 msgstr ""
 
-#: e2fsck/problem.c:565
+#: e2fsck/problem.c:585
 #, no-c-format
 #. @-expanded: inode %i is a zero-length directory.  
 msgid "@i %i is a @z @d.  "
 msgstr ""
 
-#: e2fsck/problem.c:570
+#: e2fsck/problem.c:590
 #. @-expanded: group %g's block bitmap at %b conflicts with some other fs block.\n
 msgid "@g %g's @b @B at %b @C.\n"
 msgstr ""
 
-#: e2fsck/problem.c:575
+#: e2fsck/problem.c:595
 #. @-expanded: group %g's inode bitmap at %b conflicts with some other fs block.\n
 msgid "@g %g's @i @B at %b @C.\n"
 msgstr ""
 
-#: e2fsck/problem.c:580
+#: e2fsck/problem.c:600
 #. @-expanded: group %g's inode table at %b conflicts with some other fs block.\n
 msgid "@g %g's @i table at %b @C.\n"
 msgstr ""
 
-#: e2fsck/problem.c:585
+#: e2fsck/problem.c:605
 #. @-expanded: group %g's block bitmap (%b) is bad.  
 msgid "@g %g's @b @B (%b) is bad.  "
 msgstr ""
 
-#: e2fsck/problem.c:590
+#: e2fsck/problem.c:610
 #. @-expanded: group %g's inode bitmap (%b) is bad.  
 msgid "@g %g's @i @B (%b) is bad.  "
 msgstr ""
 
-#: e2fsck/problem.c:595
+#: e2fsck/problem.c:615
 #. @-expanded: inode %i, i_size is %Is, should be %N.  
 msgid "@i %i, i_size is %Is, @s %N.  "
 msgstr ""
 
-#: e2fsck/problem.c:600
+#: e2fsck/problem.c:620
 #. @-expanded: inode %i, i_blocks is %Ib, should be %N.  
 msgid "@i %i, i_@bs is %Ib, @s %N.  "
 msgstr ""
 
-#: e2fsck/problem.c:605
+#: e2fsck/problem.c:625
 #. @-expanded: illegal %B (%b) in inode %i.  
 msgid "@I %B (%b) in @i %i.  "
 msgstr ""
 
-#: e2fsck/problem.c:610
+#: e2fsck/problem.c:630
 #. @-expanded: %B (%b) overlaps filesystem metadata in inode %i.  
 msgid "%B (%b) overlaps @f metadata in @i %i.  "
 msgstr ""
 
-#: e2fsck/problem.c:616
+#: e2fsck/problem.c:636
 #, no-c-format
 #. @-expanded: inode %i has illegal block(s).  
 msgid "@i %i has illegal @b(s).  "
 msgstr ""
 
-#: e2fsck/problem.c:622
+#: e2fsck/problem.c:642
 #, no-c-format
 #. @-expanded: Too many illegal blocks in inode %i.\n
 msgid "Too many illegal @bs in @i %i.\n"
 msgstr ""
 
-#: e2fsck/problem.c:627
+#: e2fsck/problem.c:647
 #. @-expanded: illegal %B (%b) in bad block inode.  
 msgid "@I %B (%b) in bad @b @i.  "
 msgstr ""
 
-#: e2fsck/problem.c:632
+#: e2fsck/problem.c:652
 #. @-expanded: Bad block inode has illegal block(s).  
 msgid "Bad @b @i has illegal @b(s).  "
 msgstr ""
 
-#: e2fsck/problem.c:637
+#: e2fsck/problem.c:657
 #. @-expanded: Duplicate or bad block in use!\n
 msgid "Duplicate or bad @b in use!\n"
 msgstr ""
 
-#: e2fsck/problem.c:642
+#: e2fsck/problem.c:662
 #. @-expanded: Bad block %b used as bad block inode indirect block.  
 msgid "Bad @b %b used as bad @b @i indirect @b.  "
 msgstr ""
 
-#: e2fsck/problem.c:647
+#: e2fsck/problem.c:667
 #. @-expanded: \n
 #. @-expanded: The bad block inode has probably been corrupted.  You probably\n
 #. @-expanded: should stop now and run e2fsck -c to scan for bad blocks\n
@@ -1397,7 +1430,7 @@ msgid ""
 "in the @f.\n"
 msgstr ""
 
-#: e2fsck/problem.c:654
+#: e2fsck/problem.c:674
 #. @-expanded: \n
 #. @-expanded: If the block is really bad, the filesystem can not be fixed.\n
 msgid ""
@@ -1405,7 +1438,7 @@ msgid ""
 "If the @b is really bad, the @f can not be fixed.\n"
 msgstr ""
 
-#: e2fsck/problem.c:659
+#: e2fsck/problem.c:679
 #. @-expanded: You can remove this block from the bad block list and hope\n
 #. @-expanded: that the block is really OK.  But there are no guarantees.\n
 #. @-expanded: \n
@@ -1415,120 +1448,120 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:665
+#: e2fsck/problem.c:685
 #. @-expanded: The primary superblock (%b) is on the bad block list.\n
 msgid "The primary @S (%b) is on the bad @b list.\n"
 msgstr ""
 
-#: e2fsck/problem.c:670
+#: e2fsck/problem.c:690
 #. @-expanded: Block %b in the primary group descriptors is on the bad block list\n
 msgid "Block %b in the primary @g descriptors is on the bad @b list\n"
 msgstr ""
 
-#: e2fsck/problem.c:676
+#: e2fsck/problem.c:696
 #. @-expanded: Warning: Group %g's superblock (%b) is bad.\n
 msgid "Warning: Group %g's @S (%b) is bad.\n"
 msgstr ""
 
-#: e2fsck/problem.c:682
+#: e2fsck/problem.c:702
 #. @-expanded: Warning: Group %g's copy of the group descriptors has a bad block (%b).\n
 msgid "Warning: Group %g's copy of the @g descriptors has a bad @b (%b).\n"
 msgstr ""
 
-#: e2fsck/problem.c:688
+#: e2fsck/problem.c:708
 #. @-expanded: Programming error?  block #%b claimed for no reason in process_bad_block.\n
 msgid "Programming error?  @b #%b claimed for no reason in process_bad_@b.\n"
 msgstr ""
 
-#: e2fsck/problem.c:694
+#: e2fsck/problem.c:714
 #. @-expanded: error allocating %N contiguous block(s) in block group %g for %s: %m\n
 msgid "@A %N contiguous @b(s) in @b @g %g for %s: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:700
+#: e2fsck/problem.c:720
 #, no-c-format
 #. @-expanded: error allocating block buffer for relocating %s\n
 msgid "@A @b buffer for relocating %s\n"
 msgstr ""
 
-#: e2fsck/problem.c:705
+#: e2fsck/problem.c:725
 #. @-expanded: Relocating group %g's %s from %b to %c...\n
 msgid "Relocating @g %g's %s from %b to %c...\n"
 msgstr ""
 
-#: e2fsck/problem.c:711
+#: e2fsck/problem.c:731
 #, no-c-format
 #. @-expanded: Relocating group %g's %s to %c...\n
 msgid "Relocating @g %g's %s to %c...\n"
 msgstr ""
 
-#: e2fsck/problem.c:716
+#: e2fsck/problem.c:736
 #. @-expanded: Warning: could not read block %b of %s: %m\n
 msgid "Warning: could not read @b %b of %s: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:721
+#: e2fsck/problem.c:741
 #. @-expanded: Warning: could not write block %b for %s: %m\n
 msgid "Warning: could not write @b %b for %s: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:726 e2fsck/problem.c:1936
+#: e2fsck/problem.c:746 e2fsck/problem.c:1965
 #. @-expanded: error allocating inode bitmap (%N): %m\n
 msgid "@A @i @B (%N): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:731
+#: e2fsck/problem.c:751
 #. @-expanded: error allocating block bitmap (%N): %m\n
 msgid "@A @b @B (%N): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:737
+#: e2fsck/problem.c:757
 #, no-c-format
 #. @-expanded: error allocating icount link information: %m\n
 msgid "@A icount link information: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:743
+#: e2fsck/problem.c:763
 #, no-c-format
 #. @-expanded: error allocating directory block array: %m\n
 msgid "@A @d @b array: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:749
+#: e2fsck/problem.c:769
 #, no-c-format
 #. @-expanded: Error while scanning inodes (%i): %m\n
 msgid "Error while scanning @is (%i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:755
+#: e2fsck/problem.c:775
 #, no-c-format
 #. @-expanded: Error while iterating over blocks in inode %i: %m\n
 msgid "Error while iterating over @bs in @i %i: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:760
+#: e2fsck/problem.c:780
 #. @-expanded: Error storing inode count information (inode=%i, count=%N): %m\n
 msgid "Error storing @i count information (@i=%i, count=%N): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:765
+#: e2fsck/problem.c:785
 #. @-expanded: Error storing directory block information (inode=%i, block=%b, num=%N): %m\n
 msgid "Error storing @d @b information (@i=%i, @b=%b, num=%N): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:772
+#: e2fsck/problem.c:792
 #, no-c-format
 #. @-expanded: Error reading inode %i: %m\n
 msgid "Error reading @i %i: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:781
+#: e2fsck/problem.c:801
 #, no-c-format
 #. @-expanded: inode %i has imagic flag set.  
 msgid "@i %i has imagic flag set.  "
 msgstr ""
 
-#: e2fsck/problem.c:787
+#: e2fsck/problem.c:807
 #, no-c-format
 #. @-expanded: Special (device/socket/fifo/symlink) file (inode %i) has immutable\n
 #. @-expanded: or append-only flag set.  
@@ -1537,142 +1570,142 @@ msgid ""
 "or append-only flag set.  "
 msgstr ""
 
-#: e2fsck/problem.c:794
+#: e2fsck/problem.c:814
 #, no-c-format
 #. @-expanded: Special (device/socket/fifo) inode %i has non-zero size.  
 msgid "Special (@v/socket/fifo) @i %i has non-zero size.  "
 msgstr ""
 
-#: e2fsck/problem.c:804
+#: e2fsck/problem.c:824
 #. @-expanded: journal inode is not in use, but contains data.  
 msgid "@j @i is not in use, but contains data.  "
 msgstr ""
 
-#: e2fsck/problem.c:809
+#: e2fsck/problem.c:829
 #. @-expanded: journal is not regular file.  
 msgid "@j is not regular file.  "
 msgstr ""
 
-#: e2fsck/problem.c:815
+#: e2fsck/problem.c:835
 #, no-c-format
 #. @-expanded: inode %i was part of the orphaned inode list.  
 msgid "@i %i was part of the @o @i list.  "
 msgstr ""
 
-#: e2fsck/problem.c:821
+#: e2fsck/problem.c:841
 #. @-expanded: inodes that were part of a corrupted orphan linked list found.  
 msgid "@is that were part of a corrupted orphan linked list found.  "
 msgstr ""
 
-#: e2fsck/problem.c:826
+#: e2fsck/problem.c:846
 #. @-expanded: error allocating refcount structure (%N): %m\n
 msgid "@A refcount structure (%N): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:831
+#: e2fsck/problem.c:851
 #. @-expanded: Error reading extended attribute block %b for inode %i.  
 msgid "Error reading @a @b %b for @i %i.  "
 msgstr ""
 
-#: e2fsck/problem.c:836
+#: e2fsck/problem.c:856
 #. @-expanded: inode %i has a bad extended attribute block %b.  
 msgid "@i %i has a bad @a @b %b.  "
 msgstr ""
 
-#: e2fsck/problem.c:841
+#: e2fsck/problem.c:861
 #. @-expanded: Error reading extended attribute block %b (%m).  
 msgid "Error reading @a @b %b (%m).  "
 msgstr ""
 
-#: e2fsck/problem.c:846
+#: e2fsck/problem.c:866
 #. @-expanded: extended attribute block %b has reference count %r, should be %N.  
 msgid "@a @b %b has reference count %r, @s %N.  "
 msgstr ""
 
-#: e2fsck/problem.c:851
+#: e2fsck/problem.c:871
 #. @-expanded: Error writing extended attribute block %b (%m).  
 msgid "Error writing @a @b %b (%m).  "
 msgstr ""
 
-#: e2fsck/problem.c:856
+#: e2fsck/problem.c:876
 #. @-expanded: extended attribute block %b has h_blocks > 1.  
 msgid "@a @b %b has h_@bs > 1.  "
 msgstr ""
 
-#: e2fsck/problem.c:861
+#: e2fsck/problem.c:881
 #. @-expanded: error allocating extended attribute region allocation structure.  
 msgid "@A @a region allocation structure.  "
 msgstr ""
 
-#: e2fsck/problem.c:866
+#: e2fsck/problem.c:886
 #. @-expanded: extended attribute block %b is corrupt (allocation collision).  
 msgid "@a @b %b is corrupt (allocation collision).  "
 msgstr ""
 
-#: e2fsck/problem.c:871
+#: e2fsck/problem.c:891
 #. @-expanded: extended attribute block %b is corrupt (invalid name).  
 msgid "@a @b %b is corrupt (@n name).  "
 msgstr ""
 
-#: e2fsck/problem.c:876
+#: e2fsck/problem.c:896
 #. @-expanded: extended attribute block %b is corrupt (invalid value).  
 msgid "@a @b %b is corrupt (@n value).  "
 msgstr ""
 
-#: e2fsck/problem.c:882
+#: e2fsck/problem.c:902
 #, no-c-format
 #. @-expanded: inode %i is too big.  
 msgid "@i %i is too big.  "
 msgstr ""
 
-#: e2fsck/problem.c:886
+#: e2fsck/problem.c:906
 #. @-expanded: %B (%b) causes directory to be too big.  
 msgid "%B (%b) causes @d to be too big.  "
 msgstr ""
 
-#: e2fsck/problem.c:891
+#: e2fsck/problem.c:911
 msgid "%B (%b) causes file to be too big.  "
 msgstr ""
 
-#: e2fsck/problem.c:896
+#: e2fsck/problem.c:916
 msgid "%B (%b) causes symlink to be too big.  "
 msgstr ""
 
-#: e2fsck/problem.c:902
+#: e2fsck/problem.c:922
 #, no-c-format
 #. @-expanded: inode %i has INDEX_FL flag set on filesystem without htree support.\n
 msgid "@i %i has INDEX_FL flag set on @f without htree support.\n"
 msgstr ""
 
-#: e2fsck/problem.c:908
+#: e2fsck/problem.c:928
 #, no-c-format
 #. @-expanded: inode %i has INDEX_FL flag set but is not a directory.\n
 msgid "@i %i has INDEX_FL flag set but is not a @d.\n"
 msgstr ""
 
-#: e2fsck/problem.c:914
+#: e2fsck/problem.c:934
 #, no-c-format
 #. @-expanded: HTREE directory inode %i has an invalid root node.\n
 msgid "@h %i has an @n root node.\n"
 msgstr ""
 
-#: e2fsck/problem.c:919
+#: e2fsck/problem.c:939
 #. @-expanded: HTREE directory inode %i has an unsupported hash version (%N)\n
 msgid "@h %i has an unsupported hash version (%N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:925
+#: e2fsck/problem.c:945
 #, no-c-format
 #. @-expanded: HTREE directory inode %i uses an incompatible htree root node flag.\n
 msgid "@h %i uses an incompatible htree root node flag.\n"
 msgstr ""
 
-#: e2fsck/problem.c:930
+#: e2fsck/problem.c:950
 #. @-expanded: HTREE directory inode %i has a tree depth (%N) which is too big\n
 msgid "@h %i has a tree depth (%N) which is too big\n"
 msgstr ""
 
-#: e2fsck/problem.c:936
+#: e2fsck/problem.c:956
 #. @-expanded: Bad block inode has an indirect block (%b) that conflicts with\n
 #. @-expanded: filesystem metadata.  
 msgid ""
@@ -1680,54 +1713,54 @@ msgid ""
 "@f metadata.  "
 msgstr ""
 
-#: e2fsck/problem.c:943
+#: e2fsck/problem.c:963
 #, no-c-format
 #. @-expanded: Resize inode (re)creation failed: %m.
 msgid "Resize @i (re)creation failed: %m."
 msgstr ""
 
-#: e2fsck/problem.c:948
+#: e2fsck/problem.c:968
 #. @-expanded: inode %i has a extra size (%IS) which is invalid\n
 msgid "@i %i has a extra size (%IS) which is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:953
+#: e2fsck/problem.c:973
 #. @-expanded: extended attribute in inode %i has a namelen (%N) which is invalid\n
 msgid "@a in @i %i has a namelen (%N) which is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:958
+#: e2fsck/problem.c:978
 #. @-expanded: extended attribute in inode %i has a value offset (%N) which is invalid\n
 msgid "@a in @i %i has a value offset (%N) which is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:963
+#: e2fsck/problem.c:983
 #. @-expanded: extended attribute in inode %i has a value block (%N) which is invalid (must be 0)\n
 msgid "@a in @i %i has a value @b (%N) which is @n (must be 0)\n"
 msgstr ""
 
-#: e2fsck/problem.c:968
+#: e2fsck/problem.c:988
 #. @-expanded: extended attribute in inode %i has a value size (%N) which is invalid\n
 msgid "@a in @i %i has a value size (%N) which is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:973
+#: e2fsck/problem.c:993
 #. @-expanded: extended attribute in inode %i has a hash (%N) which is invalid\n
 msgid "@a in @i %i has a hash (%N) which is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:978
+#: e2fsck/problem.c:998
 #. @-expanded: inode %i is a %It but it looks like it is really a directory.\n
 msgid "@i %i is a %It but it looks like it is really a directory.\n"
 msgstr ""
 
-#: e2fsck/problem.c:984
+#: e2fsck/problem.c:1004
 #, no-c-format
 #. @-expanded: Error while reading over extent tree in inode %i: %m\n
 msgid "Error while reading over @x tree in @i %i: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:989
+#: e2fsck/problem.c:1009
 #. @-expanded: Failed to iterate extents in inode %i\n
 #. @-expanded: \t(op %s, blk %b, lblk %c): %m\n
 msgid ""
@@ -1735,7 +1768,7 @@ msgid ""
 "\t(op %s, blk %b, lblk %c): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:995
+#: e2fsck/problem.c:1015
 #. @-expanded: inode %i has an invalid extent\n
 #. @-expanded: \t(logical block %c, invalid physical block %b, len %N)\n
 msgid ""
@@ -1743,7 +1776,7 @@ msgid ""
 "\t(logical @b %c, @n physical @b %b, len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1000
+#: e2fsck/problem.c:1020
 #. @-expanded: inode %i has an invalid extent\n
 #. @-expanded: \t(logical block %c, physical block %b, invalid len %N)\n
 msgid ""
@@ -1751,30 +1784,30 @@ msgid ""
 "\t(logical @b %c, physical @b %b, @n len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1006
+#: e2fsck/problem.c:1026
 #, no-c-format
 #. @-expanded: inode %i has EXTENTS_FL flag set on filesystem without extents support.\n
 msgid "@i %i has EXTENTS_FL flag set on @f without extents support.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1012
+#: e2fsck/problem.c:1032
 #, no-c-format
 #. @-expanded: inode %i is in extent format, but superblock is missing EXTENTS feature\n
 msgid "@i %i is in extent format, but @S is missing EXTENTS feature\n"
 msgstr ""
 
-#: e2fsck/problem.c:1018
+#: e2fsck/problem.c:1038
 #, no-c-format
 #. @-expanded: inode %i missing EXTENT_FL, but is in extents format\n
 msgid "@i %i missing EXTENT_FL, but is in extents format\n"
 msgstr ""
 
-#: e2fsck/problem.c:1024
+#: e2fsck/problem.c:1044
 #, no-c-format
 msgid "Fast symlink %i has EXTENT_FL set.  "
 msgstr ""
 
-#: e2fsck/problem.c:1029
+#: e2fsck/problem.c:1049
 #. @-expanded: inode %i has out of order extents\n
 #. @-expanded: \t(invalid logical block %c, physical block %b, len %N)\n
 msgid ""
@@ -1782,38 +1815,38 @@ msgid ""
 "\t(@n logical @b %c, physical @b %b, len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1033
+#: e2fsck/problem.c:1053
 #. @-expanded: inode %i has an invalid extent node (blk %b, lblk %c)\n
 msgid "@i %i has an invalid extent node (blk %b, lblk %c)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1039
+#: e2fsck/problem.c:1059
 #, no-c-format
 #. @-expanded: Error converting subcluster block bitmap: %m\n
 msgid "Error converting subcluster @b @B: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1044
+#: e2fsck/problem.c:1064
 #. @-expanded: quota inode is not a regular file.  
 msgid "@q @i is not a regular file.  "
 msgstr ""
 
-#: e2fsck/problem.c:1049
+#: e2fsck/problem.c:1069
 #. @-expanded: quota inode is not in use, but contains data.  
 msgid "@q @i is not in use, but contains data.  "
 msgstr ""
 
-#: e2fsck/problem.c:1054
+#: e2fsck/problem.c:1074
 #. @-expanded: quota inode is visible to the user.  
 msgid "@q @i is visible to the user.  "
 msgstr ""
 
-#: e2fsck/problem.c:1059
+#: e2fsck/problem.c:1079
 #. @-expanded: The bad block inode looks invalid.  
 msgid "The bad @b @i looks @n.  "
 msgstr ""
 
-#: e2fsck/problem.c:1064
+#: e2fsck/problem.c:1084
 #. @-expanded: inode %i has zero length extent\n
 #. @-expanded: \t(invalid logical block %c, physical block %b)\n
 msgid ""
@@ -1821,25 +1854,25 @@ msgid ""
 "\t(@n logical @b %c, physical @b %b)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1070
+#: e2fsck/problem.c:1090
 #, no-c-format
 #. @-expanded: inode %i seems to contain garbage.  
 msgid "@i %i seems to contain garbage.  "
 msgstr ""
 
-#: e2fsck/problem.c:1076
+#: e2fsck/problem.c:1096
 #, no-c-format
 #. @-expanded: inode %i passes checks, but checksum does not match inode.  
 msgid "@i %i passes checks, but checksum does not match @i.  "
 msgstr ""
 
-#: e2fsck/problem.c:1082
+#: e2fsck/problem.c:1102
 #, no-c-format
 #. @-expanded: inode %i extended attribute is corrupt (allocation collision).  
 msgid "@i %i @a is corrupt (allocation collision).  "
 msgstr ""
 
-#: e2fsck/problem.c:1090
+#: e2fsck/problem.c:1110
 #. @-expanded: inode %i extent block passes checks, but checksum does not match extent\n
 #. @-expanded: \t(logical block %c, physical block %b, len %N)\n
 msgid ""
@@ -1847,12 +1880,12 @@ msgid ""
 "\t(logical @b %c, physical @b %b, len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1099
+#: e2fsck/problem.c:1119
 #. @-expanded: inode %i extended attribute block %b passes checks, but checksum does not match block.  
 msgid "@i %i @a @b %b passes checks, but checksum does not match @b.  "
 msgstr ""
 
-#: e2fsck/problem.c:1104
+#: e2fsck/problem.c:1124
 #. @-expanded: Interior extent node level %N of inode %i:\n
 #. @-expanded: Logical start %b does not match logical start %c at next level.  
 msgid ""
@@ -1860,7 +1893,7 @@ msgid ""
 "Logical start %b does not match logical start %c at next level.  "
 msgstr ""
 
-#: e2fsck/problem.c:1110
+#: e2fsck/problem.c:1130
 #. @-expanded: inode %i, end of extent exceeds allowed value\n
 #. @-expanded: \t(logical block %c, physical block %b, len %N)\n
 msgid ""
@@ -1868,37 +1901,37 @@ msgid ""
 "\t(logical @b %c, physical @b %b, len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1116
+#: e2fsck/problem.c:1136
 #, no-c-format
 #. @-expanded: inode %i has inline data, but superblock is missing INLINE_DATA feature\n
 msgid "@i %i has inline data, but @S is missing INLINE_DATA feature\n"
 msgstr ""
 
-#: e2fsck/problem.c:1122
+#: e2fsck/problem.c:1142
 #, no-c-format
 #. @-expanded: inode %i has INLINE_DATA_FL flag on filesystem without inline data support.\n
 msgid "@i %i has INLINE_DATA_FL flag on @f without inline data support.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1130
+#: e2fsck/problem.c:1150
 #, no-c-format
 #. @-expanded: inode %i block %b conflicts with critical metadata, skipping block checks.\n
 msgid ""
 "@i %i block %b conflicts with critical metadata, skipping block checks.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1135
+#: e2fsck/problem.c:1155
 #. @-expanded: directory inode %i block %b should be at block %c.  
 msgid "@d @i %i @b %b should be at @b %c.  "
 msgstr ""
 
-#: e2fsck/problem.c:1141
+#: e2fsck/problem.c:1161
 #, no-c-format
 #. @-expanded: directory inode %i has extent marked uninitialized at block %c.  
 msgid "@d @i %i has @x marked uninitialized at @b %c.  "
 msgstr ""
 
-#: e2fsck/problem.c:1146
+#: e2fsck/problem.c:1166
 #. @-expanded: inode %i logical block %b (physical block %c) violates cluster allocation rules.\n
 #. @-expanded: Will fix in pass 1B.\n
 msgid ""
@@ -1906,13 +1939,13 @@ msgid ""
 "Will fix in pass 1B.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1152
+#: e2fsck/problem.c:1172
 #, no-c-format
 #. @-expanded: inode %i has INLINE_DATA_FL flag but extended attribute not found.  
 msgid "@i %i has INLINE_DATA_FL flag but @a not found.  "
 msgstr ""
 
-#: e2fsck/problem.c:1159
+#: e2fsck/problem.c:1179
 #, no-c-format
 #. @-expanded: Special (device/socket/fifo) file (inode %i) has extents\n
 #. @-expanded: or inline-data flag set.  
@@ -1921,41 +1954,41 @@ msgid ""
 "or inline-data flag set.  "
 msgstr ""
 
-#: e2fsck/problem.c:1166
+#: e2fsck/problem.c:1186
 #, no-c-format
 #. @-expanded: inode %i has extent header but inline data flag is set.\n
 msgid "@i %i has @x header but inline data flag is set.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1172
+#: e2fsck/problem.c:1192
 #, no-c-format
 #. @-expanded: inode %i seems to have inline data but extent flag is set.\n
 msgid "@i %i seems to have inline data but @x flag is set.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1178
+#: e2fsck/problem.c:1198
 #, no-c-format
 #. @-expanded: inode %i seems to have block map but inline data and extent flags set.\n
 msgid "@i %i seems to have @b map but inline data and @x flags set.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1184
+#: e2fsck/problem.c:1204
 #, no-c-format
 #. @-expanded: inode %i has inline data and extent flags set but i_block contains junk.\n
 msgid "@i %i has inline data and @x flags set but i_block contains junk.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1189
+#: e2fsck/problem.c:1209
 #. @-expanded: Bad block list says the bad block list inode is bad.  
 msgid "Bad block list says the bad block list @i is bad.  "
 msgstr ""
 
-#: e2fsck/problem.c:1194
+#: e2fsck/problem.c:1214
 #. @-expanded: error allocating extent region allocation structure.  
 msgid "@A @x region allocation structure.  "
 msgstr ""
 
-#: e2fsck/problem.c:1199
+#: e2fsck/problem.c:1219
 #. @-expanded: inode %i has a duplicate extent mapping\n
 #. @-expanded: \t(logical block %c, invalid physical block %b, len %N)\n
 msgid ""
@@ -1963,45 +1996,45 @@ msgid ""
 "\t(logical @b %c, @n physical @b %b, len %N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1204
+#: e2fsck/problem.c:1224
 #. @-expanded: error allocating %N bytes of memory for encrypted inode list\n
 msgid "@A %N bytes of memory for encrypted @i list\n"
 msgstr ""
 
-#: e2fsck/problem.c:1209
+#: e2fsck/problem.c:1229
 #. @-expanded: inode %i extent tree could be more shallow (%b; could be <= %c)\n
 msgid "@i %i @x tree could be more shallow (%b; could be <= %c)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1215
+#: e2fsck/problem.c:1235
 #, no-c-format
 #. @-expanded: inode %i on bigalloc filesystem cannot be block mapped.  
 msgid "@i %i on bigalloc @f cannot be @b mapped.  "
 msgstr ""
 
-#: e2fsck/problem.c:1221
+#: e2fsck/problem.c:1241
 #, no-c-format
 #. @-expanded: inode %i has corrupt extent header.  
 msgid "@i %i has corrupt @x header.  "
 msgstr ""
 
-#: e2fsck/problem.c:1227
+#: e2fsck/problem.c:1247
 #, no-c-format
 #. @-expanded: Timestamp(s) on inode %i beyond 2310-04-04 are likely pre-1970.\n
 msgid "Timestamp(s) on @i %i beyond 2310-04-04 are likely pre-1970.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1232
+#: e2fsck/problem.c:1252
 #. @-expanded: inode %i has illegal extended attribute value inode %N.\n
 msgid "@i %i has @I @a value @i %N.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1238
+#: e2fsck/problem.c:1258
 #. @-expanded: inode %i has invalid extended attribute. EA inode %N missing EA_INODE flag.\n
 msgid "@i %i has @n @a. EA @i %N missing EA_INODE flag.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1243
+#: e2fsck/problem.c:1263
 #. @-expanded: EA inode %N for parent inode %i missing EA_INODE flag.\n
 #. @-expanded:  
 msgid ""
@@ -2009,19 +2042,19 @@ msgid ""
 " "
 msgstr ""
 
-#: e2fsck/problem.c:1249
+#: e2fsck/problem.c:1269
 #, no-c-format
 #. @-expanded: inode %i has extent marked uninitialized at block %c (len %N).  
 msgid "@i %i has @x marked uninitialized at @b %c (len %N).  "
 msgstr ""
 
-#: e2fsck/problem.c:1254
+#: e2fsck/problem.c:1274
 #, c-format
 #. @-expanded: inode %i has the casefold flag set but is not a directory.  
 msgid "@i %i has the casefold flag set but is not a directory.  "
 msgstr ""
 
-#: e2fsck/problem.c:1259
+#: e2fsck/problem.c:1279
 #, c-format
 #. @-expanded: directory %p has the casefold flag, but the\n
 #. @-expanded: casefold feature is not enabled.  
@@ -2030,30 +2063,42 @@ msgid ""
 "casefold feature is not enabled.  "
 msgstr ""
 
-#: e2fsck/problem.c:1264
+#: e2fsck/problem.c:1284
 #, c-format
 #. @-expanded: inode %i has encrypt flag but no encryption extended attribute.\n
 msgid "@i %i has encrypt flag but no encryption @a.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1269
+#: e2fsck/problem.c:1289
 #, c-format
 #. @-expanded: Encrypted inode %i has corrupt encryption extended attribute.\n
 msgid "Encrypted @i %i has corrupt encryption @a.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1274
+#: e2fsck/problem.c:1294
 #. @-expanded: HTREE directory inode %i uses hash version (%N), but should use SipHash (6) \n
 msgid "@h %i uses hash version (%N), but should use SipHash (6) \n"
 msgstr ""
 
-#: e2fsck/problem.c:1279
+#: e2fsck/problem.c:1299
 #, c-format
 #. @-expanded: HTREE directory inode %i uses SipHash, but should not.  
 msgid "@h %i uses SipHash, but should not.  "
 msgstr ""
 
-#: e2fsck/problem.c:1287
+#: e2fsck/problem.c:1304
+#, c-format
+#. @-expanded: Orphan file inode %i is not regular file.  
+msgid "Orphan file @i %i is not regular file.  "
+msgstr ""
+
+#: e2fsck/problem.c:1309
+#, c-format
+#. @-expanded: Orphan file inode %i is not in use, but contains data.  
+msgid "Orphan file @i %i is not in use, but contains data.  "
+msgstr ""
+
+#: e2fsck/problem.c:1316
 #. @-expanded: \n
 #. @-expanded: Running additional passes to resolve blocks claimed by more than one inode...\n
 #. @-expanded: Pass 1B: Rescanning for multiply-claimed blocks\n
@@ -2063,45 +2108,45 @@ msgid ""
 "Pass 1B: Rescanning for @m @bs\n"
 msgstr ""
 
-#: e2fsck/problem.c:1294
+#: e2fsck/problem.c:1323
 #, no-c-format
 #. @-expanded: multiply-claimed block(s) in inode %i:
 msgid "@m @b(s) in @i %i:"
 msgstr ""
 
-#: e2fsck/problem.c:1310
+#: e2fsck/problem.c:1339
 #, no-c-format
 msgid "Error while scanning inodes (%i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1316
+#: e2fsck/problem.c:1345
 #, no-c-format
 #. @-expanded: error allocating inode bitmap (inode_dup_map): %m\n
 msgid "@A @i @B (@i_dup_map): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1322
+#: e2fsck/problem.c:1351
 #, no-c-format
 #. @-expanded: Error while iterating over blocks in inode %i (%s): %m\n
 msgid "Error while iterating over @bs in @i %i (%s): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1327 e2fsck/problem.c:1707
+#: e2fsck/problem.c:1356 e2fsck/problem.c:1736
 #. @-expanded: Error adjusting refcount for extended attribute block %b (inode %i): %m\n
 msgid "Error adjusting refcount for @a @b %b (@i %i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1337
+#: e2fsck/problem.c:1366
 #. @-expanded: Pass 1C: Scanning directories for inodes with multiply-claimed blocks\n
 msgid "Pass 1C: Scanning directories for @is with @m @bs\n"
 msgstr ""
 
-#: e2fsck/problem.c:1343
+#: e2fsck/problem.c:1372
 #. @-expanded: Pass 1D: Reconciling multiply-claimed blocks\n
 msgid "Pass 1D: Reconciling @m @bs\n"
 msgstr ""
 
-#: e2fsck/problem.c:1348
+#: e2fsck/problem.c:1377
 #. @-expanded: File %Q (inode #%i, mod time %IM) \n
 #. @-expanded:   has %r multiply-claimed block(s), shared with %N file(s):\n
 msgid ""
@@ -2109,17 +2154,17 @@ msgid ""
 "  has %r @m @b(s), shared with %N file(s):\n"
 msgstr ""
 
-#: e2fsck/problem.c:1354
+#: e2fsck/problem.c:1383
 #. @-expanded: \t%Q (inode #%i, mod time %IM)\n
 msgid "\t%Q (@i #%i, mod time %IM)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1359
+#: e2fsck/problem.c:1388
 #. @-expanded: \t<filesystem metadata>\n
 msgid "\t<@f metadata>\n"
 msgstr ""
 
-#: e2fsck/problem.c:1364
+#: e2fsck/problem.c:1393
 #. @-expanded: (There are %N inodes containing multiply-claimed blocks.)\n
 #. @-expanded: \n
 msgid ""
@@ -2127,7 +2172,7 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1369
+#: e2fsck/problem.c:1398
 #. @-expanded: multiply-claimed blocks already reassigned or cloned.\n
 #. @-expanded: \n
 msgid ""
@@ -2135,348 +2180,348 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1383
+#: e2fsck/problem.c:1412
 #, no-c-format
 msgid "Couldn't clone file: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1389
+#: e2fsck/problem.c:1418
 #. @-expanded: Pass 1E: Optimizing extent trees\n
 msgid "Pass 1E: Optimizing @x trees\n"
 msgstr ""
 
-#: e2fsck/problem.c:1395
+#: e2fsck/problem.c:1424
 #, no-c-format
 #. @-expanded: Failed to optimize extent tree %p (%i): %m\n
 msgid "Failed to optimize @x tree %p (%i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1400
+#: e2fsck/problem.c:1429
 #. @-expanded: Optimizing extent trees: 
 msgid "Optimizing @x trees: "
 msgstr ""
 
-#: e2fsck/problem.c:1415
+#: e2fsck/problem.c:1444
 msgid "Internal error: max extent tree depth too large (%b; expected=%c).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1420
+#: e2fsck/problem.c:1449
 #. @-expanded: inode %i extent tree (at level %b) could be shorter.  
 msgid "@i %i @x tree (at level %b) could be shorter.  "
 msgstr ""
 
-#: e2fsck/problem.c:1425
+#: e2fsck/problem.c:1454
 #. @-expanded: inode %i extent tree (at level %b) could be narrower.  
 msgid "@i %i @x tree (at level %b) could be narrower.  "
 msgstr ""
 
-#: e2fsck/problem.c:1432
+#: e2fsck/problem.c:1461
 #. @-expanded: Pass 2: Checking directory structure\n
 msgid "Pass 2: Checking @d structure\n"
 msgstr ""
 
-#: e2fsck/problem.c:1438
+#: e2fsck/problem.c:1467
 #, no-c-format
 #. @-expanded: invalid inode number for '.' in directory inode %i.\n
 msgid "@n @i number for '.' in @d @i %i.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1443
+#: e2fsck/problem.c:1472
 #. @-expanded: entry '%Dn' in %p (%i) has invalid inode #: %Di.\n
 msgid "@E has @n @i #: %Di.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1448
+#: e2fsck/problem.c:1477
 #. @-expanded: entry '%Dn' in %p (%i) has deleted/unused inode %Di.  
 msgid "@E has @D/unused @i %Di.  "
 msgstr ""
 
-#: e2fsck/problem.c:1453
+#: e2fsck/problem.c:1482
 #. @-expanded: entry '%Dn' in %p (%i) is a link to '.'  
 msgid "@E @L to '.'  "
 msgstr ""
 
-#: e2fsck/problem.c:1458
+#: e2fsck/problem.c:1487
 #. @-expanded: entry '%Dn' in %p (%i) points to inode (%Di) located in a bad block.\n
 msgid "@E points to @i (%Di) located in a bad @b.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1463
+#: e2fsck/problem.c:1492
 #. @-expanded: entry '%Dn' in %p (%i) is a link to directory %P (%Di).\n
 msgid "@E @L to @d %P (%Di).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1468
+#: e2fsck/problem.c:1497
 #. @-expanded: entry '%Dn' in %p (%i) is a link to the root inode.\n
 msgid "@E @L to the @r.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1473
+#: e2fsck/problem.c:1502
 #. @-expanded: entry '%Dn' in %p (%i) has illegal characters in its name.\n
 msgid "@E has illegal characters in its name.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1479
+#: e2fsck/problem.c:1508
 #, no-c-format
 #. @-expanded: Missing '.' in directory inode %i.\n
 msgid "Missing '.' in @d @i %i.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1485
+#: e2fsck/problem.c:1514
 #, no-c-format
 #. @-expanded: Missing '..' in directory inode %i.\n
 msgid "Missing '..' in @d @i %i.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1490
+#: e2fsck/problem.c:1519
 #. @-expanded: First entry '%Dn' (inode=%Di) in directory inode %i (%p) should be '.'\n
 msgid "First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"
 msgstr ""
 
-#: e2fsck/problem.c:1495
+#: e2fsck/problem.c:1524
 #. @-expanded: Second entry '%Dn' (inode=%Di) in directory inode %i should be '..'\n
 msgid "Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"
 msgstr ""
 
-#: e2fsck/problem.c:1500
+#: e2fsck/problem.c:1529
 #. @-expanded: i_faddr for inode %i (%Q) is %IF, should be zero.\n
 msgid "i_faddr @F %IF, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1505
+#: e2fsck/problem.c:1534
 #. @-expanded: i_file_acl for inode %i (%Q) is %If, should be zero.\n
 msgid "i_file_acl @F %If, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1510
+#: e2fsck/problem.c:1539
 #. @-expanded: i_size_high for inode %i (%Q) is %Id, should be zero.\n
 msgid "i_size_high @F %Id, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1515
+#: e2fsck/problem.c:1544
 #. @-expanded: i_frag for inode %i (%Q) is %N, should be zero.\n
 msgid "i_frag @F %N, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1520
+#: e2fsck/problem.c:1549
 #. @-expanded: i_fsize for inode %i (%Q) is %N, should be zero.\n
 msgid "i_fsize @F %N, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1525
+#: e2fsck/problem.c:1554
 #. @-expanded: inode %i (%Q) has invalid mode (%Im).\n
 msgid "@i %i (%Q) has @n mode (%Im).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1530
+#: e2fsck/problem.c:1559
 #. @-expanded: directory inode %i, %B, offset %N: directory corrupted\n
 msgid "@d @i %i, %B, offset %N: @d corrupted\n"
 msgstr ""
 
-#: e2fsck/problem.c:1535
+#: e2fsck/problem.c:1564
 #. @-expanded: directory inode %i, %B, offset %N: filename too long\n
 msgid "@d @i %i, %B, offset %N: filename too long\n"
 msgstr ""
 
-#: e2fsck/problem.c:1540
+#: e2fsck/problem.c:1569
 #. @-expanded: directory inode %i has an unallocated %B.  
 msgid "@d @i %i has an unallocated %B.  "
 msgstr ""
 
-#: e2fsck/problem.c:1546
+#: e2fsck/problem.c:1575
 #, no-c-format
 #. @-expanded: '.' directory entry in directory inode %i is not NULL terminated\n
 msgid "'.' @d @e in @d @i %i is not NULL terminated\n"
 msgstr ""
 
-#: e2fsck/problem.c:1552
+#: e2fsck/problem.c:1581
 #, no-c-format
 #. @-expanded: '..' directory entry in directory inode %i is not NULL terminated\n
 msgid "'..' @d @e in @d @i %i is not NULL terminated\n"
 msgstr ""
 
-#: e2fsck/problem.c:1557
+#: e2fsck/problem.c:1586
 #. @-expanded: inode %i (%Q) is an illegal character device.\n
 msgid "@i %i (%Q) is an @I character @v.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1562
+#: e2fsck/problem.c:1591
 #. @-expanded: inode %i (%Q) is an illegal block device.\n
 msgid "@i %i (%Q) is an @I @b @v.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1567
+#: e2fsck/problem.c:1596
 #. @-expanded: entry '%Dn' in %p (%i) is duplicate '.' entry.\n
 msgid "@E is duplicate '.' @e.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1572
+#: e2fsck/problem.c:1601
 #. @-expanded: entry '%Dn' in %p (%i) is duplicate '..' entry.\n
 msgid "@E is duplicate '..' @e.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1578 e2fsck/problem.c:1963
+#: e2fsck/problem.c:1607 e2fsck/problem.c:1992
 #, no-c-format
 msgid "Internal error: couldn't find dir_info for %i.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1583
+#: e2fsck/problem.c:1612
 #. @-expanded: entry '%Dn' in %p (%i) has rec_len of %Dr, should be %N.\n
 msgid "@E has rec_len of %Dr, @s %N.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1589
+#: e2fsck/problem.c:1618
 #, no-c-format
 #. @-expanded: error allocating icount structure: %m\n
 msgid "@A icount structure: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1595
+#: e2fsck/problem.c:1624
 #, no-c-format
 #. @-expanded: Error iterating over directory blocks: %m\n
 msgid "Error iterating over @d @bs: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1600
+#: e2fsck/problem.c:1629
 #. @-expanded: Error reading directory block %b (inode %i): %m\n
 msgid "Error reading @d @b %b (@i %i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1605
+#: e2fsck/problem.c:1634
 #. @-expanded: Error writing directory block %b (inode %i): %m\n
 msgid "Error writing @d @b %b (@i %i): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1611
+#: e2fsck/problem.c:1640
 #, no-c-format
 #. @-expanded: error allocating new directory block for inode %i (%s): %m\n
 msgid "@A new @d @b for @i %i (%s): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1617
+#: e2fsck/problem.c:1646
 #, no-c-format
 #. @-expanded: Error deallocating inode %i: %m\n
 msgid "Error deallocating @i %i: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1623
+#: e2fsck/problem.c:1652
 #, no-c-format
 #. @-expanded: directory entry for '.' in %p (%i) is big.\n
 msgid "@d @e for '.' in %p (%i) is big.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1628
+#: e2fsck/problem.c:1657
 #. @-expanded: inode %i (%Q) is an illegal FIFO.\n
 msgid "@i %i (%Q) is an @I FIFO.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1633
+#: e2fsck/problem.c:1662
 #. @-expanded: inode %i (%Q) is an illegal socket.\n
 msgid "@i %i (%Q) is an @I socket.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1638
+#: e2fsck/problem.c:1667
 #. @-expanded: Setting filetype for entry '%Dn' in %p (%i) to %N.\n
 msgid "Setting filetype for @E to %N.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1643
+#: e2fsck/problem.c:1672
 #. @-expanded: entry '%Dn' in %p (%i) has an incorrect filetype (was %Dt, should be %N).\n
 msgid "@E has an incorrect filetype (was %Dt, @s %N).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1648
+#: e2fsck/problem.c:1677
 #. @-expanded: entry '%Dn' in %p (%i) has filetype set.\n
 msgid "@E has filetype set.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1653
+#: e2fsck/problem.c:1682
 #. @-expanded: entry '%Dn' in %p (%i) has a zero-length name.\n
 msgid "@E has a @z name.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1658
+#: e2fsck/problem.c:1687
 #. @-expanded: Symlink %Q (inode #%i) is invalid.\n
 msgid "Symlink %Q (@i #%i) is @n.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1663
+#: e2fsck/problem.c:1692
 #. @-expanded: extended attribute block for inode %i (%Q) is invalid (%If).\n
 msgid "@a @b @F @n (%If).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1668
+#: e2fsck/problem.c:1697
 #. @-expanded: filesystem contains large files, but lacks LARGE_FILE flag in superblock.\n
 msgid "@f contains large files, but lacks LARGE_FILE flag in @S.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1673
+#: e2fsck/problem.c:1702
 #. @-expanded: problem in HTREE directory inode %d: %B not referenced\n
 msgid "@p @h %d: %B not referenced\n"
 msgstr ""
 
-#: e2fsck/problem.c:1678
+#: e2fsck/problem.c:1707
 #. @-expanded: problem in HTREE directory inode %d: %B referenced twice\n
 msgid "@p @h %d: %B referenced twice\n"
 msgstr ""
 
-#: e2fsck/problem.c:1683
+#: e2fsck/problem.c:1712
 #. @-expanded: problem in HTREE directory inode %d: %B has bad min hash\n
 msgid "@p @h %d: %B has bad min hash\n"
 msgstr ""
 
-#: e2fsck/problem.c:1688
+#: e2fsck/problem.c:1717
 #. @-expanded: problem in HTREE directory inode %d: %B has bad max hash\n
 msgid "@p @h %d: %B has bad max hash\n"
 msgstr ""
 
-#: e2fsck/problem.c:1693
+#: e2fsck/problem.c:1722
 #. @-expanded: invalid HTREE directory inode %d (%q).  
 msgid "@n @h %d (%q).  "
 msgstr ""
 
-#: e2fsck/problem.c:1697
+#: e2fsck/problem.c:1726
 #. @-expanded: filesystem has large directories, but lacks LARGE_DIR flag in superblock.\n
 msgid "@f has large directories, but lacks LARGE_DIR flag in @S.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1702
+#: e2fsck/problem.c:1731
 #. @-expanded: problem in HTREE directory inode %d (%q): bad block number %b.\n
 msgid "@p @h %d (%q): bad @b number %b.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1713
+#: e2fsck/problem.c:1742
 #, no-c-format
 #. @-expanded: problem in HTREE directory inode %d: root node is invalid\n
 msgid "@p @h %d: root node is @n\n"
 msgstr ""
 
-#: e2fsck/problem.c:1718
+#: e2fsck/problem.c:1747
 #. @-expanded: problem in HTREE directory inode %d: %B has invalid limit (%N)\n
 msgid "@p @h %d: %B has @n limit (%N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1723
+#: e2fsck/problem.c:1752
 #. @-expanded: problem in HTREE directory inode %d: %B has invalid count (%N)\n
 msgid "@p @h %d: %B has @n count (%N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1728
+#: e2fsck/problem.c:1757
 #. @-expanded: problem in HTREE directory inode %d: %B has an unordered hash table\n
 msgid "@p @h %d: %B has an unordered hash table\n"
 msgstr ""
 
-#: e2fsck/problem.c:1733
+#: e2fsck/problem.c:1762
 #. @-expanded: problem in HTREE directory inode %d: %B has invalid depth (%N)\n
 msgid "@p @h %d: %B has @n depth (%N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1738
+#: e2fsck/problem.c:1767
 #. @-expanded: Duplicate entry '%Dn' in %p (%i) found.  
 msgid "Duplicate @E found.  "
 msgstr ""
 
-#: e2fsck/problem.c:1743
+#: e2fsck/problem.c:1772
 #, no-c-format
 #. @-expanded: entry '%Dn' in %p (%i) has a non-unique filename.\n
 #. @-expanded: Rename to %s
@@ -2485,7 +2530,7 @@ msgid ""
 "Rename to %s"
 msgstr ""
 
-#: e2fsck/problem.c:1748
+#: e2fsck/problem.c:1777
 #. @-expanded: Duplicate entry '%Dn' found.\n
 #. @-expanded: \tMarking %p (%i) to be rebuilt.\n
 #. @-expanded: \n
@@ -2495,175 +2540,175 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1753
+#: e2fsck/problem.c:1782
 #. @-expanded: i_blocks_hi for inode %i (%Q) is %N, should be zero.\n
 msgid "i_blocks_hi @F %N, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1758
+#: e2fsck/problem.c:1787
 #. @-expanded: Unexpected block in HTREE directory inode %d (%q).\n
 msgid "Unexpected @b in @h %d (%q).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1763
+#: e2fsck/problem.c:1792
 #. @-expanded: entry '%Dn' in %p (%i) references inode %Di in group %g where _INODE_UNINIT is set.\n
 msgid "@E references @i %Di in @g %g where _INODE_UNINIT is set.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1768
+#: e2fsck/problem.c:1797
 #. @-expanded: entry '%Dn' in %p (%i) references inode %Di found in group %g's unused inodes area.\n
 msgid "@E references @i %Di found in @g %g's unused inodes area.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1773
+#: e2fsck/problem.c:1802
 #. @-expanded: i_file_acl_hi for inode %i (%Q) is %N, should be zero.\n
 msgid "i_file_acl_hi @F %N, @s zero.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1779
+#: e2fsck/problem.c:1808
 #, no-c-format
 #. @-expanded: problem in HTREE directory inode %d: root node fails checksum.\n
 msgid "@p @h %d: root node fails checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1785
+#: e2fsck/problem.c:1814
 #, no-c-format
 #. @-expanded: problem in HTREE directory inode %d: internal node fails checksum.\n
 msgid "@p @h %d: internal node fails checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1790
+#: e2fsck/problem.c:1819
 #. @-expanded: directory inode %i, %B, offset %N: directory has no checksum.\n
 msgid "@d @i %i, %B, offset %N: @d has no checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1795
+#: e2fsck/problem.c:1824
 #. @-expanded: directory inode %i, %B: directory passes checks but fails checksum.\n
 msgid "@d @i %i, %B: @d passes checks but fails checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1800
+#: e2fsck/problem.c:1829
 #. @-expanded: Inline directory inode %i size (%N) must be a multiple of 4.\n
 msgid "Inline @d @i %i size (%N) must be a multiple of 4.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1806
+#: e2fsck/problem.c:1835
 #, no-c-format
 #. @-expanded: Fixing size of inline directory inode %i failed.\n
 msgid "Fixing size of inline @d @i %i failed.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1811
+#: e2fsck/problem.c:1840
 #. @-expanded: Encrypted entry '%Dn' in %p (%i) is too short.\n
 msgid "Encrypted @E is too short.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1816
+#: e2fsck/problem.c:1845
 #. @-expanded: Encrypted entry '%Dn' in %p (%i) references unencrypted inode %Di.\n
 msgid "Encrypted @E references unencrypted @i %Di.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1821
+#: e2fsck/problem.c:1850
 #. @-expanded: Encrypted entry '%Dn' in %p (%i) references inode %Di, which has a different encryption policy.\n
 msgid ""
 "Encrypted @E references @i %Di, which has a different encryption policy.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1826
+#: e2fsck/problem.c:1855
 #. @-expanded: entry '%Dn' in %p (%i) has illegal UTF-8 characters in its name.\n
 msgid "@E has illegal UTF-8 characters in its name.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1831
+#: e2fsck/problem.c:1860
 #. @-expanded: Duplicate filename entry '%Dn' in %p (%i) found.  
 msgid "Duplicate filename @E found.  "
 msgstr ""
 
-#: e2fsck/problem.c:1839
+#: e2fsck/problem.c:1868
 #. @-expanded: Pass 3: Checking directory connectivity\n
 msgid "Pass 3: Checking @d connectivity\n"
 msgstr ""
 
-#: e2fsck/problem.c:1844
+#: e2fsck/problem.c:1873
 #. @-expanded: root inode not allocated.  
 msgid "@r not allocated.  "
 msgstr ""
 
-#: e2fsck/problem.c:1849
+#: e2fsck/problem.c:1878
 #. @-expanded: No room in lost+found directory.  
 msgid "No room in @l @d.  "
 msgstr ""
 
-#: e2fsck/problem.c:1855
+#: e2fsck/problem.c:1884
 #, no-c-format
 #. @-expanded: Unconnected directory inode %i (was in %q)\n
 msgid "Unconnected @d @i %i (was in %q)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1860
+#: e2fsck/problem.c:1889
 #. @-expanded: /lost+found not found.  
 msgid "/@l not found.  "
 msgstr ""
 
-#: e2fsck/problem.c:1865
+#: e2fsck/problem.c:1894
 #. @-expanded: '..' in %Q (%i) is %P (%j), should be %q (%d).\n
 msgid "'..' in %Q (%i) is %P (%j), @s %q (%d).\n"
 msgstr ""
 
-#: e2fsck/problem.c:1871
+#: e2fsck/problem.c:1900
 #, no-c-format
 #. @-expanded: Bad or non-existent /lost+found.  Cannot reconnect.\n
 msgid "Bad or non-existent /@l.  Cannot reconnect.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1877
+#: e2fsck/problem.c:1906
 #, no-c-format
 #. @-expanded: Could not expand /lost+found: %m\n
 msgid "Could not expand /@l: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1883
+#: e2fsck/problem.c:1912
 #, no-c-format
 msgid "Could not reconnect %i: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1889
+#: e2fsck/problem.c:1918
 #, no-c-format
 #. @-expanded: Error while trying to find /lost+found: %m\n
 msgid "Error while trying to find /@l: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1895
+#: e2fsck/problem.c:1924
 #, no-c-format
 #. @-expanded: ext2fs_new_block: %m while trying to create /lost+found directory\n
 msgid "ext2fs_new_@b: %m while trying to create /@l @d\n"
 msgstr ""
 
-#: e2fsck/problem.c:1901
+#: e2fsck/problem.c:1930
 #, no-c-format
 #. @-expanded: ext2fs_new_inode: %m while trying to create /lost+found directory\n
 msgid "ext2fs_new_@i: %m while trying to create /@l @d\n"
 msgstr ""
 
-#: e2fsck/problem.c:1907
+#: e2fsck/problem.c:1936
 #, no-c-format
 #. @-expanded: ext2fs_new_dir_block: %m while creating new directory block\n
 msgid "ext2fs_new_dir_@b: %m while creating new @d @b\n"
 msgstr ""
 
-#: e2fsck/problem.c:1913
+#: e2fsck/problem.c:1942
 #, no-c-format
 #. @-expanded: ext2fs_write_dir_block: %m while writing the directory block for /lost+found\n
 msgid "ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"
 msgstr ""
 
-#: e2fsck/problem.c:1919
+#: e2fsck/problem.c:1948
 #, no-c-format
 #. @-expanded: Error while adjusting inode count on inode %i\n
 msgid "Error while adjusting @i count on @i %i\n"
 msgstr ""
 
-#: e2fsck/problem.c:1925
+#: e2fsck/problem.c:1954
 #, no-c-format
 #. @-expanded: Couldn't fix parent of inode %i: %m\n
 #. @-expanded: \n
@@ -2672,7 +2717,7 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1931
+#: e2fsck/problem.c:1960
 #, no-c-format
 #. @-expanded: Couldn't fix parent of inode %i: Couldn't find parent directory entry\n
 #. @-expanded: \n
@@ -2681,40 +2726,40 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1942
+#: e2fsck/problem.c:1971
 #, no-c-format
 #. @-expanded: Error creating root directory (%s): %m\n
 msgid "Error creating root @d (%s): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1948
+#: e2fsck/problem.c:1977
 #, no-c-format
 #. @-expanded: Error creating /lost+found directory (%s): %m\n
 msgid "Error creating /@l @d (%s): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:1953
+#: e2fsck/problem.c:1982
 #. @-expanded: root inode is not a directory; aborting.\n
 msgid "@r is not a @d; aborting.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1958
+#: e2fsck/problem.c:1987
 #. @-expanded: Cannot proceed without a root inode.\n
 msgid "Cannot proceed without a @r.\n"
 msgstr ""
 
-#: e2fsck/problem.c:1969
+#: e2fsck/problem.c:1998
 #, no-c-format
 #. @-expanded: /lost+found is not a directory (ino=%i)\n
 msgid "/@l is not a @d (ino=%i)\n"
 msgstr ""
 
-#: e2fsck/problem.c:1974
+#: e2fsck/problem.c:2003
 #. @-expanded: /lost+found has inline data\n
 msgid "/@l has inline data\n"
 msgstr ""
 
-#: e2fsck/problem.c:1979
+#: e2fsck/problem.c:2008
 #. @-expanded: Cannot allocate space for /lost+found.\n
 #. @-expanded: Place lost files in root directory instead
 msgid ""
@@ -2722,7 +2767,7 @@ msgid ""
 "Place lost files in root directory instead"
 msgstr ""
 
-#: e2fsck/problem.c:1984
+#: e2fsck/problem.c:2013
 #. @-expanded: Insufficient space to recover lost files!\n
 #. @-expanded: Move data off the filesystem and re-run e2fsck.\n
 #. @-expanded: \n
@@ -2732,56 +2777,56 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/problem.c:1989
+#: e2fsck/problem.c:2018
 #. @-expanded: /lost+found is encrypted\n
 msgid "/@l is encrypted\n"
 msgstr ""
 
-#: e2fsck/problem.c:1995
+#: e2fsck/problem.c:2024
 #, no-c-format
 #. @-expanded: Recursively looped directory inode %i (%p)\n
 msgid "Recursively looped @d @i %i (%p)\n"
 msgstr ""
 
-#: e2fsck/problem.c:2002
+#: e2fsck/problem.c:2031
 msgid "Pass 3A: Optimizing directories\n"
 msgstr ""
 
-#: e2fsck/problem.c:2008
+#: e2fsck/problem.c:2037
 #, no-c-format
 msgid "Failed to create dirs_to_hash iterator: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2013
+#: e2fsck/problem.c:2042
 msgid "Failed to optimize directory %q (%d): %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2018
+#: e2fsck/problem.c:2047
 msgid "Optimizing directories: "
 msgstr ""
 
-#: e2fsck/problem.c:2035
+#: e2fsck/problem.c:2064
 msgid "Pass 4: Checking reference counts\n"
 msgstr ""
 
-#: e2fsck/problem.c:2041
+#: e2fsck/problem.c:2070
 #, no-c-format
 #. @-expanded: unattached zero-length inode %i.  
 msgid "@u @z @i %i.  "
 msgstr ""
 
-#: e2fsck/problem.c:2047
+#: e2fsck/problem.c:2076
 #, no-c-format
 #. @-expanded: unattached inode %i\n
 msgid "@u @i %i\n"
 msgstr ""
 
-#: e2fsck/problem.c:2052
+#: e2fsck/problem.c:2081
 #. @-expanded: inode %i ref count is %Il, should be %N.  
 msgid "@i %i ref count is %Il, @s %N.  "
 msgstr ""
 
-#: e2fsck/problem.c:2056
+#: e2fsck/problem.c:2085
 #. @-expanded: WARNING: PROGRAMMING BUG IN E2FSCK!\n
 #. @-expanded: \tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n
 #. @-expanded: inode_link_info[%i] is %N, inode.i_links_count is %Il.  They should be the same!\n
@@ -2791,72 +2836,72 @@ msgid ""
 "@i_link_info[%i] is %N, @i.i_links_count is %Il.  They @s the same!\n"
 msgstr ""
 
-#: e2fsck/problem.c:2063
+#: e2fsck/problem.c:2092
 #. @-expanded: extended attribute inode %i ref count is %N, should be %n. 
 msgid "@a @i %i ref count is %N, @s %n. "
 msgstr ""
 
-#: e2fsck/problem.c:2068
+#: e2fsck/problem.c:2097
 #. @-expanded: directory exceeds max links, but no DIR_NLINK feature in superblock.\n
 msgid "@d exceeds max links, but no DIR_NLINK feature in @S.\n"
 msgstr ""
 
-#: e2fsck/problem.c:2073
+#: e2fsck/problem.c:2102
 #. @-expanded: directory inode %i ref count set to overflow but could be exact value %N.  
 msgid "@d @i %i ref count set to overflow but could be exact value %N.  "
 msgstr ""
 
-#: e2fsck/problem.c:2080
+#: e2fsck/problem.c:2109
 #. @-expanded: Pass 5: Checking group summary information\n
 msgid "Pass 5: Checking @g summary information\n"
 msgstr ""
 
-#: e2fsck/problem.c:2085
+#: e2fsck/problem.c:2114
 #. @-expanded: Padding at end of inode bitmap is not set. 
 msgid "Padding at end of @i @B is not set. "
 msgstr ""
 
-#: e2fsck/problem.c:2090
+#: e2fsck/problem.c:2119
 #. @-expanded: Padding at end of block bitmap is not set. 
 msgid "Padding at end of @b @B is not set. "
 msgstr ""
 
-#: e2fsck/problem.c:2095
+#: e2fsck/problem.c:2124
 #. @-expanded: block bitmap differences: 
 msgid "@b @B differences: "
 msgstr ""
 
-#: e2fsck/problem.c:2117
+#: e2fsck/problem.c:2146
 #. @-expanded: inode bitmap differences: 
 msgid "@i @B differences: "
 msgstr ""
 
-#: e2fsck/problem.c:2139
+#: e2fsck/problem.c:2168
 #. @-expanded: Free inodes count wrong for group #%g (%i, counted=%j).\n
 msgid "Free @is count wrong for @g #%g (%i, counted=%j).\n"
 msgstr ""
 
-#: e2fsck/problem.c:2144
+#: e2fsck/problem.c:2173
 #. @-expanded: Directories count wrong for group #%g (%i, counted=%j).\n
 msgid "Directories count wrong for @g #%g (%i, counted=%j).\n"
 msgstr ""
 
-#: e2fsck/problem.c:2149
+#: e2fsck/problem.c:2178
 #. @-expanded: Free inodes count wrong (%i, counted=%j).\n
 msgid "Free @is count wrong (%i, counted=%j).\n"
 msgstr ""
 
-#: e2fsck/problem.c:2154
+#: e2fsck/problem.c:2183
 #. @-expanded: Free blocks count wrong for group #%g (%b, counted=%c).\n
 msgid "Free @bs count wrong for @g #%g (%b, counted=%c).\n"
 msgstr ""
 
-#: e2fsck/problem.c:2159
+#: e2fsck/problem.c:2188
 #. @-expanded: Free blocks count wrong (%b, counted=%c).\n
 msgid "Free @bs count wrong (%b, counted=%c).\n"
 msgstr ""
 
-#: e2fsck/problem.c:2164
+#: e2fsck/problem.c:2193
 #. @-expanded: PROGRAMMING ERROR: filesystem (#%N) bitmap endpoints (%b, %c) don't match calculated bitmap 
 #. @-expanded: endpoints (%i, %j)\n
 msgid ""
@@ -2864,81 +2909,128 @@ msgid ""
 "endpoints (%i, %j)\n"
 msgstr ""
 
-#: e2fsck/problem.c:2170
+#: e2fsck/problem.c:2199
 msgid "Internal error: fudging end of bitmap (%N)\n"
 msgstr ""
 
-#: e2fsck/problem.c:2176
+#: e2fsck/problem.c:2205
 #, no-c-format
 #. @-expanded: Error copying in replacement inode bitmap: %m\n
 msgid "Error copying in replacement @i @B: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2182
+#: e2fsck/problem.c:2211
 #, no-c-format
 #. @-expanded: Error copying in replacement block bitmap: %m\n
 msgid "Error copying in replacement @b @B: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2212
+#: e2fsck/problem.c:2241
 #, no-c-format
 #. @-expanded: group %g block(s) in use but group is marked BLOCK_UNINIT\n
 msgid "@g %g @b(s) in use but @g is marked BLOCK_UNINIT\n"
 msgstr ""
 
-#: e2fsck/problem.c:2218
+#: e2fsck/problem.c:2247
 #, no-c-format
 #. @-expanded: group %g inode(s) in use but group is marked INODE_UNINIT\n
 msgid "@g %g @i(s) in use but @g is marked INODE_UNINIT\n"
 msgstr ""
 
-#: e2fsck/problem.c:2224
+#: e2fsck/problem.c:2253
 #, no-c-format
 #. @-expanded: group %g inode bitmap does not match checksum.\n
 msgid "@g %g @i @B does not match checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:2230
+#: e2fsck/problem.c:2259
 #, no-c-format
 #. @-expanded: group %g block bitmap does not match checksum.\n
 msgid "@g %g @b @B does not match checksum.\n"
 msgstr ""
 
-#: e2fsck/problem.c:2237
+#: e2fsck/problem.c:2266
 #. @-expanded: Recreate journal
 msgid "Recreate @j"
 msgstr ""
 
-#: e2fsck/problem.c:2242
+#: e2fsck/problem.c:2271
 msgid "Update quota info for quota type %N"
 msgstr ""
 
-#: e2fsck/problem.c:2248
+#: e2fsck/problem.c:2277
 #, no-c-format
 #. @-expanded: Error setting block group checksum info: %m\n
 msgid "Error setting @b @g checksum info: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2254
+#: e2fsck/problem.c:2283
 #, no-c-format
 msgid "Error writing file system info: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2260
+#: e2fsck/problem.c:2289
 #, no-c-format
 msgid "Error flushing writes to storage device: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2265
+#: e2fsck/problem.c:2294
 msgid "Error writing quota info for quota type %N: %m\n"
 msgstr ""
 
-#: e2fsck/problem.c:2430
+#: e2fsck/problem.c:2299
+#. @-expanded: superblock has orphan file without journal.\n
+msgid "@S has orphan file without @j.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2304
+msgid "Failed to truncate orphan file.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2309
+msgid "Failed to initialize orphan file.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2314
+msgid "Cannot fix corrupted orphan file with invalid bitmaps.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2319
+#, c-format
+#. @-expanded: Failed to truncate orphan file (inode %i).\n
+msgid "Failed to truncate orphan file (@i %i).\n"
+msgstr ""
+
+#: e2fsck/problem.c:2324
+#. @-expanded: Orphan file (inode %i) block %b is not clean.\n
+msgid "Orphan file (@i %i) @b %b is not clean.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2329
+msgid "Feature orphan_present is set but orphan file is clean.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2334
+msgid "Feature orphan_present is set but feature orphan_file is not.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2339
+#, c-format
+#. @-expanded: Orphan file (inode %i) size is not multiple of block size.\n
+msgid "Orphan file (@i %i) size is not multiple of block size.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2344
+#. @-expanded: Orphan file (inode %i) contains hole at block %b.\n
+msgid "Orphan file (@i %i) contains hole at @b %b.\n"
+msgstr ""
+
+#: e2fsck/problem.c:2509
 #, c-format
 msgid "Unhandled error code (0x%x)!\n"
 msgstr ""
 
-#: e2fsck/problem.c:2558 e2fsck/problem.c:2562
+#: e2fsck/problem.c:2637 e2fsck/problem.c:2641
 msgid "IGNORED"
 msgstr ""
 
@@ -2978,14 +3070,29 @@ msgstr ""
 msgid "while calling ext2fs_adjust_ea_refcount2 for inode %u"
 msgstr ""
 
-#: e2fsck/super.c:375
+#: e2fsck/super.c:329
 msgid "Truncating"
 msgstr ""
 
-#: e2fsck/super.c:376
+#: e2fsck/super.c:329
 msgid "Clearing"
 msgstr ""
 
+#: e2fsck/super.c:453
+#, c-format
+msgid "while reading inode %d"
+msgstr ""
+
+#: e2fsck/super.c:473 e2fsck/super.c:677
+#, c-format
+msgid "while calling ext2fs_block_iterate for inode %d"
+msgstr ""
+
+#: e2fsck/super.c:481 e2fsck/super.c:685
+#, c-format
+msgid "while reading blocks of inode %d"
+msgstr ""
+
 #: e2fsck/unix.c:79
 #, c-format
 msgid ""
@@ -3151,7 +3258,7 @@ msgid_plural "%12u files\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: e2fsck/unix.c:241 misc/badblocks.c:1001 misc/tune2fs.c:3085 misc/util.c:135
+#: e2fsck/unix.c:241 misc/badblocks.c:1001 misc/tune2fs.c:3324 misc/util.c:135
 #: resize/main.c:359
 #, c-format
 msgid "while determining whether %s is mounted."
@@ -3312,7 +3419,7 @@ msgid "The -t option is not supported on this version of e2fsck.\n"
 msgstr ""
 
 #: e2fsck/unix.c:947 e2fsck/unix.c:1025 misc/e2initrd_helper.c:331
-#: misc/tune2fs.c:1783 misc/tune2fs.c:2083 misc/tune2fs.c:2101
+#: misc/tune2fs.c:1914 misc/tune2fs.c:2214 misc/tune2fs.c:2232
 #, c-format
 msgid "Unable to resolve '%s'"
 msgstr ""
@@ -3389,8 +3496,8 @@ msgid "while reading MMP block"
 msgstr ""
 
 #: e2fsck/unix.c:1322 e2fsck/unix.c:1374 misc/e2undo.c:240 misc/e2undo.c:285
-#: misc/mke2fs.c:2760 misc/mke2fs.c:2811 misc/tune2fs.c:2808
-#: misc/tune2fs.c:2853 resize/main.c:188 resize/main.c:233
+#: misc/mke2fs.c:2802 misc/mke2fs.c:2853 misc/tune2fs.c:2954
+#: misc/tune2fs.c:2999 resize/main.c:188 resize/main.c:233
 #, c-format
 msgid ""
 "Overwriting existing filesystem; this can be undone using the command:\n"
@@ -3398,13 +3505,13 @@ msgid ""
 "\n"
 msgstr ""
 
-#: e2fsck/unix.c:1363 misc/e2undo.c:274 misc/mke2fs.c:2800 misc/tune2fs.c:2842
+#: e2fsck/unix.c:1363 misc/e2undo.c:274 misc/mke2fs.c:2842 misc/tune2fs.c:2988
 #: resize/main.c:222
 #, c-format
 msgid "while trying to delete %s"
 msgstr ""
 
-#: e2fsck/unix.c:1389 misc/mke2fs.c:2826 resize/main.c:243
+#: e2fsck/unix.c:1389 misc/mke2fs.c:2868 resize/main.c:243
 msgid "while trying to setup undo file\n"
 msgstr ""
 
@@ -3550,7 +3657,7 @@ msgstr ""
 msgid "Creating journal (%d blocks): "
 msgstr ""
 
-#: e2fsck/unix.c:1952
+#: e2fsck/unix.c:1952 e2fsck/unix.c:2024
 msgid " Done.\n"
 msgstr ""
 
@@ -3569,39 +3676,44 @@ msgstr ""
 msgid "%s: e2fsck canceled.\n"
 msgstr ""
 
-#: e2fsck/unix.c:1989
+#: e2fsck/unix.c:2012
+#, c-format
+msgid "Creating orphan file (%d blocks): "
+msgstr ""
+
+#: e2fsck/unix.c:2056
 msgid "Restarting e2fsck from the beginning...\n"
 msgstr ""
 
-#: e2fsck/unix.c:1993
+#: e2fsck/unix.c:2060
 msgid "while resetting context"
 msgstr ""
 
-#: e2fsck/unix.c:2052
+#: e2fsck/unix.c:2120
 #, c-format
 msgid ""
 "\n"
 "%s: ***** FILE SYSTEM ERRORS CORRECTED *****\n"
 msgstr ""
 
-#: e2fsck/unix.c:2054
+#: e2fsck/unix.c:2122
 #, c-format
 msgid "%s: File system was modified.\n"
 msgstr ""
 
-#: e2fsck/unix.c:2058 e2fsck/util.c:67
+#: e2fsck/unix.c:2126 e2fsck/util.c:67
 #, c-format
 msgid ""
 "\n"
 "%s: ***** FILE SYSTEM WAS MODIFIED *****\n"
 msgstr ""
 
-#: e2fsck/unix.c:2063
+#: e2fsck/unix.c:2131
 #, c-format
 msgid "%s: ***** REBOOT SYSTEM *****\n"
 msgstr ""
 
-#: e2fsck/unix.c:2073 e2fsck/util.c:73
+#: e2fsck/unix.c:2141 e2fsck/util.c:73
 #, c-format
 msgid ""
 "\n"
@@ -4063,7 +4175,7 @@ msgstr ""
 
 #: misc/create_inode.c:180 misc/create_inode.c:207 misc/create_inode.c:1064
 #: misc/e2undo.c:186 misc/e2undo.c:483 misc/e2undo.c:489 misc/e2undo.c:495
-#: misc/mke2fs.c:361
+#: misc/mke2fs.c:363
 msgid "while allocating memory"
 msgstr ""
 
@@ -4301,7 +4413,7 @@ msgstr ""
 msgid "Bad blocks: %u"
 msgstr ""
 
-#: misc/dumpe2fs.c:375 misc/tune2fs.c:379
+#: misc/dumpe2fs.c:375 misc/tune2fs.c:409
 msgid "while reading journal inode"
 msgstr ""
 
@@ -4317,7 +4429,7 @@ msgstr ""
 msgid "Journal superblock magic number invalid!\n"
 msgstr ""
 
-#: misc/dumpe2fs.c:414 misc/tune2fs.c:222
+#: misc/dumpe2fs.c:414 misc/tune2fs.c:252
 msgid "while reading journal superblock"
 msgstr ""
 
@@ -4334,7 +4446,7 @@ msgstr ""
 msgid "reading MMP block %llu from '%s'\n"
 msgstr ""
 
-#: misc/dumpe2fs.c:520 misc/mke2fs.c:811 misc/tune2fs.c:2123
+#: misc/dumpe2fs.c:520 misc/mke2fs.c:813 misc/tune2fs.c:2254
 msgid "Couldn't allocate memory to parse options!\n"
 msgstr ""
 
@@ -4362,12 +4474,12 @@ msgid ""
 "\tblocksize=<blocksize>\n"
 msgstr ""
 
-#: misc/dumpe2fs.c:663 misc/mke2fs.c:1913
+#: misc/dumpe2fs.c:663 misc/mke2fs.c:1939
 #, c-format
 msgid "\tUsing %s\n"
 msgstr ""
 
-#: misc/dumpe2fs.c:710 misc/e2image.c:1642 misc/tune2fs.c:3011
+#: misc/dumpe2fs.c:710 misc/e2image.c:1643 misc/tune2fs.c:3249
 #: resize/main.c:424
 msgid "Couldn't find valid filesystem superblock.\n"
 msgstr ""
@@ -4539,52 +4651,52 @@ msgstr ""
 msgid "while getting next inode"
 msgstr ""
 
-#: misc/e2image.c:1379 misc/e2image.c:1393
+#: misc/e2image.c:1380 misc/e2image.c:1394
 #, c-format
 msgid "while iterating over inode %u"
 msgstr ""
 
-#: misc/e2image.c:1425
+#: misc/e2image.c:1426
 msgid "Raw and qcow2 images cannot be installed"
 msgstr ""
 
-#: misc/e2image.c:1447
+#: misc/e2image.c:1448
 msgid "error reading bitmaps"
 msgstr ""
 
-#: misc/e2image.c:1459
+#: misc/e2image.c:1460
 msgid "while opening device file"
 msgstr ""
 
-#: misc/e2image.c:1470
+#: misc/e2image.c:1471
 msgid "while restoring the image table"
 msgstr ""
 
-#: misc/e2image.c:1578
+#: misc/e2image.c:1579
 msgid "-a option can only be used with raw or QCOW2 images."
 msgstr ""
 
-#: misc/e2image.c:1583
+#: misc/e2image.c:1584
 msgid "-b option can only be used with raw or QCOW2 images."
 msgstr ""
 
-#: misc/e2image.c:1589
+#: misc/e2image.c:1590
 msgid "Offsets are only allowed with raw images."
 msgstr ""
 
-#: misc/e2image.c:1594
+#: misc/e2image.c:1595
 msgid "Move mode is only allowed with raw images."
 msgstr ""
 
-#: misc/e2image.c:1599
+#: misc/e2image.c:1600
 msgid "Move mode requires all data mode."
 msgstr ""
 
-#: misc/e2image.c:1609
+#: misc/e2image.c:1610
 msgid "checking if mounted"
 msgstr ""
 
-#: misc/e2image.c:1616
+#: misc/e2image.c:1617
 msgid ""
 "\n"
 "Running e2image on a R/W mounted filesystem can result in an\n"
@@ -4592,51 +4704,51 @@ msgid ""
 "Use -f option if you really want to do that.\n"
 msgstr ""
 
-#: misc/e2image.c:1670
+#: misc/e2image.c:1671
 msgid "QCOW2 image can not be written to the stdout!\n"
 msgstr ""
 
-#: misc/e2image.c:1676
+#: misc/e2image.c:1677
 msgid "Can not stat output\n"
 msgstr ""
 
-#: misc/e2image.c:1686
+#: misc/e2image.c:1687
 #, c-format
 msgid "Image (%s) is compressed\n"
 msgstr ""
 
-#: misc/e2image.c:1689
+#: misc/e2image.c:1690
 #, c-format
 msgid "Image (%s) is encrypted\n"
 msgstr ""
 
-#: misc/e2image.c:1692
+#: misc/e2image.c:1693
 #, c-format
 msgid "Image (%s) is corrupted\n"
 msgstr ""
 
-#: misc/e2image.c:1696
+#: misc/e2image.c:1697
 #, c-format
 msgid "while trying to convert qcow2 image (%s) into raw image (%s)"
 msgstr ""
 
-#: misc/e2image.c:1706
+#: misc/e2image.c:1707
 msgid "The -c option only supported in raw mode\n"
 msgstr ""
 
-#: misc/e2image.c:1711
+#: misc/e2image.c:1712
 msgid "The -c option not supported when writing to stdout\n"
 msgstr ""
 
-#: misc/e2image.c:1718
+#: misc/e2image.c:1719
 msgid "while allocating check_buf"
 msgstr ""
 
-#: misc/e2image.c:1724
+#: misc/e2image.c:1725
 msgid "The -p option only supported in raw mode\n"
 msgstr ""
 
-#: misc/e2image.c:1734
+#: misc/e2image.c:1735
 #, c-format
 msgid "%d blocks already contained the data to be copied\n"
 msgstr ""
@@ -4666,7 +4778,7 @@ msgstr ""
 msgid "e2label: not an ext2 filesystem\n"
 msgstr ""
 
-#: misc/e2label.c:97 misc/tune2fs.c:3220
+#: misc/e2label.c:97 misc/tune2fs.c:3136 misc/tune2fs.c:3459
 #, c-format
 msgid "Warning: label too long, truncating.\n"
 msgstr ""
@@ -4681,7 +4793,7 @@ msgstr ""
 msgid "e2label: error writing superblock\n"
 msgstr ""
 
-#: misc/e2label.c:117 misc/tune2fs.c:1775
+#: misc/e2label.c:117 misc/tune2fs.c:1906
 #, c-format
 msgid "Usage: e2label device [newlabel]\n"
 msgstr ""
@@ -5001,7 +5113,7 @@ msgstr ""
 msgid "%s: %s.\n"
 msgstr ""
 
-#: misc/fuse2fs.c:3789 misc/fuse2fs.c:3808 misc/tune2fs.c:3111
+#: misc/fuse2fs.c:3789 misc/fuse2fs.c:3808 misc/tune2fs.c:3350
 #, c-format
 msgid "Please run e2fsck -fy %s.\n"
 msgstr ""
@@ -5064,7 +5176,7 @@ msgstr ""
 msgid "Couldn't allocate path variable in lsattr_dir_proc\n"
 msgstr ""
 
-#: misc/mke2fs.c:131
+#: misc/mke2fs.c:133
 #, c-format
 msgid ""
 "Usage: %s [-c|-l filename] [-b block-size] [-C cluster-size]\n"
@@ -5078,35 +5190,35 @@ msgid ""
 "\t[-jnqvDFSV] device [blocks-count]\n"
 msgstr ""
 
-#: misc/mke2fs.c:263
+#: misc/mke2fs.c:265
 #, c-format
 msgid "Running command: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:267
+#: misc/mke2fs.c:269
 #, c-format
 msgid "while trying to run '%s'"
 msgstr ""
 
-#: misc/mke2fs.c:274
+#: misc/mke2fs.c:276
 msgid "while processing list of bad blocks from program"
 msgstr ""
 
-#: misc/mke2fs.c:301
+#: misc/mke2fs.c:303
 #, c-format
 msgid "Block %d in primary superblock/group descriptor area bad.\n"
 msgstr ""
 
-#: misc/mke2fs.c:303
+#: misc/mke2fs.c:305
 #, c-format
 msgid "Blocks %u through %u must be good in order to build a filesystem.\n"
 msgstr ""
 
-#: misc/mke2fs.c:306
+#: misc/mke2fs.c:308
 msgid "Aborting....\n"
 msgstr ""
 
-#: misc/mke2fs.c:326
+#: misc/mke2fs.c:328
 #, c-format
 msgid ""
 "Warning: the backup superblock/group descriptors at block %u contain\n"
@@ -5114,263 +5226,268 @@ msgid ""
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:345 misc/mke2fs.c:3320
+#: misc/mke2fs.c:347 misc/mke2fs.c:3374
 msgid "while marking bad blocks as used"
 msgstr ""
 
-#: misc/mke2fs.c:370
+#: misc/mke2fs.c:372
 msgid "while writing reserved inodes"
 msgstr ""
 
-#: misc/mke2fs.c:422
+#: misc/mke2fs.c:424
 msgid "Writing inode tables: "
 msgstr ""
 
-#: misc/mke2fs.c:444
+#: misc/mke2fs.c:446
 #, c-format
 msgid ""
 "\n"
 "Could not write %d blocks in inode table starting at %llu: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:459 misc/mke2fs.c:2872 misc/mke2fs.c:3280
+#: misc/mke2fs.c:461 misc/mke2fs.c:2914 misc/mke2fs.c:3334
 msgid "done                            \n"
 msgstr ""
 
-#: misc/mke2fs.c:474
+#: misc/mke2fs.c:476
 msgid "while creating root dir"
 msgstr ""
 
-#: misc/mke2fs.c:481
+#: misc/mke2fs.c:483
 msgid "while reading root inode"
 msgstr ""
 
-#: misc/mke2fs.c:493
+#: misc/mke2fs.c:495
 msgid "while setting root inode ownership"
 msgstr ""
 
-#: misc/mke2fs.c:511
+#: misc/mke2fs.c:513
 msgid "while creating /lost+found"
 msgstr ""
 
-#: misc/mke2fs.c:518
+#: misc/mke2fs.c:520
 msgid "while looking up /lost+found"
 msgstr ""
 
-#: misc/mke2fs.c:531
+#: misc/mke2fs.c:533
 msgid "while expanding /lost+found"
 msgstr ""
 
-#: misc/mke2fs.c:546
+#: misc/mke2fs.c:548
 msgid "while setting bad block inode"
 msgstr ""
 
-#: misc/mke2fs.c:573
+#: misc/mke2fs.c:575
 #, c-format
 msgid "Out of memory erasing sectors %d-%d\n"
 msgstr ""
 
-#: misc/mke2fs.c:583
+#: misc/mke2fs.c:585
 #, c-format
 msgid "Warning: could not read block 0: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:601
+#: misc/mke2fs.c:603
 #, c-format
 msgid "Warning: could not erase sector %d: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:617
+#: misc/mke2fs.c:619
 msgid "while splitting the journal size"
 msgstr ""
 
-#: misc/mke2fs.c:624
+#: misc/mke2fs.c:626
 msgid "while initializing journal superblock"
 msgstr ""
 
-#: misc/mke2fs.c:632
+#: misc/mke2fs.c:634
 msgid "Zeroing journal device: "
 msgstr ""
 
-#: misc/mke2fs.c:644
+#: misc/mke2fs.c:646
 #, c-format
 msgid "while zeroing journal device (block %llu, count %d)"
 msgstr ""
 
-#: misc/mke2fs.c:662
+#: misc/mke2fs.c:664
 msgid "while writing journal superblock"
 msgstr ""
 
-#: misc/mke2fs.c:676
+#: misc/mke2fs.c:678
 #, c-format
 msgid "Creating filesystem with %llu %dk blocks and %u inodes\n"
 msgstr ""
 
-#: misc/mke2fs.c:684
+#: misc/mke2fs.c:686
 #, c-format
 msgid ""
 "warning: %llu blocks unused.\n"
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:688
+#: misc/mke2fs.c:690
 #, c-format
 msgid "Filesystem label=%.*s\n"
 msgstr ""
 
-#: misc/mke2fs.c:692
+#: misc/mke2fs.c:694
 #, c-format
 msgid "OS type: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:694
+#: misc/mke2fs.c:696
 #, c-format
 msgid "Block size=%u (log=%u)\n"
 msgstr ""
 
-#: misc/mke2fs.c:697
+#: misc/mke2fs.c:699
 #, c-format
 msgid "Cluster size=%u (log=%u)\n"
 msgstr ""
 
-#: misc/mke2fs.c:701
+#: misc/mke2fs.c:703
 #, c-format
 msgid "Fragment size=%u (log=%u)\n"
 msgstr ""
 
-#: misc/mke2fs.c:703
+#: misc/mke2fs.c:705
 #, c-format
 msgid "Stride=%u blocks, Stripe width=%u blocks\n"
 msgstr ""
 
-#: misc/mke2fs.c:705
+#: misc/mke2fs.c:707
 #, c-format
 msgid "%u inodes, %llu blocks\n"
 msgstr ""
 
-#: misc/mke2fs.c:707
+#: misc/mke2fs.c:709
 #, c-format
 msgid "%llu blocks (%2.2f%%) reserved for the super user\n"
 msgstr ""
 
-#: misc/mke2fs.c:710
+#: misc/mke2fs.c:712
 #, c-format
 msgid "First data block=%u\n"
 msgstr ""
 
-#: misc/mke2fs.c:712
+#: misc/mke2fs.c:714
 #, c-format
 msgid "Root directory owner=%u:%u\n"
 msgstr ""
 
-#: misc/mke2fs.c:714
+#: misc/mke2fs.c:716
 #, c-format
 msgid "Maximum filesystem blocks=%lu\n"
 msgstr ""
 
-#: misc/mke2fs.c:718
+#: misc/mke2fs.c:720
 #, c-format
 msgid "%u block groups\n"
 msgstr ""
 
-#: misc/mke2fs.c:720
+#: misc/mke2fs.c:722
 #, c-format
 msgid "%u block group\n"
 msgstr ""
 
-#: misc/mke2fs.c:722
+#: misc/mke2fs.c:724
 #, c-format
 msgid "%u blocks per group, %u clusters per group\n"
 msgstr ""
 
-#: misc/mke2fs.c:725
+#: misc/mke2fs.c:727
 #, c-format
 msgid "%u blocks per group, %u fragments per group\n"
 msgstr ""
 
-#: misc/mke2fs.c:727
+#: misc/mke2fs.c:729
 #, c-format
 msgid "%u inodes per group\n"
 msgstr ""
 
-#: misc/mke2fs.c:736
+#: misc/mke2fs.c:738
 #, c-format
 msgid "Filesystem UUID: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:737
+#: misc/mke2fs.c:739
 msgid "Superblock backups stored on blocks: "
 msgstr ""
 
-#: misc/mke2fs.c:833
+#: misc/mke2fs.c:835
 #, c-format
 msgid "%s requires '-O 64bit'\n"
 msgstr ""
 
-#: misc/mke2fs.c:839
+#: misc/mke2fs.c:841
 #, c-format
 msgid "'%s' must be before 'resize=%u'\n"
 msgstr ""
 
-#: misc/mke2fs.c:852
+#: misc/mke2fs.c:854
 #, c-format
 msgid "Invalid desc_size: '%s'\n"
 msgstr ""
 
-#: misc/mke2fs.c:866
+#: misc/mke2fs.c:868
 #, c-format
 msgid "Invalid hash seed: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:878
+#: misc/mke2fs.c:880
 #, c-format
 msgid "Invalid offset: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:892 misc/tune2fs.c:2151
+#: misc/mke2fs.c:894 misc/tune2fs.c:2282
 #, c-format
 msgid "Invalid mmp_update_interval: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:909
+#: misc/mke2fs.c:911
 #, c-format
 msgid "Invalid # of backup superblocks: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:931
+#: misc/mke2fs.c:933
 #, c-format
 msgid "Invalid stride parameter: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:946
+#: misc/mke2fs.c:948
 #, c-format
 msgid "Invalid stripe-width parameter: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:969
+#: misc/mke2fs.c:971
 #, c-format
 msgid "Invalid resize parameter: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:976
+#: misc/mke2fs.c:978
 msgid "The resize maximum must be greater than the filesystem size.\n"
 msgstr ""
 
-#: misc/mke2fs.c:1000
+#: misc/mke2fs.c:1002
 msgid "On-line resizing not supported with revision 0 filesystems\n"
 msgstr ""
 
-#: misc/mke2fs.c:1026 misc/mke2fs.c:1035
+#: misc/mke2fs.c:1033 misc/mke2fs.c:1042
 #, c-format
 msgid "Invalid root_owner: '%s'\n"
 msgstr ""
 
-#: misc/mke2fs.c:1080
+#: misc/mke2fs.c:1087
 #, c-format
 msgid "Invalid encoding: %s"
 msgstr ""
 
-#: misc/mke2fs.c:1098
+#: misc/mke2fs.c:1109 misc/tune2fs.c:2417
+#, c-format
+msgid "Invalid size of orphan file %s\n"
+msgstr ""
+
+#: misc/mke2fs.c:1120
 #, c-format
 msgid ""
 "\n"
@@ -5396,10 +5513,11 @@ msgid ""
 "\tencoding=<encoding>\n"
 "\tencoding_flags=<flags>\n"
 "\tquotatype=<quota type(s) to be enabled>\n"
+"\tassume_storage_prezeroed=<0 to disable, 1 to enable>\n"
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:1125
+#: misc/mke2fs.c:1148
 #, c-format
 msgid ""
 "\n"
@@ -5407,52 +5525,52 @@ msgid ""
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:1136 misc/tune2fs.c:2287
+#: misc/mke2fs.c:1159 misc/tune2fs.c:2433
 #, c-format
 msgid "error: Invalid encoding flag: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:1142 misc/tune2fs.c:2296
+#: misc/mke2fs.c:1165 misc/tune2fs.c:2442
 #, c-format
 msgid ""
 "error: An encoding must be explicitly specified when passing encoding-flags\n"
 msgstr ""
 
-#: misc/mke2fs.c:1192
+#: misc/mke2fs.c:1216
 #, c-format
 msgid ""
 "Syntax error in mke2fs config file (%s, line #%d)\n"
 "\t%s\n"
 msgstr ""
 
-#: misc/mke2fs.c:1205 misc/tune2fs.c:1111
+#: misc/mke2fs.c:1229 misc/tune2fs.c:1176
 #, c-format
 msgid "Invalid filesystem option set: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:1217 misc/tune2fs.c:425
+#: misc/mke2fs.c:1241 misc/tune2fs.c:455
 #, c-format
 msgid "Invalid mount option set: %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:1353
+#: misc/mke2fs.c:1377
 #, c-format
 msgid ""
 "\n"
 "Your mke2fs.conf file does not define the %s filesystem type.\n"
 msgstr ""
 
-#: misc/mke2fs.c:1357
+#: misc/mke2fs.c:1381
 msgid ""
 "You probably need to install an updated mke2fs.conf file.\n"
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:1361
+#: misc/mke2fs.c:1385
 msgid "Aborting...\n"
 msgstr ""
 
-#: misc/mke2fs.c:1402
+#: misc/mke2fs.c:1426
 #, c-format
 msgid ""
 "\n"
@@ -5460,164 +5578,164 @@ msgid ""
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:1590
+#: misc/mke2fs.c:1616
 msgid "Couldn't allocate memory for new PATH.\n"
 msgstr ""
 
-#: misc/mke2fs.c:1630
+#: misc/mke2fs.c:1656
 #, c-format
 msgid "Couldn't init profile successfully (error: %ld).\n"
 msgstr ""
 
-#: misc/mke2fs.c:1663
+#: misc/mke2fs.c:1689
 #, c-format
 msgid "invalid block size - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1667
+#: misc/mke2fs.c:1693
 #, c-format
 msgid "Warning: blocksize %d not usable on most systems.\n"
 msgstr ""
 
-#: misc/mke2fs.c:1683
+#: misc/mke2fs.c:1709
 #, c-format
 msgid "invalid cluster size - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1696
+#: misc/mke2fs.c:1722
 msgid "'-R' is deprecated, use '-E' instead"
 msgstr ""
 
-#: misc/mke2fs.c:1710 misc/tune2fs.c:1877
+#: misc/mke2fs.c:1736 misc/tune2fs.c:2008
 #, c-format
 msgid "bad error behavior - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1722
+#: misc/mke2fs.c:1748
 msgid "Illegal number for blocks per group"
 msgstr ""
 
-#: misc/mke2fs.c:1727
+#: misc/mke2fs.c:1753
 msgid "blocks per group must be multiple of 8"
 msgstr ""
 
-#: misc/mke2fs.c:1735
+#: misc/mke2fs.c:1761
 msgid "Illegal number for flex_bg size"
 msgstr ""
 
-#: misc/mke2fs.c:1741
+#: misc/mke2fs.c:1767
 msgid "flex_bg size must be a power of 2"
 msgstr ""
 
-#: misc/mke2fs.c:1746
+#: misc/mke2fs.c:1772
 #, c-format
 msgid "flex_bg size (%lu) must be less than or equal to 2^31"
 msgstr ""
 
-#: misc/mke2fs.c:1756
+#: misc/mke2fs.c:1782
 #, c-format
 msgid "invalid inode ratio %s (min %d/max %d)"
 msgstr ""
 
-#: misc/mke2fs.c:1766
+#: misc/mke2fs.c:1792
 #, c-format
 msgid "invalid inode size - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1781
+#: misc/mke2fs.c:1807
 msgid ""
 "Warning: -K option is deprecated and should not be used anymore. Use '-E "
 "nodiscard' extended option instead!\n"
 msgstr ""
 
-#: misc/mke2fs.c:1792
+#: misc/mke2fs.c:1818
 msgid "in malloc for bad_blocks_filename"
 msgstr ""
 
-#: misc/mke2fs.c:1801
+#: misc/mke2fs.c:1827
 #, c-format
 msgid ""
 "Warning: label too long; will be truncated to '%s'\n"
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:1810
+#: misc/mke2fs.c:1836
 #, c-format
 msgid "invalid reserved blocks percent - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1825
+#: misc/mke2fs.c:1851
 #, c-format
 msgid "bad num inodes - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1838
+#: misc/mke2fs.c:1864
 msgid "while allocating fs_feature string"
 msgstr ""
 
-#: misc/mke2fs.c:1855
+#: misc/mke2fs.c:1881
 #, c-format
 msgid "bad revision level - %s"
 msgstr ""
 
-#: misc/mke2fs.c:1860
+#: misc/mke2fs.c:1886
 #, c-format
 msgid "while trying to create revision %d"
 msgstr ""
 
-#: misc/mke2fs.c:1874
+#: misc/mke2fs.c:1900
 msgid "The -t option may only be used once"
 msgstr ""
 
-#: misc/mke2fs.c:1882
+#: misc/mke2fs.c:1908
 msgid "The -T option may only be used once"
 msgstr ""
 
-#: misc/mke2fs.c:1938 misc/mke2fs.c:3403
+#: misc/mke2fs.c:1964 misc/mke2fs.c:3457
 #, c-format
 msgid "while trying to open journal device %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:1944
+#: misc/mke2fs.c:1970
 #, c-format
 msgid "Journal dev blocksize (%d) smaller than minimum blocksize %d\n"
 msgstr ""
 
-#: misc/mke2fs.c:1950
+#: misc/mke2fs.c:1976
 #, c-format
 msgid "Using journal device's blocksize: %d\n"
 msgstr ""
 
-#: misc/mke2fs.c:1961
+#: misc/mke2fs.c:1987
 #, c-format
 msgid "invalid blocks '%s' on device '%s'"
 msgstr ""
 
-#: misc/mke2fs.c:1981
+#: misc/mke2fs.c:2007
 msgid "filesystem"
 msgstr ""
 
-#: misc/mke2fs.c:1996 lib/support/plausible.c:187
+#: misc/mke2fs.c:2022 lib/support/plausible.c:187
 #, c-format
 msgid "The file %s does not exist and no size was specified.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2008 lib/support/plausible.c:195
+#: misc/mke2fs.c:2034 lib/support/plausible.c:195
 #, c-format
 msgid "Creating regular file %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:2013 resize/main.c:512
+#: misc/mke2fs.c:2039 resize/main.c:512
 msgid "while trying to determine filesystem size"
 msgstr ""
 
-#: misc/mke2fs.c:2019
+#: misc/mke2fs.c:2045
 msgid ""
 "Couldn't determine device size; you must specify\n"
 "the size of the filesystem\n"
 msgstr ""
 
-#: misc/mke2fs.c:2026
+#: misc/mke2fs.c:2052
 msgid ""
 "Device size reported to be zero.  Invalid partition specified, or\n"
 "\tpartition table wasn't reread after running fdisk, due to\n"
@@ -5625,149 +5743,149 @@ msgid ""
 "\tto re-read your partition table.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2043
+#: misc/mke2fs.c:2069
 msgid "Filesystem larger than apparent device size."
 msgstr ""
 
-#: misc/mke2fs.c:2066
+#: misc/mke2fs.c:2092
 msgid "Failed to parse fs types list\n"
 msgstr ""
 
-#: misc/mke2fs.c:2116
+#: misc/mke2fs.c:2158
 msgid "The HURD does not support the filetype feature.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2121
+#: misc/mke2fs.c:2163
 msgid "The HURD does not support the huge_file feature.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2126
+#: misc/mke2fs.c:2168
 msgid "The HURD does not support the metadata_csum feature.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2131
+#: misc/mke2fs.c:2173
 msgid "The HURD does not support the ea_inode feature.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2141
+#: misc/mke2fs.c:2183
 msgid "while trying to determine hardware sector size"
 msgstr ""
 
-#: misc/mke2fs.c:2147
+#: misc/mke2fs.c:2189
 msgid "while trying to determine physical sector size"
 msgstr ""
 
-#: misc/mke2fs.c:2179
+#: misc/mke2fs.c:2221
 msgid "while setting blocksize; too small for device\n"
 msgstr ""
 
-#: misc/mke2fs.c:2184
+#: misc/mke2fs.c:2226
 #, c-format
 msgid ""
 "Warning: specified blocksize %d is less than device physical sectorsize %d\n"
 msgstr ""
 
-#: misc/mke2fs.c:2208
+#: misc/mke2fs.c:2250
 #, c-format
 msgid ""
 "%s: Size of device (0x%llx blocks) %s too big to be expressed\n"
 "\tin 32 bits using a blocksize of %d.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2222
+#: misc/mke2fs.c:2264
 #, c-format
 msgid ""
 "%s: Size of device (0x%llx blocks) %s too big to create\n"
 "\ta filesystem using a blocksize of %d.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2244
+#: misc/mke2fs.c:2286
 msgid "fs_types for mke2fs.conf resolution: "
 msgstr ""
 
-#: misc/mke2fs.c:2251
+#: misc/mke2fs.c:2293
 msgid "Filesystem features not supported with revision 0 filesystems\n"
 msgstr ""
 
-#: misc/mke2fs.c:2259
+#: misc/mke2fs.c:2301
 msgid "Sparse superblocks not supported with revision 0 filesystems\n"
 msgstr ""
 
-#: misc/mke2fs.c:2269
+#: misc/mke2fs.c:2311
 msgid "Journals not supported with revision 0 filesystems\n"
 msgstr ""
 
-#: misc/mke2fs.c:2282
+#: misc/mke2fs.c:2324
 #, c-format
 msgid "invalid reserved blocks percent - %lf"
 msgstr ""
 
-#: misc/mke2fs.c:2299
+#: misc/mke2fs.c:2341
 msgid ""
 "Extents MUST be enabled for a 64-bit filesystem.  Pass -O extents to "
 "rectify.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2319
+#: misc/mke2fs.c:2361
 msgid "The cluster size may not be smaller than the block size.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2325
+#: misc/mke2fs.c:2367
 msgid "specifying a cluster size requires the bigalloc feature"
 msgstr ""
 
-#: misc/mke2fs.c:2345
+#: misc/mke2fs.c:2387
 #, c-format
 msgid "warning: Unable to get device geometry for %s\n"
 msgstr ""
 
-#: misc/mke2fs.c:2357
+#: misc/mke2fs.c:2399
 #, c-format
 msgid "%s alignment is offset by %lu bytes.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2359
+#: misc/mke2fs.c:2401
 #, c-format
 msgid ""
 "This may result in very poor performance, (re)-partitioning suggested.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2365
+#: misc/mke2fs.c:2407
 #, c-format
 msgid ""
 "%s is capable of DAX but current block size %u is different from system page "
 "size %u so filesystem will not support DAX.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2389
+#: misc/mke2fs.c:2431
 #, c-format
 msgid "%d-byte blocks too big for system (max %d)"
 msgstr ""
 
-#: misc/mke2fs.c:2393
+#: misc/mke2fs.c:2435
 #, c-format
 msgid ""
 "Warning: %d-byte blocks too big for system (max %d), forced to continue\n"
 msgstr ""
 
-#: misc/mke2fs.c:2401
+#: misc/mke2fs.c:2443
 #, c-format
 msgid ""
 "Suggestion: Use Linux kernel >= 3.18 for improved stability of the metadata "
 "and journal checksum features.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2447
+#: misc/mke2fs.c:2489
 #, c-format
 msgid "Unknown filename encoding from profile: %s"
 msgstr ""
 
-#: misc/mke2fs.c:2458
+#: misc/mke2fs.c:2500
 #, c-format
 msgid "Unknown encoding flags from profile: %s"
 msgstr ""
 
-#: misc/mke2fs.c:2483
+#: misc/mke2fs.c:2525
 #, c-format
 msgid ""
 "\n"
@@ -5777,66 +5895,66 @@ msgid ""
 "\n"
 msgstr ""
 
-#: misc/mke2fs.c:2498
+#: misc/mke2fs.c:2540
 #, c-format
 msgid "%d byte inodes are too small for project quota"
 msgstr ""
 
-#: misc/mke2fs.c:2520
+#: misc/mke2fs.c:2562
 msgid "Can't support bigalloc feature without extents feature"
 msgstr ""
 
-#: misc/mke2fs.c:2527
+#: misc/mke2fs.c:2569
 msgid ""
 "The resize_inode and meta_bg features are not compatible.\n"
 "They can not be both enabled simultaneously.\n"
 msgstr ""
 
-#: misc/mke2fs.c:2536
+#: misc/mke2fs.c:2578
 msgid ""
 "\n"
 "Warning: bigalloc file systems with a cluster size greater than\n"
 "16 times the block size is considered experimental\n"
 msgstr ""
 
-#: misc/mke2fs.c:2548
+#: misc/mke2fs.c:2590
 msgid "reserved online resize blocks not supported on non-sparse filesystem"
 msgstr ""
 
-#: misc/mke2fs.c:2557
+#: misc/mke2fs.c:2599
 msgid "blocks per group count out of range"
 msgstr ""
 
-#: misc/mke2fs.c:2579
+#: misc/mke2fs.c:2621
 msgid "Flex_bg feature not enabled, so flex_bg size may not be specified"
 msgstr ""
 
-#: misc/mke2fs.c:2591
+#: misc/mke2fs.c:2633
 #, c-format
 msgid "invalid inode size %d (min %d/max %d)"
 msgstr ""
 
-#: misc/mke2fs.c:2606
+#: misc/mke2fs.c:2648
 #, c-format
 msgid "%d byte inodes are too small for inline data; specify larger size"
 msgstr ""
 
-#: misc/mke2fs.c:2621
+#: misc/mke2fs.c:2663
 #, c-format
 msgid "128-byte inodes cannot handle dates beyond 2038 and are deprecated\n"
 msgstr ""
 
-#: misc/mke2fs.c:2632
+#: misc/mke2fs.c:2674
 #, c-format
 msgid "too many inodes (%llu), raise inode ratio?"
 msgstr ""
 
-#: misc/mke2fs.c:2640
+#: misc/mke2fs.c:2682
 #, c-format
 msgid "too many inodes (%llu), specify < 2^32 inodes"
 msgstr ""
 
-#: misc/mke2fs.c:2654
+#: misc/mke2fs.c:2696
 #, c-format
 msgid ""
 "inode_size (%u) * inodes_count (%u) too big for a\n"
@@ -5844,161 +5962,175 @@ msgid ""
 "\tor lower inode count (-N).\n"
 msgstr ""
 
-#: misc/mke2fs.c:2851
+#: misc/mke2fs.c:2893
 msgid "Discarding device blocks: "
 msgstr ""
 
-#: misc/mke2fs.c:2867
+#: misc/mke2fs.c:2909
 msgid "failed - "
 msgstr ""
 
-#: misc/mke2fs.c:2926
+#: misc/mke2fs.c:2968
 msgid "while initializing quota context"
 msgstr ""
 
-#: misc/mke2fs.c:2933
+#: misc/mke2fs.c:2975
 msgid "while writing quota inodes"
 msgstr ""
 
-#: misc/mke2fs.c:2958
+#: misc/mke2fs.c:3000
 #, c-format
 msgid "bad error behavior in profile - %s"
 msgstr ""
 
-#: misc/mke2fs.c:3037
+#: misc/mke2fs.c:3079
 msgid "in malloc for android_sparse_params"
 msgstr ""
 
-#: misc/mke2fs.c:3051
+#: misc/mke2fs.c:3093
 msgid "while setting up superblock"
 msgstr ""
 
-#: misc/mke2fs.c:3067
+#: misc/mke2fs.c:3109
 msgid ""
 "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"
 msgstr ""
 
-#: misc/mke2fs.c:3074
+#: misc/mke2fs.c:3116
 msgid ""
 "64-bit filesystem support is not enabled.  The larger fields afforded by "
 "this feature enable full-strength checksumming.  Pass -O 64bit to rectify.\n"
 msgstr ""
 
-#: misc/mke2fs.c:3082
+#: misc/mke2fs.c:3124
 msgid "The metadata_csum_seed feature requires the metadata_csum feature.\n"
 msgstr ""
 
-#: misc/mke2fs.c:3106
+#: misc/mke2fs.c:3145
+msgid ""
+"Assuming the storage device is prezeroed - skipping inode table and journal "
+"wipe\n"
+msgstr ""
+
+#: misc/mke2fs.c:3160
 msgid "Discard succeeded and will return 0s - skipping inode table wipe\n"
 msgstr ""
 
-#: misc/mke2fs.c:3205
+#: misc/mke2fs.c:3259
 #, c-format
 msgid "unknown os - %s"
 msgstr ""
 
-#: misc/mke2fs.c:3268
+#: misc/mke2fs.c:3322
 msgid "Allocating group tables: "
 msgstr ""
 
-#: misc/mke2fs.c:3276
+#: misc/mke2fs.c:3330
 msgid "while trying to allocate filesystem tables"
 msgstr ""
 
-#: misc/mke2fs.c:3291
+#: misc/mke2fs.c:3345
 msgid "while unmarking bad blocks"
 msgstr ""
 
-#: misc/mke2fs.c:3302
+#: misc/mke2fs.c:3356
 msgid ""
 "\n"
 "\twhile converting subcluster bitmap"
 msgstr ""
 
-#: misc/mke2fs.c:3311
+#: misc/mke2fs.c:3365
 msgid "while calculating overhead"
 msgstr ""
 
-#: misc/mke2fs.c:3330
+#: misc/mke2fs.c:3384
 #, c-format
 msgid "%s may be further corrupted by superblock rewrite\n"
 msgstr ""
 
-#: misc/mke2fs.c:3371
+#: misc/mke2fs.c:3425
 #, c-format
 msgid "while zeroing block %llu at end of filesystem"
 msgstr ""
 
-#: misc/mke2fs.c:3384
+#: misc/mke2fs.c:3438
 msgid "while reserving blocks for online resize"
 msgstr ""
 
-#: misc/mke2fs.c:3396 misc/tune2fs.c:1573
+#: misc/mke2fs.c:3450 misc/tune2fs.c:1704
 msgid "journal"
 msgstr ""
 
-#: misc/mke2fs.c:3408
+#: misc/mke2fs.c:3462
 #, c-format
 msgid "Adding journal to device %s: "
 msgstr ""
 
-#: misc/mke2fs.c:3415
+#: misc/mke2fs.c:3469
 #, c-format
 msgid ""
 "\n"
 "\twhile trying to add journal to device %s"
 msgstr ""
 
-#: misc/mke2fs.c:3420 misc/mke2fs.c:3450 misc/mke2fs.c:3492
-#: misc/mk_hugefiles.c:486 misc/tune2fs.c:1602 misc/tune2fs.c:1624
+#: misc/mke2fs.c:3474 misc/mke2fs.c:3507 misc/mke2fs.c:3566
+#: misc/mk_hugefiles.c:486 misc/tune2fs.c:1733 misc/tune2fs.c:1755
 msgid "done\n"
 msgstr ""
 
-#: misc/mke2fs.c:3427
+#: misc/mke2fs.c:3481
 msgid "Skipping journal creation in super-only mode\n"
 msgstr ""
 
-#: misc/mke2fs.c:3437
+#: misc/mke2fs.c:3494
 #, c-format
 msgid "Creating journal (%u blocks): "
 msgstr ""
 
-#: misc/mke2fs.c:3446
+#: misc/mke2fs.c:3503
 msgid ""
 "\n"
 "\twhile trying to create journal"
 msgstr ""
 
-#: misc/mke2fs.c:3458 misc/tune2fs.c:1176
+#: misc/mke2fs.c:3515 misc/tune2fs.c:1291
 msgid ""
 "\n"
 "Error while enabling multiple mount protection feature."
 msgstr ""
 
-#: misc/mke2fs.c:3463
+#: misc/mke2fs.c:3520
 #, c-format
 msgid "Multiple mount protection is enabled with update interval %d seconds.\n"
 msgstr ""
 
-#: misc/mke2fs.c:3483
+#: misc/mke2fs.c:3535
+msgid "cannot set orphan_file feature without a journal."
+msgstr ""
+
+#: misc/mke2fs.c:3546 misc/tune2fs.c:3516
+msgid "while creating orphan file"
+msgstr ""
+
+#: misc/mke2fs.c:3557
 msgid "Copying files into the device: "
 msgstr ""
 
-#: misc/mke2fs.c:3489
+#: misc/mke2fs.c:3563
 msgid "while populating file system"
 msgstr ""
 
-#: misc/mke2fs.c:3496
+#: misc/mke2fs.c:3570
 msgid "Writing superblocks and filesystem accounting information: "
 msgstr ""
 
-#: misc/mke2fs.c:3503 misc/tune2fs.c:3466
+#: misc/mke2fs.c:3577 misc/tune2fs.c:3764
 msgid "while writing out and closing file system"
 msgstr ""
 
-#: misc/mke2fs.c:3506
+#: misc/mke2fs.c:3580
 msgid ""
 "done\n"
 "\n"
@@ -6068,21 +6200,21 @@ msgstr ""
 msgid "%s: h=%3d s=%3d c=%4d   start=%8d size=%8lu end=%8d\n"
 msgstr ""
 
-#: misc/tune2fs.c:121
+#: misc/tune2fs.c:148
 msgid ""
 "\n"
 "This operation requires a freshly checked filesystem.\n"
 msgstr ""
 
-#: misc/tune2fs.c:123
+#: misc/tune2fs.c:150
 msgid "Please run e2fsck -f on the filesystem.\n"
 msgstr ""
 
-#: misc/tune2fs.c:125
+#: misc/tune2fs.c:152
 msgid "Please run e2fsck -fD on the filesystem.\n"
 msgstr ""
 
-#: misc/tune2fs.c:138
+#: misc/tune2fs.c:165
 #, c-format
 msgid ""
 "Usage: %s [-c max_mounts_count] [-e errors_behavior] [-f] [-g group]\n"
@@ -6095,304 +6227,340 @@ msgid ""
 "\t[-I new_inode_size] [-z undo_file] device\n"
 msgstr ""
 
-#: misc/tune2fs.c:229
+#: misc/tune2fs.c:259
 msgid "Journal superblock not found!\n"
 msgstr ""
 
-#: misc/tune2fs.c:287
+#: misc/tune2fs.c:317
 msgid "while trying to open external journal"
 msgstr ""
 
-#: misc/tune2fs.c:293 misc/tune2fs.c:2899
+#: misc/tune2fs.c:323 misc/tune2fs.c:3045
 #, c-format
 msgid "%s is not a journal device.\n"
 msgstr ""
 
-#: misc/tune2fs.c:302 misc/tune2fs.c:2908
+#: misc/tune2fs.c:332 misc/tune2fs.c:3054
 #, c-format
 msgid ""
 "Journal superblock is corrupted, nr_users\n"
 "is too high (%d).\n"
 msgstr ""
 
-#: misc/tune2fs.c:309 misc/tune2fs.c:2915
+#: misc/tune2fs.c:339 misc/tune2fs.c:3061
 msgid "Filesystem's UUID not found on journal device.\n"
 msgstr ""
 
-#: misc/tune2fs.c:333
+#: misc/tune2fs.c:363
 msgid ""
 "Cannot locate journal device. It was NOT removed\n"
 "Use -f option to remove missing journal device.\n"
 msgstr ""
 
-#: misc/tune2fs.c:342
+#: misc/tune2fs.c:372
 msgid "Journal removed\n"
 msgstr ""
 
-#: misc/tune2fs.c:386
+#: misc/tune2fs.c:416
 msgid "while reading bitmaps"
 msgstr ""
 
-#: misc/tune2fs.c:394
+#: misc/tune2fs.c:424
 msgid "while clearing journal inode"
 msgstr ""
 
-#: misc/tune2fs.c:407
+#: misc/tune2fs.c:437
 msgid "while writing journal inode"
 msgstr ""
 
-#: misc/tune2fs.c:443 misc/tune2fs.c:468 misc/tune2fs.c:481
+#: misc/tune2fs.c:473 misc/tune2fs.c:498 misc/tune2fs.c:511
 msgid "(and reboot afterwards!)\n"
 msgstr ""
 
-#: misc/tune2fs.c:496
+#: misc/tune2fs.c:526
 #, c-format
 msgid "After running e2fsck, please run `resize2fs %s %s"
 msgstr ""
 
-#: misc/tune2fs.c:499
+#: misc/tune2fs.c:529
 #, c-format
 msgid "Please run `resize2fs %s %s"
 msgstr ""
 
-#: misc/tune2fs.c:503
+#: misc/tune2fs.c:533
 #, c-format
 msgid " -z \"%s\""
 msgstr ""
 
-#: misc/tune2fs.c:505
+#: misc/tune2fs.c:535
 #, c-format
 msgid "' to enable 64-bit mode.\n"
 msgstr ""
 
-#: misc/tune2fs.c:507
+#: misc/tune2fs.c:537
 #, c-format
 msgid "' to disable 64-bit mode.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1078
+#: misc/tune2fs.c:1143
 msgid ""
 "WARNING: Could not confirm kernel support for metadata_csum_seed.\n"
 "  This requires Linux >= v4.4.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1114
+#: misc/tune2fs.c:1179
 #, c-format
 msgid "Clearing filesystem feature '%s' not supported.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1120
+#: misc/tune2fs.c:1185
 #, c-format
 msgid "Setting filesystem feature '%s' not supported.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1129
+#: misc/tune2fs.c:1194
 msgid ""
 "The has_journal feature may only be cleared when the filesystem is\n"
 "unmounted or mounted read-only.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1137
+#: misc/tune2fs.c:1202
 msgid ""
 "The needs_recovery flag is set.  Please run e2fsck before clearing\n"
 "the has_journal flag.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1155
+#: misc/tune2fs.c:1221
+msgid ""
+"The orphan_file feature may only be cleared when the filesystem is "
+"unmounted.\n"
+msgstr ""
+
+#: misc/tune2fs.c:1226
+msgid ""
+"The orphan_present feature is set. Please run e2fsck before clearing "
+"orphan_file feature.\n"
+msgstr ""
+
+#: misc/tune2fs.c:1235 misc/tune2fs.c:3509
+msgid "while loading bitmaps"
+msgstr ""
+
+#: misc/tune2fs.c:1241
+msgid ""
+"\n"
+"\twhile trying to delete orphan file\n"
+msgstr ""
+
+#: misc/tune2fs.c:1254
+msgid "orphan_file feature can be set only for filesystems with journal.\n"
+msgstr ""
+
+#: misc/tune2fs.c:1270
 msgid ""
 "Setting filesystem feature 'sparse_super' not supported\n"
 "for filesystems with the meta_bg feature enabled.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1168
+#: misc/tune2fs.c:1283
 msgid ""
 "The multiple mount protection feature can't\n"
 "be set if the filesystem is mounted or\n"
 "read-only.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1186
+#: misc/tune2fs.c:1301
 #, c-format
 msgid "Multiple mount protection has been enabled with update interval %ds.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1195
+#: misc/tune2fs.c:1310
 msgid ""
 "The multiple mount protection feature cannot\n"
 "be disabled if the filesystem is readonly.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1203
+#: misc/tune2fs.c:1318
 msgid "Error while reading bitmaps\n"
 msgstr ""
 
-#: misc/tune2fs.c:1212
+#: misc/tune2fs.c:1327
 #, c-format
 msgid "Magic number in MMP block does not match. expected: %x, actual: %x\n"
 msgstr ""
 
-#: misc/tune2fs.c:1217
+#: misc/tune2fs.c:1332
 msgid "while reading MMP block."
 msgstr ""
 
-#: misc/tune2fs.c:1250
+#: misc/tune2fs.c:1365
 msgid ""
 "Disabling directory index on filesystem with checksums could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:1254
+#: misc/tune2fs.c:1369
 msgid "Cannot disable dir_index on a mounted filesystem!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1267
+#: misc/tune2fs.c:1382
 msgid ""
 "Clearing the flex_bg flag would cause the the filesystem to be\n"
 "inconsistent.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1278
+#: misc/tune2fs.c:1393
 msgid ""
 "The huge_file feature may only be cleared when the filesystem is\n"
 "unmounted or mounted read-only.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1289
+#: misc/tune2fs.c:1404
 msgid "Enabling checksums could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:1292
+#: misc/tune2fs.c:1407
 msgid "Cannot enable metadata_csum on a mounted filesystem!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1298
+#: misc/tune2fs.c:1413
 msgid ""
 "Extents are not enabled.  The file extent tree can be checksummed, whereas "
 "block maps cannot.  Not enabling extents reduces the coverage of metadata "
 "checksumming.  Re-run with -O extent to rectify.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1305
+#: misc/tune2fs.c:1420
 msgid ""
 "64-bit filesystem support is not enabled.  The larger fields afforded by "
 "this feature enable full-strength checksumming.  Run resize2fs -b to "
 "rectify.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1331
+#: misc/tune2fs.c:1446
 msgid "Disabling checksums could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:1334
+#: misc/tune2fs.c:1449
 msgid "Cannot disable metadata_csum on a mounted filesystem!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1375
+#: misc/tune2fs.c:1490
 msgid "Cannot enable uninit_bg on a mounted filesystem!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1390
+#: misc/tune2fs.c:1505
 msgid "Cannot disable uninit_bg on a mounted filesystem!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1409
+#: misc/tune2fs.c:1524
 #, c-format
 msgid "Cannot enable 64-bit mode while mounted!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1419
+#: misc/tune2fs.c:1534
 #, c-format
 msgid "Cannot disable 64-bit mode while mounted!\n"
 msgstr ""
 
-#: misc/tune2fs.c:1449
+#: misc/tune2fs.c:1564
 #, c-format
 msgid "Cannot enable project feature; inode size too small.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1470
+#: misc/tune2fs.c:1585
 msgid ""
 "\n"
 "Warning: '^quota' option overrides '-Q'arguments.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1487 misc/tune2fs.c:2249
+#: misc/tune2fs.c:1602 misc/tune2fs.c:2380
 msgid ""
 "The casefold feature may only be enabled when the filesystem is unmounted.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1499
+#: misc/tune2fs.c:1613
+msgid ""
+"The casefold feature may only be disabled when the filesystem is unmounted.\n"
+msgstr ""
+
+#: misc/tune2fs.c:1618
+msgid ""
+"The casefold feature can't be cleared when there are inodes with +F flag.\n"
+msgstr ""
+
+#: misc/tune2fs.c:1630
 msgid ""
 "Setting feature 'metadata_csum_seed' is only supported\n"
 "on filesystems with the metadata_csum feature enabled.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1517
+#: misc/tune2fs.c:1648
 msgid ""
 "UUID has changed since enabling metadata_csum.  Filesystem must be "
 "unmounted \n"
 "to safely rewrite all metadata to match the new UUID.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1523
+#: misc/tune2fs.c:1654
 msgid "Recalculating checksums could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:1566
+#: misc/tune2fs.c:1697
 msgid "The filesystem already has a journal.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1586
+#: misc/tune2fs.c:1717
 #, c-format
 msgid ""
 "\n"
 "\twhile trying to open journal on %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:1590
+#: misc/tune2fs.c:1721
 #, c-format
 msgid "Creating journal on device %s: "
 msgstr ""
 
-#: misc/tune2fs.c:1598
+#: misc/tune2fs.c:1729
 #, c-format
 msgid "while adding filesystem to journal on %s"
 msgstr ""
 
-#: misc/tune2fs.c:1604
+#: misc/tune2fs.c:1735
 msgid "Creating journal inode: "
 msgstr ""
 
-#: misc/tune2fs.c:1618
+#: misc/tune2fs.c:1749
 msgid ""
 "\n"
 "\twhile trying to create journal file"
 msgstr ""
 
-#: misc/tune2fs.c:1660
+#: misc/tune2fs.c:1791
 #, c-format
 msgid "Cannot enable project quota; inode size too small.\n"
 msgstr ""
 
-#: misc/tune2fs.c:1673
+#: misc/tune2fs.c:1804
 msgid "while initializing quota context in support library"
 msgstr ""
 
-#: misc/tune2fs.c:1689
+#: misc/tune2fs.c:1820
 #, c-format
 msgid "while updating quota limits (%d)"
 msgstr ""
 
-#: misc/tune2fs.c:1699
+#: misc/tune2fs.c:1830
 #, c-format
 msgid "while writing quota file (%d)"
 msgstr ""
 
-#: misc/tune2fs.c:1717
+#: misc/tune2fs.c:1848
 #, c-format
 msgid "while removing quota file (%d)"
 msgstr ""
 
-#: misc/tune2fs.c:1760
+#: misc/tune2fs.c:1891
 msgid ""
 "\n"
 "Bad quota options specified.\n"
@@ -6406,65 +6574,65 @@ msgid ""
 "\n"
 msgstr ""
 
-#: misc/tune2fs.c:1818
+#: misc/tune2fs.c:1949
 #, c-format
 msgid "Couldn't parse date/time specifier: %s"
 msgstr ""
 
-#: misc/tune2fs.c:1850 misc/tune2fs.c:1861
+#: misc/tune2fs.c:1981 misc/tune2fs.c:1992
 #, c-format
 msgid "bad mounts count - %s"
 msgstr ""
 
-#: misc/tune2fs.c:1904
+#: misc/tune2fs.c:2035
 #, c-format
 msgid "bad gid/group name - %s"
 msgstr ""
 
-#: misc/tune2fs.c:1937
+#: misc/tune2fs.c:2068
 #, c-format
 msgid "bad interval - %s"
 msgstr ""
 
-#: misc/tune2fs.c:1966
+#: misc/tune2fs.c:2097
 #, c-format
 msgid "bad reserved block ratio - %s"
 msgstr ""
 
-#: misc/tune2fs.c:1981
+#: misc/tune2fs.c:2112
 msgid "-o may only be specified once"
 msgstr ""
 
-#: misc/tune2fs.c:1990
+#: misc/tune2fs.c:2121
 msgid "-O may only be specified once"
 msgstr ""
 
-#: misc/tune2fs.c:2007
+#: misc/tune2fs.c:2138
 #, c-format
 msgid "bad reserved blocks count - %s"
 msgstr ""
 
-#: misc/tune2fs.c:2036
+#: misc/tune2fs.c:2167
 #, c-format
 msgid "bad uid/user name - %s"
 msgstr ""
 
-#: misc/tune2fs.c:2053
+#: misc/tune2fs.c:2184
 #, c-format
 msgid "bad inode size - %s"
 msgstr ""
 
-#: misc/tune2fs.c:2060
+#: misc/tune2fs.c:2191
 #, c-format
 msgid "Inode size must be a power of two- %s"
 msgstr ""
 
-#: misc/tune2fs.c:2160
+#: misc/tune2fs.c:2291
 #, c-format
 msgid "mmp_update_interval too big: %lu\n"
 msgstr ""
 
-#: misc/tune2fs.c:2165
+#: misc/tune2fs.c:2296
 #, c-format
 msgid "Setting multiple mount protection update interval to %lu second\n"
 msgid_plural ""
@@ -6472,52 +6640,52 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: misc/tune2fs.c:2174
+#: misc/tune2fs.c:2305
 #, c-format
 msgid "Setting filesystem error flag to force fsck.\n"
 msgstr ""
 
-#: misc/tune2fs.c:2192
+#: misc/tune2fs.c:2323
 #, c-format
 msgid "Invalid RAID stride: %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:2207
+#: misc/tune2fs.c:2338
 #, c-format
 msgid "Invalid RAID stripe-width: %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:2222
+#: misc/tune2fs.c:2353
 #, c-format
 msgid "Invalid hash algorithm: %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:2228
+#: misc/tune2fs.c:2359
 #, c-format
 msgid "Setting default hash algorithm to %s (%d)\n"
 msgstr ""
 
-#: misc/tune2fs.c:2255
+#: misc/tune2fs.c:2386
 #, c-format
 msgid "Cannot alter existing encoding\n"
 msgstr ""
 
-#: misc/tune2fs.c:2261
+#: misc/tune2fs.c:2392
 #, c-format
 msgid "Invalid encoding: %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:2267
+#: misc/tune2fs.c:2398
 #, c-format
 msgid "Setting encoding to '%s'\n"
 msgstr ""
 
-#: misc/tune2fs.c:2291
+#: misc/tune2fs.c:2437
 #, c-format
 msgid "Setting encoding_flags to '%s'\n"
 msgstr ""
 
-#: misc/tune2fs.c:2301
+#: misc/tune2fs.c:2447
 msgid ""
 "\n"
 "Bad options specified.\n"
@@ -6539,72 +6707,93 @@ msgid ""
 "\tencoding_flags=<flags>\n"
 msgstr ""
 
-#: misc/tune2fs.c:2717
+#: misc/tune2fs.c:2863
 msgid "Failed to read inode bitmap\n"
 msgstr ""
 
-#: misc/tune2fs.c:2722
+#: misc/tune2fs.c:2868
 msgid "Failed to read block bitmap\n"
 msgstr ""
 
-#: misc/tune2fs.c:2739 resize/resize2fs.c:1368
+#: misc/tune2fs.c:2885 resize/resize2fs.c:1368
 msgid "blocks to be moved"
 msgstr ""
 
-#: misc/tune2fs.c:2742
+#: misc/tune2fs.c:2888
 msgid "Failed to allocate block bitmap when increasing inode size\n"
 msgstr ""
 
-#: misc/tune2fs.c:2748
+#: misc/tune2fs.c:2894
 msgid "Not enough space to increase inode size \n"
 msgstr ""
 
-#: misc/tune2fs.c:2753
+#: misc/tune2fs.c:2899
 msgid "Failed to relocate blocks during inode resize \n"
 msgstr ""
 
-#: misc/tune2fs.c:2785
+#: misc/tune2fs.c:2931
 msgid ""
 "Error in resizing the inode size.\n"
 "Run e2undo to undo the file system changes. \n"
 msgstr ""
 
-#: misc/tune2fs.c:2998
+#: misc/tune2fs.c:3100
+msgid "while checking mount status"
+msgstr ""
+
+#: misc/tune2fs.c:3108
+#, c-format
+msgid "Unknown mount point for %s\n"
+msgstr ""
+
+#: misc/tune2fs.c:3114
+msgid "while opening mount point"
+msgstr ""
+
+#: misc/tune2fs.c:3124
+msgid "while trying to get fs label"
+msgstr ""
+
+#: misc/tune2fs.c:3146
+msgid "while trying to set fs label"
+msgstr ""
+
+#: misc/tune2fs.c:3236
 msgid ""
 "If you are sure the filesystem is not in use on any node, run:\n"
 "'tune2fs -f -E clear_mmp {device}'\n"
 msgstr ""
 
-#: misc/tune2fs.c:3005
+#: misc/tune2fs.c:3243
 #, c-format
 msgid ""
 "MMP block magic is bad. Try to fix it by running:\n"
 "'e2fsck -f %s'\n"
 msgstr ""
 
-#: misc/tune2fs.c:3017
+#: misc/tune2fs.c:3255
 msgid "Cannot modify a journal device.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3030
+#: misc/tune2fs.c:3268
 #, c-format
 msgid "The inode size is already %lu\n"
 msgstr ""
 
-#: misc/tune2fs.c:3037
+#: misc/tune2fs.c:3275
 msgid "Shrinking inode size is not supported\n"
 msgstr ""
 
-#: misc/tune2fs.c:3042
+#: misc/tune2fs.c:3280
 #, c-format
 msgid "Invalid inode size %lu (max %d)\n"
 msgstr ""
 
-#: misc/tune2fs.c:3048
+#: misc/tune2fs.c:3286
 msgid "Resizing inodes could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:3097
+#: misc/tune2fs.c:3336
 #, c-format
 msgid ""
 "Warning: The journal is dirty. You may wish to replay the journal like:\n"
@@ -6615,159 +6804,159 @@ msgid ""
 "by journal recovery.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3106
+#: misc/tune2fs.c:3345
 #, c-format
 msgid "Recovering journal.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3130
+#: misc/tune2fs.c:3369
 #, c-format
 msgid "Setting maximal mount count to %d\n"
 msgstr ""
 
-#: misc/tune2fs.c:3136
+#: misc/tune2fs.c:3375
 #, c-format
 msgid "Setting current mount count to %d\n"
 msgstr ""
 
-#: misc/tune2fs.c:3141
+#: misc/tune2fs.c:3380
 #, c-format
 msgid "Setting error behavior to %d\n"
 msgstr ""
 
-#: misc/tune2fs.c:3146
+#: misc/tune2fs.c:3385
 #, c-format
 msgid "Setting reserved blocks gid to %lu\n"
 msgstr ""
 
-#: misc/tune2fs.c:3151
+#: misc/tune2fs.c:3390
 #, c-format
 msgid "interval between checks is too big (%lu)"
 msgstr ""
 
-#: misc/tune2fs.c:3158
+#: misc/tune2fs.c:3397
 #, c-format
 msgid "Setting interval between checks to %lu seconds\n"
 msgstr ""
 
-#: misc/tune2fs.c:3165
+#: misc/tune2fs.c:3404
 #, c-format
 msgid "Setting reserved blocks percentage to %g%% (%llu blocks)\n"
 msgstr ""
 
-#: misc/tune2fs.c:3172
+#: misc/tune2fs.c:3411
 #, c-format
 msgid "reserved blocks count is too big (%llu)"
 msgstr ""
 
-#: misc/tune2fs.c:3179
+#: misc/tune2fs.c:3418
 #, c-format
 msgid "Setting reserved blocks count to %llu\n"
 msgstr ""
 
-#: misc/tune2fs.c:3184
+#: misc/tune2fs.c:3423
 msgid ""
 "\n"
 "The filesystem already has sparse superblocks.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3187
+#: misc/tune2fs.c:3426
 msgid ""
 "\n"
 "Setting the sparse superblock flag not supported\n"
 "for filesystems with the meta_bg feature enabled.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3197
+#: misc/tune2fs.c:3436
 #, c-format
 msgid ""
 "\n"
 "Sparse superblock flag set.  %s"
 msgstr ""
 
-#: misc/tune2fs.c:3202
+#: misc/tune2fs.c:3441
 msgid ""
 "\n"
 "Clearing the sparse superblock flag not supported.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3210
+#: misc/tune2fs.c:3449
 #, c-format
 msgid "Setting time filesystem last checked to %s\n"
 msgstr ""
 
-#: misc/tune2fs.c:3216
+#: misc/tune2fs.c:3455
 #, c-format
 msgid "Setting reserved blocks uid to %lu\n"
 msgstr ""
 
-#: misc/tune2fs.c:3248
+#: misc/tune2fs.c:3487
 msgid "Error in using clear_mmp. It must be used with -f\n"
 msgstr ""
 
-#: misc/tune2fs.c:3267
+#: misc/tune2fs.c:3524
 msgid ""
 "The quota feature may only be changed when the filesystem is unmounted.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3284
+#: misc/tune2fs.c:3543
 msgid ""
 "Cannot change the UUID of this filesystem because it has the stable_inodes "
 "feature flag.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3294
+#: misc/tune2fs.c:3553
 msgid "Setting the UUID on this filesystem could take some time."
 msgstr ""
 
-#: misc/tune2fs.c:3311
+#: misc/tune2fs.c:3570
 msgid "The UUID may only be changed when the filesystem is unmounted.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3314
+#: misc/tune2fs.c:3573
 msgid ""
 "If you only use kernels newer than v4.4, run 'tune2fs -O metadata_csum_seed' "
 "and re-run this command.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3345
+#: misc/tune2fs.c:3623
 msgid "Invalid UUID format\n"
 msgstr ""
 
-#: misc/tune2fs.c:3361
+#: misc/tune2fs.c:3657
 msgid "Need to update journal superblock.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3383
+#: misc/tune2fs.c:3677
 msgid "The inode size may only be changed when the filesystem is unmounted.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3390
+#: misc/tune2fs.c:3684
 msgid ""
 "Changing the inode size not supported for filesystems with the flex_bg\n"
 "feature enabled.\n"
 msgstr ""
 
-#: misc/tune2fs.c:3408
+#: misc/tune2fs.c:3702
 #, c-format
 msgid "Setting inode size %lu\n"
 msgstr ""
 
-#: misc/tune2fs.c:3412
+#: misc/tune2fs.c:3706
 msgid "Failed to change inode size\n"
 msgstr ""
 
-#: misc/tune2fs.c:3432
+#: misc/tune2fs.c:3726
 #, c-format
 msgid "Setting stride size to %d\n"
 msgstr ""
 
-#: misc/tune2fs.c:3437
+#: misc/tune2fs.c:3731
 #, c-format
 msgid "Setting stripe width to %d\n"
 msgstr ""
 
-#: misc/tune2fs.c:3444
+#: misc/tune2fs.c:3738
 #, c-format
 msgid "Setting extended default mount options to '%s'\n"
 msgstr ""
@@ -7277,7 +7466,7 @@ msgid "Should never happen: resize inode corrupt!\n"
 msgstr ""
 
 #: lib/ext2fs/ext2_err.c:11
-msgid "EXT2FS Library version 1.46.6"
+msgid "EXT2FS Library version 1.47.0"
 msgstr ""
 
 #: lib/ext2fs/ext2_err.c:12
index 5fd68f34b8a04efacba674018fd3e2a7d5d3af98..265f458ca2fc10901fa990a379e67ed306e3bb6a 100644 (file)
@@ -28,6 +28,7 @@ s/\\015//g
 s/, csum 0x\([0-9a-f]*\)//g
 s/ csum 0x\([0-9a-f]*\)//g
 /^Checksum:/d
+/^Checksum seed:/d
 s/while trying to open [^ ]*/while trying to open test.img/
 s/he filesystem on [^ ]* /he filesystem on test.img /
 s/^[^ ]* contains a \([a-z]*\) file system /test.img contains a \1 file system /
diff --git a/tests/m_assume_storage_prezeroed/expect b/tests/m_assume_storage_prezeroed/expect
new file mode 100644 (file)
index 0000000..b735e24
--- /dev/null
@@ -0,0 +1,2 @@
+> 10000
+224
diff --git a/tests/m_assume_storage_prezeroed/script b/tests/m_assume_storage_prezeroed/script
new file mode 100644 (file)
index 0000000..1a8d846
--- /dev/null
@@ -0,0 +1,63 @@
+test_description="test prezeroed storage metadata allocation"
+FILE_SIZE=16M
+
+LOG=$test_name.log
+OUT=$test_name.out
+EXP=$test_dir/expect
+
+if test "$(id -u)" -ne 0 ; then
+    echo "$test_name: $test_description: skipped (not root)"
+elif ! command -v losetup >/dev/null ; then
+    echo "$test_name: $test_description: skipped (no losetup)"
+else
+    dd if=/dev/zero of=$TMPFILE.1 bs=1 count=0 seek=$FILE_SIZE >> $LOG 2>&1
+    dd if=/dev/zero of=$TMPFILE.2 bs=1 count=0 seek=$FILE_SIZE >> $LOG 2>&1
+
+    LOOP1=$(losetup --show --sector-size 4096 -f $TMPFILE.1)
+    if [ ! -b "$LOOP1" ]; then
+        echo "$test_name: $DESCRIPTION: skipped (no loop devices)"
+        rm -f $TMPFILE.1 $TMPFILE.2
+        exit 0
+    fi
+    LOOP2=$(losetup --show --sector-size 4096 -f $TMPFILE.2)
+    if [ ! -b "$LOOP2" ]; then
+        echo "$test_name: $DESCRIPTION: skipped (no loop devices)"
+        rm -f $TMPFILE.1 $TMPFILE.2
+       losetup -d $LOOP1
+        exit 0
+    fi
+
+    echo $MKE2FS -o Linux -t ext4 $LOOP1 >> $LOG 2>&1
+    $MKE2FS -o Linux -t ext4 $LOOP1 >> $LOG 2>&1
+    sync
+    stat $TMPFILE.1 >> $LOG 2>&1
+    SZ=$(stat -c "%b" $TMPFILE.1)
+    if test $SZ -gt 10000 ; then
+       echo "> 10000" > $OUT
+    else
+       echo "$SZ" > $OUT
+    fi
+
+    echo $MKE2FS -o Linux -t ext4 -E assume_storage_prezeroed=1 $LOOP2 >> $LOG 2>&1
+    $MKE2FS -o Linux -t ext4 -E assume_storage_prezeroed=1 $LOOP2 >> $LOG 2>&1
+    sync
+    stat $TMPFILE.2 >> $LOG 2>&1
+    stat -c "%b" $TMPFILE.2 >> $OUT
+
+    losetup -d $LOOP1
+    losetup -d $LOOP2
+    rm -f $TMPFILE.1 $TMPFILE.2
+
+    cmp -s $OUT $EXP
+    status=$?
+
+    if [ "$status" = 0 ] ; then
+       echo "$test_name: $test_description: ok"
+       touch $test_name.ok
+    else
+       echo "$test_name: $test_description: failed"
+       cat $LOG > $test_name.failed
+       diff $EXP $OUT >> $test_name.failed
+    fi
+fi
+unset LOG OUT EXP FILE_SIZE LOOP1 LOOP2
index 5a8863aec96b3663243f2952f5c1acee024bf77b..db245cee4821486b7e74025a60f133c1c19abfa7 100644 (file)
--- a/version.h
+++ b/version.h
@@ -9,5 +9,5 @@
  * License v2.
  */
 
-#define E2FSPROGS_VERSION "1.46.6"
-#define E2FSPROGS_DATE "1-Feb-2023"
+#define E2FSPROGS_VERSION "1.47.0"
+#define E2FSPROGS_DATE "5-Feb-2023"