[Pkg-lustre-svn-commit] updated: [7f5cc23] Import new patches from sun
Patrick Winnertz
winnie at debian.org
Thu Aug 6 08:09:48 UTC 2009
The following commit has been merged in the master branch:
commit 7f5cc2393e8a276f0d13fe844591d9194370cd27
Author: Patrick Winnertz <winnie at debian.org>
Date: Thu Aug 6 10:01:29 2009 +0200
Import new patches from sun
Signed-off-by: Patrick Winnertz <winnie at debian.org>
diff --git a/debian/changelog b/debian/changelog
index ea07f6a..5529978 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,12 +1,12 @@
-ldiskfsprogs (1.40.11-3) unstable; urgency=low
+ldiskfsprogs (1.41.6-1) unstable; urgency=low
- * [6ba0ef7] Use lbdb-dev (>=4.4.20) instead of libdb4.4-dev as db4.4
+ * New Upstream Version
+ * [6ba0ef7] Use libdb-dev (>=4.4.20) instead of libdb4.4-dev as db4.4
is going to be removed from unstable (Closes: #515860)
* [b4b26cf] Build ldiskfsck and lfsck only on i386, amd64 and ia64 as
it is not supposed to be used on powerpc (Closes: #511722)
- * [255f21a] Commit output of git-dch
- -- Patrick Winnertz <winnie at debian.org> Fri, 13 Mar 2009 11:07:02 +0100
+ -- Patrick Winnertz <winnie at debian.org> Thu, 06 Aug 2009 10:00:28 +0200
ldiskfsprogs (1.40.11-2) unstable; urgency=low
diff --git a/debian/patches/.dpkg-source-applied b/debian/patches/.dpkg-source-applied
deleted file mode 100644
index 4464637..0000000
--- a/debian/patches/.dpkg-source-applied
+++ /dev/null
@@ -1,7 +0,0 @@
-e2fsprogs-version.patch
-e2fsprogs-misc.patch
-e2fsprogs-disp-htree-bad-depth.patch
-e2fsprogs-blkid-zfs.patch
-e2fsprogs-specdotin.patch
-e2fsprogs-eacheck.patch
-e2fsprogs-extended_ops.patch
diff --git a/debian/patches/ChangeLog b/debian/patches/ChangeLog
index d0c2a1e..a9b5ca6 100644
--- a/debian/patches/ChangeLog
+++ b/debian/patches/ChangeLog
@@ -1,6 +1,96 @@
+2009-06-13 Sun Microsystems, Inc.
+ * version 1.41.6-sun1
+
+Severity : major
+Frequency : always
+Bugzilla : 18779
+Description: Fix a critical regression in e2fsck introduced version 1.41.5
+ which can undo updates to the block group descriptors after a
+ journal replay.
+
+Severity : enhancement
+Bugzilla : 19536
+Description: add regression tests for MMP feature
+
+Severity : major
+Frequency : always
+Bugzilla : 19536
+Description: Free block statistics correctly when MMP is turned off
+
+
+2009-05-12 Sun Microsystems, Inc.
+ * version 1.41.5-sun2
+
+Severity : major
+Frequency : always
+Bugzilla : 18735
+Description: e2fsck reading cached MMP block misses MMP block update
+
+---------------------------------------------------------------------------
+
+2009-04-30 Sun Microsystems, Inc.
+ * version 1.41.5-sun1
+
+Severity : enhancement
+Description: update to latest upstream e2fsprogs release
+Details : Update to upstream e2fsprogs release 1.41.5. This moves a
+ number of lustre patches into mainstream e2fsprogs, like extents,
+ uninitialized groups, and many smaller fixes. See RELEASE-NOTES.
+
+Severity : enhancement
+Bugzilla : 13419
+Description: lsattr print 'H' flag for huge files; document it and extent flag
+
+Severity : normal
+Frequency : if MMP was enabled with e2fsck, and e2fsck exited uncleanly
+Bugzilla : 18735
+Description: clear MMP e2fsck marker if e2fsck is interrupted
+Details : clear MMP e2fsck marker from the SIGINT and SIGTERM signal
+ handlers, or if e2fsck hits a fatal error.
+
+Severity : enhancement
+Bugzilla : 18735
+Description: add "clear-mmp" option to tune2fs to reset the MMP e2fsck marker
+Details : add an option to run "tune2fs -f -E clear-mmp" to reset the MMP
+ block, which is easier than disabling and re-enabling it.
+
+Severity : enhancement
+Bugzilla : 10555
+Description: Add FIEMAP(FIle Extent MAP) ioctl support to filefrag
+Details : FIEMAP ioctl allows applications to efficiently fetch the extent
+ information of a file. It can be used to map logical blocks in a
+ in a file to physical blocks in the block device. filefrag has
+ been modified to use the FIEMAP ioctl.
+
+Severity : normal
+Frequency : if MMP was enabled with tune2fs
+Bugzilla : 17531
+Description: Free block count should be updated when MMP enabled using tune2fs
+
+---------------------------------------------------------------------------
+
+2008-07-11 Sun Microsystems, Inc.
+ * version 1.40.11-sun1
+
+Severity : major
+Frequency : rare, if on-disk data is corrupted
+Bugzilla : 15320
+Description: kernel assertion with invalid eh_depth that e2fsck does not fix
+Details : fix invalid eh_depth in the inode if the last index was invalid
+
+Severity : enhancement
+Bugzilla : 15604
+Description: display i_version in debugfs "stat" command
+
+---------------------------------------------------------------------------
+
2008-05-20 Sun Microsystems, Inc.
* version 1.40.7-sun3
+Severity : enhancement
+Bugzilla : 9570
+Description: improve e2fsck error message for invalid HTREE depth
+
Severity : major
Bugzilla : 15872
Description: tune2fs cannot disable uninit_groups or mmp features
diff --git a/debian/patches/README b/debian/patches/README
index 2a94a6f..846b3a0 100644
--- a/debian/patches/README
+++ b/debian/patches/README
@@ -1,10 +1,11 @@
README for e2fsprogs/patches
-This directory contains patches from CFS that are ALREADY applied to this
-version of e2fsprogs, in the order specified by "series". Some of the
-patches here are "historical" in the sense that they have already been
-added to the upstream e2fsprogs repository since this release, but they are
-not in any official e2fsprogs release so are included here for reference.
+This directory contains patches from Sun Microsystems, Inc. that are
+ALREADY applied to this version of e2fsprogs, in the order specified
+by "series". Some of the patches here are "historical" in the sense
+that they have already been added to the upstream e2fsprogs repository
+since this release, but they are not in any official e2fsprogs release
+so are included here for reference.
Unfortunately, it isn't possible to have an SRPM that doesn't have the
patches applied, because the patches change the "configure" script, and
diff --git a/debian/patches/e2fsprogs-add-io_channel_readahead.patch b/debian/patches/e2fsprogs-add-io_channel_readahead.patch
index 7ec78f6..5f14f5e 100644
--- a/debian/patches/e2fsprogs-add-io_channel_readahead.patch
+++ b/debian/patches/e2fsprogs-add-io_channel_readahead.patch
@@ -1,18 +1,17 @@
-
-Index: e2fsprogs-1.40.11/lib/ext2fs/ext2_io.h
+Index: e2fsprogs-1.41.1/lib/ext2fs/ext2_io.h
===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ext2_io.h
-+++ e2fsprogs-1.40.11/lib/ext2fs/ext2_io.h
-@@ -63,6 +63,8 @@ struct struct_io_manager {
- errcode_t (*set_blksize)(io_channel channel, int blksize);
- errcode_t (*read_blk)(io_channel channel, unsigned long block,
- int count, void *data);
+--- e2fsprogs-1.41.1.orig/lib/ext2fs/ext2_io.h
++++ e2fsprogs-1.41.1/lib/ext2fs/ext2_io.h
+@@ -83,6 +83,8 @@ struct struct_io_manager {
+ int count, void *data);
+ errcode_t (*write_blk64)(io_channel channel, unsigned long long block,
+ int count, const void *data);
+ errcode_t (*readahead)(io_channel channel, unsigned long block,
+ int count);
- errcode_t (*write_blk)(io_channel channel, unsigned long block,
- int count, const void *data);
- errcode_t (*flush)(io_channel channel);
-@@ -82,6 +84,7 @@ struct struct_io_manager {
+ long reserved[16];
+ };
+
+@@ -95,6 +97,7 @@ struct struct_io_manager {
#define io_channel_close(c) ((c)->manager->close((c)))
#define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s))
#define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d))
@@ -20,19 +19,10 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/ext2_io.h
#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
#define io_channel_flush(c) ((c)->manager->flush((c)))
#define io_channel_bumpcount(c) ((c)->refcount++)
-@@ -92,6 +95,8 @@ extern errcode_t io_channel_set_options(
- extern errcode_t io_channel_write_byte(io_channel channel,
- unsigned long offset,
- int count, const void *data);
-+extern errcode_t readahead_noop(io_channel channel, unsigned long block,
-+ int count);
-
- /* unix_io.c */
- extern io_manager unix_io_manager;
-Index: e2fsprogs-1.40.11/lib/ext2fs/unix_io.c
+Index: e2fsprogs-1.41.1/lib/ext2fs/unix_io.c
===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/unix_io.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/unix_io.c
+--- e2fsprogs-1.41.1.orig/lib/ext2fs/unix_io.c
++++ e2fsprogs-1.41.1/lib/ext2fs/unix_io.c
@@ -15,6 +15,8 @@
* %End-Header%
*/
@@ -42,7 +32,7 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/unix_io.c
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
-@@ -77,6 +79,8 @@ static errcode_t unix_close(io_channel c
+@@ -78,6 +80,8 @@ static errcode_t unix_close(io_channel c
static errcode_t unix_set_blksize(io_channel channel, int blksize);
static errcode_t unix_read_blk(io_channel channel, unsigned long block,
int count, void *data);
@@ -51,15 +41,15 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/unix_io.c
static errcode_t unix_write_blk(io_channel channel, unsigned long block,
int count, const void *data);
static errcode_t unix_flush(io_channel channel);
-@@ -103,6 +107,7 @@ static struct struct_io_manager struct_u
- unix_close,
- unix_set_blksize,
- unix_read_blk,
+@@ -120,6 +124,7 @@ static struct struct_io_manager struct_u
+ unix_get_stats,
+ unix_read_blk64,
+ unix_write_blk64,
+ unix_readahead,
- unix_write_blk,
- unix_flush,
- #ifdef NEED_BOUNCE_BUFFER
-@@ -587,6 +592,18 @@ static errcode_t unix_read_blk(io_channe
+ };
+
+ io_manager unix_io_manager = &struct_unix_manager;
+@@ -674,6 +679,18 @@ static errcode_t unix_write_blk64(io_cha
#endif /* NO_IO_CACHE */
}
@@ -78,65 +68,3 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/unix_io.c
static errcode_t unix_write_blk(io_channel channel, unsigned long block,
int count, const void *buf)
{
-Index: e2fsprogs-1.40.11/lib/ext2fs/inode_io.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/inode_io.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/inode_io.c
-@@ -64,6 +64,7 @@ static struct struct_io_manager struct_i
- inode_close,
- inode_set_blksize,
- inode_read_blk,
-+ readahead_noop,
- inode_write_blk,
- inode_flush,
- inode_write_byte
-Index: e2fsprogs-1.40.11/lib/ext2fs/dosio.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/dosio.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/dosio.c
-@@ -64,6 +64,7 @@ static struct struct_io_manager struct_d
- dos_close,
- dos_set_blksize,
- dos_read_blk,
-+ readahead_noop,
- dos_write_blk,
- dos_flush
- };
-Index: e2fsprogs-1.40.11/lib/ext2fs/nt_io.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/nt_io.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/nt_io.c
-@@ -236,6 +236,7 @@ static struct struct_io_manager struct_n
- nt_close,
- nt_set_blksize,
- nt_read_blk,
-+ readahead_noop,
- nt_write_blk,
- nt_flush
- };
-Index: e2fsprogs-1.40.11/lib/ext2fs/test_io.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/test_io.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/test_io.c
-@@ -74,6 +74,7 @@ static struct struct_io_manager struct_t
- test_close,
- test_set_blksize,
- test_read_blk,
-+ readahead_noop,
- test_write_blk,
- test_flush,
- test_write_byte,
-Index: e2fsprogs-1.40.11/lib/ext2fs/io_manager.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/io_manager.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/io_manager.c
-@@ -67,3 +67,9 @@ errcode_t io_channel_write_byte(io_chann
-
- return EXT2_ET_UNIMPLEMENTED;
- }
-+
-+errcode_t readahead_noop(io_channel channel, unsigned long block,
-+ int count)
-+{
-+ return 0;
-+}
diff --git a/debian/patches/e2fsprogs-blkid-zfs.patch b/debian/patches/e2fsprogs-blkid-zfs.patch
index 72de285..87a4c26 100644
--- a/debian/patches/e2fsprogs-blkid-zfs.patch
+++ b/debian/patches/e2fsprogs-blkid-zfs.patch
@@ -1,8 +1,8 @@
-Index: e2fsprogs-1.40.11/lib/blkid/probe.h
+Index: e2fsprogs-1.41.4/lib/blkid/probe.h
===================================================================
---- e2fsprogs-1.40.11.orig/lib/blkid/probe.h
-+++ e2fsprogs-1.40.11/lib/blkid/probe.h
-@@ -190,6 +190,16 @@ struct jfs_super_block {
+--- e2fsprogs-1.41.4.orig/lib/blkid/probe.h
++++ e2fsprogs-1.41.4/lib/blkid/probe.h
+@@ -193,6 +193,16 @@ struct jfs_super_block {
unsigned char js_loguuid[16];
};
@@ -19,12 +19,30 @@ Index: e2fsprogs-1.40.11/lib/blkid/probe.h
struct romfs_super_block {
unsigned char ros_magic[8];
__u32 ros_dummy1[2];
-Index: e2fsprogs-1.40.11/lib/blkid/tests/zfs.results
+Index: e2fsprogs-1.41.4/lib/blkid/probe.c
===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/blkid/tests/zfs.results
-@@ -0,0 +1 @@
-+TYPE='zfs'
-Index: e2fsprogs-1.40.11/lib/blkid/tests/zfs.img.bz2
-===================================================================
-Binary files /dev/null and e2fsprogs-1.40.11/lib/blkid/tests/zfs.img.bz2 differ
+--- e2fsprogs-1.41.4.orig/lib/blkid/probe.c
++++ e2fsprogs-1.41.4/lib/blkid/probe.c
+@@ -1359,10 +1359,18 @@ static struct blkid_magic type_array[] =
+ { "iso9660", 32, 1, 5, "CD001", probe_iso9660 },
+ { "iso9660", 32, 9, 5, "CDROM", probe_iso9660 },
+ { "jfs", 32, 0, 4, "JFS1", probe_jfs },
+- { "zfs", 8, 0, 8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs },
+- { "zfs", 8, 0, 8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs },
+- { "zfs", 264, 0, 8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs },
+- { "zfs", 264, 0, 8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs },
++ { "zfs", 128, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 128, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
++ { "zfs", 132, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 132, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
++ { "zfs", 136, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 136, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
++ { "zfs", 384, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 384, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
++ { "zfs", 388, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 388, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
++ { "zfs", 392, 0, 8, "\0\0\0\0\0\xba\xb1\xc",probe_zfs },
++ { "zfs", 392, 0, 8, "\xc\xb1\xba\0\0\0\0\0",probe_zfs },
+ { "hfsplus", 1, 0, 2, "BD", probe_hfsplus },
+ { "hfsplus", 1, 0, 2, "H+", probe_hfsplus },
+ { "hfsplus", 1, 0, 2, "HX", probe_hfsplus },
diff --git a/debian/patches/e2fsprogs-debugfs-supported_features.patch b/debian/patches/e2fsprogs-debugfs-supported_features.patch
deleted file mode 100644
index 5fe1114..0000000
--- a/debian/patches/e2fsprogs-debugfs-supported_features.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-Print out the currently supported features of e2fsprogs/libext2fs
-via a new "debugfs supported_features" command.
-
-Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-
-Index: e2fsprogs-1.40.11/debugfs/debug_cmds.ct
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/debug_cmds.ct
-+++ e2fsprogs-1.40.11/debugfs/debug_cmds.ct
-@@ -154,5 +154,8 @@ request do_dump_unused, "Dump unused blo
- request do_set_current_time, "Set current time to use when setting filesystme fields",
- set_current_time;
-
-+request do_supported_features, "Print features supported by this version of e2fsprogs",
-+ supported_features;
-+
- end;
-
-Index: e2fsprogs-1.40.11/debugfs/debugfs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/debugfs.c
-+++ e2fsprogs-1.40.11/debugfs/debugfs.c
-@@ -36,6 +36,7 @@ extern char *optarg;
- #include <ext2fs/ext2_ext_attr.h>
-
- #include "../version.h"
-+#include "jfs_user.h"
-
- extern ss_request_table debug_cmds;
-
-@@ -1780,6 +1781,71 @@ void do_set_current_time(int argc, char
- }
- }
-
-+static int find_supp_feature(__u32 *supp, int feature_type, char *name)
-+{
-+ int compat, bit, ret;
-+ unsigned int feature_mask;
-+
-+ if (name) {
-+ if (feature_type == E2P_FS_FEATURE)
-+ ret = e2p_string2feature(name, &compat, &feature_mask);
-+ else
-+ ret = e2p_jrnl_string2feature(name, &compat,
-+ &feature_mask);
-+ if (ret)
-+ return ret;
-+
-+ if (!(supp[compat] & feature_mask))
-+ return 1;
-+ } else {
-+ for (compat = 0; compat < 3; compat++) {
-+ for (bit = 0, feature_mask = 1; bit < 32;
-+ bit++, feature_mask <<= 1) {
-+ if (supp[compat] & feature_mask) {
-+ if (feature_type == E2P_FS_FEATURE)
-+ fprintf(stdout, " %s",
-+ e2p_feature2string(compat,
-+ feature_mask));
-+ else
-+ fprintf(stdout, " %s",
-+ e2p_jrnl_feature2string(compat,
-+ feature_mask));
-+ }
-+ }
-+ }
-+ fprintf(stdout, "\n");
-+ }
-+
-+ return 0;
-+}
-+
-+void do_supported_features(int argc, char *argv[])
-+{
-+ int i, j, ret;
-+ __u32 supp[3] = { EXT2_LIB_FEATURE_COMPAT_SUPP,
-+ EXT2_LIB_FEATURE_INCOMPAT_SUPP,
-+ EXT2_LIB_FEATURE_RO_COMPAT_SUPP };
-+ __u32 jrnl_supp[3] = { JFS_KNOWN_COMPAT_FEATURES,
-+ JFS_KNOWN_INCOMPAT_FEATURES,
-+ JFS_KNOWN_ROCOMPAT_FEATURES };
-+
-+ if (argc > 1) {
-+ ret = find_supp_feature(supp, E2P_FS_FEATURE, argv[1]);
-+ if (ret) {
-+ ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE,
-+ argv[1]);
-+ }
-+ if (ret)
-+ com_err(argv[0], 0, "Unknown feature: %s\n", argv[1]);
-+ else
-+ fprintf(stdout, "Supported feature: %s\n", argv[1]);
-+ } else {
-+ fprintf(stdout, "Supported features:");
-+ ret = find_supp_feature(supp, E2P_FS_FEATURE, NULL);
-+ ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE, NULL);
-+ }
-+}
-+
- static int source_file(const char *cmd_file, int sci_idx)
- {
- FILE *f;
-Index: e2fsprogs-1.40.11/lib/e2p/e2p.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/e2p.h
-+++ e2fsprogs-1.40.11/lib/e2p/e2p.h
-@@ -11,6 +11,9 @@
-
- #define E2P_FEATURE_NEGATE_FLAG 0x80
-
-+#define E2P_FS_FEATURE 0
-+#define E2P_JOURNAL_FEATURE 1
-+
- /* `options' for print_flags() */
-
- #define PFOPT_LONG 1 /* Must be 1 for compatibility with `int long_format'. */
-Index: e2fsprogs-1.40.11/lib/e2p/feature.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/feature.c
-+++ e2fsprogs-1.40.11/lib/e2p/feature.c
-@@ -15,6 +15,8 @@
- #include <errno.h>
-
- #include "e2p.h"
-+#include <ext2fs/ext2fs.h>
-+#include <ext2fs/jfs_user.h>
-
- struct feature {
- int compat;
-@@ -72,6 +74,17 @@ static struct feature feature_list[] = {
- { 0, 0, 0 },
- };
-
-+static struct feature jrnl_feature_list[] = {
-+ { E2P_FEATURE_COMPAT, JFS_FEATURE_COMPAT_CHECKSUM,
-+ "journal_checksum" },
-+
-+ { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_REVOKE,
-+ "journal_incompat_revoke" },
-+ { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT,
-+ "journal_async_commit" },
-+ { 0, 0, 0 },
-+};
-+
- const char *e2p_feature2string(int compat, unsigned int mask)
- {
- struct feature *f;
-@@ -146,6 +159,79 @@ int e2p_string2feature(char *string, int
- return 0;
- }
-
-+const char *e2p_jrnl_feature2string(int compat, unsigned int mask)
-+{
-+ struct feature *f;
-+ static char buf[20];
-+ char fchar;
-+ int fnum;
-+
-+ for (f = jrnl_feature_list; f->string; f++) {
-+ if ((compat == f->compat) &&
-+ (mask == f->mask))
-+ return f->string;
-+ }
-+ switch (compat) {
-+ case E2P_FEATURE_COMPAT:
-+ fchar = 'C';
-+ break;
-+ case E2P_FEATURE_INCOMPAT:
-+ fchar = 'I';
-+ break;
-+ case E2P_FEATURE_RO_INCOMPAT:
-+ fchar = 'R';
-+ break;
-+ default:
-+ fchar = '?';
-+ break;
-+ }
-+ for (fnum = 0; mask >>= 1; fnum++);
-+ sprintf(buf, "FEATURE_%c%d", fchar, fnum);
-+ return buf;
-+}
-+
-+int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
-+{
-+ struct feature *f;
-+ char *eptr;
-+ int num;
-+
-+ for (f = jrnl_feature_list; f->string; f++) {
-+ if (!strcasecmp(string, f->string)) {
-+ *compat_type = f->compat;
-+ *mask = f->mask;
-+ return 0;
-+ }
-+ }
-+ if (strncasecmp(string, "FEATURE_", 8))
-+ return 1;
-+
-+ switch (string[8]) {
-+ case 'c':
-+ case 'C':
-+ *compat_type = E2P_FEATURE_COMPAT;
-+ break;
-+ case 'i':
-+ case 'I':
-+ *compat_type = E2P_FEATURE_INCOMPAT;
-+ break;
-+ case 'r':
-+ case 'R':
-+ *compat_type = E2P_FEATURE_RO_INCOMPAT;
-+ break;
-+ default:
-+ return 1;
-+ }
-+ if (string[9] == 0)
-+ return 1;
-+ num = strtol(string+9, &eptr, 10);
-+ if (num > 32 || num < 0)
-+ return 1;
-+ if (*eptr)
-+ return 1;
-+ *mask = 1 << num;
-+ return 0;
-+}
- static char *skip_over_blanks(char *cp)
- {
- while (*cp && isspace(*cp))
-@@ -250,3 +336,38 @@ int e2p_edit_feature(const char *str, __
- {
- return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
- }
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+ int compat, i;
-+ unsigned int mask;
-+ const char *str;
-+ struct feature *f;
-+
-+ for (i = 1; i < 2; i++) {
-+ if (i == 0)
-+ f = feature_list;
-+ else
-+ f = jrnl_feature_list;
-+ for (; f->string; f++) {
-+ if (i == 0) {
-+ e2p_string2feature((char *)f->string, &compat,
-+ &mask);
-+ str = e2p_feature2string(compat, mask);
-+ } else {
-+ e2p_jrnl_string2feature((char *)f->string,
-+ &compat, &mask);
-+ str = e2p_jrnl_feature2string(compat, mask);
-+ }
-+
-+ printf("Compat = %d, Mask = %u, %s\n", compat, mask,
-+ f->string);
-+ if (strcmp(f->string, str)) {
-+ fprintf(stderr, "Failure!\n");
-+ exit(1);
-+ }
-+ }
-+ }
-+}
-+#endif
-Index: e2fsprogs-1.40.11/lib/e2p/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/Makefile.in
-+++ e2fsprogs-1.40.11/lib/e2p/Makefile.in
-@@ -69,8 +69,14 @@ tst_ostype: $(srcdir)/ostype.c
- @$(CC) -DTEST_PROGRAM -I$(top_srcdir)/lib -o tst_ostype \
- $(srcdir)/ostype.c $(ALL_CFLAGS)
-
--check:: tst_ostype
-+tst_feature: $(srcdir)/feature.c
-+ @echo " LD $@"
-+ @$(CC) -DTEST_PROGRAM -I$(top_srcdir)/lib -o tst_feature \
-+ $(srcdir)/feature.c $(ALL_CFLAGS)
-+
-+check:: tst_ostype tst_feature
- ./tst_ostype
-+ ./tst_feature
-
- installdirs::
- @echo " MKINSTALLDIRS $(libdir) $(includedir)/e2p"
-@@ -96,7 +102,7 @@ uninstall::
-
- clean::
- $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
-- $(RM) -f ../libe2p.a ../libe2p_p.a tst_ostype
-+ $(RM) -f ../libe2p.a ../libe2p_p.a tst_ostype tst_feature
-
- mostlyclean:: clean
- distclean:: clean
-Index: e2fsprogs-1.40.11/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/Makefile.in
-+++ e2fsprogs-1.40.11/Makefile.in
-@@ -10,7 +10,7 @@ INSTALL = @INSTALL@
- @RESIZER_CMT at RESIZE_DIR= resize
- @DEBUGFS_CMT at DEBUGFS_DIR= debugfs
-
--LIB_SUBDIRS=lib/et lib/ss lib/e2p lib/ext2fs lib/uuid lib/blkid intl
-+LIB_SUBDIRS=lib/et lib/ss lib/ext2fs lib/e2p lib/uuid lib/blkid intl
- PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po
- SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests
-
diff --git a/debian/patches/e2fsprogs-debugfs-supported_features.patch.new b/debian/patches/e2fsprogs-debugfs-supported_features.patch.new
deleted file mode 100644
index 5fe1114..0000000
--- a/debian/patches/e2fsprogs-debugfs-supported_features.patch.new
+++ /dev/null
@@ -1,309 +0,0 @@
-Print out the currently supported features of e2fsprogs/libext2fs
-via a new "debugfs supported_features" command.
-
-Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-
-Index: e2fsprogs-1.40.11/debugfs/debug_cmds.ct
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/debug_cmds.ct
-+++ e2fsprogs-1.40.11/debugfs/debug_cmds.ct
-@@ -154,5 +154,8 @@ request do_dump_unused, "Dump unused blo
- request do_set_current_time, "Set current time to use when setting filesystme fields",
- set_current_time;
-
-+request do_supported_features, "Print features supported by this version of e2fsprogs",
-+ supported_features;
-+
- end;
-
-Index: e2fsprogs-1.40.11/debugfs/debugfs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/debugfs.c
-+++ e2fsprogs-1.40.11/debugfs/debugfs.c
-@@ -36,6 +36,7 @@ extern char *optarg;
- #include <ext2fs/ext2_ext_attr.h>
-
- #include "../version.h"
-+#include "jfs_user.h"
-
- extern ss_request_table debug_cmds;
-
-@@ -1780,6 +1781,71 @@ void do_set_current_time(int argc, char
- }
- }
-
-+static int find_supp_feature(__u32 *supp, int feature_type, char *name)
-+{
-+ int compat, bit, ret;
-+ unsigned int feature_mask;
-+
-+ if (name) {
-+ if (feature_type == E2P_FS_FEATURE)
-+ ret = e2p_string2feature(name, &compat, &feature_mask);
-+ else
-+ ret = e2p_jrnl_string2feature(name, &compat,
-+ &feature_mask);
-+ if (ret)
-+ return ret;
-+
-+ if (!(supp[compat] & feature_mask))
-+ return 1;
-+ } else {
-+ for (compat = 0; compat < 3; compat++) {
-+ for (bit = 0, feature_mask = 1; bit < 32;
-+ bit++, feature_mask <<= 1) {
-+ if (supp[compat] & feature_mask) {
-+ if (feature_type == E2P_FS_FEATURE)
-+ fprintf(stdout, " %s",
-+ e2p_feature2string(compat,
-+ feature_mask));
-+ else
-+ fprintf(stdout, " %s",
-+ e2p_jrnl_feature2string(compat,
-+ feature_mask));
-+ }
-+ }
-+ }
-+ fprintf(stdout, "\n");
-+ }
-+
-+ return 0;
-+}
-+
-+void do_supported_features(int argc, char *argv[])
-+{
-+ int i, j, ret;
-+ __u32 supp[3] = { EXT2_LIB_FEATURE_COMPAT_SUPP,
-+ EXT2_LIB_FEATURE_INCOMPAT_SUPP,
-+ EXT2_LIB_FEATURE_RO_COMPAT_SUPP };
-+ __u32 jrnl_supp[3] = { JFS_KNOWN_COMPAT_FEATURES,
-+ JFS_KNOWN_INCOMPAT_FEATURES,
-+ JFS_KNOWN_ROCOMPAT_FEATURES };
-+
-+ if (argc > 1) {
-+ ret = find_supp_feature(supp, E2P_FS_FEATURE, argv[1]);
-+ if (ret) {
-+ ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE,
-+ argv[1]);
-+ }
-+ if (ret)
-+ com_err(argv[0], 0, "Unknown feature: %s\n", argv[1]);
-+ else
-+ fprintf(stdout, "Supported feature: %s\n", argv[1]);
-+ } else {
-+ fprintf(stdout, "Supported features:");
-+ ret = find_supp_feature(supp, E2P_FS_FEATURE, NULL);
-+ ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE, NULL);
-+ }
-+}
-+
- static int source_file(const char *cmd_file, int sci_idx)
- {
- FILE *f;
-Index: e2fsprogs-1.40.11/lib/e2p/e2p.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/e2p.h
-+++ e2fsprogs-1.40.11/lib/e2p/e2p.h
-@@ -11,6 +11,9 @@
-
- #define E2P_FEATURE_NEGATE_FLAG 0x80
-
-+#define E2P_FS_FEATURE 0
-+#define E2P_JOURNAL_FEATURE 1
-+
- /* `options' for print_flags() */
-
- #define PFOPT_LONG 1 /* Must be 1 for compatibility with `int long_format'. */
-Index: e2fsprogs-1.40.11/lib/e2p/feature.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/feature.c
-+++ e2fsprogs-1.40.11/lib/e2p/feature.c
-@@ -15,6 +15,8 @@
- #include <errno.h>
-
- #include "e2p.h"
-+#include <ext2fs/ext2fs.h>
-+#include <ext2fs/jfs_user.h>
-
- struct feature {
- int compat;
-@@ -72,6 +74,17 @@ static struct feature feature_list[] = {
- { 0, 0, 0 },
- };
-
-+static struct feature jrnl_feature_list[] = {
-+ { E2P_FEATURE_COMPAT, JFS_FEATURE_COMPAT_CHECKSUM,
-+ "journal_checksum" },
-+
-+ { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_REVOKE,
-+ "journal_incompat_revoke" },
-+ { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT,
-+ "journal_async_commit" },
-+ { 0, 0, 0 },
-+};
-+
- const char *e2p_feature2string(int compat, unsigned int mask)
- {
- struct feature *f;
-@@ -146,6 +159,79 @@ int e2p_string2feature(char *string, int
- return 0;
- }
-
-+const char *e2p_jrnl_feature2string(int compat, unsigned int mask)
-+{
-+ struct feature *f;
-+ static char buf[20];
-+ char fchar;
-+ int fnum;
-+
-+ for (f = jrnl_feature_list; f->string; f++) {
-+ if ((compat == f->compat) &&
-+ (mask == f->mask))
-+ return f->string;
-+ }
-+ switch (compat) {
-+ case E2P_FEATURE_COMPAT:
-+ fchar = 'C';
-+ break;
-+ case E2P_FEATURE_INCOMPAT:
-+ fchar = 'I';
-+ break;
-+ case E2P_FEATURE_RO_INCOMPAT:
-+ fchar = 'R';
-+ break;
-+ default:
-+ fchar = '?';
-+ break;
-+ }
-+ for (fnum = 0; mask >>= 1; fnum++);
-+ sprintf(buf, "FEATURE_%c%d", fchar, fnum);
-+ return buf;
-+}
-+
-+int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
-+{
-+ struct feature *f;
-+ char *eptr;
-+ int num;
-+
-+ for (f = jrnl_feature_list; f->string; f++) {
-+ if (!strcasecmp(string, f->string)) {
-+ *compat_type = f->compat;
-+ *mask = f->mask;
-+ return 0;
-+ }
-+ }
-+ if (strncasecmp(string, "FEATURE_", 8))
-+ return 1;
-+
-+ switch (string[8]) {
-+ case 'c':
-+ case 'C':
-+ *compat_type = E2P_FEATURE_COMPAT;
-+ break;
-+ case 'i':
-+ case 'I':
-+ *compat_type = E2P_FEATURE_INCOMPAT;
-+ break;
-+ case 'r':
-+ case 'R':
-+ *compat_type = E2P_FEATURE_RO_INCOMPAT;
-+ break;
-+ default:
-+ return 1;
-+ }
-+ if (string[9] == 0)
-+ return 1;
-+ num = strtol(string+9, &eptr, 10);
-+ if (num > 32 || num < 0)
-+ return 1;
-+ if (*eptr)
-+ return 1;
-+ *mask = 1 << num;
-+ return 0;
-+}
- static char *skip_over_blanks(char *cp)
- {
- while (*cp && isspace(*cp))
-@@ -250,3 +336,38 @@ int e2p_edit_feature(const char *str, __
- {
- return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
- }
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+ int compat, i;
-+ unsigned int mask;
-+ const char *str;
-+ struct feature *f;
-+
-+ for (i = 1; i < 2; i++) {
-+ if (i == 0)
-+ f = feature_list;
-+ else
-+ f = jrnl_feature_list;
-+ for (; f->string; f++) {
-+ if (i == 0) {
-+ e2p_string2feature((char *)f->string, &compat,
-+ &mask);
-+ str = e2p_feature2string(compat, mask);
-+ } else {
-+ e2p_jrnl_string2feature((char *)f->string,
-+ &compat, &mask);
-+ str = e2p_jrnl_feature2string(compat, mask);
-+ }
-+
-+ printf("Compat = %d, Mask = %u, %s\n", compat, mask,
-+ f->string);
-+ if (strcmp(f->string, str)) {
-+ fprintf(stderr, "Failure!\n");
-+ exit(1);
-+ }
-+ }
-+ }
-+}
-+#endif
-Index: e2fsprogs-1.40.11/lib/e2p/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/Makefile.in
-+++ e2fsprogs-1.40.11/lib/e2p/Makefile.in
-@@ -69,8 +69,14 @@ tst_ostype: $(srcdir)/ostype.c
- @$(CC) -DTEST_PROGRAM -I$(top_srcdir)/lib -o tst_ostype \
- $(srcdir)/ostype.c $(ALL_CFLAGS)
-
--check:: tst_ostype
-+tst_feature: $(srcdir)/feature.c
-+ @echo " LD $@"
-+ @$(CC) -DTEST_PROGRAM -I$(top_srcdir)/lib -o tst_feature \
-+ $(srcdir)/feature.c $(ALL_CFLAGS)
-+
-+check:: tst_ostype tst_feature
- ./tst_ostype
-+ ./tst_feature
-
- installdirs::
- @echo " MKINSTALLDIRS $(libdir) $(includedir)/e2p"
-@@ -96,7 +102,7 @@ uninstall::
-
- clean::
- $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
-- $(RM) -f ../libe2p.a ../libe2p_p.a tst_ostype
-+ $(RM) -f ../libe2p.a ../libe2p_p.a tst_ostype tst_feature
-
- mostlyclean:: clean
- distclean:: clean
-Index: e2fsprogs-1.40.11/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/Makefile.in
-+++ e2fsprogs-1.40.11/Makefile.in
-@@ -10,7 +10,7 @@ INSTALL = @INSTALL@
- @RESIZER_CMT at RESIZE_DIR= resize
- @DEBUGFS_CMT at DEBUGFS_DIR= debugfs
-
--LIB_SUBDIRS=lib/et lib/ss lib/e2p lib/ext2fs lib/uuid lib/blkid intl
-+LIB_SUBDIRS=lib/et lib/ss lib/ext2fs lib/e2p lib/uuid lib/blkid intl
- PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po
- SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests
-
diff --git a/debian/patches/e2fsprogs-disp-htree-bad-depth.patch b/debian/patches/e2fsprogs-disp-htree-bad-depth.patch
deleted file mode 100644
index 71490d9..0000000
--- a/debian/patches/e2fsprogs-disp-htree-bad-depth.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-Index: e2fsprogs-1.40.7/e2fsck/pass2.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass2.c
-+++ e2fsprogs-1.40.7/e2fsck/pass2.c
-@@ -213,6 +213,7 @@ void e2fsck_pass2(e2fsck_t ctx)
- if (dx_db->type == DX_DIRBLOCK_LEAF) {
- depth = htree_depth(dx_dir, dx_db);
- if (depth != dx_dir->depth) {
-+ pctx.num = dx_dir->depth;
- code = PR_2_HTREE_BAD_DEPTH;
- fix_problem(ctx, code, &pctx);
- bad_dir++;
-Index: e2fsprogs-1.40.7/e2fsck/problem.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.7/e2fsck/problem.c
-@@ -1165,7 +1165,7 @@ static struct e2fsck_problem problem_tab
-
- /* Node in HTREE directory has invalid depth */
- { PR_2_HTREE_BAD_DEPTH,
-- N_("@p @h %d: node (%B) has @n depth\n"),
-+ N_("@p @h %d: node (%B) has @n depth (%N)\n"),
- PROMPT_NONE, 0 },
-
- /* Duplicate directory entry found */
-Index: e2fsprogs-1.40.7/tests/f_h_badnode/expect.1
-===================================================================
---- e2fsprogs-1.40.7.orig/tests/f_h_badnode/expect.1
-+++ e2fsprogs-1.40.7/tests/f_h_badnode/expect.1
-@@ -3,7 +3,7 @@ Pass 2: Checking directory structure
- Problem in HTREE directory inode 12929: node (531) has bad max hash
- Problem in HTREE directory inode 12929: node (993) referenced twice
- Problem in HTREE directory inode 12929: node (1061) has bad min hash
--Problem in HTREE directory inode 12929: node (1062) has invalid depth
-+Problem in HTREE directory inode 12929: node (1062) has invalid depth (2)
- Problem in HTREE directory inode 12929: node (1062) has bad max hash
- Problem in HTREE directory inode 12929: node (1062) not referenced
- Invalid HTREE directory inode 12929 (/test2). Clear? yes
diff --git a/debian/patches/e2fsprogs-disp-i_version.patch b/debian/patches/e2fsprogs-disp-i_version.patch
deleted file mode 100644
index 168df04..0000000
--- a/debian/patches/e2fsprogs-disp-i_version.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-Index: e2fsprogs-1.40.7/debugfs/debugfs.c
-===================================================================
---- e2fsprogs-1.40.7.orig/debugfs/debugfs.c
-+++ e2fsprogs-1.40.7/debugfs/debugfs.c
-@@ -38,6 +38,10 @@ extern char *optarg;
- #include "../version.h"
- #include "jfs_user.h"
-
-+#ifndef offsetof
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+#endif
-+
- extern ss_request_table debug_cmds;
-
- ext2_filsys current_fs = NULL;
-@@ -475,6 +479,7 @@ static void internal_dump_inode_extra(FI
- __u32 *magic;
- char *start, *end;
- unsigned int storage_size;
-+ __u64 inode_version;
-
- fprintf(out, "Size of extra inode fields: %u\n", inode->i_extra_isize);
- if (inode->i_extra_isize > EXT2_INODE_SIZE(current_fs->super) -
-@@ -483,6 +488,13 @@ static void internal_dump_inode_extra(FI
- inode->i_extra_isize);
- return;
- }
-+
-+ inode_version = inode->i_disk_version;
-+ if (EXT2_FITS_IN_INODE(inode, i_version_hi))
-+ inode_version |= (__u64)inode->i_version_hi << 32;
-+
-+ fprintf(out, "Inode version: %llu\n", (long long)inode_version);
-+
- storage_size = EXT2_INODE_SIZE(current_fs->super) -
- EXT2_GOOD_OLD_INODE_SIZE -
- inode->i_extra_isize;
-Index: e2fsprogs-1.40.7/debugfs/debugfs.h
-===================================================================
---- e2fsprogs-1.40.7.orig/debugfs/debugfs.h
-+++ e2fsprogs-1.40.7/debugfs/debugfs.h
-@@ -12,6 +12,8 @@
- #define const
- #endif
-
-+#define i_disk_version osd1.linux1.l_i_version
-+
- /*
- * Flags used by the common argument processing functions
- */
-Index: e2fsprogs-1.40.7/tests/r_inline_xattr/expect
-===================================================================
---- e2fsprogs-1.40.7.orig/tests/r_inline_xattr/expect
-+++ e2fsprogs-1.40.7/tests/r_inline_xattr/expect
-@@ -1,6 +1,7 @@
- resize2fs test
- debugfs -R ''stat file'' ./test.img 2>&1 | grep ''^Inode\|in inode body\|name = ''
- Inode: 1550 Type: regular Mode: 0644 Flags: 0x0 Generation: 3498507810
-+Inode version: 0
- Extended attributes stored in inode body:
- name = "propervalue" (11)
- Exit status is 0
-@@ -11,6 +12,7 @@ The filesystem on ./test.img is now 5120
- Exit status is 0
- debugfs -R ''stat file'' ./test.img 2>&1 | grep ''^Inode\|in inode body\|name = ''
- Inode: 12 Type: regular Mode: 0644 Flags: 0x0 Generation: 3498507810
-+Inode version: 0
- Extended attributes stored in inode body:
- name = "propervalue" (11)
- Exit status is 0
diff --git a/debian/patches/e2fsprogs-e2freefrag.patch b/debian/patches/e2fsprogs-e2freefrag.patch
index 319728a..2838611 100644
--- a/debian/patches/e2fsprogs-e2freefrag.patch
+++ b/debian/patches/e2fsprogs-e2freefrag.patch
@@ -1,8 +1,8 @@
-Index: e2fsprogs-1.40.7/misc/e2freefrag.8.in
+Index: e2fsprogs-1.41.4/misc/e2freefrag.8.in
===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.7/misc/e2freefrag.8.in
-@@ -0,0 +1,93 @@
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ e2fsprogs-1.41.4/misc/e2freefrag.8.in 2009-04-21 13:24:09.000000000 -0600
+@@ -0,0 +1,100 @@
+.\" -*- nroff -*-
+.TH E2FREEFRAG 8
+.SH NAME
@@ -49,12 +49,12 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.8.in
+.br
+Blocksize: 4096 bytes
+.br
-+
+Total blocks: 5120710
+.br
+Free blocks: 831744 (16.2%)
+.br
-+
++Chunk size: 1048576 bytes (256 blocks)
++.br
+Total chunks: 20003
+.br
+Free chunks: 2174 (10.9%)
@@ -96,11 +96,31 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.8.in
+ 8M... 16M- : 4
+.br
+ 16M... 32M- : 1
-Index: e2fsprogs-1.40.7/misc/e2freefrag.c
++.SH AUTHOR
++This version of e2freefrag was written by Rupesh Thakare, and modified by
++Andreas Dilger <adilger at sun.com>, and Kalpak Shah <kalpak.shah at sun.com>.
++.SH SEE ALSO
++.IR debugfs (8),
++.IR dumpe2fs (8),
++.IR e2fsck (8)
+Index: e2fsprogs-1.41.4/misc/e2freefrag.c
===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.7/misc/e2freefrag.c
-@@ -0,0 +1,266 @@
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ e2fsprogs-1.41.4/misc/e2freefrag.c 2009-04-21 13:18:30.000000000 -0600
+@@ -0,0 +1,275 @@
++/*
++ * e2freefrag - report filesystem free-space fragmentation
++ *
++ * Copyright (C) 2007 Cluster File Systems, Inc.
++ *
++ * Author2: Rupesh Thakare <rupesh at clusterfs.com>
++ * Andreas Dilger <adilger at clusterfs.com>
++ *
++ * %Begin-Header%
++ * This file may be redistributed under the terms of the GNU Public
++ * License version 2.
++ * %End-Header%
++ */
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
@@ -156,19 +176,16 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.c
+
+void scan_block_bitmap(ext2_filsys fs, struct chunk_info *info)
+{
-+ unsigned long blocks_count = fs->super->s_blocks_count;
-+ unsigned long chunks = (blocks_count + info->blks_in_chunk) >>
++ unsigned long long blocks_count = fs->super->s_blocks_count;
++ unsigned long long chunks = (blocks_count + info->blks_in_chunk) >>
+ (info->chunkbits - info->blocksize_bits);
-+ unsigned long chunk_num;
++ unsigned long long chunk_num;
+ unsigned long last_chunk_size = 0;
-+ unsigned long index;
-+ blk_t blk;
-+ int ret, not_free = 0, free_chunk = 0;
++ unsigned long long chunk_start_blk = 0;
+
+ for (chunk_num = 0; chunk_num < chunks; chunk_num++) {
-+ blk_t chunk_start_blk = chunk_num << (info->chunkbits -
-+ info->blocksize_bits);
-+ unsigned long num_blks;
++ unsigned long long blk, num_blks;
++ int chunk_free;
+
+ /* Last chunk may be smaller */
+ if (chunk_start_blk + info->blks_in_chunk > blocks_count)
@@ -176,25 +193,22 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.c
+ else
+ num_blks = info->blks_in_chunk;
+
-+ free_chunk = 0;
++ chunk_free = 0;
+
+ /* Initialize starting block for first chunk correctly else
+ * there is a segfault when blocksize = 1024 in which case
+ * block_map->start = 1 */
+ for (blk = (chunk_num == 0 ? fs->super->s_first_data_block : 0);
-+ blk < num_blks; blk++) {
-+ if (ext2fs_fast_test_block_bitmap(fs->block_map,
-+ chunk_start_blk + blk)) {
-+ not_free = 1;
-+ } else {
++ blk < num_blks; blk++, chunk_start_blk++) {
++ int used = ext2fs_fast_test_block_bitmap(fs->block_map,
++ chunk_start_blk);
++ if (!used) {
+ last_chunk_size++;
-+ free_chunk++;
-+ not_free = 0;
++ chunk_free++;
+ }
+
-+ if (not_free) {
-+ if (last_chunk_size == 0)
-+ continue;
++ if (used && last_chunk_size != 0) {
++ unsigned long index;
+
+ index = ul_log2(last_chunk_size) + 1;
+ info->histogram.fc_buckets[index]++;
@@ -210,7 +224,7 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.c
+ }
+ }
+
-+ if (free_chunk == info->blks_in_chunk)
++ if (chunk_free == info->blks_in_chunk)
+ info->free_chunks++;
+ }
+}
@@ -225,14 +239,16 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.c
+
+ scan_block_bitmap(fs, info);
+
-+ printf("\nTotal blocks: %lu\nFree blocks: %lu (%0.1f%%)\n",
++ printf("Total blocks: %lu\nFree blocks: %lu (%0.1f%%)\n",
+ fs->super->s_blocks_count, fs->super->s_free_blocks_count,
+ (double)fs->super->s_free_blocks_count * 100 /
+ fs->super->s_blocks_count);
+
++ printf("\nChunksize: %u bytes (%u blocks)\n",
++ info->chunkbytes, info->blks_in_chunk);
+ total_chunks = (fs->super->s_blocks_count + info->blks_in_chunk) >>
+ (info->chunkbits - info->blocksize_bits);
-+ printf("\nTotal chunks: %lu\nFree chunks: %lu (%0.1f%%)\n",
++ printf("Total chunks: %lu\nFree chunks: %lu (%0.1f%%)\n",
+ total_chunks, info->free_chunks,
+ (double)info->free_chunks * 100 / total_chunks);
+
@@ -367,11 +383,11 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.c
+
+ return retval;
+}
-Index: e2fsprogs-1.40.7/misc/e2freefrag.h
+Index: e2fsprogs-1.41.4/misc/e2freefrag.h
===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.7/misc/e2freefrag.h
-@@ -0,0 +1,20 @@
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ e2fsprogs-1.41.4/misc/e2freefrag.h 2009-04-21 13:19:48.000000000 -0600
+@@ -0,0 +1,19 @@
+#include <sys/types.h>
+
+#define DEFAULT_CHUNKSIZE (1024*1024)
@@ -384,19 +400,18 @@ Index: e2fsprogs-1.40.7/misc/e2freefrag.h
+struct chunk_info {
+ unsigned long chunkbytes; /* chunk size in bytes */
+ int chunkbits; /* chunk size in bits */
-+ unsigned long free_chunks; /* total no of free chunks of given size */
++ unsigned long free_chunks; /* total free chunks of given size */
+ unsigned long real_free_chunks; /* free chunks of any size */
+ int blocksize_bits; /* fs blocksize in bits */
+ int blks_in_chunk; /* number of blocks in a chunk */
+ unsigned long min, max, avg; /* chunk size stats */
-+ struct free_chunk_histogram histogram; /* histogram of chunks of all sizes */
++ struct free_chunk_histogram histogram; /* histogram of all chunk sizes*/
+};
-+
-Index: e2fsprogs-1.40.7/e2fsprogs.spec.in
+Index: e2fsprogs-1.41.4/e2fsprogs.spec.in
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsprogs.spec.in
-+++ e2fsprogs-1.40.7/e2fsprogs.spec.in
-@@ -138,6 +138,7 @@ exit 0
+--- e2fsprogs-1.41.4.orig/e2fsprogs.spec.in 2009-04-14 05:56:43.000000000 -0600
++++ e2fsprogs-1.41.4/e2fsprogs.spec.in 2009-04-21 13:25:19.000000000 -0600
+@@ -143,6 +143,7 @@
%{_root_sbindir}/tune2fs
%{_sbindir}/filefrag
%{_sbindir}/mklost+found
@@ -404,7 +419,7 @@ Index: e2fsprogs-1.40.7/e2fsprogs.spec.in
%{_root_libdir}/libblkid.so.*
%{_root_libdir}/libcom_err.so.*
-@@ -177,6 +178,7 @@ exit 0
+@@ -187,6 +188,7 @@
%{_mandir}/man8/resize2fs.8*
%{_mandir}/man8/tune2fs.8*
%{_mandir}/man8/filefrag.8*
@@ -412,44 +427,43 @@ Index: e2fsprogs-1.40.7/e2fsprogs.spec.in
%files devel
%defattr(-,root,root)
-Index: e2fsprogs-1.40.7/misc/Makefile.in
+Index: e2fsprogs-1.41.4/misc/Makefile.in
===================================================================
---- e2fsprogs-1.40.7.orig/misc/Makefile.in
-+++ e2fsprogs-1.40.7/misc/Makefile.in
-@@ -19,10 +19,10 @@ INSTALL = @INSTALL@
+--- e2fsprogs-1.41.4.orig/misc/Makefile.in 2009-04-14 05:56:43.000000000 -0600
++++ e2fsprogs-1.41.4/misc/Makefile.in 2009-04-14 06:09:57.000000000 -0600
+@@ -19,10 +19,10 @@
- SPROGS= mke2fs badblocks tune2fs dumpe2fs blkid logsave \
- $(E2IMAGE_PROG) @FSCK_PROG@
+ SPROGS= mke2fs badblocks tune2fs dumpe2fs $(BLKID_PROG) logsave \
+ $(E2IMAGE_PROG) @FSCK_PROG@ e2undo
-USPROGS= mklost+found filefrag $(UUIDD_PROG)
+USPROGS= mklost+found filefrag e2freefrag $(UUIDD_PROG)
SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
- e2label.8 findfs.8 blkid.8 $(E2IMAGE_MAN) \
-- logsave.8 filefrag.8 $(UUIDD_MAN) @FSCK_MAN@
-+ logsave.8 filefrag.8 e2freefrag.8 $(UUIDD_MAN) @FSCK_MAN@
+ e2label.8 $(FINDFS_MAN) $(BLKID_MAN) $(E2IMAGE_MAN) \
+- logsave.8 filefrag.8 e2undo.8 $(UUIDD_MAN) @FSCK_MAN@
++ logsave.8 filefrag.8 e2freefrag.8 e2undo.8 $(UUIDD_MAN) @FSCK_MAN@
FMANPAGES= mke2fs.conf.5
UPROGS= chattr lsattr uuidgen
-@@ -43,6 +43,7 @@ E2IMAGE_OBJS= e2image.o
- FSCK_OBJS= fsck.o base_device.o ismounted.o
+@@ -44,6 +44,7 @@
BLKID_OBJS= blkid.o
FILEFRAG_OBJS= filefrag.o
+ E2UNDO_OBJS= e2undo.o
+E2FREEFRAG_OBJS= e2freefrag.o
- XTRA_CFLAGS= -I$(srcdir)/../e2fsck -I.
-
-@@ -51,7 +52,8 @@ SRCS= $(srcdir)/tune2fs.c $(srcdir)/mklo
- $(srcdir)/badblocks.c $(srcdir)/fsck.c $(srcdir)/util.c \
+ PROFILED_TUNE2FS_OBJS= profiled/tune2fs.o profiled/util.o
+ PROFILED_MKLPF_OBJS= profiled/mklost+found.o
+@@ -71,7 +72,7 @@
$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
$(srcdir)/filefrag.c $(srcdir)/base_device.c \
-- $(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c
-+ $(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
-+ $(srcdir)/e2freefrag.c
+ $(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
+- $(srcdir)/e2undo.c
++ $(srcdir)/e2undo.c $(srcdir)/e2freefrag.c
LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
-@@ -169,6 +171,10 @@ logsave: logsave.o
+@@ -276,6 +277,10 @@
@echo " LD $@"
- @$(CC) $(ALL_LDFLAGS) -o logsave logsave.o
+ @$(CC) $(ALL_LDFLAGS) -g -pg -o logsave.profiled profiled/logsave.o
+e2freefrag: $(E2FREEFRAG_OBJS)
+ @echo "LD $@"
@@ -458,7 +472,7 @@ Index: e2fsprogs-1.40.7/misc/Makefile.in
filefrag: $(FILEFRAG_OBJS)
@echo " LD $@"
@$(CC) $(ALL_LDFLAGS) -o filefrag $(FILEFRAG_OBJS)
-@@ -245,6 +251,10 @@ blkid.1: $(DEP_SUBSTITUTE) $(srcdir)/blk
+@@ -361,6 +366,10 @@
@echo " SUBST $@"
@$(SUBSTITUTE_UPTIME) $(srcdir)/blkid.1.in blkid.1
@@ -469,16 +483,16 @@ Index: e2fsprogs-1.40.7/misc/Makefile.in
filefrag.8: $(DEP_SUBSTITUTE) $(srcdir)/filefrag.8.in
@echo " SUBST $@"
@$(SUBSTITUTE_UPTIME) $(srcdir)/filefrag.8.in filefrag.8
-@@ -370,7 +380,7 @@ uninstall:
+@@ -522,7 +531,7 @@
clean:
$(RM) -f $(SPROGS) $(USPROGS) $(UPROGS) $(UMANPAGES) $(SMANPAGES) \
$(FMANPAGES) \
- base_device base_device.out mke2fs.static filefrag \
+ base_device base_device.out mke2fs.static filefrag e2freefrag \
e2initrd_helper partinfo prof_err.[ch] default_profile.c \
- uuidd e2image tst_ismounted \#* *.s *.o *.a *~ core
-
-@@ -446,6 +456,9 @@ uuidgen.o: $(srcdir)/uuidgen.c $(top_src
+ uuidd e2image tune2fs.static tst_ismounted fsck.profiled \
+ blkid.profiled tune2fs.profiled e2image.profiled \
+@@ -603,6 +612,9 @@
blkid.o: $(srcdir)/blkid.c $(top_srcdir)/lib/blkid/blkid.h \
$(top_builddir)/lib/blkid/blkid_types.h
logsave.o: $(srcdir)/logsave.c
diff --git a/debian/patches/e2fsprogs-e2scan.patch b/debian/patches/e2fsprogs-e2scan.patch
index 64afa49..b44579b 100644
--- a/debian/patches/e2fsprogs-e2scan.patch
+++ b/debian/patches/e2fsprogs-e2scan.patch
@@ -1,8 +1,8 @@
-Index: e2fsprogs-1.40.11/configure.in
+Index: e2fsprogs-1.41.5/configure.in
===================================================================
---- e2fsprogs-1.40.11.orig/configure.in
-+++ e2fsprogs-1.40.11/configure.in
-@@ -438,6 +438,28 @@ DEBUGFS_CMT=
+--- e2fsprogs-1.41.5.orig/configure.in
++++ e2fsprogs-1.41.5/configure.in
+@@ -483,6 +483,28 @@ DEBUGFS_CMT=
)
AC_SUBST(DEBUGFS_CMT)
dnl
@@ -31,14 +31,14 @@ Index: e2fsprogs-1.40.11/configure.in
dnl handle --enable-imager
dnl
AC_ARG_ENABLE([imager],
-@@ -672,6 +694,7 @@ else
- fi
- AC_CHECK_HEADERS(dirent.h errno.h getopt.h malloc.h mntent.h paths.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h unistd.h utime.h linux/fd.h linux/major.h net/if_dl.h netinet/in.h sys/disklabel.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/prctl.h sys/queue.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h)
+@@ -687,6 +709,7 @@ AC_CHECK_HEADERS(net/if.h,,,
+ #endif
+ ]])
AC_CHECK_HEADERS(db.h)
+AC_CHECK_HEADERS(sqlite3.h)
- AC_CHECK_HEADERS(sys/disk.h sys/mount.h,,,
- [[
- #if HAVE_SYS_QUEUE_H
+ AC_FUNC_VPRINTF
+ dnl Check to see if dirent has member d_reclen. On cygwin those d_reclen
+ dnl is not decleared.
@@ -822,6 +845,53 @@ AC_CHECK_LIB(db-4.6, db_env_create,
AC_DEFINE(HAVE_DB)])
AC_SUBST(DB_LIB)
@@ -93,7 +93,7 @@ Index: e2fsprogs-1.40.11/configure.in
dnl See if optreset exists
dnl
AC_MSG_CHECKING(for optreset)
-@@ -1023,7 +1093,7 @@ for i in MCONFIG Makefile e2fsprogs.spec
+@@ -1038,7 +1108,7 @@ for i in MCONFIG Makefile e2fsprogs.spec
lib/ss/ss.pc lib/uuid/uuid.pc lib/et/com_err.pc \
lib/e2p/e2p.pc lib/blkid/blkid.pc lib/ext2fs/ext2fs.pc \
misc/Makefile ext2ed/Makefile e2fsck/Makefile \
@@ -102,92 +102,85 @@ Index: e2fsprogs-1.40.11/configure.in
resize/Makefile doc/Makefile intl/Makefile po/Makefile.in ; do
if test -d `dirname ${srcdir}/$i` ; then
outlist="$outlist $i"
-Index: e2fsprogs-1.40.11/configure
+Index: e2fsprogs-1.41.5/configure
===================================================================
---- e2fsprogs-1.40.11.orig/configure
-+++ e2fsprogs-1.40.11/configure
-@@ -689,6 +689,8 @@ STATIC_LIB_EXT
- PROFILED_LIB_EXT
- SWAPFS_CMT
+--- e2fsprogs-1.41.5.orig/configure
++++ e2fsprogs-1.41.5/configure
+@@ -699,6 +699,8 @@ PROFILED_LIBBLKID
+ DEPPROFILED_LIBBLKID
+ BLKID_CMT
DEBUGFS_CMT
+E2SCAN_CMT
+E2SCAN_MAN
IMAGER_CMT
RESIZER_CMT
FSCK_PROG
-@@ -759,6 +761,7 @@ SIZEOF_LONG_LONG
- SOCKET_LIB
- DLOPEN_LIB
- DB_LIB
-+SQLITE3_LIB
- UNI_DIFF_OPTS
- LINUX_CMT
- CYGWIN_CMT
-@@ -1380,6 +1383,7 @@ Optional Features:
- --enable-testio-debug enable the use of the test I/O manager for debugging
- --disable-swapfs disable support of legacy byte-swapped filesystems
+@@ -1385,6 +1387,7 @@ Optional Features:
+ --disable-testio-debug disable the use of the test I/O manager for debugging
+ --disable-libblkid do not build private blkid library
--disable-debugfs disable support of debugfs program
+ --disable-e2scan disable support of e2scan program
--disable-imager disable support of e2image program
--disable-resizer disable support of e2resize program
--enable-fsck build fsck wrapper program
-@@ -1406,6 +1410,7 @@ Optional Packages:
- --with-included-gettext use the GNU gettext library included here
+@@ -1410,6 +1413,7 @@ Optional Packages:
--with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib
--without-libintl-prefix don't search for libintl in includedir and libdir
+ --with-lustre=LUSTRE specify the path to Lustre sources for lfsck
+ --with-sqlite3=DIR static sqlite3 location
Some influential environment variables:
CC C compiler command
-@@ -4092,6 +4097,28 @@ DEBUGFS_CMT=
+@@ -4368,6 +4372,30 @@ DEBUGFS_CMT=
fi
-+# Check whether --enable-e2scan was given.
++# Check whether --enable-e2scan or --disable-e2scan was given.
+if test "${enable_e2scan+set}" = set; then
-+ enableval=$enable_e2scan; if test "$enableval" = "no"
++ enableval="$enable_e2scan"; if test "$enableval" = "no"
+then
-+ echo "Disabling e2scan support"
++ { echo "$as_me:$LINENO: result: Disabling e2scan support" >&5
++echo "${ECHO_T}Disabling e2scan support" >&6; }
+ E2SCAN_CMT="#"
+ E2SCAN_MAN=.\"
+else
+ E2SCAN_CMT=
+ E2SCAN_MAN=
-+ echo "Enabling e2scan support"
++ { echo "$as_me:$LINENO: result: Enabling e2scan support" >&5
++echo "${ECHO_T}Enabling e2scan support" >&6; }
+fi
+
+else
-+ echo "Enabling e2scan support by default"
++ { echo "$as_me:$LINENO: result: Enabling e2scan support by default" >&5
++echo "${ECHO_T}Enabling e2scan support by default" >&6; }
+E2SCAN_CMT=
+E2SCAN_MAN=
+
+fi
+
+
-+
# Check whether --enable-imager was given.
if test "${enable_imager+set}" = set; then
enableval=$enable_imager; if test "$enableval" = "no"
-@@ -12167,6 +12194,146 @@ fi
+@@ -12093,6 +12121,156 @@ fi
done
+for ac_header in sqlite3.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
-+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
-+ac_res=`eval echo '${'$as_ac_Header'}'`
-+ { echo "$as_me:$LINENO: result: $ac_res" >&5
-+echo "${ECHO_T}$ac_res" >&6; }
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
-+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
++echo "$as_me:$LINENO: checking $ac_header usability" >&5
++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
@@ -198,37 +191,41 @@ Index: e2fsprogs-1.40.11/configure
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
-+if { (ac_try="$ac_compile"
-+case "(($ac_try" in
-+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+ *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+ (eval "$ac_compile") 2>conftest.er1
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } && {
-+ test -z "$ac_c_werror_flag" ||
-+ test ! -s conftest.err
-+ } && test -s conftest.$ac_objext; then
++ (exit $ac_status); } &&
++ { ac_try='test -z "$ac_c_werror_flag"
++ || test ! -s conftest.err'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
-+ ac_header_compiler=no
++ac_header_compiler=no
+fi
-+
-+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-+echo "${ECHO_T}$ac_header_compiler" >&6; }
++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
++echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
-+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
++echo "$as_me:$LINENO: checking $ac_header presence" >&5
++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
@@ -237,22 +234,24 @@ Index: e2fsprogs-1.40.11/configure
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
-+if { (ac_try="$ac_cpp conftest.$ac_ext"
-+case "(($ac_try" in
-+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+ *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+ (exit $ac_status); } >/dev/null && {
-+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-+ test ! -s conftest.err
-+ }; then
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
@@ -260,10 +259,9 @@ Index: e2fsprogs-1.40.11/configure
+
+ ac_header_preproc=no
+fi
-+
+rm -f conftest.err conftest.$ac_ext
-+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-+echo "${ECHO_T}$ac_header_preproc" >&6; }
++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
++echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
@@ -287,19 +285,25 @@ Index: e2fsprogs-1.40.11/configure
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-+
++ (
++ cat <<\_ASBOX
++## ------------------------------------------ ##
++## Report this to the AC_PACKAGE_NAME lists. ##
++## ------------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
-+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
++echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
-+ac_res=`eval echo '${'$as_ac_Header'}'`
-+ { echo "$as_me:$LINENO: result: $ac_res" >&5
-+echo "${ECHO_T}$ac_res" >&6; }
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
@@ -315,23 +319,23 @@ Index: e2fsprogs-1.40.11/configure
for ac_header in sys/disk.h sys/mount.h
do
-@@ -15598,6 +15765,137 @@ _ACEOF
+@@ -15668,6 +15846,126 @@ _ACEOF
fi
+OLD_LIBS=$LIBS
+
-+# Check whether --with-sqlite3 was given.
++# Check whether --with-sqlite3 or --without-sqlite3 was given.
+if test "${with_sqlite3+set}" = set; then
-+ withval=$with_sqlite3;
-+fi
++ withval="$with_sqlite3"
+
++fi;
+if test x"$with_sqlite3" != x; then
+ LIBS="$with_sqlite3/libsqlite3.a"
+ as_ac_File=`echo "ac_cv_file_$LIBS" | $as_tr_sh`
-+{ echo "$as_me:$LINENO: checking for $LIBS" >&5
-+echo $ECHO_N "checking for $LIBS... $ECHO_C" >&6; }
-+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
++echo "$as_me:$LINENO: checking for $LIBS" >&5
++echo $ECHO_N "checking for $LIBS... $ECHO_C" >&6
++if eval "test \"\${$as_ac_File+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ test "$cross_compiling" = yes &&
@@ -344,9 +348,8 @@ Index: e2fsprogs-1.40.11/configure
+ eval "$as_ac_File=no"
+fi
+fi
-+ac_res=`eval echo '${'$as_ac_File'}'`
-+ { echo "$as_me:$LINENO: result: $ac_res" >&5
-+echo "${ECHO_T}$ac_res" >&6; }
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_File'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_File'}'`" >&6
+if test `eval echo '${'$as_ac_File'}'` = yes; then
+
+ LIBS="$LIBS -lpthread"
@@ -357,9 +360,9 @@ Index: e2fsprogs-1.40.11/configure
+ for lib in /lib /usr/lib /usr/local/lib; do
+ LIBS="$lib/libsqlite3.a"
+ as_ac_File=`echo "ac_cv_file_$LIBS" | $as_tr_sh`
-+{ echo "$as_me:$LINENO: checking for $LIBS" >&5
-+echo $ECHO_N "checking for $LIBS... $ECHO_C" >&6; }
-+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
++echo "$as_me:$LINENO: checking for $LIBS" >&5
++echo $ECHO_N "checking for $LIBS... $ECHO_C" >&6
++if eval "test \"\${$as_ac_File+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ test "$cross_compiling" = yes &&
@@ -372,9 +375,8 @@ Index: e2fsprogs-1.40.11/configure
+ eval "$as_ac_File=no"
+fi
+fi
-+ac_res=`eval echo '${'$as_ac_File'}'`
-+ { echo "$as_me:$LINENO: result: $ac_res" >&5
-+echo "${ECHO_T}$ac_res" >&6; }
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_File'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_File'}'`" >&6
+if test `eval echo '${'$as_ac_File'}'` = yes; then
+
+ LIBS="$LIBS -lpthread"
@@ -408,22 +410,13 @@ Index: e2fsprogs-1.40.11/configure
+
+_ACEOF
+rm -f conftest$ac_exeext
-+if { (ac_try="$ac_link"
-+case "(($ac_try" in
-+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+ *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+ (eval "$ac_link") 2>&5
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-+ { (case "(($ac_try" in
-+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+ *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+ (eval "$ac_try") 2>&5
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
@@ -442,18 +435,18 @@ Index: e2fsprogs-1.40.11/configure
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
-+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
-+
-+
+if test x"$SQLITE3_LIB" == x; then
+ { echo "$as_me:$LINENO: WARNING: no static sqlite3 - e2scan will not support database" >&5
+echo "$as_me: WARNING: no static sqlite3 - e2scan will not support database" >&2;}
+fi
++
++
{ echo "$as_me:$LINENO: checking for optreset" >&5
echo $ECHO_N "checking for optreset... $ECHO_C" >&6; }
if test "${ac_cv_have_optreset+set}" = set; then
-@@ -15829,7 +16127,7 @@ for i in MCONFIG Makefile e2fsprogs.spec
+@@ -16203,7 +16501,7 @@ for i in MCONFIG Makefile e2fsprogs.spec
lib/ss/ss.pc lib/uuid/uuid.pc lib/et/com_err.pc \
lib/e2p/e2p.pc lib/blkid/blkid.pc lib/ext2fs/ext2fs.pc \
misc/Makefile ext2ed/Makefile e2fsck/Makefile \
@@ -462,37 +455,37 @@ Index: e2fsprogs-1.40.11/configure
resize/Makefile doc/Makefile intl/Makefile po/Makefile.in ; do
if test -d `dirname ${srcdir}/$i` ; then
outlist="$outlist $i"
-@@ -16637,6 +16935,8 @@ for ac_last_try in false false false fal
- PROFILED_LIB_EXT!$PROFILED_LIB_EXT$ac_delim
- SWAPFS_CMT!$SWAPFS_CMT$ac_delim
+@@ -17021,6 +17319,8 @@ PROFILED_LIBBLKID!$PROFILED_LIBBLKID$ac_
+ DEPPROFILED_LIBBLKID!$DEPPROFILED_LIBBLKID$ac_delim
+ BLKID_CMT!$BLKID_CMT$ac_delim
DEBUGFS_CMT!$DEBUGFS_CMT$ac_delim
+E2SCAN_CMT!$E2SCAN_CMT$ac_delim
+E2SCAN_MAN!$E2SCAN_MAN$ac_delim
IMAGER_CMT!$IMAGER_CMT$ac_delim
RESIZER_CMT!$RESIZER_CMT$ac_delim
FSCK_PROG!$FSCK_PROG$ac_delim
-@@ -16707,6 +17007,7 @@ SIZEOF_LONG_LONG!$SIZEOF_LONG_LONG$ac_de
+@@ -17085,6 +17385,7 @@ SIZEOF_LONG_LONG!$SIZEOF_LONG_LONG$ac_de
SOCKET_LIB!$SOCKET_LIB$ac_delim
DLOPEN_LIB!$DLOPEN_LIB$ac_delim
DB_LIB!$DB_LIB$ac_delim
+SQLITE3_LIB!$SQLITE3_LIB$ac_delim
+ SEM_INIT_LIB!$SEM_INIT_LIB$ac_delim
UNI_DIFF_OPTS!$UNI_DIFF_OPTS$ac_delim
LINUX_CMT!$LINUX_CMT$ac_delim
- CYGWIN_CMT!$CYGWIN_CMT$ac_delim
-@@ -16727,7 +17028,7 @@ LIBOBJS!$LIBOBJS$ac_delim
+@@ -17106,7 +17407,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
-- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
-+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then
+- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-Index: e2fsprogs-1.40.11/e2fsprogs.spec.in
+Index: e2fsprogs-1.41.5/e2fsprogs.spec.in
===================================================================
---- e2fsprogs-1.40.11.orig/e2fsprogs.spec.in
-+++ e2fsprogs-1.40.11/e2fsprogs.spec.in
-@@ -144,6 +144,7 @@ exit 0
+--- e2fsprogs-1.41.5.orig/e2fsprogs.spec.in
++++ e2fsprogs-1.41.5/e2fsprogs.spec.in
+@@ -149,6 +149,7 @@ exit 0
%{_sbindir}/mklost+found
%{_sbindir}/e2freefrag
@LFSCK_CMT@%{_sbindir}/lfsck
@@ -500,18 +493,18 @@ Index: e2fsprogs-1.40.11/e2fsprogs.spec.in
%{_root_libdir}/libblkid.so.*
%{_root_libdir}/libcom_err.so.*
-@@ -175,6 +176,7 @@ exit 0
- %{_mandir}/man8/fsck.ext3.8*
+@@ -182,6 +183,7 @@ exit 0
+ %{_mandir}/man8/fsck.ext4dev.8*
%{_mandir}/man8/e2image.8*
%{_mandir}/man8/e2label.8*
+ at E2SCAN_CMT@%{_mandir}/man8/e2scan.8*
+ %{_mandir}/man8/e2undo.8*
%{_mandir}/man8/fsck.8*
%{_mandir}/man8/logsave.8*
- %{_mandir}/man8/mke2fs.8*
-Index: e2fsprogs-1.40.11/e2scan/db.c
+Index: e2fsprogs-1.41.5/e2scan/db.c
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.11/e2scan/db.c
++++ e2fsprogs-1.41.5/e2scan/db.c
@@ -0,0 +1,265 @@
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
@@ -778,10 +771,10 @@ Index: e2fsprogs-1.40.11/e2scan/db.c
+}
+
+#endif
-Index: e2fsprogs-1.40.11/e2scan/e2scan.8.in
+Index: e2fsprogs-1.41.5/e2scan/e2scan.8.in
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.11/e2scan/e2scan.8.in
++++ e2fsprogs-1.41.5/e2scan/e2scan.8.in
@@ -0,0 +1,116 @@
+.TH e2scan 1 "2006 Sep 26" Lustre "backup utilities"
+.SH NAME
@@ -899,11 +892,11 @@ Index: e2fsprogs-1.40.11/e2scan/e2scan.8.in
+and Andreas Dilger <adilger at sun.com>.
+.SH SEE ALSO
+.BR find (1)
-Index: e2fsprogs-1.40.11/e2scan/e2scan.c
+Index: e2fsprogs-1.41.5/e2scan/e2scan.c
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.11/e2scan/e2scan.c
-@@ -0,0 +1,632 @@
++++ e2fsprogs-1.41.5/e2scan/e2scan.c
+@@ -0,0 +1,640 @@
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+#define _XOPEN_SOURCE /* for getdate */
@@ -927,10 +920,13 @@ Index: e2fsprogs-1.40.11/e2scan/e2scan.c
+void usage(char *prog)
+{
+ fprintf(stderr,
-+ "\nUsage: %s {-l | -f} [ options ] device-filename\n"
-+ "Modes:"
-+ "\t-l: list recently changed files\n"
++#if defined(HAVE_SQLITE3) && defined(HAVE_SQLITE3_H)
++ "\nUsage: %s {-l | -f} [ options ] device-filename\nModes:"
+ "\t-f: create file database\n"
++#else
++ "\nUsage: %s -l [ options ] device-filename\nModes:"
++#endif
++ "\t-l: list recently changed files\n"
+ "Options:\n"
+ "\t-a groups: readahead 'groups' inode tables (default %d)\n"
+ "\t-b blocks: buffer 'blocks' inode table blocks\n"
@@ -1224,7 +1220,12 @@ Index: e2fsprogs-1.40.11/e2scan/e2scan.c
+ outfile = stdout;
+
+ opterr = 0;
-+ while ((c = getopt(argc, argv, "a:b:C:d:Dfhln:N:o:")) != EOF) {
++#if defined(HAVE_SQLITE3) && defined(HAVE_SQLITE3_H)
++#define OPTF "f"
++#else
++#define OPTF ""
++#endif
++ while ((c = getopt(argc, argv, "a:b:C:d:D"OPTF"hln:N:o:")) != EOF) {
+ char *end;
+
+ switch (c) {
@@ -1536,10 +1537,10 @@ Index: e2fsprogs-1.40.11/e2scan/e2scan.c
+
+ return 0;
+}
-Index: e2fsprogs-1.40.11/e2scan/Makefile.in
+Index: e2fsprogs-1.41.5/e2scan/Makefile.in
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.11/e2scan/Makefile.in
++++ e2fsprogs-1.41.5/e2scan/Makefile.in
@@ -0,0 +1,104 @@
+#
+# Standard e2fsprogs prologue....
@@ -1645,23 +1646,23 @@ Index: e2fsprogs-1.40.11/e2scan/Makefile.in
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-Index: e2fsprogs-1.40.11/Makefile.in
+Index: e2fsprogs-1.41.5/Makefile.in
===================================================================
---- e2fsprogs-1.40.11.orig/Makefile.in
-+++ e2fsprogs-1.40.11/Makefile.in
-@@ -9,9 +9,10 @@ INSTALL = @INSTALL@
-
+--- e2fsprogs-1.41.5.orig/Makefile.in
++++ e2fsprogs-1.41.5/Makefile.in
+@@ -12,9 +12,10 @@ INSTALL = @INSTALL@
@RESIZER_CMT at RESIZE_DIR= resize
@DEBUGFS_CMT at DEBUGFS_DIR= debugfs
+ @BLKID_CMT at BLKID_LIB_SUBDIR= lib/blkid
+ at E2SCAN_CMT@E2SCAN_DIR= e2scan
- LIB_SUBDIRS=lib/et lib/ss lib/ext2fs lib/e2p lib/uuid lib/blkid intl
+ LIB_SUBDIRS=lib/et lib/ss lib/e2p lib/uuid lib/ext2fs $(BLKID_LIB_SUBDIR) intl
-PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po
+PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po $(E2SCAN_DIR)
SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests
SUBS= lib/ext2fs/ext2_types.h lib/blkid/blkid_types.h lib/uuid/uuid_types.h
-@@ -52,7 +53,7 @@ distclean-doc:
+@@ -58,7 +59,7 @@ distclean-doc:
install: subs all-libs-recursive install-progs-recursive \
install-shlibs-libs-recursive install-doc-libs
@@ -1670,10 +1671,10 @@ Index: e2fsprogs-1.40.11/Makefile.in
install-strip: subs all-libs-recursive install-strip-progs-recursive \
install-shlibs-strip-libs-recursive install-doc-libs
-Index: e2fsprogs-1.40.11/lib/ext2fs/dblist.c
+Index: e2fsprogs-1.41.5/lib/ext2fs/dblist.c
===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/dblist.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/dblist.c
+--- e2fsprogs-1.41.5.orig/lib/ext2fs/dblist.c
++++ e2fsprogs-1.41.5/lib/ext2fs/dblist.c
@@ -149,7 +149,6 @@ errcode_t ext2fs_copy_dblist(ext2_dblist
* (moved to closefs.c)
*/
@@ -1682,19 +1683,10 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/dblist.c
/*
* Add a directory block to the directory block list
*/
-@@ -164,7 +163,7 @@ errcode_t ext2fs_add_dir_block(ext2_dbli
-
- if (dblist->count >= dblist->size) {
- old_size = dblist->size * sizeof(struct ext2_db_entry);
-- dblist->size += 100;
-+ dblist->size += dblist->size > 200 ? dblist->size / 2 : 100;
- retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
- sizeof(struct ext2_db_entry),
- &dblist->list);
-Index: e2fsprogs-1.40.11/e2scan/filelist.c
+Index: e2fsprogs-1.41.5/e2scan/filelist.c
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.11/e2scan/filelist.c
++++ e2fsprogs-1.41.5/e2scan/filelist.c
@@ -0,0 +1,455 @@
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
@@ -2151,10 +2143,10 @@ Index: e2fsprogs-1.40.11/e2scan/filelist.c
+ ret |= DIRENT_ABORT;
+ return ret;
+}
-Index: e2fsprogs-1.40.11/util/subst.conf.in
+Index: e2fsprogs-1.41.5/util/subst.conf.in
===================================================================
---- e2fsprogs-1.40.11.orig/util/subst.conf.in
-+++ e2fsprogs-1.40.11/util/subst.conf.in
+--- e2fsprogs-1.41.5.orig/util/subst.conf.in
++++ e2fsprogs-1.41.5/util/subst.conf.in
@@ -5,6 +5,8 @@ SS_DIR @SS_DIR@
E2FSPROGS_MONTH @E2FSPROGS_MONTH@
E2FSPROGS_YEAR @E2FSPROGS_YEAR@
diff --git a/debian/patches/e2fsprogs-eacheck.patch b/debian/patches/e2fsprogs-eacheck.patch
deleted file mode 100644
index 270c461..0000000
--- a/debian/patches/e2fsprogs-eacheck.patch
+++ /dev/null
@@ -1,459 +0,0 @@
-Verify in-inode EA structure.
-Allow in-inode EAs to have a checksum.
-Connect zero-length inodes that have an EA to lost+found.
-
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-
-Index: e2fsprogs-1.40.7/e2fsck/e2fsck.h
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.7/e2fsck/e2fsck.h
-@@ -477,6 +477,9 @@ extern void init_resource_track(struct r
- extern int inode_has_valid_blocks(struct ext2_inode *inode);
- extern void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
- struct ext2_inode * inode, const char * proc);
-+extern void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
-+ struct ext2_inode *inode,
-+ const int bufsize, const char *proc);
- extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
- struct ext2_inode * inode, const char * proc);
- extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
-Index: e2fsprogs-1.40.7/e2fsck/pass1.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass1.c
-+++ e2fsprogs-1.40.7/e2fsck/pass1.c
-@@ -264,6 +264,7 @@ static void check_ea_in_inode(e2fsck_t c
- remain = storage_size - sizeof(__u32);
-
- while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
-+ __u32 hash;
-
- /* header eats this space */
- remain -= sizeof(struct ext2_ext_attr_entry);
-@@ -291,9 +292,12 @@ static void check_ea_in_inode(e2fsck_t c
- problem = PR_1_ATTR_VALUE_BLOCK;
- goto fix;
- }
--
-- /* e_hash must be 0 in inode's ea */
-- if (entry->e_hash != 0) {
-+
-+ hash = ext2fs_ext_attr_hash_entry(entry,
-+ start + entry->e_value_offs);
-+
-+ /* e_hash may be 0 in older inode's ea */
-+ if (entry->e_hash != 0 && entry->e_hash != hash) {
- pctx->num = entry->e_hash;
- problem = PR_1_ATTR_HASH;
- goto fix;
-@@ -308,13 +312,10 @@ fix:
- * it seems like a corruption. it's very unlikely we could repair
- * EA(s) in automatic fashion -bzzz
- */
--#if 0
-- problem = PR_1_ATTR_HASH;
--#endif
- if (problem == 0 || !fix_problem(ctx, problem, pctx))
- return;
-
-- /* simple remove all possible EA(s) */
-+ /* simply remove all possible EA(s) */
- *((__u32 *)start) = 0UL;
- e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *) inode,
- EXT2_INODE_SIZE(sb), "pass1");
-@@ -1364,10 +1365,13 @@ static int check_ext_attr(e2fsck_t ctx,
- entry = (struct ext2_ext_attr_entry *)(header+1);
- end = block_buf + fs->blocksize;
- while ((char *)entry < end && *(__u32 *)entry) {
-+ __u32 hash;
-+
- if (region_allocate(region, (char *)entry - (char *)header,
- EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
-+ break;
- }
- if ((ctx->ext_attr_ver == 1 &&
- (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
-@@ -1375,6 +1379,7 @@ static int check_ext_attr(e2fsck_t ctx,
- entry->e_name_index == 0)) {
- if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
- goto clear_extattr;
-+ break;
- }
- if (entry->e_value_block != 0) {
- if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
-@@ -1391,6 +1396,17 @@ static int check_ext_attr(e2fsck_t ctx,
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
- }
-+
-+ hash = ext2fs_ext_attr_hash_entry(entry, block_buf +
-+ entry->e_value_offs);
-+
-+ if (entry->e_hash != hash) {
-+ pctx->num = entry->e_hash;
-+ if (fix_problem(ctx, PR_1_ATTR_HASH, pctx))
-+ goto clear_extattr;
-+ entry->e_hash = hash;
-+ }
-+
- entry = EXT2_EXT_ATTR_NEXT(entry);
- }
- if (region_allocate(region, (char *)entry - (char *)header, 4)) {
-@@ -1512,8 +1528,11 @@ static void check_blocks(e2fsck_t ctx, s
- }
- }
-
-- if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
-+ if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) {
-+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-+ goto out;
- pb.num_blocks++;
-+ }
-
- if (ext2fs_inode_has_valid_blocks(inode))
- pctx->errcode = ext2fs_block_iterate2(fs, ino,
-Index: e2fsprogs-1.40.7/e2fsck/pass4.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass4.c
-+++ e2fsprogs-1.40.7/e2fsck/pass4.c
-@@ -15,6 +15,7 @@
-
- #include "e2fsck.h"
- #include "problem.h"
-+#include <ext2fs/ext2_ext_attr.h>
-
- /*
- * This routine is called when an inode is not connected to the
-@@ -23,31 +24,41 @@
- * 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,
-+ struct ext2_inode *inode)
- {
- ext2_filsys fs = ctx->fs;
-- struct ext2_inode inode;
- struct problem_context pctx;
-+ __u32 eamagic = 0;
-+ int extra_size = 0;
-
-- e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
-+ if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE) {
-+ e2fsck_read_inode_full(ctx, i, inode,EXT2_INODE_SIZE(fs->super),
-+ "pass4: disconnect_inode");
-+ extra_size = ((struct ext2_inode_large *)inode)->i_extra_isize;
-+ } else {
-+ e2fsck_read_inode(ctx, i, inode, "pass4: disconnect_inode");
-+ }
- clear_problem_context(&pctx);
- pctx.ino = i;
-- pctx.inode = &inode;
-+ pctx.inode = inode;
-
-+ if (EXT2_INODE_SIZE(fs->super) -EXT2_GOOD_OLD_INODE_SIZE -extra_size >0)
-+ eamagic = *(__u32 *)(((char *)inode) +EXT2_GOOD_OLD_INODE_SIZE +
-+ extra_size);
- /*
- * Offer to delete any zero-length files that does not have
- * blocks. If there is an EA block, it might have useful
- * information, so we won't prompt to delete it, but let it be
- * reconnected to lost+found.
- */
-- if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
-- LINUX_S_ISDIR(inode.i_mode))) {
-+ if (!inode->i_blocks && eamagic != EXT2_EXT_ATTR_MAGIC &&
-+ (LINUX_S_ISREG(inode->i_mode) || LINUX_S_ISDIR(inode->i_mode))) {
- if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
- ext2fs_icount_store(ctx->inode_link_info, i, 0);
-- inode.i_links_count = 0;
-- inode.i_dtime = ctx->now;
-- e2fsck_write_inode(ctx, i, &inode,
-- "disconnect_inode");
-+ inode->i_links_count = 0;
-+ inode->i_dtime = ctx->now;
-+ e2fsck_write_inode(ctx, i, inode, "disconnect_inode");
- /*
- * Fix up the bitmaps...
- */
-@@ -55,7 +66,7 @@ static int disconnect_inode(e2fsck_t ctx
- ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
- ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
- ext2fs_inode_alloc_stats2(fs, i, -1,
-- LINUX_S_ISDIR(inode.i_mode));
-+ LINUX_S_ISDIR(inode->i_mode));
- return 0;
- }
- }
-@@ -83,7 +94,7 @@ void e2fsck_pass4(e2fsck_t ctx)
- {
- ext2_filsys fs = ctx->fs;
- ext2_ino_t i;
-- struct ext2_inode inode;
-+ struct ext2_inode *inode;
- #ifdef RESOURCE_TRACK
- struct resource_track rtrack;
- #endif
-@@ -111,6 +122,9 @@ void e2fsck_pass4(e2fsck_t ctx)
- if ((ctx->progress)(ctx, 4, 0, maxgroup))
- return;
-
-+ inode = e2fsck_allocate_memory(ctx, EXT2_INODE_SIZE(fs->super),
-+ "scratch inode");
-+
- /* Protect loop from wrap-around if s_inodes_count maxed */
- for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) {
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-@@ -138,7 +152,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))
-+ if (disconnect_inode(ctx, i, inode))
- continue;
- ext2fs_icount_fetch(ctx->inode_link_info, i,
- &link_count);
-@@ -146,18 +160,18 @@ void e2fsck_pass4(e2fsck_t ctx)
- &link_counted);
- }
- if (link_counted != link_count) {
-- e2fsck_read_inode(ctx, i, &inode, "pass4");
-+ e2fsck_read_inode(ctx, i, inode, "pass4");
- pctx.ino = i;
-- pctx.inode = &inode;
-- if (link_count != inode.i_links_count) {
-+ pctx.inode = inode;
-+ if (link_count != inode->i_links_count) {
- pctx.num = link_count;
- fix_problem(ctx,
- PR_4_INCONSISTENT_COUNT, &pctx);
- }
- pctx.num = link_counted;
- if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
-- inode.i_links_count = link_counted;
-- e2fsck_write_inode(ctx, i, &inode, "pass4");
-+ inode->i_links_count = link_counted;
-+ e2fsck_write_inode(ctx, i, inode, "pass4");
- }
- }
- }
-@@ -170,6 +184,8 @@ void e2fsck_pass4(e2fsck_t ctx)
- errout:
- if (buf)
- ext2fs_free_mem(&buf);
-+
-+ ext2fs_free_mem(&inode);
- #ifdef RESOURCE_TRACK
- if (ctx->options & E2F_OPT_TIME2) {
- e2fsck_clear_progbar(ctx);
-Index: e2fsprogs-1.40.7/e2fsck/problem.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.7/e2fsck/problem.c
-@@ -776,7 +776,7 @@ static struct e2fsck_problem problem_tab
-
- /* invalid ea entry->e_hash */
- { PR_1_ATTR_HASH,
-- N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
-+ N_("@a in @i %i has a hash (%N) which is @n\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* inode appears to be a directory */
-Index: e2fsprogs-1.40.7/e2fsck/util.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/util.c
-+++ e2fsprogs-1.40.7/e2fsck/util.c
-@@ -363,6 +363,20 @@ void e2fsck_read_inode(e2fsck_t ctx, uns
- }
- }
-
-+void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
-+ struct ext2_inode *inode, int bufsize,
-+ const char *proc)
-+{
-+ int retval;
-+
-+ retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize);
-+ if (retval) {
-+ com_err("ext2fs_read_inode_full", retval,
-+ _("while reading inode %ld in %s"), ino, proc);
-+ fatal_error(ctx, 0);
-+ }
-+}
-+
- extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
- struct ext2_inode * inode, int bufsize,
- const char *proc)
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_ext_attr.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
-@@ -30,7 +30,7 @@ struct ext2_ext_attr_entry {
- __u32 e_value_block; /* disk block attribute is stored on (n/i) */
- __u32 e_value_size; /* size of attribute value */
- __u32 e_hash; /* hash value of name and value */
--#if 0
-+#if 1
- char e_name[0]; /* attribute name */
- #endif
- };
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-@@ -83,10 +83,12 @@ typedef __u32 ext2_dirhash_t;
- #include "com_err.h"
- #include "ext2_io.h"
- #include "ext2_err.h"
-+#include "ext2_ext_attr.h"
- #else
- #include <et/com_err.h>
- #include <ext2fs/ext2_io.h>
- #include <ext2fs/ext2_err.h>
-+#include <ext2fs/ext2_ext_attr.h>
- #endif
-
- /*
-@@ -715,6 +717,8 @@ extern errcode_t ext2fs_dup_handle(ext2_
- extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
-
- /* ext_attr.c */
-+extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
-+ void *data);
- extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
- extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
- void *buf);
-@@ -942,6 +946,10 @@ extern errcode_t ext2fs_copy_bitmap(ext2
- /* swapfs.c */
- extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
- int has_header);
-+extern void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
-+ struct ext2_ext_attr_header *from_hdr);
-+extern void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
-+ struct ext2_ext_attr_entry *from_entry);
- extern void ext2fs_swap_super(struct ext2_super_block * super);
- extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
- extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext_attr.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
-@@ -23,6 +23,43 @@
-
- #include "ext2fs.h"
-
-+#define NAME_HASH_SHIFT 5
-+#define VALUE_HASH_SHIFT 16
-+
-+/*
-+ * ext2_xattr_hash_entry()
-+ *
-+ * Compute the hash of an extended attribute.
-+ */
-+__u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry, void *data)
-+{
-+ __u32 hash = 0;
-+ char *name = entry->e_name;
-+ int n;
-+
-+ for (n = 0; n < entry->e_name_len; n++) {
-+ hash = (hash << NAME_HASH_SHIFT) ^
-+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
-+ *name++;
-+ }
-+
-+ /* The hash needs to be calculated on the data in little-endian. */
-+ if (entry->e_value_block == 0 && entry->e_value_size != 0) {
-+ __u32 *value = (__u32 *)data;
-+ for (n = (entry->e_value_size + EXT2_EXT_ATTR_ROUND) >>
-+ EXT2_EXT_ATTR_PAD_BITS; n; n--) {
-+ hash = (hash << VALUE_HASH_SHIFT) ^
-+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
-+ ext2fs_le32_to_cpu(*value++);
-+ }
-+ }
-+
-+ return hash;
-+}
-+
-+#undef NAME_HASH_SHIFT
-+#undef VALUE_HASH_SHIFT
-+
- errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
- {
- errcode_t retval;
-Index: e2fsprogs-1.40.7/lib/ext2fs/swapfs.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/swapfs.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/swapfs.c
-@@ -90,6 +90,29 @@ void ext2fs_swap_group_desc(struct ext2_
- gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
- }
-
-+void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
-+ struct ext2_ext_attr_header *from_header)
-+{
-+ int n;
-+
-+ to_header->h_magic = ext2fs_swab32(from_header->h_magic);
-+ to_header->h_blocks = ext2fs_swab32(from_header->h_blocks);
-+ to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
-+ to_header->h_hash = ext2fs_swab32(from_header->h_hash);
-+ for (n = 0; n < 4; n++)
-+ to_header->h_reserved[n] =
-+ ext2fs_swab32(from_header->h_reserved[n]);
-+}
-+
-+void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
-+ struct ext2_ext_attr_entry *from_entry)
-+{
-+ to_entry->e_value_offs = ext2fs_swab16(from_entry->e_value_offs);
-+ to_entry->e_value_block = ext2fs_swab32(from_entry->e_value_block);
-+ to_entry->e_value_size = ext2fs_swab32(from_entry->e_value_size);
-+ to_entry->e_hash = ext2fs_swab32(from_entry->e_hash);
-+}
-+
- void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
- {
- struct ext2_ext_attr_header *from_header =
-@@ -98,32 +121,22 @@ void ext2fs_swap_ext_attr(char *to, char
- (struct ext2_ext_attr_header *)to;
- struct ext2_ext_attr_entry *from_entry, *to_entry;
- char *from_end = (char *)from_header + bufsize;
-- int n;
-
- if (to_header != from_header)
- memcpy(to_header, from_header, bufsize);
-
-- from_entry = (struct ext2_ext_attr_entry *)from_header;
-- to_entry = (struct ext2_ext_attr_entry *)to_header;
--
- if (has_header) {
-- to_header->h_magic = ext2fs_swab32(from_header->h_magic);
-- to_header->h_blocks = ext2fs_swab32(from_header->h_blocks);
-- to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
-- for (n=0; n<4; n++)
-- to_header->h_reserved[n] =
-- ext2fs_swab32(from_header->h_reserved[n]);
-+ ext2fs_swap_ext_attr_header(to_header, from_header);
-+
- from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
- to_entry = (struct ext2_ext_attr_entry *)(to_header+1);
-+ } else {
-+ from_entry = (struct ext2_ext_attr_entry *)from_header;
-+ to_entry = (struct ext2_ext_attr_entry *)to_header;
- }
-
- while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
-- to_entry->e_value_offs =
-- ext2fs_swab16(from_entry->e_value_offs);
-- to_entry->e_value_block =
-- ext2fs_swab32(from_entry->e_value_block);
-- to_entry->e_value_size =
-- ext2fs_swab32(from_entry->e_value_size);
-+ ext2fs_swap_ext_attr_entry(to_entry, from_entry);
- from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
- to_entry = EXT2_EXT_ATTR_NEXT(to_entry);
- }
diff --git a/debian/patches/e2fsprogs-expand-extra-isize.patch b/debian/patches/e2fsprogs-expand-extra-isize.patch
index 88e6d88..493abd7 100644
--- a/debian/patches/e2fsprogs-expand-extra-isize.patch
+++ b/debian/patches/e2fsprogs-expand-extra-isize.patch
@@ -9,10 +9,10 @@ version fields are required for all inodes in the filesystem.
Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext_attr.c
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext_attr.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext_attr.c 2009-02-27 22:56:41.000000000 -0500
++++ e2fsprogs-1.41.6/lib/ext2fs/ext_attr.c 2009-06-10 08:01:08.000000000 -0400
@@ -17,6 +17,7 @@
#endif
#include <string.h>
@@ -61,17 +61,17 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
+ retval = io_channel_read_blk(fs->io, block, 1, buf);
if (retval)
return retval;
- #ifdef EXT2FS_ENABLE_SWAPFS
-@@ -92,7 +121,7 @@ errcode_t ext2fs_write_ext_attr(ext2_fil
- } else
+ #ifdef WORDS_BIGENDIAN
+@@ -88,7 +117,7 @@ errcode_t ext2fs_write_ext_attr(ext2_fil
+ #else
+ write_buf = (char *) inbuf;
#endif
- write_buf = (char *) inbuf;
- retval = io_channel_write_blk(fs->io, block, 1, write_buf);
+ retval = io_channel_write_blk(fs->io, block, 1, write_buf);
if (buf)
ext2fs_free_mem(&buf);
if (!retval)
-@@ -126,7 +155,10 @@ errcode_t ext2fs_adjust_ea_refcount(ext2
+@@ -122,7 +151,10 @@ errcode_t ext2fs_adjust_ea_refcount(ext2
if (retval)
goto errout;
@@ -83,7 +83,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
header->h_refcount += adjust;
if (newcount)
*newcount = header->h_refcount;
-@@ -140,3 +172,881 @@ errout:
+@@ -136,3 +168,881 @@ errout:
ext2fs_free_mem(&buf);
return retval;
}
@@ -965,11 +965,11 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext_attr.c
+
+ return error;
+}
-Index: e2fsprogs-1.40.7/e2fsck/unix.c
+Index: e2fsprogs-1.41.6/e2fsck/unix.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.7/e2fsck/unix.c
-@@ -620,6 +620,12 @@ static void parse_extended_opts(e2fsck_t
+--- e2fsprogs-1.41.6.orig/e2fsck/unix.c 2009-06-10 07:30:47.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/unix.c 2009-06-10 08:01:08.000000000 -0400
+@@ -658,6 +658,12 @@ static void parse_extended_opts(e2fsck_t
extended_usage++;
continue;
}
@@ -982,15 +982,15 @@ Index: e2fsprogs-1.40.7/e2fsck/unix.c
} else {
fprintf(stderr, _("Unknown extended option: %s\n"),
token);
-@@ -636,6 +642,7 @@ static void parse_extended_opts(e2fsck_t
- "\tshared=<preserve|lost+found|delete>\n"
- "\tclone=<dup|zero>\n"
- "\tea_ver=<ea_version (1 or 2)>\n"
-+ "\texpand_extra_isize\n"
- "\n"), stderr);
+@@ -675,6 +681,7 @@ static void parse_extended_opts(e2fsck_t
+ fputs(("\tfragcheck\n"), stderr);
+ fputs(("\tshared=<preserve|lost+found|delete>\n"), stderr);
+ fputs(("\tclone=<dup|zero>\n"), stderr);
++ fputs(("\texpand_extra_isize\n"), stderr);
+ fputc('\n', stderr);
exit(1);
}
-@@ -1302,6 +1309,54 @@ print_unsupp_features:
+@@ -1357,6 +1364,54 @@ print_unsupp_features:
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
fatal_error(ctx, 0);
check_if_skip(ctx);
@@ -1042,13 +1042,13 @@ Index: e2fsprogs-1.40.7/e2fsck/unix.c
+ ctx->flags |= E2F_FLAG_EXPAND_EISIZE;
+ }
+
+ check_resize_inode(ctx);
if (bad_blocks_file)
read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
- else if (cflag)
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2_ext_attr.h
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_ext_attr.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2_ext_attr.h 2009-02-14 08:49:08.000000000 -0500
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2_ext_attr.h 2009-06-10 08:01:08.000000000 -0400
@@ -15,6 +15,9 @@
/* Maximum number of references to one attribute block */
#define EXT2_EXT_ATTR_REFCOUNT_MAX 1024
@@ -1059,19 +1059,25 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
struct ext2_ext_attr_header {
__u32 h_magic; /* magic number for identification */
__u32 h_refcount; /* reference count */
-@@ -35,6 +38,32 @@ struct ext2_ext_attr_entry {
+@@ -30,11 +33,37 @@ struct ext2_ext_attr_entry {
+ __u32 e_value_block; /* disk block attribute is stored on (n/i) */
+ __u32 e_value_size; /* size of attribute value */
+ __u32 e_hash; /* hash value of name and value */
+-#if 0
++#if 1
+ char e_name[0]; /* attribute name */
#endif
};
+#define BHDR(block) ((struct ext2_ext_attr_header *) block)
-+#define IHDR(inode) \
-+ ((__u32 *) ((char *)inode + \
++#define IHDR(inode) \
++ ((__u32 *) ((char *)inode + \
+ EXT2_GOOD_OLD_INODE_SIZE + \
+ (inode)->i_extra_isize))
+#define ENTRY(ptr) ((struct ext2_ext_attr_entry *)(ptr))
+
+/* Name indexes */
-+#define EXT2_ATTR_INDEX_USER 1
++#define EXT2_ATTR_INDEX_USER 1
+#define EXT2_ATTR_INDEX_POSIX_ACL_ACCESS 2
+#define EXT2_ATTR_INDEX_POSIX_ACL_DEFAULT 3
+#define EXT2_ATTR_INDEX_TRUSTED 4
@@ -1092,19 +1098,19 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_ext_attr.h
#define EXT2_EXT_ATTR_PAD_BITS 2
#define EXT2_EXT_ATTR_PAD ((unsigned) 1<<EXT2_EXT_ATTR_PAD_BITS)
#define EXT2_EXT_ATTR_ROUND (EXT2_EXT_ATTR_PAD-1)
-Index: e2fsprogs-1.40.7/e2fsck/e2fsck.h
+Index: e2fsprogs-1.41.6/e2fsck/e2fsck.h
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.7/e2fsck/e2fsck.h
-@@ -171,6 +171,7 @@ struct resource_track {
- #define E2F_FLAG_RESTARTED 0x0200 /* E2fsck has been restarted */
+--- e2fsprogs-1.41.6.orig/e2fsck/e2fsck.h 2009-06-10 07:30:47.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/e2fsck.h 2009-06-10 08:01:08.000000000 -0400
+@@ -176,6 +176,7 @@ struct resource_track {
#define E2F_FLAG_RESIZE_INODE 0x0400 /* Request to recreate resize inode */
#define E2F_FLAG_GOT_DEVSIZE 0x0800 /* Device size has been fetched */
+ #define E2F_FLAG_EXITING 0x1000 /* E2fsck exiting due to errors */
+#define E2F_FLAG_EXPAND_EISIZE 0x2000 /* Expand the inodes (i_extra_isize) */
/*
* Defines for indicating the e2fsck pass number
-@@ -348,6 +349,15 @@ struct e2fsck_struct {
+@@ -357,6 +358,15 @@ struct e2fsck_struct {
profile_t profile;
int blocks_per_page;
@@ -1120,29 +1126,24 @@ Index: e2fsprogs-1.40.7/e2fsck/e2fsck.h
/*
* For the use of callers of the e2fsck functions; not used by
* e2fsck functions themselves.
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2_fs.h
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
-@@ -415,10 +415,17 @@ struct ext2_inode_large {
- __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
- __u32 i_crtime; /* File creation time */
- __u32 i_crtime_extra; /* extra File creation time (nsec << 2 | epoch)*/
-+ __u32 i_version_hi; /* high 32 bits for 64-bit version */
- };
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2_fs.h 2009-02-27 22:57:34.000000000 -0500
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2_fs.h 2009-06-10 08:01:08.000000000 -0400
+@@ -421,6 +421,12 @@ struct ext2_inode_large {
#define i_size_high i_dir_acl
-+#define EXT2_FITS_IN_INODE(inode, field) \
-+ ((offsetof(struct ext2_inode_large, field) + \
-+ sizeof((inode)->field)) <= \
-+ (EXT2_GOOD_OLD_INODE_SIZE + \
-+ (inode)->i_extra_isize)) \
++#define EXT2_FITS_IN_INODE(inode, field) \
++ ((offsetof(struct ext2_inode_large, field) + \
++ sizeof((inode)->field)) <= \
++ (EXT2_GOOD_OLD_INODE_SIZE + \
++ (inode)->i_extra_isize)) \
+
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
-@@ -661,6 +668,7 @@ struct ext2_super_block {
+@@ -651,6 +657,7 @@ struct ext2_super_block {
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
@@ -1150,10 +1151,10 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
/*
-Index: e2fsprogs-1.40.7/e2fsck/pass1.c
+Index: e2fsprogs-1.41.6/e2fsck/pass1.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass1.c
-+++ e2fsprogs-1.40.7/e2fsck/pass1.c
+--- e2fsprogs-1.41.6.orig/e2fsck/pass1.c 2009-06-10 07:30:33.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/pass1.c 2009-06-10 08:01:08.000000000 -0400
@@ -23,6 +23,7 @@
* - A bitmap of which inodes have bad fields. (inode_bad_map)
* - A bitmap of which inodes are in bad blocks. (inode_bb_map)
@@ -1162,7 +1163,7 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
* - A bitmap of which blocks are in use. (block_found_map)
* - A bitmap of which blocks are in use by two inodes (block_dup_map)
* - The data blocks of the directory inodes. (dir_map)
-@@ -353,16 +354,27 @@ static void check_inode_extra_space(e2fs
+@@ -381,18 +382,30 @@ static void check_inode_extra_space(e2fs
(inode->i_extra_isize < min || inode->i_extra_isize > max)) {
if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
return;
@@ -1177,6 +1178,7 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
- inode->i_extra_isize);
- if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
- /* it seems inode has an extended attribute(s) in body */
+- check_ea_in_inode(ctx, pctx);
+ eamagic = IHDR(inode);
+ if (*eamagic != EXT2_EXT_ATTR_MAGIC &&
+ (ctx->flags & E2F_FLAG_EXPAND_EISIZE) &&
@@ -1191,11 +1193,14 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
+ "check_inode_extra_space");
+ if (inode->i_extra_isize < ctx->min_extra_isize)
+ ctx->min_extra_isize = inode->i_extra_isize;
-+ } else {
- check_ea_in_inode(ctx, pctx);
}
++
++ if (*eamagic == EXT2_EXT_ATTR_MAGIC)
++ check_ea_in_inode(ctx, pctx);
}
-@@ -468,6 +480,156 @@ extern void e2fsck_setup_tdb_icount(e2fs
+
+ /*
+@@ -500,6 +513,156 @@ extern void e2fsck_setup_tdb_icount(e2fs
*ret = 0;
}
@@ -1352,17 +1357,18 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
void e2fsck_pass1(e2fsck_t ctx)
{
int i;
-@@ -490,6 +652,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+@@ -520,6 +683,8 @@ void e2fsck_pass1(e2fsck_t ctx)
+ int imagic_fs, extent_fs;
+ int busted_fs_time = 0;
int inode_size;
- struct ext3_extent_header *eh;
- int extent_fs;
+ int inode_exp = 0;
++
- #ifdef RESOURCE_TRACK
- init_resource_track(&rtrack);
-@@ -984,6 +1147,22 @@ void e2fsck_pass1(e2fsck_t ctx)
- }
- }
+ init_resource_track(&rtrack, ctx->fs->io);
+ clear_problem_context(&pctx);
+@@ -1037,6 +1202,22 @@ void e2fsck_pass1(e2fsck_t ctx)
+ } else
+ check_blocks(ctx, &pctx, block_buf);
+ if (ctx->flags & E2F_FLAG_EXPAND_EISIZE) {
+ struct ext2_inode_large *inode_l;
@@ -1383,7 +1389,7 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
return;
-@@ -1286,11 +1465,17 @@ static void adjust_extattr_refcount(e2fs
+@@ -1336,11 +1517,17 @@ static void adjust_extattr_refcount(e2fs
break;
pctx.blk = blk;
pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
@@ -1402,7 +1408,7 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
pctx.blkcount = header->h_refcount;
should_be = header->h_refcount + adjust_sign * count;
pctx.num = should_be;
-@@ -1396,7 +1581,7 @@ static int check_ext_attr(e2fsck_t ctx,
+@@ -1446,7 +1633,7 @@ static int check_ext_attr(e2fsck_t ctx,
pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
goto clear_extattr;
@@ -1411,11 +1417,11 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
pctx->blk = inode->i_file_acl;
if (((ctx->ext_attr_ver == 1) &&
(header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2fs.h
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-@@ -426,6 +426,12 @@ typedef struct ext2_icount *ext2_icount_
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2fs.h 2009-05-28 10:16:41.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2fs.h 2009-06-10 08:01:08.000000000 -0400
+@@ -491,6 +491,12 @@ typedef struct ext2_icount *ext2_icount_
#define EXT2_CHECK_MAGIC(struct, code) \
if ((struct)->magic != (code)) return (code)
@@ -1423,20 +1429,12 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
+ * Flags for returning status of ext2fs_expand_extra_isize()
+ */
+#define EXT2_EXPAND_EISIZE_UNSAFE 0x0001
-+#define EXT2_EXPAND_EISIZE_NEW_BLOCK 0x0002
++#define EXT2_EXPAND_EISIZE_NEW_BLOCK 0x0002
+#define EXT2_EXPAND_EISIZE_NOSPC 0x0004
/*
* For ext2 compression support
-@@ -469,6 +475,7 @@ typedef struct ext2_icount *ext2_icount_
- #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
-+ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| \
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
-
- /*
-@@ -730,6 +737,16 @@ extern errcode_t ext2fs_expand_dir(ext2_
+@@ -828,6 +834,16 @@ extern errcode_t ext2fs_expand_dir(ext2_
/* ext_attr.c */
extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
void *data);
@@ -1453,30 +1451,30 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
void *buf);
-Index: e2fsprogs-1.40.7/e2fsck/problem.h
+Index: e2fsprogs-1.41.6/e2fsck/problem.h
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.7/e2fsck/problem.h
-@@ -212,6 +212,16 @@ struct problem_context {
- /* Last group block bitmap is uninitialized. */
- #define PR_0_BB_UNINIT_LAST 0x000039
+--- e2fsprogs-1.41.6.orig/e2fsck/problem.h 2009-06-10 07:30:47.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/problem.h 2009-06-10 08:01:08.000000000 -0400
+@@ -218,6 +218,16 @@ struct problem_context {
+ /* The test_fs filesystem flag is set and ext4 is available */
+ #define PR_0_CLEAR_TESTFS_FLAG 0x00003B
+/* Invalid s_min_extra_isize */
-+#define PR_0_MIN_EXTRA_ISIZE_INVALID 0x00003A
++#define PR_0_MIN_EXTRA_ISIZE_INVALID 0x000040
+
+/* Invalid s_want_extra_isize */
-+#define PR_0_WANT_EXTRA_ISIZE_INVALID 0x00003B
++#define PR_0_WANT_EXTRA_ISIZE_INVALID 0x000041
+
+/* Clear EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE flag */
-+#define PR_0_CLEAR_EXTRA_ISIZE 0x00003C
++#define PR_0_CLEAR_EXTRA_ISIZE 0x000042
+
+
/*
* Pass 1 errors
*/
-@@ -498,6 +508,25 @@ struct problem_context {
- /* extent/index was modified & repaired - not really a problem */
- #define PR_1_EXTENT_CHANGED 0x010067
+@@ -519,6 +529,25 @@ struct problem_context {
+ /* eh_depth for in-inode header is bad */
+ #define PR_1_EXTENT_EH_DEPTH_BAD 0x010063
+/* Warning for user that all inodes need to be expanded atleast by
+ * s_min_extra_isize
@@ -1500,7 +1498,7 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.h
/*
* Pass 1b errors
*/
-@@ -961,6 +990,9 @@ struct problem_context {
+@@ -989,6 +1018,9 @@ struct problem_context {
/* Inode in use but group is marked INODE_UNINIT */
#define PR_5_INODE_UNINIT 0x050019
@@ -1510,13 +1508,13 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.h
/*
* Post-Pass 5 errors
*/
-Index: e2fsprogs-1.40.7/e2fsck/problem.c
+Index: e2fsprogs-1.41.6/e2fsck/problem.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.7/e2fsck/problem.c
-@@ -376,6 +376,19 @@ static struct e2fsck_problem problem_tab
- N_("last @g @b @B uninitialized. "),
- PROMPT_FIX, PR_PREEN_OK },
+--- e2fsprogs-1.41.6.orig/e2fsck/problem.c 2009-06-10 07:30:47.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/problem.c 2009-06-10 08:01:08.000000000 -0400
+@@ -385,6 +385,19 @@ static struct e2fsck_problem problem_tab
+ N_("The test_fs flag is set (and ext4 is available). "),
+ PROMPT_CLEAR, PR_PREEN_OK },
+ { PR_0_MIN_EXTRA_ISIZE_INVALID,
+ N_("@S has invalid s_min_extra_isize. "),
@@ -1534,9 +1532,9 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.c
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */
-@@ -849,6 +862,38 @@ static struct e2fsck_problem problem_tab
- N_("@i %i has high 16 bits of extent/index @b set\n"),
- PROMPT_CLEAR, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
+@@ -888,6 +901,38 @@ static struct e2fsck_problem problem_tab
+ N_("@i %i has extent header with incorrect eh_depth\n"),
+ PROMPT_FIX, 0 },
+ /* expand inode */
+ { PR_1_EXPAND_EISIZE_WARNING,
@@ -1545,7 +1543,7 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.c
+ "Inode %i does not have enough free space. Either some EAs\n"
+ "need to be deleted from this inode or the RO_COMPAT_EXTRA_ISIZE\n"
+ "flag must be cleared.\n\n"), PROMPT_NONE, PR_PREEN_OK | PR_NO_OK |
-+ PR_PREEN_NOMSG },
++ PR_PREEN_NOMSG },
+
+ /* expand inode */
+ { PR_1_EXPAND_EISIZE,
@@ -1573,7 +1571,7 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.c
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
-@@ -1587,6 +1632,11 @@ static struct e2fsck_problem problem_tab
+@@ -1635,6 +1680,11 @@ static struct e2fsck_problem problem_tab
N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"),
PROMPT_FIX, PR_PREEN_OK },
@@ -1582,26 +1580,26 @@ Index: e2fsprogs-1.40.7/e2fsck/problem.c
+ N_("Expanding @i %i.\n"),
+ PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
+
+ /* Post-Pass 5 errors */
+
/* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
- { PR_6_RECREATE_JOURNAL,
- N_("Recreate journal to make the filesystem ext3 again?\n"),
-Index: e2fsprogs-1.40.7/e2fsck/e2fsck.c
+Index: e2fsprogs-1.41.6/e2fsck/e2fsck.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/e2fsck.c
-+++ e2fsprogs-1.40.7/e2fsck/e2fsck.c
-@@ -151,6 +151,7 @@ errcode_t e2fsck_reset_context(e2fsck_t
- ctx->fs_tind_count = 0;
+--- e2fsprogs-1.41.6.orig/e2fsck/e2fsck.c 2009-02-27 22:56:41.000000000 -0500
++++ e2fsprogs-1.41.6/e2fsck/e2fsck.c 2009-06-10 08:01:08.000000000 -0400
+@@ -155,6 +155,7 @@ errcode_t e2fsck_reset_context(e2fsck_t
ctx->fs_fragmented = 0;
+ ctx->fs_fragmented_dir = 0;
ctx->large_files = 0;
+ ctx->fs_unexpanded_inodes = 0;
- /* Reset the superblock to the user's requested value */
- ctx->superblock = ctx->use_superblock;
-Index: e2fsprogs-1.40.7/e2fsck/pass5.c
+ for (i=0; i < MAX_EXTENT_DEPTH_COUNT; i++)
+ ctx->extent_depth_count[i] = 0;
+Index: e2fsprogs-1.41.6/e2fsck/pass5.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass5.c
-+++ e2fsprogs-1.40.7/e2fsck/pass5.c
-@@ -64,6 +64,42 @@ void e2fsck_pass5(e2fsck_t ctx)
+--- e2fsprogs-1.41.6.orig/e2fsck/pass5.c 2009-06-10 07:30:27.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/pass5.c 2009-06-10 08:02:11.000000000 -0400
+@@ -61,6 +61,42 @@ void e2fsck_pass5(e2fsck_t ctx)
ext2fs_free_block_bitmap(ctx->block_found_map);
ctx->block_found_map = 0;
@@ -1641,16 +1639,16 @@ Index: e2fsprogs-1.40.7/e2fsck/pass5.c
+ ext2fs_mark_super_dirty(ctx->fs);
+ }
+
- #ifdef RESOURCE_TRACK
- if (ctx->options & E2F_OPT_TIME2) {
- e2fsck_clear_progbar(ctx);
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_err.et.in
+ print_resource_track(ctx, _("Pass 5"), &rtrack, ctx->fs->io);
+ }
+
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2_err.et.in
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_err.et.in
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_err.et.in
-@@ -338,5 +338,29 @@ ec EXT2_ET_EXTENT_LEAF_BAD,
- ec EXT2_ET_EXTENT_NO_SPACE,
- "No free space in extent map"
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2_err.et.in 2009-05-29 00:09:50.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2_err.et.in 2009-06-10 08:01:08.000000000 -0400
+@@ -419,4 +419,28 @@ ec EXT2_ET_IO_CHANNEL_NO_SUPPORT_64,
+ ec EXT2_NO_MTAB_FILE,
+ "Can't check if filesystem is mounted due to missing mtab file"
+ec EXT2_ET_EA_BAD_MAGIC,
+ "Extended attribute block has bad magic value"
@@ -1677,4 +1675,3 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_err.et.in
+ "Extended attribute name already exists"
+
end
-
diff --git a/debian/patches/e2fsprogs-extended_ops.patch b/debian/patches/e2fsprogs-extended_ops.patch
index 4d36ed4..bfda885 100644
--- a/debian/patches/e2fsprogs-extended_ops.patch
+++ b/debian/patches/e2fsprogs-extended_ops.patch
@@ -2,11 +2,11 @@ Minor reformatting patch to make applying later patches easier.
Signed-off-by: Andreas Dilger <adilger at sun.com>
-Index: e2fsprogs-cfs/e2fsck/unix.c
+Index: e2fsprogs-1.41.1/e2fsck/unix.c
===================================================================
---- e2fsprogs-cfs.orig/e2fsck/unix.c
-+++ e2fsprogs-cfs/e2fsck/unix.c
-@@ -537,14 +537,13 @@ static void parse_extended_opts(e2fsck_t
+--- e2fsprogs-1.41.1.orig/e2fsck/unix.c
++++ e2fsprogs-1.41.1/e2fsck/unix.c
+@@ -561,14 +561,13 @@ static void parse_extended_opts(e2fsck_t
continue;
}
ea_ver = strtoul(arg, &p, 0);
@@ -22,16 +22,6 @@ Index: e2fsprogs-cfs/e2fsck/unix.c
continue;
}
- ctx->ext_attr_ver = ea_ver;
- } else {
- fprintf(stderr, _("Unknown extended option: %s\n"),
- token);
-@@ -558,7 +557,8 @@ static void parse_extended_opts(e2fsck_t
- "and may take an argument which\n"
- "is set off by an equals ('=') sign. "
- "Valid extended options are:\n"
-- "\tea_ver=<ea_version (1 or 2)>\n\n"), stderr);
-+ "\tea_ver=<ea_version (1 or 2)>\n"
-+ "\n"), stderr);
- exit(1);
- }
- }
+ } else if (strcmp(token, "fragcheck") == 0) {
+ ctx->options |= E2F_OPT_FRAGCHECK;
+ continue;
diff --git a/debian/patches/e2fsprogs-extents.patch b/debian/patches/e2fsprogs-extents.patch
index 7ecb771..a18747c 100644
--- a/debian/patches/e2fsprogs-extents.patch
+++ b/debian/patches/e2fsprogs-extents.patch
@@ -1,82 +1,8 @@
-Support for checking 32-bit extents format inodes and the INCOMPAT_EXTENTS
-feature.
-
-Clear the high 16 bits of extents and index entries, since the
-extents patches did not do this explicitly. Some parts of this
-code need fixing for checking > 32-bit block filesystems (when
-INCOMPAT_64BIT support is added), marked "FIXME: 48-bit support".
-
-Verify extent headers in blocks, logical ordering of extents,
-logical ordering of indexes.
-
-Add explicit checking of {d,t,}indirect and index blocks to detect
-corruption instead of implicitly doing this by checking the referred
-blocks and only block-at-a-time correctness. This avoids incorrectly
-invoking the very lengthy duplicate blocks pass for bad indirect/index
-blocks. We may want to tune the "threshold" for how many errors make
-a "bad" indirect/index block.
-
-Add ability to split or remove extents in order to allow extent
-reallocation during the duplicate blocks pass.
-
-Index: e2fsprogs-1.40.11/e2fsck/Makefile.in
+Index: e2fsprogs-1.41.4/e2fsck/pass1.c
===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/Makefile.in
-+++ e2fsprogs-1.40.11/e2fsck/Makefile.in
-@@ -257,6 +257,7 @@ super.o: $(srcdir)/super.c $(top_srcdir)
- pass1.o: $(srcdir)/pass1.c $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
-+ $(top_srcdir)/lib/ext2fs/ext3_extents.h \
- $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(top_srcdir)/lib/blkid/blkid.h $(top_builddir)/lib/blkid/blkid_types.h \
-Index: e2fsprogs-1.40.11/e2fsck/e2fsck.h
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.11/e2fsck/e2fsck.h
-@@ -326,6 +326,7 @@ struct e2fsck_struct {
- __u32 large_files;
- __u32 fs_ext_attr_inodes;
- __u32 fs_ext_attr_blocks;
-+ __u32 extent_files;
-
- /* misc fields */
- time_t now;
-Index: e2fsprogs-1.40.11/e2fsck/pass1.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/pass1.c
-+++ e2fsprogs-1.40.11/e2fsck/pass1.c
-@@ -46,6 +46,7 @@
-
- #include "e2fsck.h"
- #include <ext2fs/ext2_ext_attr.h>
-+#include <ext2fs/ext3_extents.h>
-
- #include "problem.h"
-
-@@ -79,16 +80,19 @@ static void adjust_extattr_refcount(e2fs
- struct process_block_struct {
- ext2_ino_t ino;
- unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
-- fragmented:1, compressed:1, bbcheck:1;
-+ fragmented:1, compressed:1, bbcheck:1, extent:1;
- blk_t num_blocks;
- blk_t max_blocks;
- e2_blkcnt_t last_block;
- int num_illegal_blocks;
-+ int last_illegal_blocks;
- blk_t previous_block;
- struct ext2_inode *inode;
- struct problem_context *pctx;
- ext2fs_block_bitmap fs_meta_blocks;
- e2fsck_t ctx;
-+ struct ext3_extent_header *eh_prev;
-+ void *block_buf;
- };
-
- struct process_inode_block {
-@@ -137,7 +141,7 @@ int e2fsck_pass1_check_device_inode(ext2
+--- e2fsprogs-1.41.4.orig/e2fsck/pass1.c
++++ e2fsprogs-1.41.4/e2fsck/pass1.c
+@@ -137,7 +137,7 @@ int e2fsck_pass1_check_device_inode(ext2
* If the index flag is set, then this is a bogus
* device/fifo/socket
*/
@@ -85,35 +11,16 @@ Index: e2fsprogs-1.40.11/e2fsck/pass1.c
return 0;
/*
-@@ -171,7 +175,7 @@ int e2fsck_pass1_check_symlink(ext2_fils
- blk_t blocks;
+@@ -174,7 +174,7 @@ int e2fsck_pass1_check_symlink(ext2_fils
+ struct ext2fs_extent extent;
if ((inode->i_size_high || inode->i_size == 0) ||
- (inode->i_flags & EXT2_INDEX_FL))
+ (inode->i_flags & (EXT2_INDEX_FL | EXT4_EXTENTS_FL)))
return 0;
- blocks = ext2fs_inode_data_blocks(fs, inode);
-@@ -484,7 +488,9 @@ void e2fsck_pass1(e2fsck_t ctx)
- int imagic_fs;
- int busted_fs_time = 0;
- int inode_size;
--
-+ struct ext3_extent_header *eh;
-+ int extent_fs;
-+
- #ifdef RESOURCE_TRACK
- init_resource_track(&rtrack);
- #endif
-@@ -515,6 +521,7 @@ void e2fsck_pass1(e2fsck_t ctx)
- #undef EXT2_BPP
-
- imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
-+ extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
-
- /*
- * Allocate bitmaps structures
-@@ -895,8 +902,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+ if (inode->i_flags & EXT4_EXTENTS_FL) {
+@@ -1004,8 +1004,7 @@ void e2fsck_pass1(e2fsck_t ctx)
check_blocks(ctx, &pctx, block_buf);
continue;
}
@@ -123,471 +30,105 @@ Index: e2fsprogs-1.40.11/e2fsck/pass1.c
e2fsck_pass1_check_device_inode(fs, inode)) {
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
-@@ -908,21 +914,75 @@ void e2fsck_pass1(e2fsck_t ctx)
- ctx->fs_sockets_count++;
- } else
- mark_inode_bad(ctx, ino);
-- if (inode->i_block[EXT2_IND_BLOCK])
-- ctx->fs_ind_count++;
-- if (inode->i_block[EXT2_DIND_BLOCK])
-- ctx->fs_dind_count++;
-- if (inode->i_block[EXT2_TIND_BLOCK])
-- ctx->fs_tind_count++;
-- if (inode->i_block[EXT2_IND_BLOCK] ||
-- inode->i_block[EXT2_DIND_BLOCK] ||
-- inode->i_block[EXT2_TIND_BLOCK] ||
-- inode->i_file_acl) {
-- inodes_to_process[process_inode_count].ino = ino;
-- inodes_to_process[process_inode_count].inode = *inode;
-- process_inode_count++;
-- } else
-- check_blocks(ctx, &pctx, block_buf);
-+
-+ eh = (struct ext3_extent_header *)inode->i_block;
-+ if ((inode->i_flags & EXT4_EXTENTS_FL)) {
-+ if ((LINUX_S_ISREG(inode->i_mode) ||
-+ LINUX_S_ISDIR(inode->i_mode)) &&
-+ ext2fs_extent_header_verify(eh, EXT2_N_BLOCKS *
-+ sizeof(__u32)) == 0) {
-+ if (!extent_fs &&
-+ fix_problem(ctx,PR_1_EXTENT_FEATURE,&pctx)){
-+ sb->s_feature_incompat |=
-+ EXT3_FEATURE_INCOMPAT_EXTENTS;
-+ ext2fs_mark_super_dirty(fs);
-+ extent_fs = 1;
-+ }
-+ } else if (fix_problem(ctx, PR_1_SET_EXTENT_FL, &pctx)){
-+ inode->i_flags &= ~EXT4_EXTENTS_FL;
-+ e2fsck_write_inode(ctx, ino, inode, "pass1");
-+ goto check_ind_inode;
-+ }
-+ } else if (extent_fs &&
-+ (LINUX_S_ISREG(inode->i_mode) ||
-+ LINUX_S_ISDIR(inode->i_mode)) &&
-+ ext2fs_extent_header_verify(eh, EXT2_N_BLOCKS *
-+ sizeof(__u32)) == 0 &&
-+ fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx)) {
-+ inode->i_flags |= EXT4_EXTENTS_FL;
-+ e2fsck_write_inode(ctx, ino, inode, "pass1");
-+ }
-+ if (extent_fs && inode->i_flags & EXT4_EXTENTS_FL) {
-+ ctx->extent_files++;
-+ switch(eh->eh_depth) {
-+ case 0:
-+ break;
-+ case 1:
-+ ctx->fs_ind_count++;
-+ break;
-+ case 2:
-+ ctx->fs_dind_count++;
-+ break;
-+ default:
-+ ctx->fs_tind_count++;
-+ break;
-+ }
-+ if (eh->eh_depth > 0) {
-+ inodes_to_process[process_inode_count].ino = ino;
-+ inodes_to_process[process_inode_count].inode = *inode;
-+ process_inode_count++;
-+ } else {
-+ check_blocks(ctx, &pctx, block_buf);
-+ }
-+ } else {
-+ check_ind_inode:
-+ if (inode->i_block[EXT2_IND_BLOCK])
-+ ctx->fs_ind_count++;
-+ if (inode->i_block[EXT2_DIND_BLOCK])
-+ ctx->fs_dind_count++;
-+ if (inode->i_block[EXT2_TIND_BLOCK])
-+ ctx->fs_tind_count++;
-+ if (inode->i_block[EXT2_IND_BLOCK] ||
-+ inode->i_block[EXT2_DIND_BLOCK] ||
-+ inode->i_block[EXT2_TIND_BLOCK] ||
-+ inode->i_file_acl) {
-+ inodes_to_process[process_inode_count].ino = ino;
-+ inodes_to_process[process_inode_count].inode = *inode;
-+ process_inode_count++;
-+ } else {
-+ check_blocks(ctx, &pctx, block_buf);
-+ }
-+ }
-
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
-@@ -1430,10 +1490,23 @@ clear_extattr:
- return 0;
- }
-
-+static int htree_blk_iter_cb(ext2_filsys fs EXT2FS_ATTR((unused)),
-+ blk_t *blocknr,
-+ e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
-+ blk_t ref_blk EXT2FS_ATTR((unused)),
-+ int ref_offset EXT2FS_ATTR((unused)),
-+ void *priv_data)
-+{
-+ blk_t *blk = priv_data;
-+
-+ *blk = *blocknr;
-+
-+ return BLOCK_ABORT;
-+}
-+
- /* Returns 1 if bad htree, 0 if OK */
- static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
-- ext2_ino_t ino EXT2FS_ATTR((unused)),
-- struct ext2_inode *inode,
-+ ext2_ino_t ino, struct ext2_inode *inode,
- char *block_buf)
- {
- struct ext2_dx_root_info *root;
-@@ -1447,7 +1520,8 @@ static int handle_htree(e2fsck_t ctx, st
- fix_problem(ctx, PR_1_HTREE_SET, pctx)))
- return 1;
-
-- blk = inode->i_block[0];
-+ ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE,
-+ block_buf, htree_blk_iter_cb, &blk);
- if (((blk == 0) ||
- (blk < fs->super->s_first_data_block) ||
- (blk >= fs->super->s_blocks_count)) &&
-@@ -1484,6 +1558,147 @@ static int handle_htree(e2fsck_t ctx, st
- return 0;
+@@ -1627,6 +1626,31 @@ void e2fsck_clear_inode(e2fsck_t ctx, ex
+ e2fsck_write_inode(ctx, ino, inode, source);
}
-+/* sort 0 to the end of the list so we can exit early */
-+static EXT2_QSORT_TYPE verify_ind_cmp(const void *a, const void *b)
-+{
-+ const __u32 blk_a = *(__u32 *)a - 1, blk_b = *(__u32 *)b - 1;
-+
-+ return blk_b > blk_a ? -1 : blk_a - blk_b;
-+}
-+
-+/* Verify whether an indirect block is sane. If it has multiple references
-+ * to the same block, or if it has a large number of bad or duplicate blocks
-+ * chances are that it is corrupt and we should just clear it instead of
-+ * trying to salvage it.
-+ * NOTE: this needs to get a copy of the blocks, since it reorders them */
-+static int e2fsck_ind_block_verify(struct process_block_struct *p,
-+ void *block_buf, int buflen)
++static errcode_t e2fsck_ext2fs_extent_get(e2fsck_t ctx, struct problem_context *pctx,
++ ext2_extent_handle_t ehandle, int flags,
++ struct ext2fs_extent *extent)
+{
-+ __u32 blocks[EXT2_N_BLOCKS], *indir = block_buf;
-+ int num_indir = buflen / sizeof(*indir);
-+ int i, bad = 0;
-+
-+ if (num_indir == EXT2_N_BLOCKS) {
-+ memcpy(blocks, block_buf, buflen);
-+ indir = blocks;
-+ }
-+ qsort(indir, num_indir, sizeof(*indir), verify_ind_cmp);
-+
-+ for (i = 0; i < num_indir; i++) {
-+ if (indir[i] == 0)
-+ break;
-+
-+ /* bad block number, or duplicate block */
-+ if (indir[i] < p->ctx->fs->super->s_first_data_block ||
-+ indir[i] > p->ctx->fs->super->s_blocks_count ||
-+ ext2fs_fast_test_block_bitmap(p->ctx->block_found_map,
-+ indir[i]))
-+ bad++;
-+
-+ /* shouldn't reference the same block twice within a block */
-+ if (i > 0 && indir[i] == indir[i - 1])
-+ bad++;
-+ }
-+
-+ if ((num_indir <= EXT2_N_BLOCKS && bad > 4) || bad > 8)
-+ return PR_1_INDIRECT_BAD;
-+
-+#if DEBUG_E2FSCK
-+ /* For debugging, clobber buffer to ensure it doesn't appear sane */
-+ memset(indir, 0xca, buflen);
-+#endif
-+ return 0;
-+}
-+
-+static int e2fsck_ext_block_verify(struct process_block_struct *p,
-+ void *block_buf, int buflen)
-+{
-+ struct ext3_extent_header *eh = block_buf, *eh_sav;
-+ e2fsck_t ctx = p->ctx;
-+ struct problem_context *pctx = p->pctx;
-+ int i, problem = 0, high_bits_ok = 0;
-+
-+ if (ext2fs_extent_header_verify(eh, buflen))
-+ return PR_1_EXTENT_IDX_BAD;
-+
-+ if (p->eh_prev && p->eh_prev->eh_depth != eh->eh_depth + 1)
-+ return PR_1_EXTENT_IDX_BAD;
-+
-+ if (ctx->fs->super->s_blocks_count_hi) /* FIXME: 48-bit support ??? */
-+ high_bits_ok = 1;
-+
-+ eh_sav = p->eh_prev;
-+ p->eh_prev = eh;
-+
-+ if (eh->eh_depth == 0) {
-+ struct ext3_extent *ex = EXT_FIRST_EXTENT(eh), *ex_prev = NULL;
-+
-+ for (i = 0; i < eh->eh_entries; i++, ex++) {
-+ if (ex->ee_start_hi && !high_bits_ok &&
-+ fix_problem(ctx, PR_1_EXTENT_HI, pctx)) {
-+ ex->ee_start_hi = 0;
-+ problem = PR_1_EXTENT_CHANGED;
-+ }
-+
-+ if (ext2fs_extent_verify(ctx->fs, ex, ex_prev, NULL,0)){
-+ p->num_illegal_blocks++;
-+ pctx->blkcount = ex->ee_start;
-+ pctx->num = ex->ee_len;
-+ pctx->blk = ex->ee_block;
-+ if (fix_problem(ctx, PR_1_EXTENT_BAD, pctx)) {
-+ ext2fs_extent_remove(eh, ex);
-+ i--; ex--; /* check next (moved) item */
-+ problem = PR_1_EXTENT_CHANGED;
-+ continue;
-+ }
-+ }
-+
-+ ex_prev = ex;
-+ }
-+ } else {
-+ struct ext3_extent_idx *ix =EXT_FIRST_INDEX(eh), *ix_prev =NULL;
-+
-+ if (!eh->eh_entries) {
-+ if (buflen == sizeof(p->inode->i_block)) {
-+ if (fix_problem(ctx, PR_1_EXTENT_EH_DEPTH_BAD,
-+ pctx)) {
-+ eh->eh_depth = 0;
-+ problem = PR_1_EXTENT_CHANGED;
-+ }
-+ } else {
-+ return PR_1_EXTENT_IDX_BAD;
-+ }
-+ }
-+
-+ for (i = 0; i < eh->eh_entries; i++, ix++) {
-+ if (ix->ei_leaf_hi && !high_bits_ok &&
-+ fix_problem(ctx, PR_1_EXTENT_HI, pctx)) {
-+ ix->ei_leaf_hi = ix->ei_unused = 0;
-+ problem = PR_1_EXTENT_CHANGED;
-+ }
-+
-+ if (ext2fs_extent_index_verify(ctx->fs, ix, ix_prev)) {
-+ p->num_illegal_blocks++;
-+ pctx->blkcount = ix->ei_leaf;;
-+ pctx->num = i;
-+ pctx->blk = ix->ei_block;
-+ if (fix_problem(ctx, PR_1_EXTENT_IDX_BAD,pctx)){
-+ ext2fs_extent_index_remove(eh, ix);
-+ i--; ix--; /* check next (moved) item */
-+ problem = PR_1_EXTENT_CHANGED;
-+ continue;
-+ }
-+ }
-+
-+ ix_prev = ix;
-+ }
++ __u16 blk_hi;
++ int high_bits_ok = 0;
++ int rc = 0;
++
++ rc = ext2fs_extent_get(ehandle, flags, extent);
++ if (rc)
++ return rc;
++
++ blk_hi = extent->e_pblk >> 32;
++
++ if (blk_hi && !high_bits_ok &&
++ fix_problem(ctx, PR_1_EXTENT_HI, pctx)) {
++ extent->e_pblk &= 0xFFFFFFFFULL;
++ rc = ext2fs_extent_replace(ehandle, 0, extent);
++ if (rc)
++ return rc;
+ }
+
-+ p->eh_prev = eh_sav;
-+
-+ return problem;
++ return rc;
+}
+
- /*
- * This subroutine is called on each inode to account for all of the
- * blocks used by that inode.
-@@ -1503,9 +1718,11 @@ static void check_blocks(e2fsck_t ctx, s
- pb.num_blocks = 0;
- pb.last_block = -1;
- pb.num_illegal_blocks = 0;
-+ pb.last_illegal_blocks = 0;
- pb.suppress = 0; pb.clear = 0;
- pb.fragmented = 0;
- pb.compressed = 0;
-+ pb.extent = !!(inode->i_flags & EXT4_EXTENTS_FL);
- pb.previous_block = 0;
- pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
- pb.is_reg = LINUX_S_ISREG(inode->i_mode);
-@@ -1513,6 +1730,8 @@ static void check_blocks(e2fsck_t ctx, s
- pb.inode = inode;
- pb.pctx = pctx;
- pb.ctx = ctx;
-+ pb.eh_prev = NULL;
-+ pb.block_buf = block_buf;
- pctx->ino = ino;
- pctx->errcode = 0;
-
-@@ -1534,10 +1753,27 @@ static void check_blocks(e2fsck_t ctx, s
- pb.num_blocks++;
- }
-
-- if (ext2fs_inode_has_valid_blocks(inode))
-- pctx->errcode = ext2fs_block_iterate2(fs, ino,
-- pb.is_dir ? BLOCK_FLAG_HOLE : 0,
-- block_buf, process_block, &pb);
-+ if (ext2fs_inode_has_valid_blocks(inode)) {
-+ int problem = 0;
-+
-+ if (pb.extent)
-+ problem = e2fsck_ext_block_verify(&pb, inode->i_block,
-+ sizeof(inode->i_block));
-+ else
-+ problem = e2fsck_ind_block_verify(&pb, inode->i_block,
-+ sizeof(inode->i_block));
-+ if (problem == PR_1_EXTENT_CHANGED) {
-+ dirty_inode++;
-+ problem = 0;
-+ }
-+
-+ if (problem && fix_problem(ctx, problem, pctx))
-+ pb.clear = 1;
-+ else
-+ pctx->errcode = ext2fs_block_iterate2(fs, ino,
-+ pb.is_dir ? BLOCK_FLAG_HOLE : 0,
-+ block_buf, process_block, &pb);
-+ }
- end_problem_latch(ctx, PR_LATCH_BLOCK);
- end_problem_latch(ctx, PR_LATCH_TOOBIG);
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-@@ -1723,6 +1959,9 @@ static char *describe_illegal_block(ext2
- }
- #endif
-
-+#define IND_BLKCNT(_b) ((_b) == BLOCK_COUNT_IND || (_b) == BLOCK_COUNT_DIND ||\
-+ (_b) == BLOCK_COUNT_TIND)
-+
- /*
- * This is a helper function for check_blocks().
- */
-@@ -1802,7 +2041,8 @@ static int process_block(ext2_filsys fs,
- * file be contiguous. (Which can never be true for really
- * big files that are greater than a block group.)
- */
-- if (!HOLE_BLKADDR(p->previous_block)) {
-+ if (!HOLE_BLKADDR(p->previous_block) &&
-+ !(p->extent && IND_BLKCNT(blockcnt))) {
- if (p->previous_block+1 != blk)
- p->fragmented = 1;
- }
-@@ -1819,9 +2059,34 @@ static int process_block(ext2_filsys fs,
- blk >= fs->super->s_blocks_count)
- problem = PR_1_ILLEGAL_BLOCK_NUM;
-
-+ if (!problem && IND_BLKCNT(blockcnt) && p->ino != EXT2_RESIZE_INO) {
-+ if (p->extent) {
-+ if (ext2fs_read_ext_block(ctx->fs, blk, p->block_buf))
-+ problem = PR_1_BLOCK_ITERATE;
-+ else
-+ problem = e2fsck_ext_block_verify(p,
-+ p->block_buf,
-+ fs->blocksize);
-+ if (problem == PR_1_EXTENT_CHANGED) {
-+ if (ext2fs_write_ext_block(ctx->fs, blk,
-+ p->block_buf))
-+ problem = PR_1_BLOCK_ITERATE;
-+ }
-+
-+ } else {
-+ if (ext2fs_read_ind_block(ctx->fs, blk, p->block_buf))
-+ problem = PR_1_BLOCK_ITERATE;
-+ else
-+ problem = e2fsck_ind_block_verify(p,
-+ p->block_buf,
-+ fs->blocksize);
-+ }
-+ }
-+
- if (problem) {
- p->num_illegal_blocks++;
-- if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
-+ if (!p->suppress &&
-+ p->num_illegal_blocks - p->last_illegal_blocks > 12) {
- if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
- p->clear = 1;
- return BLOCK_ABORT;
-@@ -1831,9 +2096,12 @@ static int process_block(ext2_filsys fs,
- set_latch_flags(PR_LATCH_BLOCK,
- PRL_SUPPRESS, 0);
- }
-+ p->last_illegal_blocks = p->num_illegal_blocks;
- }
- pctx->blk = blk;
- pctx->blkcount = blockcnt;
-+ if (problem == PR_1_EXTENT_CHANGED)
-+ goto mark_used;
- if (fix_problem(ctx, problem, pctx)) {
- blk = *block_nr = 0;
- ret_code = BLOCK_CHANGED;
-@@ -1842,6 +2110,7 @@ static int process_block(ext2_filsys fs,
- return 0;
+ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
+ struct process_block_struct *pb,
+ blk64_t start_block,
+@@ -1644,8 +1668,8 @@ static void scan_extent_node(e2fsck_t ct
+ if (pctx->errcode)
+ return;
+
+- pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
+- &extent);
++ pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx, ehandle,
++ EXT2_EXTENT_FIRST_SIB, &extent);
+ while (!pctx->errcode && info.num_entries-- > 0) {
+ is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
+ is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
+@@ -1673,9 +1697,9 @@ static void scan_extent_node(e2fsck_t ct
+ pctx->str = "ext2fs_extent_delete";
+ return;
+ }
+- pctx->errcode = ext2fs_extent_get(ehandle,
+- EXT2_EXTENT_CURRENT,
+- &extent);
++ pctx->errcode = e2fsck_ext2fs_extent_get(ctx,
++ pctx, ehandle,
++ EXT2_EXTENT_CURRENT, &extent);
+ if (pctx->errcode == EXT2_ET_NO_CURRENT_NODE) {
+ pctx->errcode = 0;
+ break;
+@@ -1687,8 +1711,8 @@ static void scan_extent_node(e2fsck_t ct
+
+ if (!is_leaf) {
+ blk = extent.e_pblk;
+- pctx->errcode = ext2fs_extent_get(ehandle,
+- EXT2_EXTENT_DOWN, &extent);
++ pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx,
++ ehandle, EXT2_EXTENT_DOWN, &extent);
+ if (pctx->errcode) {
+ pctx->str = "EXT2_EXTENT_DOWN";
+ problem = PR_1_EXTENT_HEADER_INVALID;
+@@ -1699,8 +1723,8 @@ static void scan_extent_node(e2fsck_t ct
+ scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
+ if (pctx->errcode)
+ return;
+- pctx->errcode = ext2fs_extent_get(ehandle,
+- EXT2_EXTENT_UP, &extent);
++ pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx,
++ ehandle, EXT2_EXTENT_UP, &extent);
+ if (pctx->errcode) {
+ pctx->str = "EXT2_EXTENT_UP";
+ return;
+@@ -1754,9 +1778,9 @@ static void scan_extent_node(e2fsck_t ct
+ if (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT))
+ pb->last_block = start_block;
+ next:
+- pctx->errcode = ext2fs_extent_get(ehandle,
+- EXT2_EXTENT_NEXT_SIB,
+- &extent);
++ pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx, ehandle,
++ EXT2_EXTENT_NEXT_SIB,
++ &extent);
}
-
-+mark_used:
- if (p->ino == EXT2_RESIZE_INO) {
- /*
- * The resize inode has already be sanity checked
-Index: e2fsprogs-1.40.11/e2fsck/pass2.c
+ if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
+ pctx->errcode = 0;
+Index: e2fsprogs-1.41.4/e2fsck/problem.c
===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/pass2.c
-+++ e2fsprogs-1.40.11/e2fsck/pass2.c
-@@ -277,7 +277,16 @@ void e2fsck_pass2(e2fsck_t ctx)
- ext2fs_mark_super_dirty(fs);
- }
- }
--
-+
-+ if (!ctx->extent_files &&
-+ (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)) {
-+ if (fs->flags & EXT2_FLAG_RW) {
-+ sb->s_feature_incompat &=
-+ ~EXT3_FEATURE_INCOMPAT_EXTENTS;
-+ ext2fs_mark_super_dirty(fs);
-+ }
-+ }
-+
- #ifdef RESOURCE_TRACK
- if (ctx->options & E2F_OPT_TIME2) {
- e2fsck_clear_progbar(ctx);
-Index: e2fsprogs-1.40.11/e2fsck/problem.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.11/e2fsck/problem.c
-@@ -784,6 +784,46 @@ static struct e2fsck_problem problem_tab
- N_("@i %i is a %It but it looks like it is really a directory.\n"),
- PROMPT_FIX, 0 },
+--- e2fsprogs-1.41.4.orig/e2fsck/problem.c
++++ e2fsprogs-1.41.4/e2fsck/problem.c
+@@ -868,6 +868,21 @@ static struct e2fsck_problem problem_tab
+ N_("@a in @i %i is corrupt (@n value)."),
+ PROMPT_CLEAR, 0},
-+ /* indirect block corrupt */
-+ { PR_1_INDIRECT_BAD,
-+ N_("@i %i has corrupt indirect block\n"),
-+ PROMPT_CLEAR, PR_PREEN_OK },
-+
-+ /* inode has extents, superblock missing INCOMPAT_EXTENTS feature */
-+ { PR_1_EXTENT_FEATURE,
-+ N_("@i %i is in extent format, but @S is missing EXTENTS feature\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* inode has EXTENTS_FL set, but is not an extent inode */
-+ { PR_1_SET_EXTENT_FL,
-+ N_("@i %i has EXTENT_FL set, but is not in extents format\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* inode missing EXTENTS_FL, but is an extent inode */
-+ { PR_1_UNSET_EXTENT_FL,
-+ N_("@i %i missing EXTENT_FL, but is in extents format\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* extent index corrupt */
-+ { PR_1_EXTENT_BAD,
-+ N_("@i %i has corrupt extent at @b %b (logical %B) length %N\n"),
-+ PROMPT_CLEAR, PR_PREEN_OK },
-+
-+ /* extent index corrupt */
-+ { PR_1_EXTENT_IDX_BAD,
-+ N_("@i %i has corrupt extent index at @b %b (logical %B) entry %N\n"),
-+ PROMPT_CLEAR, PR_PREEN_OK },
-+
+ /* extent has high 16 bits set */
+ { PR_1_EXTENT_HI,
+ N_("High 16 bits of extent/index @b set\n"),
@@ -598,21 +139,15 @@ Index: e2fsprogs-1.40.11/e2fsck/problem.c
+ N_("@i %i has high 16 bits of extent/index @b set\n"),
+ PROMPT_CLEAR, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
+
- /* Pass 1b errors */
-
- /* Pass 1B: Rescan for duplicate/bad blocks */
-@@ -827,6 +867,10 @@ static struct e2fsck_problem problem_tab
- N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
- PROMPT_NONE, 0 },
-
+ /* eh_depth should be 0 */
+ { PR_1_EXTENT_EH_DEPTH_BAD,
+ N_("@i %i has extent header with incorrect eh_depth\n"),
+ PROMPT_FIX, 0 },
++
+ /* Pass 1b errors */
- /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
- { PR_1C_PASS_HEADER,
-@@ -1522,6 +1566,7 @@ static struct latch_descr pr_latch_info[
+ /* Pass 1B: Rescan for duplicate/bad blocks */
+@@ -1631,6 +1655,7 @@ static struct latch_descr pr_latch_info[
{ PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
{ PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
{ PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
@@ -620,10 +155,10 @@ Index: e2fsprogs-1.40.11/e2fsck/problem.c
{ -1, 0, 0 },
};
-Index: e2fsprogs-1.40.11/e2fsck/problem.h
+Index: e2fsprogs-1.41.4/e2fsck/problem.h
===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.11/e2fsck/problem.h
+--- e2fsprogs-1.41.4.orig/e2fsck/problem.h
++++ e2fsprogs-1.41.4/e2fsck/problem.h
@@ -38,6 +38,7 @@ struct problem_context {
#define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
#define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */
@@ -632,1098 +167,27 @@ Index: e2fsprogs-1.40.11/e2fsck/problem.h
#define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1)
-@@ -455,6 +456,36 @@ struct problem_context {
- /* inode appears to be a directory */
- #define PR_1_TREAT_AS_DIRECTORY 0x010055
+@@ -506,6 +507,15 @@ struct problem_context {
+ /* Bad extended attribute value in inode */
+ #define PR_1_INODE_EA_BAD_VALUE 0x010060
-+/* indirect block corrupt */
-+#define PR_1_INDIRECT_BAD 0x010059
-+
-+/* wrong EXT3_FEATURE_INCOMPAT_EXTENTS flag */
-+#define PR_1_EXTENT_FEATURE 0x010060
-+
-+/* EXT4_EXTENT_FL flag set on non-extent file */
-+#define PR_1_SET_EXTENT_FL 0x010061
-+
-+/* EXT4_EXTENT_FL flag not set extent file */
-+#define PR_1_UNSET_EXTENT_FL 0x010062
-+
-+/* extent index corrupt */
-+#define PR_1_EXTENT_BAD 0x010063
-+
-+/* extent index corrupt */
-+#define PR_1_EXTENT_IDX_BAD 0x010064
-+
+/* extent/index has high 16 bits set - header */
-+#define PR_1_EXTENT_HI 0x010065
++#define PR_1_EXTENT_HI 0x010061
+
+/* extent/index has high 16 bits set */
-+#define PR_1_EXTENT_HI_LATCH 0x010066
-+
-+/* extent/index was modified & repaired - not really a problem */
-+#define PR_1_EXTENT_CHANGED 0x010067
++#define PR_1_EXTENT_HI_LATCH 0x010062
+
+/* eh_depth for in-inode header is bad */
-+#define PR_1_EXTENT_EH_DEPTH_BAD 0x01006D
++#define PR_1_EXTENT_EH_DEPTH_BAD 0x010063
+
/*
* Pass 1b errors
*/
-Index: e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/Makefile.in
-+++ e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-@@ -35,6 +35,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_O
- dir_iterate.o \
- expanddir.o \
- ext_attr.o \
-+ extents.o \
- finddev.o \
- flushb.o \
- freefs.o \
-@@ -91,6 +92,7 @@ SRCS= ext2_err.c \
- $(srcdir)/dupfs.c \
- $(srcdir)/expanddir.c \
- $(srcdir)/ext_attr.c \
-+ $(srcdir)/extents.c \
- $(srcdir)/fileio.c \
- $(srcdir)/finddev.c \
- $(srcdir)/flushb.c \
-@@ -134,6 +136,7 @@ SRCS= ext2_err.c \
- $(srcdir)/tst_bitops.c \
- $(srcdir)/tst_byteswap.c \
- $(srcdir)/tst_getsize.c \
-+ $(srcdir)/tst_types.c \
- $(srcdir)/tst_iscan.c
-
- HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h ext3_extents.h \
-@@ -402,6 +405,10 @@ ext_attr.o: $(srcdir)/ext_attr.c $(srcdi
- $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-+extents.o: $(srcdir)/extents.c $(srcdir)/ext2_fs.h \
-+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext3_extents.h \
-+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(top_srcdir)/lib/et/com_err.h \
-+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
- fileio.o: $(srcdir)/fileio.c $(srcdir)/ext2_fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
-Index: e2fsprogs-1.40.11/lib/ext2fs/block.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/block.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/block.c
-@@ -17,24 +17,17 @@
-
- #include "ext2_fs.h"
- #include "ext2fs.h"
-+#include "block.h"
-
--struct block_context {
-- ext2_filsys fs;
-- int (*func)(ext2_filsys fs,
-- blk_t *blocknr,
-- e2_blkcnt_t bcount,
-- blk_t ref_blk,
-- int ref_offset,
-- void *priv_data);
-- e2_blkcnt_t bcount;
-- int bsize;
-- int flags;
-- errcode_t errcode;
-- char *ind_buf;
-- char *dind_buf;
-- char *tind_buf;
-- void *priv_data;
--};
-+#ifdef EXT_DEBUG
-+void ext_show_inode(struct ext2_inode *inode, ext2_ino_t ino)
-+{
-+ printf("inode: %u blocks: %u\n",
-+ ino, inode->i_blocks);
-+}
-+#else
-+#define ext_show_inode(inode, ino) do { } while (0)
-+#endif
-
- static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
- int ref_offset, struct block_context *ctx)
-@@ -276,7 +269,6 @@ errcode_t ext2fs_block_iterate2(ext2_fil
- void *priv_data)
- {
- int i;
-- int got_inode = 0;
- int ret = 0;
- blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
- struct ext2_inode inode;
-@@ -286,19 +278,20 @@ errcode_t ext2fs_block_iterate2(ext2_fil
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
-+ ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-+ if (ctx.errcode)
-+ return ctx.errcode;
-+
- /*
- * Check to see if we need to limit large files
- */
- if (flags & BLOCK_FLAG_NO_LARGE) {
-- ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-- if (ctx.errcode)
-- return ctx.errcode;
-- got_inode = 1;
- if (!LINUX_S_ISDIR(inode.i_mode) &&
- (inode.i_size_high != 0))
- return EXT2_ET_FILE_TOO_BIG;
- }
-
-+ /* The in-memory inode may have been changed by e2fsck */
- retval = ext2fs_get_blocks(fs, ino, blocks);
- if (retval)
- return retval;
-@@ -325,10 +318,6 @@ errcode_t ext2fs_block_iterate2(ext2_fil
- */
- if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
- !(flags & BLOCK_FLAG_DATA_ONLY)) {
-- ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-- if (ctx.errcode)
-- goto abort_exit;
-- got_inode = 1;
- if (inode.osd1.hurd1.h_i_translator) {
- ret |= (*ctx.func)(fs,
- &inode.osd1.hurd1.h_i_translator,
-@@ -338,7 +327,16 @@ errcode_t ext2fs_block_iterate2(ext2_fil
- goto abort_exit;
- }
- }
--
-+
-+ /* Iterate over normal data blocks with extents.
-+ * We can't do any fixing here because this gets called by other
-+ * callers than e2fsck_pass1->check_blocks(). */
-+ if (inode.i_flags & EXT4_EXTENTS_FL) {
-+ ext_show_inode(&inode, ino);
-+ ret |= block_iterate_extents(blocks, sizeof(blocks), 0, 0,&ctx);
-+ goto abort_exit;
-+ }
-+
- /*
- * Iterate over normal data blocks
- */
-@@ -373,11 +371,6 @@ errcode_t ext2fs_block_iterate2(ext2_fil
-
- abort_exit:
- if (ret & BLOCK_CHANGED) {
-- if (!got_inode) {
-- retval = ext2fs_read_inode(fs, ino, &inode);
-- if (retval)
-- return retval;
-- }
- for (i=0; i < EXT2_N_BLOCKS; i++)
- inode.i_block[i] = blocks[i];
- retval = ext2fs_write_inode(fs, ino, &inode);
-Index: e2fsprogs-1.40.11/lib/ext2fs/block.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/block.h
-@@ -0,0 +1,33 @@
-+/*
-+ * block.h --- header for block iteration in block.c, extent.c
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+struct block_context {
-+ ext2_filsys fs;
-+ int (*func)(ext2_filsys fs,
-+ blk_t *blocknr,
-+ e2_blkcnt_t bcount,
-+ blk_t ref_blk,
-+ int ref_offset,
-+ void *priv_data);
-+ e2_blkcnt_t bcount;
-+ int bsize;
-+ int flags;
-+ errcode_t errcode;
-+ char *ind_buf;
-+ char *dind_buf;
-+ char *tind_buf;
-+ void *priv_data;
-+};
-+
-+/* libext2fs nternal function, in extent.c */
-+extern int block_iterate_extents(void *eh_buf, unsigned bufsize,blk_t ref_block,
-+ int ref_offset EXT2FS_ATTR((unused)),
-+ struct block_context *ctx);
-Index: e2fsprogs-1.40.11/lib/ext2fs/bmap.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/bmap.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/bmap.c
-@@ -17,6 +17,7 @@
-
- #include "ext2_fs.h"
- #include "ext2fs.h"
-+#include "ext3_extents.h"
-
- #if defined(__GNUC__) && !defined(NO_INLINE_FUNCS)
- #define _BMAP_INLINE_ __inline__
-@@ -31,6 +32,65 @@ extern errcode_t ext2fs_bmap(ext2_filsys
-
- #define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
-
-+/* see also block_iterate_extents() */
-+static errcode_t block_bmap_extents(void *eh_buf, unsigned bufsize,
-+ ext2_filsys fs, blk_t block,blk_t *phys_blk)
-+{
-+ struct ext3_extent_header *eh = eh_buf;
-+ struct ext3_extent *ex;
-+ errcode_t ret = 0;
-+ int i;
-+
-+ ret = ext2fs_extent_header_verify(eh, bufsize);
-+ if (ret)
-+ return ret;
-+
-+ if (eh->eh_depth == 0) {
-+ ex = EXT_FIRST_EXTENT(eh);
-+ for (i = 0; i < eh->eh_entries; i++, ex++) {
-+ if (block < ex->ee_block)
-+ continue;
-+
-+ if (block < ex->ee_block + ex->ee_len)
-+ /* FIXME: 48-bit support */
-+ *phys_blk = ex->ee_start + block - ex->ee_block;
-+
-+ /* only the first extent > block could hold the block
-+ * otherwise the extents would overlap */
-+ break;
-+ }
-+ } else {
-+ struct ext3_extent_idx *ix;
-+ char *block_buf;
-+
-+ ret = ext2fs_get_mem(fs->blocksize, &block_buf);
-+ if (ret)
-+ return ret;
-+
-+ ix = EXT_FIRST_INDEX(eh);
-+ for (i = 0; i < eh->eh_entries; i++, ix++) {
-+ if (block < ix->ei_block)
-+ continue;
-+
-+ ret = io_channel_read_blk(fs->io, ix->ei_leaf, 1,
-+ block_buf);
-+ if (ret)
-+ goto free_buf;
-+
-+ ret = block_bmap_extents(block_buf, fs->blocksize,
-+ fs, block, phys_blk);
-+
-+ /* only the first extent > block could hold the block
-+ * otherwise the extents would overlap */
-+ break;
-+ }
-+
-+ free_buf:
-+ ext2fs_free_mem(&block_buf);
-+ }
-+ return ret;
-+}
-+
- static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags,
- blk_t ind, char *block_buf,
- int *blocks_alloc,
-@@ -155,6 +215,16 @@ errcode_t ext2fs_bmap(ext2_filsys fs, ex
- return retval;
- inode = &inode_buf;
- }
-+
-+ if (inode->i_flags & EXT4_EXTENTS_FL) {
-+ if (bmap_flags) /* unsupported as yet */
-+ return EXT2_ET_BLOCK_ALLOC_FAIL;
-+ retval = block_bmap_extents(inode->i_block,
-+ sizeof(inode->i_block),
-+ fs, block, phys_blk);
-+ goto done;
-+ }
-+
- addr_per_block = (blk_t) fs->blocksize >> 2;
-
- if (!block_buf) {
-Index: e2fsprogs-1.40.11/lib/ext2fs/ext2_err.et.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ext2_err.et.in
-+++ e2fsprogs-1.40.11/lib/ext2fs/ext2_err.et.in
-@@ -329,5 +329,17 @@ ec EXT2_ET_TDB_ERR_RDONLY,
- ec EXT2_ET_DBLIST_EMPTY,
- "Ext2fs directory block list is empty"
-
-+ec EXT2_ET_EXTENT_HEADER_BAD,
-+ "Corrupt extent header"
-+
-+ec EXT2_ET_EXTENT_INDEX_BAD,
-+ "Corrupt extent index"
-+
-+ec EXT2_ET_EXTENT_LEAF_BAD,
-+ "Corrupt extent"
-+
-+ec EXT2_ET_EXTENT_NO_SPACE,
-+ "No free space in extent map"
-+
- end
-
-Index: e2fsprogs-1.40.11/lib/ext2fs/ext2fs.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.11/lib/ext2fs/ext2fs.h
-@@ -455,12 +455,15 @@ typedef struct ext2_icount *ext2_icount_
- EXT2_FEATURE_INCOMPAT_COMPRESSION|\
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
- EXT2_FEATURE_INCOMPAT_META_BG|\
-- EXT3_FEATURE_INCOMPAT_RECOVER)
-+ EXT3_FEATURE_INCOMPAT_RECOVER|\
-+ EXT3_FEATURE_INCOMPAT_EXTENTS)
-+
- #else
- #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
- EXT2_FEATURE_INCOMPAT_META_BG|\
-- EXT3_FEATURE_INCOMPAT_RECOVER)
-+ EXT3_FEATURE_INCOMPAT_RECOVER|\
-+ EXT3_FEATURE_INCOMPAT_EXTENTS)
- #endif
- #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
-@@ -729,6 +732,21 @@ extern errcode_t ext2fs_adjust_ea_refcou
- char *block_buf,
- int adjust, __u32 *newcount);
-
-+/* extent.c */
-+errcode_t ext2fs_extent_header_verify(struct ext3_extent_header *eh, int size);
-+errcode_t ext2fs_extent_verify(ext2_filsys fs, struct ext3_extent *ex,
-+ struct ext3_extent *ex_prev,
-+ struct ext3_extent_idx *ix, int ix_len);
-+errcode_t ext2fs_extent_index_verify(ext2_filsys fs,
-+ struct ext3_extent_idx *ix,
-+ struct ext3_extent_idx *ix_prev);
-+errcode_t ext2fs_extent_remove(struct ext3_extent_header *eh,
-+ struct ext3_extent *ex);
-+errcode_t ext2fs_extent_split(ext2_filsys fs, struct ext3_extent_header **eh,
-+ struct ext3_extent **ex, int count, int *flag);
-+errcode_t ext2fs_extent_index_remove(struct ext3_extent_header *eh,
-+ struct ext3_extent_idx *ix);
-+
- /* fileio.c */
- extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
-@@ -783,6 +801,8 @@ extern errcode_t ext2fs_image_bitmap_rea
- /* ind_block.c */
- errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
- errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-+errcode_t ext2fs_read_ext_block(ext2_filsys fs, blk_t blk, void *buf);
-+errcode_t ext2fs_write_ext_block(ext2_filsys fs, blk_t blk, void *buf);
-
- /* initialize.c */
- extern errcode_t ext2fs_initialize(const char *name, int flags,
-@@ -968,6 +988,9 @@ extern void ext2fs_swap_inode_full(ext2_
- int bufsize);
- extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
- struct ext2_inode *f, int hostorder);
-+extern void ext2fs_swap_extent_header(struct ext3_extent_header *eh);
-+extern void ext2fs_swap_extent_index(struct ext3_extent_idx *ix);
-+extern void ext2fs_swap_extent(struct ext3_extent *ex);
-
- /* valid_blk.c */
- extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
-Index: e2fsprogs-1.40.11/lib/ext2fs/extents.c
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/extents.c
-@@ -0,0 +1,485 @@
-+/*
-+ * extent.c --- iterate over all blocks in an extent-mapped inode
-+ *
-+ * Copyright (C) 2005 Alex Tomas <alex at clusterfs.com>
-+ * Copyright (C) 2006 Andreas Dilger <adilger at clusterfs.com>
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "block.h"
-+
-+#ifdef EXT_DEBUG
-+void ext_show_header(struct ext3_extent_header *eh)
-+{
-+ printf("header: magic=%x entries=%u max=%u depth=%u generation=%u\n",
-+ eh->eh_magic, eh->eh_entries, eh->eh_max, eh->eh_depth,
-+ eh->eh_generation);
-+}
-+
-+void ext_show_index(struct ext3_extent_idx *ix)
-+{
-+ printf("index: block=%u leaf=%u leaf_hi=%u unused=%u\n",
-+ ix->ei_block, ix->ei_leaf, ix->ei_leaf_hi, ix->ei_unused);
-+}
-+
-+void ext_show_extent(struct ext3_extent *ex)
-+{
-+ printf("extent: block=%u-%u len=%u start=%u start_hi=%u\n",
-+ ex->ee_block, ex->ee_block + ex->ee_len - 1,
-+ ex->ee_len, ex->ee_start, ex->ee_start_hi);
-+}
-+
-+#define ext_printf(fmt, args...) printf(fmt, ## args)
-+#else
-+#define ext_show_header(eh) do { } while (0)
-+#define ext_show_index(ix) do { } while (0)
-+#define ext_show_extent(ex) do { } while (0)
-+#define ext_printf(fmt, args...) do { } while (0)
-+#endif
-+
-+errcode_t ext2fs_extent_header_verify(struct ext3_extent_header *eh, int size)
-+{
-+ int eh_max, entry_size;
-+
-+ ext_show_header(eh);
-+ if (eh->eh_magic != EXT3_EXT_MAGIC)
-+ return EXT2_ET_EXTENT_HEADER_BAD;
-+ if (eh->eh_entries > eh->eh_max)
-+ return EXT2_ET_EXTENT_HEADER_BAD;
-+ if (eh->eh_depth == 0)
-+ entry_size = sizeof(struct ext3_extent);
-+ else
-+ entry_size = sizeof(struct ext3_extent_idx);
-+
-+ eh_max = (size - sizeof(*eh)) / entry_size;
-+ /* Allow two extent-sized items at the end of the block, for
-+ * ext4_extent_tail with checksum in the future. */
-+ if (eh->eh_max > eh_max || eh->eh_max < eh_max - 2)
-+ return EXT2_ET_EXTENT_HEADER_BAD;
-+
-+ return 0;
-+}
-+
-+/* Verify that a single extent @ex is valid. If @ex_prev is passed in,
-+ * then this was the previous logical extent in this block and we can
-+ * do additional sanity checking (though in case of error we don't know
-+ * which of the two extents is bad). Similarly, if @ix is passed in
-+ * we can check that this extent is logically part of the index that
-+ * refers to it (though again we can't know which of the two is bad). */
-+errcode_t ext2fs_extent_verify(ext2_filsys fs, struct ext3_extent *ex,
-+ struct ext3_extent *ex_prev,
-+ struct ext3_extent_idx *ix, int ix_len)
-+{
-+ ext_show_extent(ex);
-+ /* FIXME: 48-bit support */
-+ if (ex->ee_start > fs->super->s_blocks_count)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (ex->ee_len == 0)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (ex->ee_len >= fs->super->s_blocks_per_group)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (ex_prev) {
-+ /* We can't have a zero logical block except for first index */
-+ if (ex->ee_block == 0)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ /* FIXME: 48-bit support */
-+ /* extents must be in logical offset order */
-+ if (ex->ee_block < ex_prev->ee_block + ex_prev->ee_len)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ /* extents must not overlap physical blocks */
-+ if ((ex->ee_start < ex_prev->ee_start + ex_prev->ee_len) &&
-+ (ex->ee_start + ex->ee_len > ex_prev->ee_start))
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+ }
-+
-+ if (ix) {
-+ /* FIXME: 48-bit support */
-+ if (ex->ee_block < ix->ei_block)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (ix_len && ex->ee_block + ex->ee_len > ix->ei_block + ix_len)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+ }
-+
-+ return 0;
-+}
-+
-+errcode_t ext2fs_extent_index_verify(ext2_filsys fs, struct ext3_extent_idx *ix,
-+ struct ext3_extent_idx *ix_prev)
-+{
-+ ext_show_index(ix);
-+ /* FIXME: 48-bit support */
-+ if (ix->ei_leaf > fs->super->s_blocks_count)
-+ return EXT2_ET_EXTENT_INDEX_BAD;
-+
-+ if (ix_prev == NULL)
-+ return 0;
-+
-+ /* We can't have a zero logical block except for first index */
-+ if (ix->ei_block == 0)
-+ return EXT2_ET_EXTENT_INDEX_BAD;
-+
-+ if (ix->ei_block <= ix_prev->ei_block)
-+ return EXT2_ET_EXTENT_INDEX_BAD;
-+
-+ return 0;
-+}
-+
-+errcode_t ext2fs_extent_remove(struct ext3_extent_header *eh,
-+ struct ext3_extent *ex)
-+{
-+ int offs = ex - EXT_FIRST_EXTENT(eh);
-+
-+ if (offs < 0 || offs > eh->eh_entries)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ ext_printf("remove extent: offset %u\n", offs);
-+
-+ memmove(ex, ex + 1, (eh->eh_entries - offs - 1) * sizeof(*ex));
-+ --eh->eh_entries;
-+
-+ return 0;
-+}
-+
-+static errcode_t ext2fs_extent_split_internal(struct ext3_extent_header *eh,
-+ struct ext3_extent *ex, int offs)
-+{
-+ int entry = ex - EXT_FIRST_EXTENT(eh);
-+ struct ext3_extent *ex_new = ex + 1;
-+
-+ ext_printf("split: ee_len: %u ee_block: %u ee_start: %u offset: %u\n",
-+ ex->ee_len, ex->ee_block, ex->ee_start, offs);
-+ memmove(ex_new, ex, (eh->eh_entries - entry) * sizeof(*ex));
-+ ++eh->eh_entries;
-+
-+ ex->ee_len = offs;
-+ /* FIXME: 48-bit support */
-+ ex_new->ee_len -= offs;
-+ ex_new->ee_block += offs;
-+ ex_new->ee_start += offs;
-+
-+ return 0;
-+}
-+
-+errcode_t ext2fs_extent_split(ext2_filsys fs,
-+ struct ext3_extent_header **eh_orig,
-+ struct ext3_extent **ex_orig, int offs, int *flag)
-+{
-+ struct ext3_extent_header *eh_parent = *eh_orig;
-+ int retval, entry = *ex_orig - EXT_FIRST_EXTENT(eh_parent);
-+ blk_t new_block;
-+ char *buf;
-+ struct ext3_extent_idx *ei = EXT_FIRST_INDEX(eh_parent);
-+
-+ if (entry < 0 || entry > (*eh_orig)->eh_entries)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (offs > (*ex_orig)->ee_len)
-+ return EXT2_ET_EXTENT_LEAF_BAD;
-+
-+ if (eh_parent->eh_entries >= eh_parent->eh_max) {
-+ ext_printf("split: eh_entries: %u eh_max: %u\n",
-+ eh_parent->eh_entries, eh_parent->eh_max);
-+ if (eh_parent->eh_max == 4) {
-+ struct ext3_extent_header *eh_child;
-+ struct ext3_extent *ex_child;
-+
-+ retval = ext2fs_get_mem(fs->blocksize, &buf);
-+
-+ if (retval)
-+ return EXT2_ET_EXTENT_NO_SPACE;
-+
-+ memset(buf, 0, fs->blocksize);
-+ memcpy(buf, eh_parent, sizeof(*eh_parent) +
-+ eh_parent->eh_entries * sizeof(*ex_child));
-+ eh_child = (struct ext3_extent_header *)buf;
-+
-+ eh_child->eh_max = (fs->blocksize -
-+ sizeof(struct ext3_extent_header)) /
-+ sizeof(struct ext3_extent);
-+ retval = ext2fs_new_block(fs, (*ex_orig)->ee_block, 0,
-+ &new_block);
-+ if (retval)
-+ return EXT2_ET_EXTENT_NO_SPACE;
-+
-+ retval = io_channel_write_blk(fs->io, new_block, 1,buf);
-+ if (retval)
-+ return EXT2_ET_EXTENT_NO_SPACE;
-+
-+ eh_parent->eh_entries = 1;
-+ eh_parent->eh_depth = 1;
-+
-+ ex_child = EXT_FIRST_EXTENT(eh_child);
-+ ei->ei_block = ex_child->ee_block;
-+ /* FIXME: 48-bit support*/
-+ ei->ei_leaf = new_block;
-+
-+ *eh_orig = eh_child;
-+ *ex_orig = EXT_FIRST_EXTENT(eh_child) + entry;
-+
-+ *flag = BLOCK_CHANGED;
-+ } else {
-+ return EXT2_ET_EXTENT_NO_SPACE;
-+ }
-+ }
-+
-+ return ext2fs_extent_split_internal(*eh_orig, *ex_orig, offs);
-+}
-+
-+errcode_t ext2fs_extent_index_remove(struct ext3_extent_header *eh,
-+ struct ext3_extent_idx *ix)
-+{
-+ struct ext3_extent_idx *first = EXT_FIRST_INDEX(eh);
-+ int offs = ix - first;
-+
-+ ext_printf("remove index: offset %u\n", offs);
-+
-+ memmove(ix, ix + 1, (eh->eh_entries - offs - 1) * sizeof(*ix));
-+ --eh->eh_entries;
-+
-+ /* This will avoid a situation where eh_entries is 0 and
-+ * eh_depth = NON_ZERO for in-inode indices.
-+ * Plus, index pointing to this level of indices will be eventually
-+ * removed thus removing this level of indices unless current level of
-+ * indices is contained in inode.
-+ * Hence no need to check whether these set of indices are contained in
-+ * an inode.
-+ */
-+ if (!eh->eh_entries)
-+ eh->eh_depth = 0;
-+ return 0;
-+}
-+
-+/* Internal function for ext2fs_block_iterate2() to recursively walk the
-+ * extent tree, with a callback function for each block. We also call the
-+ * callback function on index blocks unless BLOCK_FLAG_DATA_ONLY is given.
-+ * We traverse the tree in-order (internal nodes before their children)
-+ * unless BLOCK_FLAG_DEPTH_FIRST is given.
-+ *
-+ * See also block_bmap_extents(). */
-+int block_iterate_extents(void *eh_buf, unsigned bufsize, blk_t ref_block,
-+ int ref_offset EXT2FS_ATTR((unused)),
-+ struct block_context *ctx)
-+{
-+ struct ext3_extent_header *orig_eh, *eh;
-+ struct ext3_extent *ex, *ex_prev = NULL;
-+ int ret = 0;
-+ int item, offs, flags, split_flag = 0;
-+ blk_t block_address;
-+
-+ orig_eh = eh = eh_buf;
-+
-+ if (ext2fs_extent_header_verify(eh, bufsize))
-+ return BLOCK_ERROR;
-+
-+ if (eh->eh_depth == 0) {
-+ ex = EXT_FIRST_EXTENT(eh);
-+ for (item = 0; item < eh->eh_entries; item++, ex++) {
-+ ext_show_extent(ex);
-+ for (offs = 0; offs < ex->ee_len; offs++) {
-+ block_address = ex->ee_start + offs;
-+ flags = (*ctx->func)(ctx->fs, &block_address,
-+ (ex->ee_block + offs),
-+ ref_block, item,
-+ ctx->priv_data);
-+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+ ret |= flags &(BLOCK_ABORT|BLOCK_ERROR);
-+ return ret;
-+ }
-+ if (!(flags & BLOCK_CHANGED))
-+ continue;
-+
-+ ext_printf("extent leaf changed: "
-+ "block was %u+%u = %u, now %u\n",
-+ ex->ee_start, offs,
-+ ex->ee_start + offs, block_address);
-+
-+ /* FIXME: 48-bit support */
-+ if (ex_prev &&
-+ block_address ==
-+ ex_prev->ee_start + ex_prev->ee_len &&
-+ ex->ee_block + offs ==
-+ ex_prev->ee_block + ex_prev->ee_len) {
-+ /* can merge block with prev extent */
-+ ex_prev->ee_len++;
-+ ex->ee_len--;
-+ ret |= BLOCK_CHANGED;
-+
-+ if (ex->ee_len == 0) {
-+ /* no blocks left in this one */
-+ ext2fs_extent_remove(eh, ex);
-+ item--; ex--;
-+ break;
-+ } else {
-+ /* FIXME: 48-bit support */
-+ ex->ee_start++;
-+ ex->ee_block++;
-+ offs--;
-+ }
-+
-+ } else if (offs > 0 && /* implies ee_len > 1 */
-+ (ctx->errcode =
-+ ext2fs_extent_split(ctx->fs, &eh,
-+ &ex, offs,
-+ &split_flag)
-+ /* advance ex past newly split item,
-+ * comparison is bogus to make sure
-+ * increment doesn't change logic */
-+ || (offs > 0 && ex++ == NULL))) {
-+ /* split before new block failed */
-+ ret |= BLOCK_ABORT | BLOCK_ERROR;
-+ return ret;
-+
-+ } else if (ex->ee_len > 1 &&
-+ (ctx->errcode =
-+ ext2fs_extent_split(ctx->fs, &eh,
-+ &ex, 1,
-+ &split_flag))) {
-+ /* split after new block failed */
-+ ret |= BLOCK_ABORT | BLOCK_ERROR;
-+ return ret;
-+
-+ } else {
-+ if (ex->ee_len != 1) {
-+ /* this is an internal error */
-+ ctx->errcode =
-+ EXT2_ET_EXTENT_INDEX_BAD;
-+ ret |= BLOCK_ABORT |BLOCK_ERROR;
-+ return ret;
-+ }
-+ /* FIXME: 48-bit support */
-+ ex->ee_start = block_address;
-+ ret |= BLOCK_CHANGED;
-+ }
-+ }
-+ ex_prev = ex;
-+ }
-+ /* Multi level split at depth == 0.
-+ * ex has been changed to point to newly allocated block
-+ * buffer. And after returning in this scenario, only inode is
-+ * updated with changed i_block. Hence explicitly write to the
-+ * block is required. */
-+ if (split_flag == BLOCK_CHANGED) {
-+ struct ext3_extent_idx *ix = EXT_FIRST_INDEX(orig_eh);
-+ ctx->errcode = ext2fs_write_ext_block(ctx->fs,
-+ ix->ei_leaf, eh);
-+ }
-+ } else {
-+ char *block_buf;
-+ struct ext3_extent_idx *ix;
-+
-+ ret = ext2fs_get_mem(ctx->fs->blocksize, &block_buf);
-+ if (ret)
-+ return ret;
-+
-+ ext_show_header(eh);
-+ ix = EXT_FIRST_INDEX(eh);
-+ for (item = 0; item < eh->eh_entries; item++, ix++) {
-+ ext_show_index(ix);
-+ /* index is processed first in e2fsck case */
-+ if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
-+ block_address = ix->ei_leaf;
-+ flags = (*ctx->func)(ctx->fs, &block_address,
-+ BLOCK_COUNT_IND, ref_block,
-+ item, ctx->priv_data);
-+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+ ret |= flags &(BLOCK_ABORT|BLOCK_ERROR);
-+ goto free_buf;
-+ }
-+ if (flags & BLOCK_CHANGED) {
-+ ret |= BLOCK_CHANGED;
-+ /* index has no more block, remove it */
-+ /* FIXME: 48-bit support */
-+ ix->ei_leaf = block_address;
-+ if (ix->ei_leaf == 0 &&
-+ ix->ei_leaf_hi == 0) {
-+ if(ext2fs_extent_index_remove(eh, ix)) {
-+ ret |= BLOCK_ABORT |BLOCK_ERROR;
-+ goto free_buf;
-+ } else {
-+ --item; --ix;
-+ continue;
-+ }
-+ }
-+ /* remapped? */
-+ }
-+ }
-+ ctx->errcode = ext2fs_read_ext_block(ctx->fs,
-+ ix->ei_leaf,
-+ block_buf);
-+ if (ctx->errcode) {
-+ ret |= BLOCK_ERROR;
-+ goto free_buf;
-+ }
-+ flags = block_iterate_extents(block_buf,
-+ ctx->fs->blocksize,
-+ ix->ei_leaf, item, ctx);
-+ if (flags & BLOCK_CHANGED) {
-+ struct ext3_extent_header *nh;
-+ ctx->errcode =
-+ ext2fs_write_ext_block(ctx->fs,
-+ ix->ei_leaf,
-+ block_buf);
-+
-+ nh = (struct ext3_extent_header *)block_buf;
-+ if (nh->eh_entries == 0)
-+ ix->ei_leaf = ix->ei_leaf_hi = 0;
-+ }
-+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+ ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+ goto free_buf;
-+ }
-+ if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
-+ flags = (*ctx->func)(ctx->fs, &block_address,
-+ BLOCK_COUNT_IND, ref_block,
-+ item, ctx->priv_data);
-+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+ ret |= flags &(BLOCK_ABORT|BLOCK_ERROR);
-+ goto free_buf;
-+ }
-+ if (flags & BLOCK_CHANGED)
-+ /* FIXME: 48-bit support */
-+ ix->ei_leaf = block_address;
-+ }
-+
-+ if (flags & BLOCK_CHANGED) {
-+ /* index has no more block, remove it */
-+ if (ix->ei_leaf == 0 && ix->ei_leaf_hi == 0 &&
-+ ext2fs_extent_index_remove(eh, ix)) {
-+ ret |= BLOCK_ABORT |BLOCK_ERROR;
-+ goto free_buf;
-+ }
-+
-+ ret |= BLOCK_CHANGED;
-+ if (ref_block == 0) {
-+ --item; --ix;
-+ continue;
-+ }
-+ /* remapped? */
-+ }
-+ }
-+
-+ free_buf:
-+ ext2fs_free_mem(&block_buf);
-+ }
-+ return ret;
-+}
-Index: e2fsprogs-1.40.11/lib/ext2fs/ind_block.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ind_block.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/ind_block.c
-@@ -22,9 +22,9 @@
- errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf)
- {
- errcode_t retval;
-- blk_t *block_nr;
-- int i;
-- int limit = fs->blocksize >> 2;
-+ int limit = fs->blocksize >> 2;
-+ blk_t *block_nr = (blk_t *)buf;
-+ int i;
-
- if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
- (fs->io != fs->image_io))
-@@ -64,3 +64,82 @@ errcode_t ext2fs_write_ind_block(ext2_fi
- }
-
-
-+errcode_t ext2fs_read_ext_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+ errcode_t retval;
-+
-+ if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-+ (fs->io != fs->image_io))
-+ memset(buf, 0, fs->blocksize);
-+ else {
-+ retval = io_channel_read_blk(fs->io, blk, 1, buf);
-+ if (retval)
-+ return retval;
-+ }
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+ if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_READ)) {
-+ struct ext3_extent_header *eh = buf;
-+ int i, limit;
-+
-+ ext2fs_swap_extent_header(eh);
-+
-+ if (eh->eh_depth == 0) {
-+ struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
-+
-+ limit = (fs->blocksize - sizeof(*eh)) / sizeof(*ex);
-+ if (eh->eh_entries < limit)
-+ limit = eh->eh_entries;
-+
-+ for (i = 0; i < limit; i++, ex++)
-+ ext2fs_swap_extent(ex);
-+ } else {
-+ struct ext3_extent_idx *ix = EXT_FIRST_INDEX(eh);
-+
-+ limit = (fs->blocksize - sizeof(*eh)) / sizeof(*ix);
-+ if (eh->eh_entries < limit)
-+ limit = eh->eh_entries;
-+
-+ for (i = 0; i < limit; i++, ix++)
-+ ext2fs_swap_extent_index(ix);
-+ }
-+ }
-+#endif
-+ return 0;
-+}
-+
-+errcode_t ext2fs_write_ext_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+ if (fs->flags & EXT2_FLAG_IMAGE_FILE)
-+ return 0;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+ if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_WRITE)) {
-+ struct ext3_extent_header *eh = buf;
-+ int i, limit;
-+
-+ if (eh->eh_depth == 0) {
-+ struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
-+
-+ limit = (fs->blocksize - sizeof(*eh)) / sizeof(*ex);
-+ if (eh->eh_entries < limit)
-+ limit = eh->eh_entries;
-+
-+ for (i = 0; i < limit; i++, ex++)
-+ ext2fs_swap_extent(ex);
-+ } else {
-+ struct ext3_extent_idx *ix = EXT_FIRST_INDEX(eh);
-+
-+ limit = (fs->blocksize - sizeof(*eh)) / sizeof(*ix);
-+ if (eh->eh_entries < limit)
-+ limit = eh->eh_entries;
-+
-+ for (i = 0; i < limit; i++, ix++)
-+ ext2fs_swap_extent_index(ix);
-+ }
-+
-+ ext2fs_swap_extent_header(eh);
-+ }
-+#endif
-+ return io_channel_write_blk(fs->io, blk, 1, buf);
-+}
-+
-Index: e2fsprogs-1.40.11/lib/ext2fs/swapfs.c
+Index: e2fsprogs-1.41.4/lib/ext2fs/swapfs.c
===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/swapfs.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/swapfs.c
-@@ -142,11 +142,33 @@ void ext2fs_swap_ext_attr(char *to, char
- }
- }
-
-+void ext2fs_swap_extent_header(struct ext3_extent_header *eh) {
-+ eh->eh_magic = ext2fs_swab16(eh->eh_magic);
-+ eh->eh_entries = ext2fs_swab16(eh->eh_entries);
-+ eh->eh_max = ext2fs_swab16(eh->eh_max);
-+ eh->eh_depth = ext2fs_swab16(eh->eh_depth);
-+ eh->eh_generation = ext2fs_swab32(eh->eh_generation);
-+}
-+
-+void ext2fs_swap_extent_index(struct ext3_extent_idx *ix) {
-+ ix->ei_block = ext2fs_swab32(ix->ei_block);
-+ ix->ei_leaf = ext2fs_swab32(ix->ei_leaf);
-+ ix->ei_leaf_hi = ext2fs_swab16(ix->ei_leaf_hi);
-+ ix->ei_unused = ext2fs_swab16(ix->ei_unused);
-+}
-+
-+void ext2fs_swap_extent(struct ext3_extent *ex) {
-+ ex->ee_block = ext2fs_swab32(ex->ee_block);
-+ ex->ee_len = ext2fs_swab16(ex->ee_len);
-+ ex->ee_start_hi =ext2fs_swab16(ex->ee_start_hi);
-+ ex->ee_start = ext2fs_swab32(ex->ee_start);
-+}
-+
- void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
- struct ext2_inode_large *f, int hostorder,
- int bufsize)
- {
-- unsigned i, has_data_blocks, extra_isize, attr_magic;
-+ unsigned i, has_data_blocks, extra_isize, attr_magic, has_extents;
- int islnk = 0;
- __u32 *eaf, *eat;
-
-@@ -164,18 +186,46 @@ void ext2fs_swap_inode_full(ext2_filsys
- t->i_gid = ext2fs_swab16(f->i_gid);
- t->i_links_count = ext2fs_swab16(f->i_links_count);
- t->i_file_acl = ext2fs_swab32(f->i_file_acl);
-- if (hostorder)
-- has_data_blocks = ext2fs_inode_data_blocks(fs,
-+ if (hostorder) {
-+ has_data_blocks = ext2fs_inode_data_blocks(fs,
- (struct ext2_inode *) f);
-- t->i_blocks = ext2fs_swab32(f->i_blocks);
-- if (!hostorder)
-- has_data_blocks = ext2fs_inode_data_blocks(fs,
-+ t->i_blocks = ext2fs_swab32(f->i_blocks);
-+ has_extents = (f->i_flags & EXT4_EXTENTS_FL);
-+ t->i_flags = ext2fs_swab32(f->i_flags);
-+ } else {
-+ t->i_blocks = ext2fs_swab32(f->i_blocks);
-+ has_data_blocks = ext2fs_inode_data_blocks(fs,
- (struct ext2_inode *) t);
-+ t->i_flags = ext2fs_swab32(f->i_flags);
-+ has_extents = (t->i_flags & EXT4_EXTENTS_FL);
-+ }
- t->i_flags = ext2fs_swab32(f->i_flags);
- t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
-- if (!islnk || has_data_blocks ) {
-- for (i = 0; i < EXT2_N_BLOCKS; i++)
-- t->i_block[i] = ext2fs_swab32(f->i_block[i]);
-+ if (!islnk || has_data_blocks) {
-+ if (has_extents) {
-+ struct ext3_extent_header *eh;
-+ int max = EXT2_N_BLOCKS * sizeof(__u32) - sizeof(*eh);
-+
-+ memcpy(t->i_block, f->i_block, sizeof(f->i_block));
-+ eh = (struct ext3_extent_header *)t->i_block;
-+ ext2fs_swap_extent_header(eh);
-+
-+ if (!eh->eh_depth) {
-+ struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
-+ max = max / sizeof(struct ext3_extent);
-+ for (i = 0; i < max; i++, ex++)
-+ ext2fs_swap_extent(ex);
-+ } else {
-+ struct ext3_extent_idx *ix =
-+ EXT_FIRST_INDEX(eh);
-+ max = max / sizeof(struct ext3_extent_idx);
-+ for (i = 0; i < max; i++, ix++)
-+ ext2fs_swap_extent_index(ix);
-+ }
-+ } else {
-+ for (i = 0; i < EXT2_N_BLOCKS; i++)
-+ t->i_block[i] = ext2fs_swab32(f->i_block[i]);
-+ }
- } else if (t != f) {
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- t->i_block[i] = f->i_block[i];
-@@ -227,11 +277,13 @@ void ext2fs_swap_inode_full(ext2_filsys
+--- e2fsprogs-1.41.4.orig/lib/ext2fs/swapfs.c
++++ e2fsprogs-1.41.4/lib/ext2fs/swapfs.c
+@@ -225,11 +225,13 @@ void ext2fs_swap_inode_full(ext2_filsys
if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
return; /* no i_extra_isize field */
@@ -1740,10 +204,10 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/swapfs.c
if (extra_isize > EXT2_INODE_SIZE(fs->super) -
sizeof(struct ext2_inode)) {
/* this is error case: i_extra_size is too large */
-Index: e2fsprogs-1.40.11/lib/ext2fs/valid_blk.c
+Index: e2fsprogs-1.41.4/lib/ext2fs/valid_blk.c
===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/valid_blk.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/valid_blk.c
+--- e2fsprogs-1.41.4.orig/lib/ext2fs/valid_blk.c
++++ e2fsprogs-1.41.4/lib/ext2fs/valid_blk.c
@@ -19,6 +19,7 @@
#include "ext2_fs.h"
@@ -1778,256 +242,144 @@ Index: e2fsprogs-1.40.11/lib/ext2fs/valid_blk.c
if (inode->i_size > 4 && inode->i_block[1] == 0)
return 1; /* definitely using i_block[] */
return 0; /* Probably a fast symlink */
-Index: e2fsprogs-1.40.11/tests/f_bad_disconnected_inode/expect.1
+Index: e2fsprogs-1.41.4/tests/f_extents/expect.1
===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_bad_disconnected_inode/expect.1
-+++ e2fsprogs-1.40.11/tests/f_bad_disconnected_inode/expect.1
-@@ -1,4 +1,10 @@
- Pass 1: Checking inodes, blocks, and sizes
-+Inode 15 has EXTENT_FL set, but is not in extents format
-+Fix? yes
-+
-+Inode 16 has EXTENT_FL set, but is not in extents format
-+Fix? yes
-+
- Pass 2: Checking directory structure
- Pass 3: Checking directory connectivity
- /lost+found not found. Create? yes
-Index: e2fsprogs-1.40.11/tests/f_bbfile/expect.1
-===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_bbfile/expect.1
-+++ e2fsprogs-1.40.11/tests/f_bbfile/expect.1
-@@ -3,46 +3,60 @@ Filesystem did not have a UUID; generati
- Pass 1: Checking inodes, blocks, and sizes
- Group 0's inode bitmap (4) is bad. Relocate? yes
-
-+Inode 11 has corrupt indirect block
-+Clear? yes
-+
- Relocating group 0's inode bitmap from 4 to 43...
-+Restarting e2fsck from the beginning...
-+Pass 1: Checking inodes, blocks, and sizes
+--- e2fsprogs-1.41.4.orig/tests/f_extents/expect.1
++++ e2fsprogs-1.41.4/tests/f_extents/expect.1
+@@ -2,51 +2,68 @@ Pass 1: Checking inodes, blocks, and siz
+ Inode 12 is in extent format, but superblock is missing EXTENTS feature
+ Fix? yes
- Running additional passes to resolve blocks claimed by more than one inode...
- Pass 1B: Rescanning for multiply-claimed blocks
- Multiply-claimed block(s) in inode 2: 21
--Multiply-claimed block(s) in inode 11: 9 10 11 12 13 14 15 16 17 18 19 20
- Multiply-claimed block(s) in inode 12: 25 26
- Pass 1C: Scanning directories for inodes with multiply-claimed blocks
- Pass 1D: Reconciling multiply-claimed blocks
--(There are 3 inodes containing multiply-claimed blocks.)
-+(There are 2 inodes containing multiply-claimed blocks.)
+-Inode 12 has an invalid extent
+- (logical block 0, invalid physical block 21994527527949, len 17)
++Inode 12 has high 16 bits of extent/index block set
+ Clear? yes
- File / (inode #2, mod time Sun Jan 2 08:29:13 1994)
- has 1 multiply-claimed block(s), shared with 1 file(s):
- <The bad blocks inode> (inode #1, mod time Sun Jul 17 00:47:58 1994)
- Clone multiply-claimed blocks? yes
+-Inode 12, i_blocks is 34, should be 0. Fix? yes
+-
++High 16 bits of extent/index block set
++CLEARED.
+ Inode 13 missing EXTENT_FL, but is in extents format
+ Fix? yes
--File /lost+found (inode #11, mod time Sun Jan 2 08:28:40 1994)
-- has 12 multiply-claimed block(s), shared with 1 file(s):
-- <The bad blocks inode> (inode #1, mod time Sun Jul 17 00:47:58 1994)
--Clone multiply-claimed blocks? yes
+-Inode 17 has an invalid extent
+- (logical block 0, invalid physical block 22011707397135, len 15)
+-Clear? yes
+-
+-Inode 17, i_blocks is 32, should be 0. Fix? yes
-
- File /termcap (inode #12, mod time Sun Jan 2 08:29:13 1994)
- has 2 multiply-claimed block(s), shared with 1 file(s):
- <The bad blocks inode> (inode #1, mod time Sun Jul 17 00:47:58 1994)
- Clone multiply-claimed blocks? yes
++High 16 bits of extent/index block set
++CLEARED.
+ Error while reading over extent tree in inode 18: Corrupt extent header
+ Clear inode? yes
- Pass 2: Checking directory structure
-+Entry 'lost+found' in / (2) has deleted/unused inode 11. Clear? yes
-+
- Pass 3: Checking directory connectivity
-+/lost+found not found. Create? yes
-+
- Pass 4: Checking reference counts
-+Inode 2 ref count is 4, should be 3. Fix? yes
-+
- Pass 5: Checking group summary information
- Block bitmap differences: +43
- Fix? yes
+ Inode 18, i_blocks is 2, should be 0. Fix? yes
--Free blocks count wrong for group #0 (57, counted=41).
-+Free blocks count wrong for group #0 (56, counted=52).
-+Fix? yes
+
-+Free blocks count wrong (56, counted=52).
-+Fix? yes
++Running additional passes to resolve blocks claimed by more than one inode...
++Pass 1B: Rescanning for multiply-claimed blocks
++Multiply-claimed block(s) in inode 12: 5133 5124 5125 5129 5132 5133 5142 5143 5144 5145
++Multiply-claimed block(s) in inode 17: 5124 5125 5129 5132 5142 5143 5144 5145
++Pass 1C: Scanning directories for inodes with multiply-claimed blocks
++Pass 1D: Reconciling multiply-claimed blocks
++(There are 2 inodes containing multiply-claimed blocks.)
+
-+Free inodes count wrong for group #0 (19, counted=20).
-+Fix? yes
++File /fdup1 (inode #12, mod time Wed Jul 5 21:55:26 2006)
++ has 10 multiply-claimed block(s), shared with 1 file(s):
++ /fdup2 (inode #17, mod time Wed Jul 5 21:55:27 2006)
++Clone multiply-claimed blocks? yes
+
-+Directories count wrong for group #0 (3, counted=2).
- Fix? yes
-
--Free blocks count wrong (57, counted=41).
-+Free inodes count wrong (19, counted=20).
- Fix? yes
-
-
- test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
--test_filesys: 12/32 files (0.0% non-contiguous), 59/100 blocks
-+test_filesys: 12/32 files (0.0% non-contiguous), 48/100 blocks
- Exit status is 1
-Index: e2fsprogs-1.40.11/tests/f_bbfile/expect.2
-===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_bbfile/expect.2
-+++ e2fsprogs-1.40.11/tests/f_bbfile/expect.2
-@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
- Pass 3: Checking directory connectivity
- Pass 4: Checking reference counts
- Pass 5: Checking group summary information
--test_filesys: 12/32 files (8.3% non-contiguous), 59/100 blocks
-+test_filesys: 12/32 files (8.3% non-contiguous), 48/100 blocks
- Exit status is 0
-Index: e2fsprogs-1.40.11/tests/f_lotsbad/expect.1
-===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_lotsbad/expect.1
-+++ e2fsprogs-1.40.11/tests/f_lotsbad/expect.1
-@@ -8,54 +8,39 @@ Inode 13, i_size is 15360, should be 122
-
- Inode 13, i_blocks is 32, should be 30. Fix? yes
++File /fdup2 (inode #17, mod time Wed Jul 5 21:55:27 2006)
++ has 8 multiply-claimed block(s), shared with 1 file(s):
++ /fdup1 (inode #12, mod time Wed Jul 5 21:55:26 2006)
++Multiply-claimed blocks already reassigned or cloned.
++
+ Pass 2: Checking directory structure
+ Entry 'fbad-flag' in / (2) has deleted/unused inode 18. Clear? yes
--Inode 12 has illegal block(s). Clear? yes
-+Inode 12 has corrupt indirect block
++Inode 19 (/fbad-sock) is an illegal FIFO.
+Clear? yes
-
--Illegal block #12 (778398818) in inode 12. CLEARED.
--Illegal block #13 (1768444960) in inode 12. CLEARED.
--Illegal block #14 (1752375411) in inode 12. CLEARED.
--Illegal block #15 (1684829551) in inode 12. CLEARED.
--Illegal block #16 (1886349344) in inode 12. CLEARED.
--Illegal block #17 (1819633253) in inode 12. CLEARED.
--Illegal block #18 (1663072620) in inode 12. CLEARED.
--Illegal block #19 (1735287144) in inode 12. CLEARED.
--Illegal block #20 (1310731877) in inode 12. CLEARED.
--Illegal block #21 (560297071) in inode 12. CLEARED.
--Illegal block #22 (543512352) in inode 12. CLEARED.
--Too many illegal blocks in inode 12.
--Clear inode? yes
-+Inode 12, i_blocks is 34, should be 24. Fix? yes
-
--Restarting e2fsck from the beginning...
--Pass 1: Checking inodes, blocks, and sizes
- Pass 2: Checking directory structure
--Entry 'termcap' in / (2) has deleted/unused inode 12. Clear? yes
--
++
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
- Inode 2 ref count is 5, should be 4. Fix? yes
-
Pass 5: Checking group summary information
--Block bitmap differences: -(27--41) -(44--45) -(74--90)
-+Block bitmap differences: -(37--41) -(74--90)
+-Block bitmap differences: -1081 +4611 -(5121--5142)
++Block bitmap differences: +4611 -(5121--5122) +(5143--5146)
Fix? yes
--Free blocks count wrong for group #0 (9, counted=43).
-+Free blocks count wrong for group #0 (9, counted=31).
+-Free blocks count wrong for group #0 (7081, counted=7098).
++Free blocks count wrong for group #0 (7081, counted=7065).
Fix? yes
--Free blocks count wrong (9, counted=43).
-+Free blocks count wrong (9, counted=31).
+-Free blocks count wrong (7081, counted=7098).
++Free blocks count wrong (7081, counted=7065).
Fix? yes
--Inode bitmap differences: -12 -14
-+Inode bitmap differences: -14
+ Inode bitmap differences: -18
Fix? yes
--Free inodes count wrong for group #0 (18, counted=20).
-+Free inodes count wrong for group #0 (18, counted=19).
+-Free inodes count wrong for group #0 (237, counted=238).
++Free inodes count wrong for group #0 (238, counted=239).
Fix? yes
- Directories count wrong for group #0 (4, counted=3).
- Fix? yes
-
--Free inodes count wrong (18, counted=20).
-+Free inodes count wrong (18, counted=19).
+-Free inodes count wrong (237, counted=238).
++Free inodes count wrong (238, counted=239).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
--test_filesys: 12/32 files (0.0% non-contiguous), 57/100 blocks
-+test_filesys: 13/32 files (7.7% non-contiguous), 69/100 blocks
+-test_filesys: 18/256 files (0.0% non-contiguous), 1094/8192 blocks
++test_filesys: 17/256 files (11.8% non-contiguous), 1127/8192 blocks
Exit status is 1
-Index: e2fsprogs-1.40.11/tests/f_lotsbad/expect.2
+Index: e2fsprogs-1.41.4/tests/f_extents/expect.2
===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_lotsbad/expect.2
-+++ e2fsprogs-1.40.11/tests/f_lotsbad/expect.2
+--- e2fsprogs-1.41.4.orig/tests/f_extents/expect.2
++++ e2fsprogs-1.41.4/tests/f_extents/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
--test_filesys: 12/32 files (0.0% non-contiguous), 57/100 blocks
-+test_filesys: 13/32 files (7.7% non-contiguous), 69/100 blocks
+-test_filesys: 18/256 files (0.0% non-contiguous), 1094/8192 blocks
++test_filesys: 17/256 files (11.8% non-contiguous), 1127/8192 blocks
Exit status is 0
-Index: e2fsprogs-1.40.11/tests/f_messy_inode/expect.1
+Index: e2fsprogs-1.41.4/tests/f_fast_symlink_extents/expect.1
===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_messy_inode/expect.1
-+++ e2fsprogs-1.40.11/tests/f_messy_inode/expect.1
-@@ -1,38 +1,36 @@
- Filesystem did not have a UUID; generating one.
-
+--- e2fsprogs-1.41.4.orig/tests/f_fast_symlink_extents/expect.1
++++ e2fsprogs-1.41.4/tests/f_fast_symlink_extents/expect.1
+@@ -1,11 +1,23 @@
Pass 1: Checking inodes, blocks, and sizes
--Inode 14 has illegal block(s). Clear? yes
--
--Illegal block #2 (4294901760) in inode 14. CLEARED.
--Illegal block #3 (4294901760) in inode 14. CLEARED.
--Illegal block #4 (4294901760) in inode 14. CLEARED.
--Illegal block #5 (4294901760) in inode 14. CLEARED.
--Illegal block #6 (4294901760) in inode 14. CLEARED.
--Illegal block #7 (4294901760) in inode 14. CLEARED.
--Illegal block #8 (4294901760) in inode 14. CLEARED.
--Illegal block #9 (4294901760) in inode 14. CLEARED.
--Illegal block #10 (4294901760) in inode 14. CLEARED.
--Inode 14, i_size is 18446462598732849291, should be 2048. Fix? yes
--
--Inode 14, i_blocks is 18, should be 4. Fix? yes
-+Inode 14 has corrupt indirect block
-+Clear? yes
+-Fast symlink 13 has EXTENT_FL set. Clear? yes
++Error while reading over extent tree in inode 13: Corrupt extent header
++Clear inode? yes
-+Restarting e2fsck from the beginning...
-+Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
--i_file_acl for inode 14 (/MAKEDEV) is 4294901760, should be zero.
--Clear? yes
-+Entry 'MAKEDEV' in / (2) has deleted/unused inode 14. Clear? yes
-
++Entry 'bar' in / (2) has deleted/unused inode 13. Clear? yes
++
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
--Block bitmap differences: -(43--49)
-+Block bitmap differences: -(41--49)
++Inode bitmap differences: -13
+Fix? yes
+
-+Free blocks count wrong for group #0 (68, counted=77).
++Free inodes count wrong for group #0 (3, counted=4).
+Fix? yes
+
-+Free blocks count wrong (68, counted=77).
++Free inodes count wrong (3, counted=4).
+Fix? yes
+
-+Inode bitmap differences: -14
- Fix? yes
-
--Free blocks count wrong for group #0 (68, counted=75).
-+Free inodes count wrong for group #0 (3, counted=4).
- Fix? yes
-
--Free blocks count wrong (68, counted=75).
-+Free inodes count wrong (3, counted=4).
- Fix? yes
-
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
--test_filesys: 29/32 files (3.4% non-contiguous), 25/100 blocks
-+test_filesys: 28/32 files (0.0% non-contiguous), 23/100 blocks
+-test_filesys: 13/16 files (0.0% non-contiguous), 21/100 blocks
++test_filesys: 12/16 files (0.0% non-contiguous), 21/100 blocks
Exit status is 1
-Index: e2fsprogs-1.40.11/tests/f_messy_inode/expect.2
+Index: e2fsprogs-1.41.4/tests/f_fast_symlink_extents/expect.2
===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_messy_inode/expect.2
-+++ e2fsprogs-1.40.11/tests/f_messy_inode/expect.2
+--- e2fsprogs-1.41.4.orig/tests/f_fast_symlink_extents/expect.2
++++ e2fsprogs-1.41.4/tests/f_fast_symlink_extents/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
--test_filesys: 29/32 files (0.0% non-contiguous), 25/100 blocks
-+test_filesys: 28/32 files (0.0% non-contiguous), 23/100 blocks
+-test_filesys: 13/16 files (0.0% non-contiguous), 21/100 blocks
++test_filesys: 12/16 files (0.0% non-contiguous), 21/100 blocks
Exit status is 0
diff --git a/debian/patches/e2fsprogs-fiemap.patch b/debian/patches/e2fsprogs-fiemap.patch
deleted file mode 100644
index 7a1033b..0000000
--- a/debian/patches/e2fsprogs-fiemap.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-Add support for ioctl(FIEMAP) to filefrag. If the kernel supports FIEMAP
-the filefrag program prefers this more efficient mechanism to get extent
-information instead of repeated FIBMAP calls.
-
-Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-
-Index: e2fsprogs-1.40.2/misc/filefrag.c
-===================================================================
---- e2fsprogs-1.40.2.orig/misc/filefrag.c
-+++ e2fsprogs-1.40.2/misc/filefrag.c
-@@ -38,11 +38,47 @@ extern int optind;
- #include <sys/vfs.h>
- #include <sys/ioctl.h>
- #include <linux/fd.h>
-+#include <ext2fs/ext2_types.h>
-
- int verbose = 0;
-
--#define FIBMAP _IO(0x00,1) /* bmap access */
--#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
-+struct fiemap_extent {
-+ __u64 fe_offset; /* offset in bytes for the start of the extent */
-+ __u64 fe_length; /* length in bytes for the extent */
-+ __u32 fe_flags; /* returned FIEMAP_EXTENT_* flags for the extent */
-+ __u32 fe_lun; /* logical device number for extent (starting at 0) */
-+};
-+
-+struct fiemap {
-+ __u64 fm_start; /* logical starting byte offset (in/out) */
-+ __u64 fm_length; /* logical length of map (in/out) */
-+ __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
-+ __u32 fm_extent_count; /* number of extents in fm_extents (in/out) */
-+ __u64 fm_unused;
-+ struct fiemap_extent fm_extents[0];
-+};
-+
-+#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
-+#define FIEMAP_FLAG_HSM_READ 0x00000002 /* get data from HSM before map */
-+#define FIEMAP_FLAG_NUM_EXTENTS 0x00000004 /* return only number of extents */
-+#define FIEMAP_FLAG_INCOMPAT 0xff000000 /* error for unknown flags in here */
-+
-+#define FIEMAP_EXTENT_HOLE 0x00000001 /* has no data or space allocation */
-+#define FIEMAP_EXTENT_UNWRITTEN 0x00000002 /* space allocated, but no data */
-+#define FIEMAP_EXTENT_UNMAPPED 0x00000004 /* has data but no space allocation*/
-+#define FIEMAP_EXTENT_ERROR 0x00000008 /* mapping error, errno in fe_start*/
-+#define FIEMAP_EXTENT_NO_DIRECT 0x00000010 /* cannot access data directly */
-+#define FIEMAP_EXTENT_LAST 0x00000020 /* last extent in the file */
-+#define FIEMAP_EXTENT_DELALLOC 0x00000040 /* has data but not yet written,
-+ must have EXTENT_UNKNOWN set */
-+#define FIEMAP_EXTENT_SECONDARY 0x00000080 /* data (also) in secondary storage,
-+ not in primary if EXTENT_UNKNOWN*/
-+#define FIEMAP_EXTENT_EOF 0x00000100 /* if fm_start+fm_len is beyond EOF*/
-+
-+
-+#define FIBMAP _IO(0x00, 1) /* bmap access */
-+#define FIGETBSZ _IO(0x00, 2) /* get the block size used for bmap */
-+#define EXT4_IOC_FIEMAP _IOWR('f', 10, struct fiemap) /* get file extent info*/
-
- #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
- #define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
-@@ -71,6 +107,62 @@ static unsigned long get_bmap(int fd, un
- return b;
- }
-
-+int filefrag_fiemap(int fd, int bs, int *num_extents)
-+{
-+ char buf[4096] = "";
-+ struct fiemap *fiemap = (struct fiemap *)buf;
-+ int count = (sizeof(buf) - sizeof(*fiemap)) /
-+ sizeof(struct fiemap_extent);
-+ __u64 logical_blk = 0, last_blk = 0;
-+ unsigned long flags;
-+ int tot_extents = 0;
-+ int eof = 0;
-+ int i;
-+ int rc;
-+
-+ memset(fiemap, 0, sizeof(struct fiemap));
-+ fiemap->fm_extent_count = count;
-+ fiemap->fm_length = ~0ULL;
-+ if (!verbose)
-+ flags |= FIEMAP_FLAG_NUM_EXTENTS;
-+
-+ do {
-+ fiemap->fm_length = ~0ULL;
-+ fiemap->fm_flags = flags;
-+ fiemap->fm_extent_count = count;
-+ rc = ioctl (fd, EXT4_IOC_FIEMAP, (unsigned long) fiemap);
-+ if (rc)
-+ return rc;
-+
-+ if (!verbose) {
-+ *num_extents = fiemap->fm_extent_count;
-+ goto out;
-+ }
-+
-+ for (i = 0; i < fiemap->fm_extent_count; i++) {
-+ __u64 phy_blk;
-+ unsigned long ext_len;
-+
-+ phy_blk = fiemap->fm_extents[i].fe_offset / bs;
-+ ext_len = fiemap->fm_extents[i].fe_length / bs;
-+ if (logical_blk && (phy_blk != last_blk+1))
-+ printf("Discontinuity: Block %llu is at %llu "
-+ "(was %llu)\n", logical_blk, phy_blk,
-+ last_blk);
-+ logical_blk += ext_len;
-+ last_blk = phy_blk + ext_len - 1;
-+ if (fiemap->fm_extents[i].fe_flags & FIEMAP_EXTENT_EOF)
-+ eof = 1;
-+ }
-+ fiemap->fm_start += fiemap->fm_length;
-+ tot_extents += fiemap->fm_extent_count;
-+ } while (0);
-+
-+ *num_extents = tot_extents;
-+out:
-+ return 0;
-+}
-+
- #define EXT2_DIRECT 12
-
- static void frag_report(const char *filename)
-@@ -86,7 +178,7 @@ static void frag_report(const char *file
- unsigned long block, last_block = 0, numblocks, i;
- long bpib; /* Blocks per indirect block */
- long cylgroups;
-- int discont = 0, expected;
-+ int num_extents = 0, expected;
- int is_ext2 = 0;
- unsigned int flags;
-
-@@ -135,7 +227,8 @@ static void frag_report(const char *file
- if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
- flags = 0;
- if (flags & EXT4_EXTENTS_FL) {
-- printf("File is stored in extents format\n");
-+ if (verbose)
-+ printf("File is stored in extents format\n");
- is_ext2 = 0;
- }
- if (verbose)
-@@ -148,32 +241,36 @@ static void frag_report(const char *file
- printf("First block: %lu\nLast block: %lu\n",
- get_bmap(fd, 0), get_bmap(fd, numblocks - 1));
- }
-- for (i=0; i < numblocks; i++) {
-- if (is_ext2 && last_block) {
-- if (((i-EXT2_DIRECT) % bpib) == 0)
-- last_block++;
-- if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
-- last_block++;
-- if (((i-EXT2_DIRECT-bpib-bpib*bpib) % (bpib*bpib*bpib)) == 0)
-- last_block++;
-- }
-- block = get_bmap(fd, i);
-- if (block == 0)
-- continue;
-- if (last_block && (block != last_block +1) ) {
-- if (verbose)
-- printf("Discontinuity: Block %ld is at %lu (was %lu)\n",
-- i, block, last_block);
-- discont++;
-+ if (is_ext2 || (filefrag_fiemap(fd, bs, &num_extents) != 0)) {
-+ for (i = 0; i < numblocks; i++) {
-+ if (is_ext2 && last_block) {
-+ if (((i-EXT2_DIRECT) % bpib) == 0)
-+ last_block++;
-+ if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
-+ last_block++;
-+ if (((i-EXT2_DIRECT-bpib-bpib*bpib) %
-+ (bpib*bpib*bpib)) == 0)
-+ last_block++;
-+ }
-+ block = get_bmap(fd, i);
-+ if (block == 0)
-+ continue;
-+ if (last_block && (block != last_block+1) ) {
-+ if (verbose)
-+ printf("Discontinuity: Block %ld is at "
-+ "%lu (was %lu)\n",
-+ i, block, last_block+1);
-+ num_extents++;
-+ }
-+ last_block = block;
- }
-- last_block = block;
- }
-- if (discont==0)
-+ if (num_extents == 1)
- printf("%s: 1 extent found", filename);
- else
-- printf("%s: %d extents found", filename, discont+1);
-+ printf("%s: %d extents found", filename, num_extents);
- expected = (numblocks/((bs*8)-(fsinfo.f_files/8/cylgroups)-3))+1;
-- if (is_ext2 && expected != discont+1)
-+ if (is_ext2 && expected != num_extents)
- printf(", perfection would be %d extent%s\n", expected,
- (expected>1) ? "s" : "");
- else
diff --git a/debian/patches/e2fsprogs-ibadness-counter.patch b/debian/patches/e2fsprogs-ibadness-counter.patch
index 17c66d1..2cb2a72 100644
--- a/debian/patches/e2fsprogs-ibadness-counter.patch
+++ b/debian/patches/e2fsprogs-ibadness-counter.patch
@@ -17,10 +17,10 @@ suddenly having shared blocks with a lot of good inodes (or each other).
Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
Signed-off-by: Girish Shilamkar <girish at clusterfs.com>
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.h
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.h
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.h
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.h
@@ -11,6 +11,7 @@
#include <stdio.h>
@@ -29,7 +29,7 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-@@ -195,6 +196,18 @@ typedef enum {
+@@ -199,6 +200,18 @@ typedef enum {
E2F_CLONE_ZERO
} clone_opt_t;
@@ -48,7 +48,7 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
/*
* Define the extended attribute refcount structure
*/
-@@ -229,7 +242,6 @@ struct e2fsck_struct {
+@@ -235,7 +248,6 @@ struct e2fsck_struct {
unsigned long max);
ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */
@@ -56,7 +56,7 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */
ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */
-@@ -244,6 +256,8 @@ struct e2fsck_struct {
+@@ -250,6 +262,8 @@ struct e2fsck_struct {
*/
ext2_icount_t inode_count;
ext2_icount_t inode_link_info;
@@ -65,27 +65,27 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
ext2_refcount_t refcount;
ext2_refcount_t refcount_extra;
-@@ -344,6 +358,7 @@ struct e2fsck_struct {
+@@ -352,6 +366,7 @@ struct e2fsck_struct {
/* misc fields */
time_t now;
time_t time_fudge; /* For working around buggy init scripts */
+ time_t now_tolerance_val;
int ext_attr_ver;
- shared_opt_t shared;
- clone_opt_t clone;
-@@ -454,6 +469,8 @@ extern int e2fsck_pass1_check_device_ino
- struct ext2_inode *inode);
- extern int e2fsck_pass1_check_symlink(ext2_filsys fs,
- struct ext2_inode *inode, char *buf);
+ shared_opt_t shared;
+ clone_opt_t clone;
+@@ -468,6 +483,8 @@ extern int e2fsck_pass1_check_symlink(ex
+ extern void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
+ struct ext2_inode *inode, int restart_flag,
+ const char *source);
+extern void e2fsck_mark_inode_bad(e2fsck_t ctx, ino_t ino, int count);
+extern int is_inode_bad(e2fsck_t ctx, ino_t ino);
/* pass2.c */
extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
-Index: e2fsprogs-1.40.4/e2fsck/pass1.c
+Index: e2fsprogs-1.41.5/e2fsck/pass1.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/pass1.c
-+++ e2fsprogs-1.40.4/e2fsck/pass1.c
+--- e2fsprogs-1.41.5.orig/e2fsck/pass1.c
++++ e2fsprogs-1.41.5/e2fsck/pass1.c
@@ -20,7 +20,8 @@
* - A bitmap of which inodes are in use. (inode_used_map)
* - A bitmap of which inodes are directories. (inode_dir_map)
@@ -96,7 +96,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
* - A bitmap of which inodes are in bad blocks. (inode_bb_map)
* - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
* - A bitmap of which inodes need to be expanded (expand_eisize_map)
-@@ -68,7 +69,6 @@ static void check_blocks(e2fsck_t ctx, s
+@@ -67,7 +68,6 @@ static void check_blocks(e2fsck_t ctx, s
static void mark_table_blocks(e2fsck_t ctx);
static void alloc_bb_map(e2fsck_t ctx);
static void alloc_imagic_map(e2fsck_t ctx);
@@ -104,7 +104,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
static void handle_fs_bad_blocks(e2fsck_t ctx);
static void process_inodes(e2fsck_t ctx, char *block_buf);
static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
-@@ -220,6 +220,7 @@ static void check_immutable(e2fsck_t ctx
+@@ -241,6 +241,7 @@ static void check_immutable(e2fsck_t ctx
if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
return;
@@ -112,15 +112,15 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
return;
-@@ -238,6 +239,7 @@ static void check_size(e2fsck_t ctx, str
+@@ -259,6 +260,7 @@ static void check_size(e2fsck_t ctx, str
if ((inode->i_size == 0) && (inode->i_size_high == 0))
return;
-
+
+ e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
return;
-
-@@ -352,6 +354,7 @@ static void check_inode_extra_space(e2fs
+
+@@ -380,6 +382,7 @@ static void check_inode_extra_space(e2fs
*/
if (inode->i_extra_isize &&
(inode->i_extra_isize < min || inode->i_extra_isize > max)) {
@@ -128,15 +128,15 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
return;
inode->i_extra_isize = ctx->want_extra_isize;
-@@ -441,6 +444,7 @@ static void check_is_really_dir(e2fsck_t
- (dirent->rec_len % 4))
+@@ -474,6 +477,7 @@ static void check_is_really_dir(e2fsck_t
+ (rec_len % 4))
return;
+ e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
- e2fsck_write_inode_full(ctx, pctx->ino, inode,
-@@ -637,6 +641,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+ e2fsck_write_inode_full(ctx, pctx->ino, inode,
+@@ -670,6 +674,7 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2_filsys fs = ctx->fs;
ext2_ino_t ino;
struct ext2_inode *inode;
@@ -144,19 +144,31 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
ext2_inode_scan scan;
char *block_buf;
#ifdef RESOURCE_TRACK
-@@ -873,8 +878,10 @@ void e2fsck_pass1(e2fsck_t ctx)
- ino, 0);
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
-+ } else {
+@@ -915,14 +920,17 @@ void e2fsck_pass1(e2fsck_t ctx)
+ ehp = inode->i_block;
+ #endif
+ if ((ext2fs_extent_header_verify(ehp,
+- sizeof(inode->i_block)) == 0) &&
+- (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx))) {
+- inode->i_flags |= EXT4_EXTENTS_FL;
++ sizeof(inode->i_block)) == 0)) {
++ if (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx)) {
+ e2fsck_mark_inode_bad(ctx, ino,
-+ BADNESS_NORMAL);
- }
--
++ BADNESS_NORMAL);
++ inode->i_flags |= EXT4_EXTENTS_FL;
+ #ifdef WORDS_BIGENDIAN
+- memcpy(inode->i_block, tmp_block,
+- sizeof(inode->i_block));
++ memcpy(inode->i_block, tmp_block,
++ sizeof(inode->i_block));
+ #endif
+- e2fsck_write_inode(ctx, ino, inode, "pass1");
++ e2fsck_write_inode(ctx, ino, inode, "pass1");
++ }
}
- /*
- * If dtime is set, offer to clear it. mke2fs
-@@ -891,6 +898,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+ }
+
+@@ -986,6 +994,7 @@ void e2fsck_pass1(e2fsck_t ctx)
e2fsck_write_inode(ctx, ino, inode,
"pass1");
}
@@ -164,26 +176,31 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
}
} else if (ino == EXT2_JOURNAL_INO) {
ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
-@@ -997,6 +1005,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+@@ -1092,6 +1101,7 @@ void e2fsck_pass1(e2fsck_t ctx)
inode->i_dtime = 0;
e2fsck_write_inode(ctx, ino, inode, "pass1");
}
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
}
-
+
ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
-@@ -1013,14 +1022,16 @@ void e2fsck_pass1(e2fsck_t ctx)
+@@ -1104,18 +1114,19 @@ void e2fsck_pass1(e2fsck_t ctx)
frag = fsize = 0;
}
-
+
+ /* Fixed in pass2, e2fsck_process_bad_inode(). */
if (inode->i_faddr || frag || fsize ||
(LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
- mark_inode_bad(ctx, ino);
+- if (!(fs->super->s_feature_incompat &
++ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
++ if (!(fs->super->s_feature_incompat &
+ EXT4_FEATURE_INCOMPAT_64BIT) &&
+ inode->osd2.linux2.l_i_file_acl_high != 0)
+- mark_inode_bad(ctx, ino);
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
-+ /* Fixed in pass2, e2fsck_process_bad_inode(). */
if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
- !(fs->super->s_feature_ro_compat &
+ !(fs->super->s_feature_ro_compat &
EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
(inode->osd2.linux2.l_i_blocks_hi != 0))
- mark_inode_bad(ctx, ino);
@@ -191,7 +208,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
if (inode->i_flags & EXT2_IMAGIC_FL) {
if (imagic_fs) {
if (!ctx->inode_imagic_map)
-@@ -1033,6 +1044,7 @@ void e2fsck_pass1(e2fsck_t ctx)
+@@ -1128,6 +1139,7 @@ void e2fsck_pass1(e2fsck_t ctx)
e2fsck_write_inode(ctx, ino,
inode, "pass1");
}
@@ -199,7 +216,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
}
}
-@@ -1075,8 +1087,41 @@ void e2fsck_pass1(e2fsck_t ctx)
+@@ -1183,8 +1195,42 @@ void e2fsck_pass1(e2fsck_t ctx)
check_immutable(ctx, &pctx);
check_size(ctx, &pctx);
ctx->fs_sockets_count++;
@@ -240,47 +257,11 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
+ (inode->osd2.linux2.l_i_blocks_hi != 0))) {
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
+ }
-
- eh = (struct ext3_extent_header *)inode->i_block;
- if ((inode->i_flags & EXT4_EXTENTS_FL)) {
-@@ -1091,19 +1136,28 @@ void e2fsck_pass1(e2fsck_t ctx)
- ext2fs_mark_super_dirty(fs);
- extent_fs = 1;
- }
-- } else if (fix_problem(ctx, PR_1_SET_EXTENT_FL, &pctx)){
-- inode->i_flags &= ~EXT4_EXTENTS_FL;
-- e2fsck_write_inode(ctx, ino, inode, "pass1");
-- goto check_ind_inode;
-+ } else {
-+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
-+ if (fix_problem(ctx, PR_1_SET_EXTENT_FL,
-+ &pctx)) {
-+ inode->i_flags &= ~EXT4_EXTENTS_FL;
-+ e2fsck_write_inode(ctx, ino,
-+ inode,"pass1");
-+ goto check_ind_inode;
-+ }
- }
- } else if (extent_fs &&
- (LINUX_S_ISREG(inode->i_mode) ||
- LINUX_S_ISDIR(inode->i_mode)) &&
- ext2fs_extent_header_verify(eh, EXT2_N_BLOCKS *
-- sizeof(__u32)) == 0 &&
-- fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx)) {
-- inode->i_flags |= EXT4_EXTENTS_FL;
-- e2fsck_write_inode(ctx, ino, inode, "pass1");
-+ sizeof(__u32)) == 0) {
-+ if (fix_problem(ctx, PR_1_UNSET_EXTENT_FL,
-+ &pctx)) {
-+ inode->i_flags |= EXT4_EXTENTS_FL;
-+ e2fsck_write_inode(ctx, ino, inode,
-+ "pass1");
-+ }
-+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- }
- if (extent_fs && inode->i_flags & EXT4_EXTENTS_FL) {
- ctx->extent_files++;
-@@ -1344,29 +1398,27 @@ static EXT2_QSORT_TYPE process_inode_cmp
++
+ if (!(inode->i_flags & EXT4_EXTENTS_FL)) {
+ if (inode->i_block[EXT2_IND_BLOCK])
+ ctx->fs_ind_count++;
+@@ -1403,29 +1449,27 @@ static EXT2_QSORT_TYPE process_inode_cmp
}
/*
@@ -291,16 +272,15 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
+void e2fsck_mark_inode_bad(e2fsck_t ctx, ino_t ino, int count)
{
- struct problem_context pctx;
--
-- if (!ctx->inode_bad_map) {
-- clear_problem_context(&pctx);
-+ struct problem_context pctx;
++ struct problem_context pctx;
+ __u16 result;
-
+
+- if (!ctx->inode_bad_map) {
++ if (!ctx->inode_badness) {
+ clear_problem_context(&pctx);
+-
- pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
- _("bad inode map"), &ctx->inode_bad_map);
-+ if (!ctx->inode_badness) {
-+ clear_problem_context(&pctx);
+ pctx.errcode = ext2fs_create_icount2(ctx->fs, 0, 0, NULL,
+ &ctx->inode_badness);
if (pctx.errcode) {
@@ -321,7 +301,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
/*
* This procedure will allocate the inode "bb" (badblock) map table
*/
-@@ -1521,7 +1573,8 @@ static int check_ext_attr(e2fsck_t ctx,
+@@ -1580,7 +1624,8 @@ static int check_ext_attr(e2fsck_t ctx,
if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
(blk < fs->super->s_first_data_block) ||
(blk >= fs->super->s_blocks_count)) {
@@ -331,7 +311,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
return 0;
}
-@@ -1701,21 +1754,28 @@ static int handle_htree(e2fsck_t ctx, st
+@@ -1746,9 +1791,11 @@ static int handle_htree(e2fsck_t ctx, st
if ((!LINUX_S_ISDIR(inode->i_mode) &&
fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
@@ -340,22 +320,22 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
- return 1;
+ (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX))) {
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
-+ if (fix_problem(ctx, PR_1_HTREE_SET, pctx))
++ if (fix_problem(ctx, PR_1_HTREE_SET, pctx))
+ return 1;
+ }
- ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE,
- block_buf, htree_blk_iter_cb, &blk);
- if (((blk == 0) ||
- (blk < fs->super->s_first_data_block) ||
-- (blk >= fs->super->s_blocks_count)) &&
-- fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
-- return 1;
-+ (blk >= fs->super->s_blocks_count))) {
+ pctx->errcode = ext2fs_bmap(fs, ino, inode, 0, 0, 0, &blk);
+
+@@ -1756,6 +1803,7 @@ static int handle_htree(e2fsck_t ctx, st
+ (blk == 0) ||
+ (blk < fs->super->s_first_data_block) ||
+ (blk >= fs->super->s_blocks_count)) {
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
-+ if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
-+ return 1;
-+ }
+ if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
+ return 1;
+ else
+@@ -1763,8 +1811,11 @@ static int handle_htree(e2fsck_t ctx, st
+ }
retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
- if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
@@ -365,50 +345,33 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
+ if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
+ return 1;
+ }
-
+
/* XXX should check that beginning matches a directory */
root = (struct ext2_dx_root_info *) (block_buf + 24);
-@@ -1785,6 +1845,9 @@ static int e2fsck_ind_block_verify(struc
- bad++;
- }
+@@ -1805,8 +1856,8 @@ void e2fsck_clear_inode(e2fsck_t ctx, ex
+ ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
+ if (ctx->inode_reg_map)
+ ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
+- if (ctx->inode_bad_map)
+- ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
++ if (ctx->inode_badness)
++ ext2fs_icount_store(ctx->inode_badness, ino, 0);
+
+ /*
+ * If the inode was partially accounted for before processing
+@@ -1877,6 +1928,11 @@ static void scan_extent_node(e2fsck_t ct
+ problem = PR_1_EXTENT_ENDS_BEYOND;
-+ if (num_indir <= EXT2_N_BLOCKS)
-+ e2fsck_mark_inode_bad(p->ctx, p->ino, bad);
+ if (problem) {
++ /* To ensure that extent is in inode */
++ if (info.curr_level == 0)
++ e2fsck_mark_inode_bad(ctx, pctx->ino,
++ BADNESS_HIGH);
+
- if ((num_indir <= EXT2_N_BLOCKS && bad > 4) || bad > 8)
- return PR_1_INDIRECT_BAD;
-
-@@ -1828,6 +1891,10 @@ static int e2fsck_ext_block_verify(struc
- pctx->blkcount = ex->ee_start;
- pctx->num = ex->ee_len;
- pctx->blk = ex->ee_block;
-+ /* To ensure that extent is in inode */
-+ if (eh->eh_max == 4)
-+ e2fsck_mark_inode_bad(p->ctx, p->ino,
-+ BADNESS_HIGH);
- if (fix_problem(ctx, PR_1_EXTENT_BAD, pctx)) {
- ext2fs_extent_remove(eh, ex);
- i--; ex--; /* check next (moved) item */
-@@ -1854,6 +1921,10 @@ static int e2fsck_ext_block_verify(struc
- pctx->blkcount = ix->ei_leaf;;
- pctx->num = i;
- pctx->blk = ix->ei_block;
-+ /* To ensure that extent_idx is in inode */
-+ if (eh->eh_max == 4)
-+ e2fsck_mark_inode_bad(p->ctx, p->ino,
-+ BADNESS_HIGH);
- if (fix_problem(ctx, PR_1_EXTENT_IDX_BAD,pctx)){
- ext2fs_extent_index_remove(eh, ix);
- i--; ix--; /* check next (moved) item */
-@@ -1861,7 +1932,6 @@ static int e2fsck_ext_block_verify(struc
- continue;
- }
- }
--
- ix_prev = ix;
- }
- }
-@@ -1916,6 +1986,7 @@ static void check_blocks(e2fsck_t ctx, s
+ report_problem:
+ pctx->blk = extent.e_pblk;
+ pctx->blk2 = extent.e_lblk;
+@@ -2059,6 +2115,7 @@ static void check_blocks(e2fsck_t ctx, s
inode->i_flags &= ~EXT2_COMPRBLK_FL;
dirty_inode++;
}
@@ -416,17 +379,9 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
}
}
-@@ -1961,6 +2032,7 @@ static void check_blocks(e2fsck_t ctx, s
- ext2fs_icount_store(ctx->inode_link_info, ino, 0);
- inode->i_dtime = ctx->now;
- dirty_inode++;
-+ ext2fs_icount_store(ctx->inode_badness, ino, 0);
- ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
- ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
- ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
-@@ -2000,6 +2072,11 @@ static void check_blocks(e2fsck_t ctx, s
+@@ -2137,6 +2194,11 @@ static void check_blocks(e2fsck_t ctx, s
ctx->fs_directory_count--;
- goto out;
+ return;
}
+ /*
+ * The mode might be in-correct. Increasing the badness by
@@ -435,8 +390,8 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
}
- pb.num_blocks *= (fs->blocksize / 512);
-@@ -2039,6 +2116,7 @@ static void check_blocks(e2fsck_t ctx, s
+ if (!(fs->super->s_feature_ro_compat &
+@@ -2189,6 +2251,7 @@ static void check_blocks(e2fsck_t ctx, s
inode->i_size_high = pctx->num >> 32;
dirty_inode++;
}
@@ -444,31 +399,59 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1.c
pctx->num = 0;
}
if (LINUX_S_ISREG(inode->i_mode) &&
-@@ -2050,6 +2128,7 @@ static void check_blocks(e2fsck_t ctx, s
- inode->i_blocks = pb.num_blocks;
+@@ -2205,6 +2268,7 @@ static void check_blocks(e2fsck_t ctx, s
+ inode->osd2.linux2.l_i_blocks_hi = 0;
dirty_inode++;
}
+ e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
pctx->num = 0;
}
out:
-Index: e2fsprogs-1.40.4/e2fsck/pass4.c
+@@ -2373,8 +2437,10 @@ static int process_block(ext2_filsys fs,
+ problem = PR_1_TOOBIG_SYMLINK;
+
+ if (blk < fs->super->s_first_data_block ||
+- blk >= fs->super->s_blocks_count)
++ blk >= fs->super->s_blocks_count) {
+ problem = PR_1_ILLEGAL_BLOCK_NUM;
++ e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
++ }
+
+ if (problem) {
+ p->num_illegal_blocks++;
+Index: e2fsprogs-1.41.5/e2fsck/pass1b.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/pass4.c
-+++ e2fsprogs-1.40.4/e2fsck/pass4.c
-@@ -185,6 +185,7 @@ void e2fsck_pass4(e2fsck_t ctx)
- }
- ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
- ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
-+ ext2fs_free_icount(ctx->inode_badness); ctx->inode_badness = 0;
- ext2fs_free_inode_bitmap(ctx->inode_bb_map);
- ctx->inode_bb_map = 0;
- ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
-Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+--- e2fsprogs-1.41.5.orig/e2fsck/pass1b.c
++++ e2fsprogs-1.41.5/e2fsck/pass1b.c
+@@ -612,8 +612,8 @@ static void delete_file(e2fsck_t ctx, ex
+ block_buf, delete_file_block, &pb);
+ if (pctx.errcode)
+ fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
+- if (ctx->inode_bad_map)
+- ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
++ if (ctx->inode_badness)
++ e2fsck_mark_inode_bad(ctx, ino, 0);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
+
+ /* Inode may have changed by block_iterate, so reread it */
+Index: e2fsprogs-1.41.5/e2fsck/pass2.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/pass2.c
-+++ e2fsprogs-1.40.4/e2fsck/pass2.c
-@@ -251,10 +251,6 @@ void e2fsck_pass2(e2fsck_t ctx)
+--- e2fsprogs-1.41.5.orig/e2fsck/pass2.c
++++ e2fsprogs-1.41.5/e2fsck/pass2.c
+@@ -33,11 +33,10 @@
+ * Pass 2 relies on the following information from previous passes:
+ * - The directory information collected in pass 1.
+ * - The inode_used_map bitmap
+- * - The inode_bad_map bitmap
++ * - The inode_badness bitmap
+ * - The inode_dir_map bitmap
+ *
+ * Pass 2 frees the following data structures
+- * - The inode_bad_map bitmap
+ * - The inode_reg_map bitmap
+ */
+
+@@ -258,10 +257,6 @@ void e2fsck_pass2(e2fsck_t ctx)
ext2fs_free_mem(&buf);
ext2fs_free_dblist(fs->dblist);
@@ -479,20 +462,20 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
if (ctx->inode_reg_map) {
ext2fs_free_inode_bitmap(ctx->inode_reg_map);
ctx->inode_reg_map = 0;
-@@ -501,6 +497,7 @@ static _INLINE_ int check_filetype(e2fsc
+@@ -494,6 +489,7 @@ static _INLINE_ int check_filetype(e2fsc
{
int filetype = dirent->name_len >> 8;
int should_be = EXT2_FT_UNKNOWN;
-+ __u32 result;
++ __u16 result;
struct ext2_inode inode;
if (!(ctx->fs->super->s_feature_incompat &
-@@ -512,16 +509,18 @@ static _INLINE_ int check_filetype(e2fsc
+@@ -505,16 +501,18 @@ static _INLINE_ int check_filetype(e2fsc
return 1;
}
+ if (ctx->inode_badness)
-+ ext2fs_icount_fetch32(ctx->inode_badness, dirent->inode,
++ ext2fs_icount_fetch(ctx->inode_badness, dirent->inode,
+ &result);
+
if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
@@ -510,7 +493,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
e2fsck_read_inode(ctx, dirent->inode, &inode,
"check_filetype");
should_be = ext2_file_type(inode.i_mode);
-@@ -956,12 +955,10 @@ static int check_dir_block(ext2_filsys f
+@@ -965,12 +963,10 @@ out_htree:
* (We wait until now so that we can display the
* pathname to the user.)
*/
@@ -527,18 +510,34 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
dirent->inode = 0;
dir_modified++;
goto next;
-@@ -1195,8 +1192,8 @@ static void deallocate_inode(e2fsck_t ct
- e2fsck_read_bitmaps(ctx);
- ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
- ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
-- if (ctx->inode_bad_map)
-- ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
-+ if (ctx->inode_badness)
-+ ext2fs_icount_store(ctx->inode_badness, ino, 0);
- ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
-
- if (inode.i_file_acl &&
-@@ -1261,8 +1258,10 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1188,9 +1184,17 @@ static void deallocate_inode(e2fsck_t ct
+ struct ext2_inode inode;
+ struct problem_context pctx;
+ __u32 count;
++ int extent_fs = 0;
+
+ e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
++ /* ext2fs_block_iterate2() depends on the extents flags */
++ if (inode.i_flags & EXT4_EXTENTS_FL)
++ extent_fs = 1;
+ e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode");
++ if (extent_fs) {
++ inode.i_flags |= EXT4_EXTENTS_FL;
++ e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
++ }
+ clear_problem_context(&pctx);
+ pctx.ino = ino;
+
+@@ -1217,6 +1221,8 @@ static void deallocate_inode(e2fsck_t ct
+ if (count == 0) {
+ ext2fs_unmark_block_bitmap(ctx->block_found_map,
+ inode.i_file_acl);
++ if (ctx->inode_badness)
++ ext2fs_icount_store(ctx->inode_badness, ino, 0);
+ ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
+ }
+ inode.i_file_acl = 0;
+@@ -1262,8 +1268,11 @@ extern int e2fsck_process_bad_inode(e2fs
int not_fixed = 0;
unsigned char *frag, *fsize;
struct problem_context pctx;
@@ -546,11 +545,12 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+ int problem = 0;
+ __u16 badness;
-+ ext2fs_icount_fetch(ctx->inode_badness, ino, &badness);
++ if (ctx->inode_badness)
++ ext2fs_icount_fetch(ctx->inode_badness, ino, &badness);
e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
clear_problem_context(&pctx);
-@@ -1277,6 +1276,7 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1278,6 +1287,7 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -558,7 +558,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
}
if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
-@@ -1310,6 +1310,11 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1311,6 +1321,11 @@ extern int e2fsck_process_bad_inode(e2fs
} else
not_fixed++;
problem = 0;
@@ -568,9 +568,9 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+ */
+ badness += BADNESS_BAD_MODE;
}
-
+
if (inode.i_faddr) {
-@@ -1318,6 +1323,7 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1319,6 +1334,7 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -578,7 +578,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
}
switch (fs->super->s_creator_os) {
-@@ -1339,6 +1345,7 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1336,6 +1352,7 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -586,7 +586,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
pctx.num = 0;
}
if (fsize && *fsize) {
-@@ -1348,11 +1355,28 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1345,9 +1362,26 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -611,12 +611,9 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+ }
+
if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
-- !(fs->super->s_feature_ro_compat &
-+ !(fs->super->s_feature_ro_compat &
+ !(fs->super->s_feature_ro_compat &
EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
- (inode.osd2.linux2.l_i_blocks_hi != 0)) {
- pctx.num = inode.osd2.linux2.l_i_blocks_hi;
-@@ -1360,6 +1384,8 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1357,6 +1391,8 @@ extern int e2fsck_process_bad_inode(e2fs
inode.osd2.linux2.l_i_blocks_hi = 0;
inode_modified++;
}
@@ -624,8 +621,16 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+ /* badness += BADNESS_NORMAL; */
}
+ if (!(fs->super->s_feature_incompat &
+@@ -1368,6 +1404,7 @@ extern int e2fsck_process_bad_inode(e2fs
+ inode_modified++;
+ } else
+ not_fixed++;
++ badness += BADNESS_NORMAL;
+ }
+
if (inode.i_file_acl &&
-@@ -1370,6 +1396,7 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1378,6 +1415,7 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -633,7 +638,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
}
if (inode.i_dir_acl &&
LINUX_S_ISDIR(inode.i_mode)) {
-@@ -1378,12 +1405,28 @@ extern int e2fsck_process_bad_inode(e2fs
+@@ -1386,12 +1424,29 @@ extern int e2fsck_process_bad_inode(e2fs
inode_modified++;
} else
not_fixed++;
@@ -643,7 +648,8 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
+ /*
+ * The high value due to BADNESS_BAD_MODE should not delete the inode.
+ */
-+ if ((badness - ((badness >= BADNESS_BAD_MODE) ? BADNESS_BAD_MODE : 0))>=
++ if (ctx->inode_badness &&
++ (badness - ((badness >= BADNESS_BAD_MODE) ? BADNESS_BAD_MODE : 0))>=
+ ctx->inode_badness_threshold) {
+ pctx.num = badness;
+ if (fix_problem(ctx, PR_2_INODE_TOOBAD, &pctx)) {
@@ -664,13 +670,25 @@ Index: e2fsprogs-1.40.4/e2fsck/pass2.c
return 0;
}
-Index: e2fsprogs-1.40.4/e2fsck/problem.c
+Index: e2fsprogs-1.41.5/e2fsck/pass4.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.4/e2fsck/problem.c
-@@ -1316,6 +1316,11 @@ static struct e2fsck_problem problem_tab
- N_("@i %i found in @g %g unused inodes area. "),
- PROMPT_FIX, PR_PREEN_OK },
+--- e2fsprogs-1.41.5.orig/e2fsck/pass4.c
++++ e2fsprogs-1.41.5/e2fsck/pass4.c
+@@ -181,6 +181,7 @@ void e2fsck_pass4(e2fsck_t ctx)
+ }
+ ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
+ ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
++ ext2fs_free_icount(ctx->inode_badness); ctx->inode_badness = 0;
+ ext2fs_free_inode_bitmap(ctx->inode_bb_map);
+ ctx->inode_bb_map = 0;
+ ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
+Index: e2fsprogs-1.41.5/e2fsck/problem.c
+===================================================================
+--- e2fsprogs-1.41.5.orig/e2fsck/problem.c
++++ e2fsprogs-1.41.5/e2fsck/problem.c
+@@ -1373,6 +1373,11 @@ static struct e2fsck_problem problem_tab
+ N_("i_file_acl_hi @F %N, @s zero.\n"),
+ PROMPT_CLEAR, 0 },
+ /* Inode too bad */
+ { PR_2_INODE_TOOBAD,
@@ -680,25 +698,25 @@ Index: e2fsprogs-1.40.4/e2fsck/problem.c
/* Pass 3 errors */
/* Pass 3: Checking directory connectivity */
-Index: e2fsprogs-1.40.4/e2fsck/problem.h
+Index: e2fsprogs-1.41.5/e2fsck/problem.h
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.4/e2fsck/problem.h
-@@ -792,6 +792,9 @@ struct problem_context {
- /* Inode found in group unused inodes area */
- #define PR_2_INOREF_IN_UNUSED 0x020047
+--- e2fsprogs-1.41.5.orig/e2fsck/problem.h
++++ e2fsprogs-1.41.5/e2fsck/problem.h
+@@ -826,6 +826,9 @@ struct problem_context {
+ /* i_file_acl_hi should be zero */
+ #define PR_2_I_FILE_ACL_HI_ZERO 0x020048
+/* Inode completely corrupt */
-+#define PR_2_INODE_TOOBAD 0x020048
++#define PR_2_INODE_TOOBAD 0x020049
+
/*
* Pass 3 errors
*/
-Index: e2fsprogs-1.40.4/lib/ext2fs/icount.c
+Index: e2fsprogs-1.41.5/lib/ext2fs/icount.c
===================================================================
---- e2fsprogs-1.40.4.orig/lib/ext2fs/icount.c
-+++ e2fsprogs-1.40.4/lib/ext2fs/icount.c
-@@ -462,6 +462,23 @@ static errcode_t get_inode_count(ext2_ic
+--- e2fsprogs-1.41.5.orig/lib/ext2fs/icount.c
++++ e2fsprogs-1.41.5/lib/ext2fs/icount.c
+@@ -467,6 +467,23 @@ static errcode_t get_inode_count(ext2_ic
return 0;
}
@@ -722,34 +740,11 @@ Index: e2fsprogs-1.40.4/lib/ext2fs/icount.c
errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
{
errcode_t ret = 0;
-@@ -501,6 +518,7 @@ errcode_t ext2fs_icount_fetch32(ext2_ico
- *ret = 0;
- return 0;
- }
-+
- get_inode_count(icount, ino, ret);
- return 0;
- }
-Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
-===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/pass1b.c
-+++ e2fsprogs-1.40.4/e2fsck/pass1b.c
-@@ -613,8 +613,8 @@ static void delete_file(e2fsck_t ctx, ex
- fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
- ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
- ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
-- if (ctx->inode_bad_map)
-- ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
-+ if (ctx->inode_badness)
-+ e2fsck_mark_inode_bad(ctx, ino, 0);
- ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
-
- /* Inode may have changed by block_iterate, so reread it */
-Index: e2fsprogs-1.40.4/e2fsck/unix.c
+Index: e2fsprogs-1.41.5/e2fsck/unix.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.4/e2fsck/unix.c
-@@ -624,6 +624,18 @@ static void parse_extended_opts(e2fsck_t
+--- e2fsprogs-1.41.5.orig/e2fsck/unix.c
++++ e2fsprogs-1.41.5/e2fsck/unix.c
+@@ -664,6 +664,18 @@ static void parse_extended_opts(e2fsck_t
extended_usage++;
continue;
}
@@ -768,15 +763,15 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
} else {
fprintf(stderr, _("Unknown extended option: %s\n"),
token);
-@@ -639,6 +646,7 @@ static void parse_extended_opts(e2fsck_t
- "\tshared=<preserve|lost+found|delete>\n"
- "\tclone=<dup|zero>\n"
- "\tea_ver=<ea_version (1 or 2)>\n"
-+ "\tinode_badness_threhold=(value)\n"
- "\texpand_extra_isize\n"
- "\n"), stderr);
+@@ -682,6 +694,7 @@ static void parse_extended_opts(e2fsck_t
+ fputs(("\tshared=<preserve|lost+found|delete>\n"), stderr);
+ fputs(("\tclone=<dup|zero>\n"), stderr);
+ fputs(("\texpand_extra_isize\n"), stderr);
++ fputs(("\tinode_badness_threhold=(value)\n"), stderr);
+ fputc('\n', stderr);
exit(1);
-@@ -703,6 +711,9 @@ static errcode_t PRS(int argc, char *arg
+ }
+@@ -746,6 +759,9 @@ static errcode_t PRS(int argc, char *arg
profile_init(config_fn, &ctx->profile);
initialize_profile_options(ctx);
@@ -786,11 +781,11 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
switch (c) {
case 'C':
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.c
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.c
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.c
-@@ -105,10 +105,6 @@ errcode_t e2fsck_reset_context(e2fsck_t
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.c
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.c
+@@ -108,10 +108,6 @@ errcode_t e2fsck_reset_context(e2fsck_t
ext2fs_free_inode_bitmap(ctx->inode_bb_map);
ctx->inode_bb_map = 0;
}
@@ -801,83 +796,73 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.c
if (ctx->inode_imagic_map) {
ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
ctx->inode_imagic_map = 0;
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.8.in
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.8.in
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.8.in
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.8.in
-@@ -191,6 +191,13 @@ in place (preserve);
- Assume the format of the extended attribute blocks in the filesystem is
- the specified version number. The version number may be 1 or 2. The
- default extended attribute version format is 2.
-+.TP
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.8.in
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.8.in
+@@ -203,6 +203,13 @@ Set the version of the extended attribut
+ will require while checking the filesystem. The version number may
+ be 1 or 2. The default extended attribute version format is 2.
+ .TP
+.BI inode_badness_threshold= threshold_value
+A badness counter is associated with every inode, which determines the degree
+of inode corruption. Each error found in the inode will increase the badness by
+1 or 2, and inodes with a badness at or above
+.I threshold_value will be prompted for deletion. The default
+.I threshold_value is 7.
- .RE
- .TP
- .B \-f
-Index: e2fsprogs-1.40.4/tests/f_bad_disconnected_inode/expect.1
++.TP
+ .BI fragcheck
+ During pass 1, print a detailed report of any discontiguous blocks for
+ files in the filesystem.
+Index: e2fsprogs-1.41.5/lib/ext2fs/ext2fs.h
===================================================================
---- e2fsprogs-1.40.4.orig/tests/f_bad_disconnected_inode/expect.1
-+++ e2fsprogs-1.40.4/tests/f_bad_disconnected_inode/expect.1
-@@ -39,10 +39,7 @@ Clear? yes
- i_blocks_hi for inode 16 (...) is 62762, should be zero.
- Clear? yes
+--- e2fsprogs-1.41.5.orig/lib/ext2fs/ext2fs.h
++++ e2fsprogs-1.41.5/lib/ext2fs/ext2fs.h
+@@ -976,6 +976,7 @@ extern errcode_t ext2fs_initialize(const
--Unattached inode 16
--Connect to /lost+found? yes
--
--Inode 16 ref count is 5925, should be 1. Fix? yes
-+Inode 16 is badly corrupt (badness value = 10). Clear? yes
+ /* icount.c */
+ extern void ext2fs_free_icount(ext2_icount_t icount);
++extern int ext2fs_icount_is_set(ext2_icount_t icount, ext2_ino_t ino);
+ extern errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
+ int flags, ext2_icount_t *ret);
+ extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
+Index: e2fsprogs-1.41.5/tests/f_messy_inode/expect.1
+===================================================================
+--- e2fsprogs-1.41.5.orig/tests/f_messy_inode/expect.1
++++ e2fsprogs-1.41.5/tests/f_messy_inode/expect.1
+@@ -20,19 +20,21 @@ Pass 2: Checking directory structure
+ i_file_acl for inode 14 (/MAKEDEV) is 4294901760, should be zero.
+ Clear? yes
++Inode 14 is badly corrupt (badness value = 13). Clear? yes
++
+ Pass 3: Checking directory connectivity
+ Pass 4: Checking reference counts
Pass 5: Checking group summary information
- Block bitmap differences: -(9--19)
-@@ -54,19 +51,16 @@ Fix? yes
- Free blocks count wrong (79, counted=91).
- Fix? yes
-
--Inode bitmap differences: +16
--Fix? yes
--
--Free inodes count wrong for group #0 (7, counted=4).
-+Free inodes count wrong for group #0 (8, counted=5).
+ Block bitmap differences: -(43--49)
Fix? yes
- Directories count wrong for group #0 (3, counted=2).
+-Free blocks count wrong for group #0 (68, counted=75).
++Free blocks count wrong for group #0 (70, counted=77).
Fix? yes
--Free inodes count wrong (7, counted=4).
-+Free inodes count wrong (8, counted=5).
+-Free blocks count wrong (68, counted=75).
++Free blocks count wrong (70, counted=77).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
--test_filesys: 12/16 files (0.0% non-contiguous), 9/100 blocks
-+test_filesys: 11/16 files (0.0% non-contiguous), 9/100 blocks
+-test_filesys: 29/32 files (3.4% non-contiguous), 25/100 blocks
++test_filesys: 28/32 files (3.6% non-contiguous), 23/100 blocks
Exit status is 1
-Index: e2fsprogs-1.40.4/tests/f_bad_disconnected_inode/expect.2
+Index: e2fsprogs-1.41.5/tests/f_messy_inode/expect.2
===================================================================
---- e2fsprogs-1.40.4.orig/tests/f_bad_disconnected_inode/expect.2
-+++ e2fsprogs-1.40.4/tests/f_bad_disconnected_inode/expect.2
+--- e2fsprogs-1.41.5.orig/tests/f_messy_inode/expect.2
++++ e2fsprogs-1.41.5/tests/f_messy_inode/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
--test_filesys: 12/16 files (0.0% non-contiguous), 9/100 blocks
-+test_filesys: 11/16 files (0.0% non-contiguous), 9/100 blocks
+-test_filesys: 29/32 files (0.0% non-contiguous), 25/100 blocks
++test_filesys: 28/32 files (0.0% non-contiguous), 23/100 blocks
Exit status is 0
-Index: e2fsprogs-1.40.4/lib/ext2fs/ext2fs.h
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.4/lib/ext2fs/ext2fs.h
-@@ -831,6 +831,7 @@ extern errcode_t ext2fs_initialize(const
-
- /* icount.c */
- extern void ext2fs_free_icount(ext2_icount_t icount);
-+extern int ext2fs_icount_is_set(ext2_icount_t icount, ext2_ino_t ino);
- extern errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
- int flags, ext2_icount_t *ret);
- extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
diff --git a/debian/patches/e2fsprogs-journal_chksum.patch b/debian/patches/e2fsprogs-journal_chksum.patch
deleted file mode 100644
index ed0e685..0000000
--- a/debian/patches/e2fsprogs-journal_chksum.patch
+++ /dev/null
@@ -1,1216 +0,0 @@
-E2fsprogs part of Journal Checksum feature.
-
-This adds support for journals with the INCOMPAT_ASYNC_COMMIT and
-COMPAT_CHECKSUM features.
-
-If CHECKSUM is set, each transaction has a checksum of the full
-transaction and it is verified before the transaction is replayed.
-If any interior block is missing or corrupted, or if the transaction is
-incomplete it will not be replayed.
-
-The ASYNC_COMMIT feature allows the kernel to avoid waiting for the
-transaction (meta)data to commit before writing the journal commit block.
-
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-Signed-off-by: Girish Shilamkar <girish at clusterfs.com>
-
-Index: e2fsprogs-1.40.11/lib/ext2fs/kernel-jbd.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/kernel-jbd.h
-+++ e2fsprogs-1.40.11/lib/ext2fs/kernel-jbd.h
-@@ -108,7 +108,29 @@ typedef struct journal_header_s
- __u32 h_sequence;
- } journal_header_t;
-
-+/*
-+ * Checksum types.
-+ */
-+#define JFS_CRC32_CHKSUM 1
-+#define JFS_MD5_CHKSUM 2
-+#define JFS_SHA1_CHKSUM 3
-+
-+#define JFS_CRC32_CHKSUM_SIZE 4
-
-+#define JFS_CHECKSUM_BYTES (32 / sizeof(__u32))
-+/*
-+ * Commit block header for storing transactional checksums:
-+ */
-+struct commit_header
-+{
-+ __u32 h_magic;
-+ __u32 h_blocktype;
-+ __u32 h_sequence;
-+ unsigned char h_chksum_type;
-+ unsigned char h_chksum_size;
-+ unsigned char h_padding[2];
-+ __u32 h_chksum[JFS_CHECKSUM_BYTES];
-+};
- /*
- * The block tag: used to describe a single buffer in the journal
- */
-@@ -194,12 +216,17 @@ typedef struct journal_superblock_s
- ((j)->j_format_version >= 2 && \
- ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
-
--#define JFS_FEATURE_INCOMPAT_REVOKE 0x00000001
-+#define JFS_FEATURE_COMPAT_CHECKSUM 0x00000001
-+
-+#define JFS_FEATURE_INCOMPAT_REVOKE 0x00000001
-+/*#define JFS_FEATURE_INCOMPAT_64BIT 0x00000002*/
-+#define JFS_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004
-
- /* Features known to this kernel version: */
--#define JFS_KNOWN_COMPAT_FEATURES 0
-+#define JFS_KNOWN_COMPAT_FEATURES JFS_FEATURE_COMPAT_CHECKSUM
- #define JFS_KNOWN_ROCOMPAT_FEATURES 0
--#define JFS_KNOWN_INCOMPAT_FEATURES JFS_FEATURE_INCOMPAT_REVOKE
-+#define JFS_KNOWN_INCOMPAT_FEATURES (JFS_FEATURE_INCOMPAT_REVOKE| \
-+ JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)
-
- #ifdef __KERNEL__
-
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc32.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc32.h
-@@ -0,0 +1,28 @@
-+/*
-+ * crc32.h
-+ * See crc32.c for license and changes
-+ */
-+#ifndef _LINUX_CRC32_H
-+#define _LINUX_CRC32_H
-+
-+typedef unsigned int u32;
-+typedef unsigned char u8;
-+
-+extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len);
-+extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len);
-+extern u32 bitreverse(u32 in);
-+
-+#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length)
-+
-+/*
-+ * Helpers for hash table generation of ethernet nics:
-+ *
-+ * Ethernet sends the least significant bit of a byte first, thus crc32_le
-+ * is used. The output of crc32_le is bit reversed [most significant bit
-+ * is in bit nr 0], thus it must be reversed before use. Except for
-+ * nics that bit swap the result internally...
-+ */
-+#define ether_crc(length, data) bitreverse(crc32_le(~0, data, length))
-+#define ether_crc_le(length, data) crc32_le(~0, data, length)
-+
-+#endif /* _LINUX_CRC32_H */
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc32.c
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc32.c
-@@ -0,0 +1,519 @@
-+/*
-+ * Oct 15, 2000 Matt Domsch <Matt_Domsch at dell.com>
-+ * Nicer crc32 functions/docs submitted by linux at horizon.com. Thanks!
-+ * Code was from the public domain, copyright abandoned. Code was
-+ * subsequently included in the kernel, thus was re-licensed under the
-+ * GNU GPL v2.
-+ *
-+ * Oct 12, 2000 Matt Domsch <Matt_Domsch at dell.com>
-+ * Same crc32 function was used in 5 other places in the kernel.
-+ * I made one version, and deleted the others.
-+ * There are various incantations of crc32(). Some use a seed of 0 or ~0.
-+ * Some xor at the end with ~0. The generic crc32() function takes
-+ * seed as an argument, and doesn't xor at the end. Then individual
-+ * users can do whatever they need.
-+ * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
-+ * fs/jffs2 uses seed 0, doesn't xor with ~0.
-+ * fs/partitions/efi.c uses seed ~0, xor's with ~0.
-+ *
-+ * This source code is licensed under the GNU General Public License,
-+ * Version 2. See the file COPYING for more details.
-+ */
-+
-+#include <stdlib.h>
-+#include "crc32_user.h"
-+#include "crc32.h"
-+#include "crc32defs.h"
-+#if CRC_LE_BITS == 8
-+#define tole(x) __constant_cpu_to_le32(x)
-+#define tobe(x) __constant_cpu_to_be32(x)
-+#else
-+#define tole(x) (x)
-+#define tobe(x) (x)
-+#endif
-+#include "crc32table.h"
-+
-+
-+#if CRC_LE_BITS == 1
-+/*
-+ * In fact, the table-based code will work in this case, but it can be
-+ * simplified by inlining the table in ?: form.
-+ */
-+
-+/**
-+ * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
-+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
-+ * other uses, or the previous crc32 value if computing incrementally.
-+ * @p - pointer to buffer over which CRC is run
-+ * @len - length of buffer @p
-+ *
-+ */
-+u32 crc32_le(u32 crc, unsigned char const *p, size_t len)
-+{
-+ int i;
-+ while (len--) {
-+ crc ^= *p++;
-+ for (i = 0; i < 8; i++)
-+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
-+ }
-+ return crc;
-+}
-+#else /* Table-based approach */
-+
-+/**
-+ * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
-+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
-+ * other uses, or the previous crc32 value if computing incrementally.
-+ * @p - pointer to buffer over which CRC is run
-+ * @len - length of buffer @p
-+ *
-+ */
-+u32 crc32_le(u32 crc, unsigned char const *p, size_t len)
-+{
-+# if CRC_LE_BITS == 8
-+ const u32 *b =(u32 *)p;
-+ const u32 *tab = crc32table_le;
-+
-+# if __BYTE_ORDER == __LITTLE_ENDIAN
-+# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
-+# else
-+# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
-+# endif
-+
-+ crc = __cpu_to_le32(crc);
-+ /* Align it */
-+ if(unlikely(((long)b)&3 && len)){
-+ do {
-+ u8 *p = (u8 *)b;
-+ DO_CRC(*p++);
-+ b = (void *)p;
-+ } while ((--len) && ((long)b)&3 );
-+ }
-+ if(likely(len >= 4)){
-+ /* load data 32 bits wide, xor data 32 bits wide. */
-+ size_t save_len = len & 3;
-+ len = len >> 2;
-+ --b; /* use pre increment below(*++b) for speed */
-+ do {
-+ crc ^= *++b;
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ } while (--len);
-+ b++; /* point to next byte(s) */
-+ len = save_len;
-+ }
-+ /* And the last few bytes */
-+ if(len){
-+ do {
-+ u8 *p = (u8 *)b;
-+ DO_CRC(*p++);
-+ b = (void *)p;
-+ } while (--len);
-+ }
-+
-+ return __le32_to_cpu(crc);
-+#undef ENDIAN_SHIFT
-+#undef DO_CRC
-+
-+# elif CRC_LE_BITS == 4
-+ while (len--) {
-+ crc ^= *p++;
-+ crc = (crc >> 4) ^ crc32table_le[crc & 15];
-+ crc = (crc >> 4) ^ crc32table_le[crc & 15];
-+ }
-+ return crc;
-+# elif CRC_LE_BITS == 2
-+ while (len--) {
-+ crc ^= *p++;
-+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
-+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
-+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
-+ crc = (crc >> 2) ^ crc32table_le[crc & 3];
-+ }
-+ return crc;
-+# endif
-+}
-+#endif
-+
-+#if CRC_BE_BITS == 1
-+/*
-+ * In fact, the table-based code will work in this case, but it can be
-+ * simplified by inlining the table in ?: form.
-+ */
-+
-+/**
-+ * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
-+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
-+ * other uses, or the previous crc32 value if computing incrementally.
-+ * @p - pointer to buffer over which CRC is run
-+ * @len - length of buffer @p
-+ *
-+ */
-+u32 crc32_be(u32 crc, unsigned char const *p, size_t len)
-+{
-+ int i;
-+ printf("CRC %u\n",crc);
-+ while (len--) {
-+ crc ^= *p++ << 24;
-+ for (i = 0; i < 8; i++)
-+ crc =
-+ (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
-+ 0);
-+ }
-+ return crc;
-+}
-+
-+#else /* Table-based approach */
-+/**
-+ * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
-+ * @crc - seed value for computation. ~0 for Ethernet, sometimes 0 for
-+ * other uses, or the previous crc32 value if computing incrementally.
-+ * @p - pointer to buffer over which CRC is run
-+ * @len - length of buffer @p
-+ *
-+ */
-+u32 crc32_be(u32 crc, unsigned char const *p, size_t len)
-+{
-+# if CRC_BE_BITS == 8
-+ const u32 *b =(u32 *)p;
-+ const u32 *tab = crc32table_be;
-+
-+# if __BYTE_ORDER == __LITTLE_ENDIAN
-+# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
-+# else
-+# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
-+# endif
-+ crc = __cpu_to_be32(crc);
-+ /* Align it */
-+ if(unlikely(((long)b)&3 && len)){
-+ do {
-+ u8 *p = (u8 *)b;
-+ DO_CRC(*p++);
-+ b = (u32 *)p;
-+ } while ((--len) && ((long)b)&3 );
-+ }
-+
-+ if(likely(len >= 4)){
-+ /* load data 32 bits wide, xor data 32 bits wide. */
-+ size_t save_len = len & 3;
-+ len = len >> 2;
-+ --b; /* use pre increment below(*++b) for speed */
-+ do {
-+ crc ^= *++b;
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ DO_CRC(0);
-+ } while (--len);
-+ b++; /* point to next byte(s) */
-+ len = save_len;
-+ }
-+ /* And the last few bytes */
-+ if(len){
-+ do {
-+ u8 *p = (u8 *)b;
-+ DO_CRC(*p++);
-+ b = (void *)p;
-+ } while (--len);
-+ }
-+ return __be32_to_cpu(crc);
-+#undef ENDIAN_SHIFT
-+#undef DO_CRC
-+
-+# elif CRC_BE_BITS == 4
-+ while (len--) {
-+ crc ^= *p++ << 24;
-+ crc = (crc << 4) ^ crc32table_be[crc >> 28];
-+ crc = (crc << 4) ^ crc32table_be[crc >> 28];
-+ }
-+ return crc;
-+# elif CRC_BE_BITS == 2
-+ while (len--) {
-+ crc ^= *p++ << 24;
-+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
-+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
-+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
-+ crc = (crc << 2) ^ crc32table_be[crc >> 30];
-+ }
-+ return crc;
-+# endif
-+}
-+#endif
-+
-+u32 bitreverse(u32 x)
-+{
-+ x = (x >> 16) | (x << 16);
-+ x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
-+ x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
-+ x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
-+ x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
-+ return x;
-+}
-+
-+
-+/*
-+ * A brief CRC tutorial.
-+ *
-+ * A CRC is a long-division remainder. You add the CRC to the message,
-+ * and the whole thing (message+CRC) is a multiple of the given
-+ * CRC polynomial. To check the CRC, you can either check that the
-+ * CRC matches the recomputed value, *or* you can check that the
-+ * remainder computed on the message+CRC is 0. This latter approach
-+ * is used by a lot of hardware implementations, and is why so many
-+ * protocols put the end-of-frame flag after the CRC.
-+ *
-+ * It's actually the same long division you learned in school, except that
-+ * - We're working in binary, so the digits are only 0 and 1, and
-+ * - When dividing polynomials, there are no carries. Rather than add and
-+ * subtract, we just xor. Thus, we tend to get a bit sloppy about
-+ * the difference between adding and subtracting.
-+ *
-+ * A 32-bit CRC polynomial is actually 33 bits long. But since it's
-+ * 33 bits long, bit 32 is always going to be set, so usually the CRC
-+ * is written in hex with the most significant bit omitted. (If you're
-+ * familiar with the IEEE 754 floating-point format, it's the same idea.)
-+ *
-+ * Note that a CRC is computed over a string of *bits*, so you have
-+ * to decide on the endianness of the bits within each byte. To get
-+ * the best error-detecting properties, this should correspond to the
-+ * order they're actually sent. For example, standard RS-232 serial is
-+ * little-endian; the most significant bit (sometimes used for parity)
-+ * is sent last. And when appending a CRC word to a message, you should
-+ * do it in the right order, matching the endianness.
-+ *
-+ * Just like with ordinary division, the remainder is always smaller than
-+ * the divisor (the CRC polynomial) you're dividing by. Each step of the
-+ * division, you take one more digit (bit) of the dividend and append it
-+ * to the current remainder. Then you figure out the appropriate multiple
-+ * of the divisor to subtract to being the remainder back into range.
-+ * In binary, it's easy - it has to be either 0 or 1, and to make the
-+ * XOR cancel, it's just a copy of bit 32 of the remainder.
-+ *
-+ * When computing a CRC, we don't care about the quotient, so we can
-+ * throw the quotient bit away, but subtract the appropriate multiple of
-+ * the polynomial from the remainder and we're back to where we started,
-+ * ready to process the next bit.
-+ *
-+ * A big-endian CRC written this way would be coded like:
-+ * for (i = 0; i < input_bits; i++) {
-+ * multiple = remainder & 0x80000000 ? CRCPOLY : 0;
-+ * remainder = (remainder << 1 | next_input_bit()) ^ multiple;
-+ * }
-+ * Notice how, to get at bit 32 of the shifted remainder, we look
-+ * at bit 31 of the remainder *before* shifting it.
-+ *
-+ * But also notice how the next_input_bit() bits we're shifting into
-+ * the remainder don't actually affect any decision-making until
-+ * 32 bits later. Thus, the first 32 cycles of this are pretty boring.
-+ * Also, to add the CRC to a message, we need a 32-bit-long hole for it at
-+ * the end, so we have to add 32 extra cycles shifting in zeros at the
-+ * end of every message,
-+ *
-+ * So the standard trick is to rearrage merging in the next_input_bit()
-+ * until the moment it's needed. Then the first 32 cycles can be precomputed,
-+ * and merging in the final 32 zero bits to make room for the CRC can be
-+ * skipped entirely.
-+ * This changes the code to:
-+ * for (i = 0; i < input_bits; i++) {
-+ * remainder ^= next_input_bit() << 31;
-+ * multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
-+ * remainder = (remainder << 1) ^ multiple;
-+ * }
-+ * With this optimization, the little-endian code is simpler:
-+ * for (i = 0; i < input_bits; i++) {
-+ * remainder ^= next_input_bit();
-+ * multiple = (remainder & 1) ? CRCPOLY : 0;
-+ * remainder = (remainder >> 1) ^ multiple;
-+ * }
-+ *
-+ * Note that the other details of endianness have been hidden in CRCPOLY
-+ * (which must be bit-reversed) and next_input_bit().
-+ *
-+ * However, as long as next_input_bit is returning the bits in a sensible
-+ * order, we can actually do the merging 8 or more bits at a time rather
-+ * than one bit at a time:
-+ * for (i = 0; i < input_bytes; i++) {
-+ * remainder ^= next_input_byte() << 24;
-+ * for (j = 0; j < 8; j++) {
-+ * multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
-+ * remainder = (remainder << 1) ^ multiple;
-+ * }
-+ * }
-+ * Or in little-endian:
-+ * for (i = 0; i < input_bytes; i++) {
-+ * remainder ^= next_input_byte();
-+ * for (j = 0; j < 8; j++) {
-+ * multiple = (remainder & 1) ? CRCPOLY : 0;
-+ * remainder = (remainder << 1) ^ multiple;
-+ * }
-+ * }
-+ * If the input is a multiple of 32 bits, you can even XOR in a 32-bit
-+ * word at a time and increase the inner loop count to 32.
-+ *
-+ * You can also mix and match the two loop styles, for example doing the
-+ * bulk of a message byte-at-a-time and adding bit-at-a-time processing
-+ * for any fractional bytes at the end.
-+ *
-+ * The only remaining optimization is to the byte-at-a-time table method.
-+ * Here, rather than just shifting one bit of the remainder to decide
-+ * in the correct multiple to subtract, we can shift a byte at a time.
-+ * This produces a 40-bit (rather than a 33-bit) intermediate remainder,
-+ * but again the multiple of the polynomial to subtract depends only on
-+ * the high bits, the high 8 bits in this case.
-+ *
-+ * The multile we need in that case is the low 32 bits of a 40-bit
-+ * value whose high 8 bits are given, and which is a multiple of the
-+ * generator polynomial. This is simply the CRC-32 of the given
-+ * one-byte message.
-+ *
-+ * Two more details: normally, appending zero bits to a message which
-+ * is already a multiple of a polynomial produces a larger multiple of that
-+ * polynomial. To enable a CRC to detect this condition, it's common to
-+ * invert the CRC before appending it. This makes the remainder of the
-+ * message+crc come out not as zero, but some fixed non-zero value.
-+ *
-+ * The same problem applies to zero bits prepended to the message, and
-+ * a similar solution is used. Instead of starting with a remainder of
-+ * 0, an initial remainder of all ones is used. As long as you start
-+ * the same way on decoding, it doesn't make a difference.
-+ */
-+
-+#ifdef UNITTEST
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+
-+#if 0 /*Not used at present */
-+static void
-+buf_dump(char const *prefix, unsigned char const *buf, size_t len)
-+{
-+ fputs(prefix, stdout);
-+ while (len--)
-+ printf(" %02x", *buf++);
-+ putchar('\n');
-+
-+}
-+#endif
-+
-+static void bytereverse(unsigned char *buf, size_t len)
-+{
-+ while (len--) {
-+ unsigned char x = *buf;
-+ x = (x >> 4) | (x << 4);
-+ x = (x >> 2 & 0x33) | (x << 2 & 0xcc);
-+ x = (x >> 1 & 0x55) | (x << 1 & 0xaa);
-+ *buf++ = x;
-+ }
-+}
-+
-+static void random_garbage(unsigned char *buf, size_t len)
-+{
-+ while (len--)
-+ *buf++ = (unsigned char) random();
-+}
-+
-+#if 0 /* Not used at present */
-+static void store_le(u32 x, unsigned char *buf)
-+{
-+ buf[0] = (unsigned char) x;
-+ buf[1] = (unsigned char) (x >> 8);
-+ buf[2] = (unsigned char) (x >> 16);
-+ buf[3] = (unsigned char) (x >> 24);
-+}
-+#endif
-+
-+static void store_be(u32 x, unsigned char *buf)
-+{
-+ buf[0] = (unsigned char) (x >> 24);
-+ buf[1] = (unsigned char) (x >> 16);
-+ buf[2] = (unsigned char) (x >> 8);
-+ buf[3] = (unsigned char) x;
-+}
-+
-+/*
-+ * This checks that CRC(buf + CRC(buf)) = 0, and that
-+ * CRC commutes with bit-reversal. This has the side effect
-+ * of bytewise bit-reversing the input buffer, and returns
-+ * the CRC of the reversed buffer.
-+ */
-+static u32 test_step(u32 init, unsigned char *buf, size_t len)
-+{
-+ u32 crc1, crc2;
-+ size_t i;
-+
-+ crc1 = crc32_be(init, buf, len);
-+ store_be(crc1, buf + len);
-+ crc2 = crc32_be(init, buf, len + 4);
-+ if (crc2)
-+ printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-+ crc2);
-+
-+ for (i = 0; i <= len + 4; i++) {
-+ crc2 = crc32_be(init, buf, i);
-+ crc2 = crc32_be(crc2, buf + i, len + 4 - i);
-+ if (crc2)
-+ printf("\nCRC split fail: 0x%08x\n", crc2);
-+ }
-+
-+ /* Now swap it around for the other test */
-+
-+ bytereverse(buf, len + 4);
-+ init = bitreverse(init);
-+ crc2 = bitreverse(crc1);
-+ if (crc1 != bitreverse(crc2))
-+ printf("\nBit reversal fail: 0x%08x -> %0x08x -> 0x%08x\n",
-+ crc1, crc2, bitreverse(crc2));
-+ crc1 = crc32_le(init, buf, len);
-+ if (crc1 != crc2)
-+ printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1,
-+ crc2);
-+ crc2 = crc32_le(init, buf, len + 4);
-+ if (crc2)
-+ printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-+ crc2);
-+
-+ for (i = 0; i <= len + 4; i++) {
-+ crc2 = crc32_le(init, buf, i);
-+ crc2 = crc32_le(crc2, buf + i, len + 4 - i);
-+ if (crc2)
-+ printf("\nCRC split fail: 0x%08x\n", crc2);
-+ }
-+
-+ return crc1;
-+}
-+
-+#define SIZE 64
-+#define INIT1 0
-+#define INIT2 0
-+
-+int main(void)
-+{
-+ unsigned char buf1[SIZE + 4];
-+ unsigned char buf2[SIZE + 4];
-+ unsigned char buf3[SIZE + 4];
-+ int i, j;
-+ u32 crc1, crc2, crc3;
-+
-+ for (i = 0; i <= SIZE; i++) {
-+ printf("\rTesting length %d...", i);
-+ fflush(stdout);
-+ random_garbage(buf1, i);
-+ random_garbage(buf2, i);
-+ for (j = 0; j < i; j++)
-+ buf3[j] = buf1[j] ^ buf2[j];
-+
-+ crc1 = test_step(INIT1, buf1, i);
-+ crc2 = test_step(INIT2, buf2, i);
-+ /* Now check that CRC(buf1 ^ buf2) = CRC(buf1) ^ CRC(buf2) */
-+ crc3 = test_step(INIT1 ^ INIT2, buf3, i);
-+ if (crc3 != (crc1 ^ crc2))
-+ printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n",
-+ crc3, crc1, crc2);
-+ }
-+ printf("\nAll test complete. No failures expected.\n");
-+ return 0;
-+}
-+
-+#endif /* UNITTEST */
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc32defs.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc32defs.h
-@@ -0,0 +1,32 @@
-+/*
-+ * There are multiple 16-bit CRC polynomials in common use, but this is
-+ * *the* standard CRC-32 polynomial, first popularized by Ethernet.
-+ * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
-+ */
-+#define CRCPOLY_LE 0xedb88320
-+#define CRCPOLY_BE 0x04c11db7
-+
-+/* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS bytes. */
-+/* For less performance-sensitive, use 4 */
-+#ifndef CRC_LE_BITS
-+# define CRC_LE_BITS 8
-+#endif
-+#ifndef CRC_BE_BITS
-+# define CRC_BE_BITS 8
-+#endif
-+
-+/*
-+ * Little-endian CRC computation. Used with serial bit streams sent
-+ * lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC.
-+ */
-+#if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1
-+# error CRC_LE_BITS must be a power of 2 between 1 and 8
-+#endif
-+
-+/*
-+ * Big-endian CRC computation. Used with serial bit streams sent
-+ * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC.
-+ */
-+#if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1
-+# error CRC_BE_BITS must be a power of 2 between 1 and 8
-+#endif
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc32table.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc32table.h
-@@ -0,0 +1,135 @@
-+/* this file is generated - do not edit */
-+
-+static const u32 crc32table_le[] = {
-+tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
-+tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
-+tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
-+tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
-+tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
-+tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
-+tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
-+tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
-+tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
-+tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
-+tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
-+tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
-+tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
-+tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
-+tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
-+tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
-+tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
-+tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
-+tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
-+tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
-+tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
-+tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
-+tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
-+tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
-+tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
-+tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
-+tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
-+tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
-+tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
-+tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
-+tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
-+tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
-+tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
-+tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
-+tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
-+tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
-+tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
-+tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
-+tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
-+tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
-+tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
-+tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
-+tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
-+tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
-+tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
-+tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
-+tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
-+tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
-+tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
-+tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
-+tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
-+tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
-+tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
-+tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
-+tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
-+tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
-+tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
-+tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
-+tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
-+tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
-+tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
-+tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
-+tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
-+tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
-+};
-+
-+static const u32 crc32table_be[] = {
-+tobe(0x00000000L), tobe(0x04c11db7L), tobe(0x09823b6eL), tobe(0x0d4326d9L),
-+tobe(0x130476dcL), tobe(0x17c56b6bL), tobe(0x1a864db2L), tobe(0x1e475005L),
-+tobe(0x2608edb8L), tobe(0x22c9f00fL), tobe(0x2f8ad6d6L), tobe(0x2b4bcb61L),
-+tobe(0x350c9b64L), tobe(0x31cd86d3L), tobe(0x3c8ea00aL), tobe(0x384fbdbdL),
-+tobe(0x4c11db70L), tobe(0x48d0c6c7L), tobe(0x4593e01eL), tobe(0x4152fda9L),
-+tobe(0x5f15adacL), tobe(0x5bd4b01bL), tobe(0x569796c2L), tobe(0x52568b75L),
-+tobe(0x6a1936c8L), tobe(0x6ed82b7fL), tobe(0x639b0da6L), tobe(0x675a1011L),
-+tobe(0x791d4014L), tobe(0x7ddc5da3L), tobe(0x709f7b7aL), tobe(0x745e66cdL),
-+tobe(0x9823b6e0L), tobe(0x9ce2ab57L), tobe(0x91a18d8eL), tobe(0x95609039L),
-+tobe(0x8b27c03cL), tobe(0x8fe6dd8bL), tobe(0x82a5fb52L), tobe(0x8664e6e5L),
-+tobe(0xbe2b5b58L), tobe(0xbaea46efL), tobe(0xb7a96036L), tobe(0xb3687d81L),
-+tobe(0xad2f2d84L), tobe(0xa9ee3033L), tobe(0xa4ad16eaL), tobe(0xa06c0b5dL),
-+tobe(0xd4326d90L), tobe(0xd0f37027L), tobe(0xddb056feL), tobe(0xd9714b49L),
-+tobe(0xc7361b4cL), tobe(0xc3f706fbL), tobe(0xceb42022L), tobe(0xca753d95L),
-+tobe(0xf23a8028L), tobe(0xf6fb9d9fL), tobe(0xfbb8bb46L), tobe(0xff79a6f1L),
-+tobe(0xe13ef6f4L), tobe(0xe5ffeb43L), tobe(0xe8bccd9aL), tobe(0xec7dd02dL),
-+tobe(0x34867077L), tobe(0x30476dc0L), tobe(0x3d044b19L), tobe(0x39c556aeL),
-+tobe(0x278206abL), tobe(0x23431b1cL), tobe(0x2e003dc5L), tobe(0x2ac12072L),
-+tobe(0x128e9dcfL), tobe(0x164f8078L), tobe(0x1b0ca6a1L), tobe(0x1fcdbb16L),
-+tobe(0x018aeb13L), tobe(0x054bf6a4L), tobe(0x0808d07dL), tobe(0x0cc9cdcaL),
-+tobe(0x7897ab07L), tobe(0x7c56b6b0L), tobe(0x71159069L), tobe(0x75d48ddeL),
-+tobe(0x6b93dddbL), tobe(0x6f52c06cL), tobe(0x6211e6b5L), tobe(0x66d0fb02L),
-+tobe(0x5e9f46bfL), tobe(0x5a5e5b08L), tobe(0x571d7dd1L), tobe(0x53dc6066L),
-+tobe(0x4d9b3063L), tobe(0x495a2dd4L), tobe(0x44190b0dL), tobe(0x40d816baL),
-+tobe(0xaca5c697L), tobe(0xa864db20L), tobe(0xa527fdf9L), tobe(0xa1e6e04eL),
-+tobe(0xbfa1b04bL), tobe(0xbb60adfcL), tobe(0xb6238b25L), tobe(0xb2e29692L),
-+tobe(0x8aad2b2fL), tobe(0x8e6c3698L), tobe(0x832f1041L), tobe(0x87ee0df6L),
-+tobe(0x99a95df3L), tobe(0x9d684044L), tobe(0x902b669dL), tobe(0x94ea7b2aL),
-+tobe(0xe0b41de7L), tobe(0xe4750050L), tobe(0xe9362689L), tobe(0xedf73b3eL),
-+tobe(0xf3b06b3bL), tobe(0xf771768cL), tobe(0xfa325055L), tobe(0xfef34de2L),
-+tobe(0xc6bcf05fL), tobe(0xc27dede8L), tobe(0xcf3ecb31L), tobe(0xcbffd686L),
-+tobe(0xd5b88683L), tobe(0xd1799b34L), tobe(0xdc3abdedL), tobe(0xd8fba05aL),
-+tobe(0x690ce0eeL), tobe(0x6dcdfd59L), tobe(0x608edb80L), tobe(0x644fc637L),
-+tobe(0x7a089632L), tobe(0x7ec98b85L), tobe(0x738aad5cL), tobe(0x774bb0ebL),
-+tobe(0x4f040d56L), tobe(0x4bc510e1L), tobe(0x46863638L), tobe(0x42472b8fL),
-+tobe(0x5c007b8aL), tobe(0x58c1663dL), tobe(0x558240e4L), tobe(0x51435d53L),
-+tobe(0x251d3b9eL), tobe(0x21dc2629L), tobe(0x2c9f00f0L), tobe(0x285e1d47L),
-+tobe(0x36194d42L), tobe(0x32d850f5L), tobe(0x3f9b762cL), tobe(0x3b5a6b9bL),
-+tobe(0x0315d626L), tobe(0x07d4cb91L), tobe(0x0a97ed48L), tobe(0x0e56f0ffL),
-+tobe(0x1011a0faL), tobe(0x14d0bd4dL), tobe(0x19939b94L), tobe(0x1d528623L),
-+tobe(0xf12f560eL), tobe(0xf5ee4bb9L), tobe(0xf8ad6d60L), tobe(0xfc6c70d7L),
-+tobe(0xe22b20d2L), tobe(0xe6ea3d65L), tobe(0xeba91bbcL), tobe(0xef68060bL),
-+tobe(0xd727bbb6L), tobe(0xd3e6a601L), tobe(0xdea580d8L), tobe(0xda649d6fL),
-+tobe(0xc423cd6aL), tobe(0xc0e2d0ddL), tobe(0xcda1f604L), tobe(0xc960ebb3L),
-+tobe(0xbd3e8d7eL), tobe(0xb9ff90c9L), tobe(0xb4bcb610L), tobe(0xb07daba7L),
-+tobe(0xae3afba2L), tobe(0xaafbe615L), tobe(0xa7b8c0ccL), tobe(0xa379dd7bL),
-+tobe(0x9b3660c6L), tobe(0x9ff77d71L), tobe(0x92b45ba8L), tobe(0x9675461fL),
-+tobe(0x8832161aL), tobe(0x8cf30badL), tobe(0x81b02d74L), tobe(0x857130c3L),
-+tobe(0x5d8a9099L), tobe(0x594b8d2eL), tobe(0x5408abf7L), tobe(0x50c9b640L),
-+tobe(0x4e8ee645L), tobe(0x4a4ffbf2L), tobe(0x470cdd2bL), tobe(0x43cdc09cL),
-+tobe(0x7b827d21L), tobe(0x7f436096L), tobe(0x7200464fL), tobe(0x76c15bf8L),
-+tobe(0x68860bfdL), tobe(0x6c47164aL), tobe(0x61043093L), tobe(0x65c52d24L),
-+tobe(0x119b4be9L), tobe(0x155a565eL), tobe(0x18197087L), tobe(0x1cd86d30L),
-+tobe(0x029f3d35L), tobe(0x065e2082L), tobe(0x0b1d065bL), tobe(0x0fdc1becL),
-+tobe(0x3793a651L), tobe(0x3352bbe6L), tobe(0x3e119d3fL), tobe(0x3ad08088L),
-+tobe(0x2497d08dL), tobe(0x2056cd3aL), tobe(0x2d15ebe3L), tobe(0x29d4f654L),
-+tobe(0xc5a92679L), tobe(0xc1683bceL), tobe(0xcc2b1d17L), tobe(0xc8ea00a0L),
-+tobe(0xd6ad50a5L), tobe(0xd26c4d12L), tobe(0xdf2f6bcbL), tobe(0xdbee767cL),
-+tobe(0xe3a1cbc1L), tobe(0xe760d676L), tobe(0xea23f0afL), tobe(0xeee2ed18L),
-+tobe(0xf0a5bd1dL), tobe(0xf464a0aaL), tobe(0xf9278673L), tobe(0xfde69bc4L),
-+tobe(0x89b8fd09L), tobe(0x8d79e0beL), tobe(0x803ac667L), tobe(0x84fbdbd0L),
-+tobe(0x9abc8bd5L), tobe(0x9e7d9662L), tobe(0x933eb0bbL), tobe(0x97ffad0cL),
-+tobe(0xafb010b1L), tobe(0xab710d06L), tobe(0xa6322bdfL), tobe(0xa2f33668L),
-+tobe(0xbcb4666dL), tobe(0xb8757bdaL), tobe(0xb5365d03L), tobe(0xb1f740b4L)
-+};
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc32_user.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc32_user.h
-@@ -0,0 +1,45 @@
-+/*
-+ * Defines macros and types required by crc32 code undefined in user space.
-+ */
-+#ifndef _LINUX_CRC32_USER_H
-+#define _LINUX_CRC32_USER_H
-+#include <linux/types.h>
-+
-+#define likely(x) __builtin_expect(!!(x), 1)
-+#define unlikely(x) __builtin_expect(!!(x), 0)
-+
-+#define __swab32(x) \
-+({ \
-+ __u32 __x = (x); \
-+ ((__u32)( \
-+ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
-+ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
-+ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
-+ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-+})
-+
-+#define ___constant_swab32(x) \
-+ ((__u32)( \
-+ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
-+ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
-+ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
-+ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
-+ (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
-+
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
-+#define __le32_to_cpu(x) ((__u32)(x))
-+#define __cpu_to_le32(x) ((__u32)(x))
-+#define __be32_to_cpu(x) __swab32((x))
-+#define __cpu_to_be32(x) __swab32((x))
-+#define __constant_cpu_to_le32(x) ((__u32)(x))
-+#define __constant_cpu_to_be32(x) (( __u32)___constant_swab32((x)))
-+#else
-+#define __le32_to_cpu(x) __swab32((x))
-+#define __cpu_to_le32(x) __swab32((x))
-+#define __be32_to_cpu(x) ((__u32)(x))
-+#define __cpu_to_be32(x) ((__u32)(x))
-+#define __constant_cpu_to_le32(x) ___constant_swab32((x))
-+#define __constant_cpu_to_be32(x) ((__u32)(x))
-+#endif
-+
-+#endif /* _LINUX_CRC32_USER_H */
-Index: e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/Makefile.in
-+++ e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-@@ -69,6 +69,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_O
- unlink.o \
- valid_blk.o \
- version.o \
-+ crc32.o \
- crc16.o \
- csum.o
-
-@@ -132,6 +133,7 @@ SRCS= ext2_err.c \
- $(srcdir)/tdb.c \
- $(srcdir)/test_io.c \
- $(srcdir)/tst_csum.c \
-+ $(srcdir)/crc32.c \
- $(srcdir)/crc16.c \
- $(srcdir)/csum.c \
- $(srcdir)/unix_io.c \
-@@ -236,10 +238,11 @@ tst_bitops: tst_bitops.o inline.o $(STAT
- @$(CC) -o tst_bitops tst_bitops.o inline.o $(ALL_CFLAGS) \
- $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
-
--tst_csum: tst_csum.o csum.o crc16.o $(STATIC_LIBEXT2FS) $(STATIC_LIBUUID)
-+tst_csum: tst_csum.o csum.o crc16.o crc32.o $(STATIC_LIBEXT2FS) \
-+ $(STATIC_LIBUUID)
- @echo " LD $@"
-- @$(CC) -o tst_csum csum.o tst_csum.o crc16.o $(STATIC_LIBEXT2FS) \
-- $(STATIC_LIBUUID) $(LIBCOM_ERR)
-+ @$(CC) -o tst_csum csum.o tst_csum.o crc16.o crc32.o \
-+ $(STATIC_LIBEXT2FS) $(STATIC_LIBUUID) $(LIBCOM_ERR)
-
- tst_getsectsize: tst_getsectsize.o getsectsize.o $(STATIC_LIBEXT2FS)
- @echo " LD $@"
-@@ -385,6 +388,8 @@ cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $
- $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
- crc16.o: $(srcdir)/crc16.c $(srcdir)/ext2_fs.h $(srcdir)/crc16.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h
-+crc32.o: $(srcdir)/crc32.c $(srcdir)/ext2_fs.h $(srcdir)/crc16.h \
-+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h
- csum.o: $(srcdir)/csum.c $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_builddir)/lib/ext2fs/ext2_err.h
- dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2_fs.h \
-Index: e2fsprogs-1.40.11/e2fsck/e2fsck.h
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.11/e2fsck/e2fsck.h
-@@ -30,10 +30,12 @@
- #if EXT2_FLAT_INCLUDES
- #include "ext2_fs.h"
- #include "ext2fs.h"
-+#include "crc32.h"
- #include "blkid.h"
- #else
- #include "ext2fs/ext2_fs.h"
- #include "ext2fs/ext2fs.h"
-+#include "ext2fs/crc32.h"
- #include "blkid/blkid.h"
- #endif
-
-Index: e2fsprogs-1.40.11/e2fsck/recovery.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/recovery.c
-+++ e2fsprogs-1.40.11/e2fsck/recovery.c
-@@ -21,6 +21,7 @@
- #include <linux/jbd.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
-+#include <linux/crc32.h>
- #endif
-
- /*
-@@ -307,6 +308,36 @@ int journal_skip_recovery(journal_t *jou
- return err;
- }
-
-+/* calc_chksums calculates the checksums for the blocks described in the
-+ * descriptor block.
-+ */
-+static int calc_chksums(journal_t *journal, struct buffer_head *bh,
-+ unsigned long *next_log_block, __u32 *crc32_sum)
-+{
-+ int i, num_blks, err;
-+ unsigned io_block;
-+ struct buffer_head *obh;
-+
-+ num_blks = count_tags(bh, journal->j_blocksize);
-+ /* Calculate checksum of the descriptor block. */
-+ *crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size);
-+ for (i = 0; i < num_blks; i++) {
-+ io_block = (*next_log_block)++;
-+ wrap(journal, *next_log_block);
-+
-+ err = jread(&obh, journal, io_block);
-+ if (err) {
-+ printk (KERN_ERR "JBD: IO error %d recovering block "
-+ "%u in log\n", err, io_block);
-+ return 1;
-+ } else {
-+ *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
-+ obh->b_size);
-+ }
-+ }
-+ return 0;
-+}
-+
- static int do_one_pass(journal_t *journal,
- struct recovery_info *info, enum passtype pass)
- {
-@@ -318,6 +349,7 @@ static int do_one_pass(journal_t *journa
- struct buffer_head * bh;
- unsigned int sequence;
- int blocktype;
-+ __u32 crc32_sum = ~0; /* Transactional Checksums */
-
- /* Precompute the maximum metadata descriptors in a descriptor block */
- int MAX_BLOCKS_PER_DESC;
-@@ -409,9 +441,24 @@ static int do_one_pass(journal_t *journa
- switch(blocktype) {
- case JFS_DESCRIPTOR_BLOCK:
- /* If it is a valid descriptor block, replay it
-- * in pass REPLAY; otherwise, just skip over the
-- * blocks it describes. */
-+ * in pass REPLAY; if journal_checksums enabled, then
-+ * calculate checksums in PASS_SCAN, otherwise,
-+ * just skip over the blocks it describes. */
- if (pass != PASS_REPLAY) {
-+ if (pass == PASS_SCAN &&
-+ JFS_HAS_COMPAT_FEATURE(journal,
-+ JFS_FEATURE_COMPAT_CHECKSUM) &&
-+ !info->end_transaction) {
-+ if (calc_chksums(journal, bh,
-+ &next_log_block,
-+ &crc32_sum)) {
-+ brelse(bh);
-+ break;
-+ }
-+ brelse(bh);
-+ continue;
-+ }
-+
- next_log_block +=
- count_tags(bh, journal->j_blocksize);
- wrap(journal, next_log_block);
-@@ -506,9 +553,96 @@ static int do_one_pass(journal_t *journa
- continue;
-
- case JFS_COMMIT_BLOCK:
-- /* Found an expected commit block: not much to
-- * do other than move on to the next sequence
-+ /* How to differentiate between interrupted commit
-+ * and journal corruption ?
-+ *
-+ * {nth transaction}
-+ * Checksum Verification Failed
-+ * |
-+ * ____________________
-+ * | |
-+ * async_commit sync_commit
-+ * | |
-+ * | GO TO NEXT "Journal Corruption"
-+ * | TRANSACTION
-+ * |
-+ * {(n+1)th transanction}
-+ * |
-+ * _______|______________
-+ * | |
-+ * Commit block found Commit block not found
-+ * | |
-+ * "Journal Corruption" |
-+ * _____________|__________
-+ * | |
-+ * nth trans corrupt OR nth trans
-+ * and (n+1)th interrupted interrupted
-+ * before commit block
-+ * could reach the disk.
-+ * (Cannot find the difference in above
-+ * mentioned conditions. Hence assume
-+ * "Interrupted Commit".)
-+ */
-+
-+ /* Found an expected commit block: if checksums
-+ * are present verify them in PASS_SCAN; else not
-+ * much to do other than move on to the next sequence
- * number. */
-+ if (pass == PASS_SCAN &&
-+ JFS_HAS_COMPAT_FEATURE(journal,
-+ JFS_FEATURE_COMPAT_CHECKSUM)) {
-+ int chksum_err, chksum_seen;
-+ struct commit_header *cbh =
-+ (struct commit_header *)bh->b_data;
-+ __u32 found_chksum = ntohl(cbh->h_chksum[0]);
-+
-+ chksum_err = chksum_seen = 0;
-+
-+ if (info->end_transaction) {
-+ printk(KERN_ERR "JBD: Transaction %u "
-+ "found to be corrupt.\n",
-+ next_commit_ID - 1);
-+ brelse(bh);
-+ break;
-+ }
-+
-+ if (crc32_sum == found_chksum &&
-+ cbh->h_chksum_type == JFS_CRC32_CHKSUM &&
-+ cbh->h_chksum_size ==
-+ JFS_CRC32_CHKSUM_SIZE) {
-+ chksum_seen = 1;
-+ } else if (!(cbh->h_chksum_type == 0 &&
-+ cbh->h_chksum_size == 0 &&
-+ found_chksum == 0 &&
-+ !chksum_seen)) {
-+ /*
-+ * If fs is mounted using an old kernel and then
-+ * kernel with journal_chksum is used then we
-+ * get a situation where the journal flag has
-+ * checksum flag set but checksums are not
-+ * present i.e chksum = 0, in the individual
-+ * commit blocks.
-+ * Hence to avoid checksum failures, in this
-+ * situation, this extra check is added.
-+ */
-+ chksum_err = 1;
-+ }
-+
-+ if (chksum_err) {
-+ info->end_transaction = next_commit_ID;
-+
-+ if (!JFS_HAS_COMPAT_FEATURE(journal,
-+ JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)){
-+ printk(KERN_ERR
-+ "JBD: Transaction %u "
-+ "found to be corrupt.\n",
-+ next_commit_ID);
-+ brelse(bh);
-+ break;
-+ }
-+ }
-+ crc32_sum = ~0;
-+ }
- brelse(bh);
- next_commit_ID++;
- continue;
-@@ -544,9 +678,10 @@ static int do_one_pass(journal_t *journa
- * transaction marks the end of the valid log.
- */
-
-- if (pass == PASS_SCAN)
-- info->end_transaction = next_commit_ID;
-- else {
-+ if (pass == PASS_SCAN) {
-+ if (!info->end_transaction)
-+ info->end_transaction = next_commit_ID;
-+ } else {
- /* It's really bad news if different passes end up at
- * different places (but possible due to IO errors). */
- if (info->end_transaction != next_commit_ID) {
-Index: e2fsprogs-1.40.11/lib/ext2fs/tst_csum.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/tst_csum.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/tst_csum.c
-@@ -1,16 +1,17 @@
- /*
-- * This testing program verifies checksumming operations
-- *
-- * Copyright (C) 2006, 2007 by Andreas Dilger <adilger at clusterfs.com>
-- *
-- * %Begin-Header%
-- * This file may be redistributed under the terms of the GNU Public
-- * License.
-- * %End-Header%
-- */
-+* This testing program verifies checksumming operations
-+*
-+* Copyright (C) 2006, 2007 by Andreas Dilger <adilger at clusterfs.com>
-+*
-+* %Begin-Header%
-+* This file may be redistributed under the terms of the GNU Public
-+* License.
-+* %End-Header%
-+*/
-
- #include "ext2fs/ext2_fs.h"
- #include "ext2fs/ext2fs.h"
-+#include "ext2fs/crc32.h"
- #include "ext2fs/crc16.h"
- #include "uuid/uuid.h"
-
-@@ -64,28 +65,61 @@ int main(int argc, char **argv)
- 0x4b, 0xae, 0xec, 0xdb } };
- __u16 csum1, csum2, csum_known = 0xd3a4;
- char data[8] = { 0x10, 0x20, 0x30, 0x40, 0xf1, 0xb2, 0xc3, 0xd4 };
-- __u16 data_crc[8] = { 0xcc01, 0x180c, 0x1118, 0xfa10,
-- 0x483a, 0x6648, 0x6726, 0x85e6 };
-- __u16 data_crc0[8] = { 0x8cbe, 0xa80d, 0xd169, 0xde10,
-- 0x481e, 0x7d48, 0x673d, 0x8ea6 };
-+ __u16 data_crc16[8] = { 0xcc01, 0x180c, 0x1118, 0xfa10,
-+ 0x483a, 0x6648, 0x6726, 0x85e6 };
-+ __u16 data_crc16_0[8] = { 0x8cbe, 0xa80d, 0xd169, 0xde10,
-+ 0x481e, 0x7d48, 0x673d, 0x8ea6 };
-+ __u32 data_crc32[8] = {
-+ 0x4c11db70, 0x88722df3, 0xe91b93c6, 0xc8756001,
-+ 0x839b9c9f, 0x4b6fef27, 0x20eb2a56, 0x7196ddd5
-+ };
-+ __u32 data_crc32_0[8] = {
-+ 0x21964c4, 0x88c5498e, 0x5e7feec6, 0xf71bd7a,
-+ 0xc48b2703, 0x71155355, 0xa1efe310, 0x1892668c
-+ };
- int i;
-
- for (i = 0; i < sizeof(data); i++) {
- csum1 = crc16(0, data, i + 1);
-- printf("crc16(0): data[%d]: %04x=%04x\n", i, csum1,data_crc[i]);
-- if (csum1 != data_crc[i]) {
-+ printf("crc16(0): data[%d]: %04x=%04x\n", i, csum1,
-+ data_crc16[i]);
-+ if (csum1 != data_crc16[i]) {
- printf("error: crc16(0) for data[%d] should be %04x\n",
-- i, data_crc[i]);
-+ i, data_crc16[i]);
- exit(1);
- }
- }
-
- for (i = 0; i < sizeof(data); i++) {
- csum1 = crc16(~0, data, i + 1);
-- printf("crc16(~0): data[%d]: %04x=%04x\n",i,csum1,data_crc0[i]);
-- if (csum1 != data_crc0[i]) {
-+ printf("crc16(~0): data[%d]: %04x=%04x\n", i, csum1,
-+ data_crc16_0[i]);
-+ if (csum1 != data_crc16_0[i]) {
- printf("error: crc16(~0) for data[%d] should be %04x\n",
-- i, data_crc0[i]);
-+ i, data_crc16_0[i]);
-+ exit(1);
-+ }
-+ }
-+ for (i = 0; i < sizeof(data); i++) {
-+ __u32 csum32;
-+ csum32 = crc32_be(0, data, i + 1);
-+ printf("crc32(0): data[%d]: %04x=%04x\n", i, csum32,
-+ data_crc32[i]);
-+ if (csum32 != data_crc32[i]) {
-+ printf("error: crc32(0) for data[%d] should be %04x\n",
-+ i, data_crc32[i]);
-+ exit(1);
-+ }
-+ }
-+
-+ for (i = 0; i < sizeof(data); i++) {
-+ __u32 csum32;
-+ csum32 = crc32_be(~0U, data, i + 1);
-+ printf("crc32(~0): data[%d]: %04x=%04x\n", i, csum32,
-+ data_crc32_0[i]);
-+ if (csum32 != data_crc32_0[i]) {
-+ printf("error: crc32(~0) for data[%d] should be %04x\n",
-+ i, data_crc32_0[i]);
- exit(1);
- }
- }
diff --git a/debian/patches/e2fsprogs-lfsck.patch b/debian/patches/e2fsprogs-lfsck.patch
index d9fe04e..aa64c41 100644
--- a/debian/patches/e2fsprogs-lfsck.patch
+++ b/debian/patches/e2fsprogs-lfsck.patch
@@ -1,23 +1,23 @@
add support for lustre lfsck tool
-Index: ldiskfsprogs-1.40.11/MCONFIG.in
+Index: e2fsprogs-1.41.5/MCONFIG.in
===================================================================
---- ldiskfsprogs-1.40.11.orig/MCONFIG.in 2008-09-05 14:42:07.000000000 +0200
-+++ ldiskfsprogs-1.40.11/MCONFIG.in 2008-09-05 15:01:30.000000000 +0200
-@@ -81,6 +81,8 @@
- LIBINTL = @LIBINTL@
+--- e2fsprogs-1.41.5.orig/MCONFIG.in
++++ e2fsprogs-1.41.5/MCONFIG.in
+@@ -80,6 +80,8 @@ LIBINTL = @LIBINTL@
+ DEPLIBSS = $(LIB)/libss at LIB_EXT@
DEPLIBUUID = $(LIB)/libuuid at LIB_EXT@
- DEPLIBBLKID = $(LIB)/libblkid at LIB_EXT@
+ DEPLIBBLKID = @DEPLIBBLKID@ @PRIVATE_LIBS_CMT@ $(LIBUUID)
+#Version of libdb lib found by configure
+LIBDB = @libdb@
- STATIC_LIBSS = $(LIB)/libss at STATIC_LIB_EXT@
- STATIC_LIBCOM_ERR = $(LIB)/libcom_err at STATIC_LIB_EXT@
-Index: ldiskfsprogs-1.40.11/configure
+ STATIC_LIBSS = $(LIB)/libss at STATIC_LIB_EXT@ @DLOPEN_LIB@
+ STATIC_LIBCOM_ERR = $(LIB)/libcom_err at STATIC_LIB_EXT@ @SEM_INIT_LIB@
+Index: e2fsprogs-1.41.5/configure
===================================================================
---- ldiskfsprogs-1.40.11.orig/configure 2008-09-05 14:42:07.000000000 +0200
-+++ ldiskfsprogs-1.40.11/configure 2008-09-05 15:14:55.000000000 +0200
-@@ -676,6 +676,9 @@
+--- e2fsprogs-1.41.5.orig/configure
++++ e2fsprogs-1.41.5/configure
+@@ -676,6 +676,9 @@ GREP
EGREP
LINUX_INCLUDE
MAINTAINER_CMT
@@ -27,15 +27,15 @@ Index: ldiskfsprogs-1.40.11/configure
HTREE_CMT
ELF_CMT
BSDLIB_CMT
-@@ -755,6 +758,7 @@
+@@ -759,6 +762,7 @@ SIZEOF_LONG
SIZEOF_LONG_LONG
SOCKET_LIB
DLOPEN_LIB
+DB_LIB
+ SEM_INIT_LIB
UNI_DIFF_OPTS
LINUX_CMT
- CYGWIN_CMT
-@@ -1364,6 +1368,7 @@
+@@ -1369,6 +1373,7 @@ Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-maintainer-mode enable makefile rules useful for maintainers
@@ -43,15 +43,15 @@ Index: ldiskfsprogs-1.40.11/configure
--enable-compression enable EXPERIMENTAL compression support
--enable-htree enable EXPERIMENTAL htree directory support
--enable-elf-shlibs select ELF shared libraries
-@@ -1394,6 +1399,7 @@
- --with-ccopts=CCOPTS select compiler command line options
- --with-ldopts=LDOPTS select linker command line options
- --with-root-prefix=PREFIX override prefix variable for files to be placed in the root
+@@ -1404,6 +1409,7 @@ Optional Packages:
+ --with-included-gettext use the GNU gettext library included here
+ --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib
+ --without-libintl-prefix don't search for libintl in includedir and libdir
+ --with-lustre=LUSTRE specify the path to Lustre sources for lfsck
- --with-gnu-ld assume the C compiler uses GNU ld default=no
- --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib
- --without-libiconv-prefix don't search for libiconv in includedir and libdir
-@@ -3794,6 +3800,46 @@
+
+ Some influential environment variables:
+ CC C compiler command
+@@ -3803,6 +3809,46 @@ echo "${ECHO_T}Disabling maintainer mode
fi
@@ -98,7 +98,7 @@ Index: ldiskfsprogs-1.40.11/configure
# Check whether --enable-compression was given.
if test "${enable_compression+set}" = set; then
enableval=$enable_compression; if test "$enableval" = "no"
-@@ -11981,6 +12027,146 @@
+@@ -12175,6 +12221,146 @@ fi
done
@@ -242,10 +242,10 @@ Index: ldiskfsprogs-1.40.11/configure
+done
+
+
-
- for ac_header in sys/disk.h sys/mount.h
+ for ac_func in vprintf
do
-@@ -15134,6 +15320,284 @@
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+@@ -15204,6 +15390,284 @@ _ACEOF
fi
@@ -463,7 +463,7 @@ Index: ldiskfsprogs-1.40.11/configure
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
-+LIBS="-ldb-4.4 $LIBS"
++LIBS="-ldb-4.6 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
@@ -519,7 +519,7 @@ Index: ldiskfsprogs-1.40.11/configure
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_db_4_6_db_env_create" >&5
+echo "${ECHO_T}$ac_cv_lib_db_4_6_db_env_create" >&6; }
+if test $ac_cv_lib_db_4_6_db_env_create = yes; then
-+ DB_LIB=-ldb-4.4
++ DB_LIB=-ldb-4.6
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DB 1
+_ACEOF
@@ -530,7 +530,7 @@ Index: ldiskfsprogs-1.40.11/configure
{ echo "$as_me:$LINENO: checking for optreset" >&5
echo $ECHO_N "checking for optreset... $ECHO_C" >&6; }
if test "${ac_cv_have_optreset+set}" = set; then
-@@ -16087,6 +16551,9 @@
+@@ -16461,6 +16925,9 @@ GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim
LINUX_INCLUDE!$LINUX_INCLUDE$ac_delim
MAINTAINER_CMT!$MAINTAINER_CMT$ac_delim
@@ -540,48 +540,37 @@ Index: ldiskfsprogs-1.40.11/configure
HTREE_CMT!$HTREE_CMT$ac_delim
ELF_CMT!$ELF_CMT$ac_delim
BSDLIB_CMT!$BSDLIB_CMT$ac_delim
-@@ -16094,9 +16561,6 @@
- CHECKER_CMT!$CHECKER_CMT$ac_delim
- LIB_EXT!$LIB_EXT$ac_delim
- STATIC_LIB_EXT!$STATIC_LIB_EXT$ac_delim
--PROFILED_LIB_EXT!$PROFILED_LIB_EXT$ac_delim
--SWAPFS_CMT!$SWAPFS_CMT$ac_delim
--DEBUGFS_CMT!$DEBUGFS_CMT$ac_delim
+@@ -16473,7 +16940,7 @@ LDFLAG_DYNAMIC!$LDFLAG_DYNAMIC$ac_delim
+ PRIVATE_LIBS_CMT!$PRIVATE_LIBS_CMT$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 73; then
-@@ -16170,6 +16634,9 @@
- ac_delim='%!_!# '
- for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-+PROFILED_LIB_EXT!$PROFILED_LIB_EXT$ac_delim
-+SWAPFS_CMT!$SWAPFS_CMT$ac_delim
-+DEBUGFS_CMT!$DEBUGFS_CMT$ac_delim
- IMAGER_CMT!$IMAGER_CMT$ac_delim
- RESIZER_CMT!$RESIZER_CMT$ac_delim
- FSCK_PROG!$FSCK_PROG$ac_delim
-@@ -16239,6 +16706,7 @@
+- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 73; then
++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 76; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+@@ -16617,6 +17084,7 @@ SIZEOF_LONG!$SIZEOF_LONG$ac_delim
SIZEOF_LONG_LONG!$SIZEOF_LONG_LONG$ac_delim
SOCKET_LIB!$SOCKET_LIB$ac_delim
DLOPEN_LIB!$DLOPEN_LIB$ac_delim
+DB_LIB!$DB_LIB$ac_delim
+ SEM_INIT_LIB!$SEM_INIT_LIB$ac_delim
UNI_DIFF_OPTS!$UNI_DIFF_OPTS$ac_delim
LINUX_CMT!$LINUX_CMT$ac_delim
- CYGWIN_CMT!$CYGWIN_CMT$ac_delim
-@@ -16259,7 +16727,7 @@
+@@ -16638,7 +17106,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
-- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 87; then
-+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
+- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 92; then
++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-Index: ldiskfsprogs-1.40.11/configure.in
+Index: e2fsprogs-1.41.5/configure.in
===================================================================
---- ldiskfsprogs-1.40.11.orig/configure.in 2008-09-05 14:42:07.000000000 +0200
-+++ ldiskfsprogs-1.40.11/configure.in 2008-09-05 15:14:55.000000000 +0200
-@@ -171,6 +171,39 @@
+--- e2fsprogs-1.41.5.orig/configure.in
++++ e2fsprogs-1.41.5/configure.in
+@@ -172,6 +172,39 @@ AC_MSG_RESULT([Disabling maintainer mode
)
AC_SUBST(MAINTAINER_CMT)
dnl
@@ -621,15 +610,15 @@ Index: ldiskfsprogs-1.40.11/configure.in
dnl handle --enable-compression
dnl
AC_ARG_ENABLE([compression],
-@@ -638,6 +671,7 @@
- AC_CHECK_PROGS(BUILD_CC, gcc cc)
- fi
- AC_CHECK_HEADERS(dirent.h errno.h getopt.h malloc.h mntent.h paths.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h unistd.h utime.h linux/fd.h linux/major.h net/if_dl.h netinet/in.h sys/disklabel.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/prctl.h sys/queue.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h)
+@@ -653,6 +686,7 @@ AC_CHECK_HEADERS(net/if.h,,,
+ #include <sys/socket.h>
+ #endif
+ ]])
+AC_CHECK_HEADERS(db.h)
- AC_CHECK_HEADERS(sys/disk.h sys/mount.h,,,
- [[
- #if HAVE_SYS_QUEUE_H
-@@ -771,6 +805,23 @@
+ AC_FUNC_VPRINTF
+ dnl Check to see if dirent has member d_reclen. On cygwin those d_reclen
+ dnl is not decleared.
+@@ -771,6 +805,23 @@ AC_CHECK_LIB(dl, dlopen,
AC_DEFINE(HAVE_DLOPEN)])
AC_SUBST(DLOPEN_LIB)
dnl
@@ -653,11 +642,11 @@ Index: ldiskfsprogs-1.40.11/configure.in
dnl See if optreset exists
dnl
AC_MSG_CHECKING(for optreset)
-Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
+Index: e2fsprogs-1.41.5/e2fsck/Makefile.in
===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/Makefile.in 2008-09-05 14:42:51.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/Makefile.in 2008-09-05 15:12:36.000000000 +0200
-@@ -13,29 +13,39 @@
+--- e2fsprogs-1.41.5.orig/e2fsck/Makefile.in
++++ e2fsprogs-1.41.5/e2fsck/Makefile.in
+@@ -12,29 +12,39 @@ INSTALL = @INSTALL@
@MCONFIG@
PROGS= e2fsck
@@ -705,29 +694,29 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
#
# Flags for using Checker
-@@ -64,7 +74,10 @@
- OBJS= dict.o unix.o e2fsck.o super.o pass1.o pass1b.o pass2.o pass3.o pass4.o \
- pass5.o journal.o swapfs.o badblocks.o util.o dirinfo.o dx_dirinfo.o \
- ehandler.o problem.o message.o recovery.o region.o revoke.o \
-- ea_refcount.o rehash.o profile.o prof_err.o $(MTRACE_OBJ)
-+ ea_refcount.o rehash.o profile.o prof_err.o pass6.o $(MTRACE_OBJ)
+@@ -63,7 +73,10 @@ COMPILE_ET=$(top_builddir)/lib/et/compil
+ OBJS= crc32.o dict.o unix.o e2fsck.o super.o pass1.o pass1b.o pass2.o \
+ pass3.o pass4.o pass5.o journal.o badblocks.o util.o dirinfo.o \
+ dx_dirinfo.o ehandler.o problem.o message.o recovery.o region.o \
+- revoke.o ea_refcount.o rehash.o profile.o prof_err.o $(MTRACE_OBJ)
++ revoke.o ea_refcount.o rehash.o profile.o prof_err.o pass6.o $(MTRACE_OBJ)
+ at LFSCK_CMT@OBJS += lfsck_common.o
+
+ at LFSCK_CMT@LFSCK_OBJS = lfsck_common.o lfsck.o
PROFILED_OBJS= profiled/dict.o profiled/unix.o profiled/e2fsck.o \
profiled/super.o profiled/pass1.o profiled/pass1b.o \
-@@ -74,7 +87,8 @@
- profiled/message.o profiled/problem.o profiled/swapfs.o \
+@@ -73,7 +86,8 @@ PROFILED_OBJS= profiled/dict.o profiled/
+ profiled/message.o profiled/problem.o \
profiled/recovery.o profiled/region.o profiled/revoke.o \
profiled/ea_refcount.o profiled/rehash.o profiled/profile.o \
-- profiled/prof_err.o
-+ profiled/pass6.o profiled/prof_err.o
+- profiled/crc32.o profiled/prof_err.o
++ profiled/crc32.o profiled/prof_err.o profiled/pass6.o
+ at LFSCK_CMT@PROFILED_OBJS += profiled/lfsck_common.o
SRCS= $(srcdir)/e2fsck.c \
- $(srcdir)/dict.c \
-@@ -85,6 +99,7 @@
+ $(srcdir)/crc32.c \
+@@ -86,6 +100,7 @@ SRCS= $(srcdir)/e2fsck.c \
$(srcdir)/pass3.c \
$(srcdir)/pass4.c \
$(srcdir)/pass5.c \
@@ -735,7 +724,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
$(srcdir)/journal.c \
$(srcdir)/recovery.c \
$(srcdir)/revoke.c \
-@@ -104,7 +119,10 @@
+@@ -104,7 +119,10 @@ SRCS= $(srcdir)/e2fsck.c \
prof_err.c \
$(MTRACE_SRC)
@@ -747,29 +736,18 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
@PROFILE_CMT at all:: e2fsck.profiled
-@@ -118,8 +136,8 @@
-
- e2fsck.static: $(OBJS) $(STATIC_DEPLIBS)
- @echo " LD $@"
-- @$(LD) $(ALL_LDFLAGS) $(LDFLAG_STATIC) -o e2fsck.static $(OBJS) \
-- $(STATIC_LIBS)
-+ @$(LD) -static $(ALL_LDFLAGS) $(LDFLAG_STATIC) -o e2fsck.static $(OBJS) \
-+ $(STATIC_LIBS) -lpthread
-
- e2fsck.profiled: $(PROFILED_OBJS) $(PROFILED_DEPLIBS)
- @echo " LD $@"
-@@ -136,6 +154,10 @@
- @$(CC) -o tst_region $(srcdir)/region.c \
- $(ALL_CFLAGS) -DTEST_PROGRAM -lcom_err
+@@ -158,6 +176,10 @@ check:: tst_refcount tst_region tst_crc3
+ LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_crc32
+ LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_problem
+ at LFSCK_CMT@lfsck: $(LFSCK_OBJS)
+ at LFSCK_CMT@ @echo " LD $@"
-+ at LFSCK_CMT@ $(LD) -static -pthread $(ALL_LDFLAGS) $(LUSTRE_INC) $(LFSCK_OBJS) -o lfsck $(LUSTRE_LIB) -llustreapi -ldb-4.4
++ at LFSCK_CMT@ $(LD) -pthread $(ALL_LDFLAGS) $(LUSTRE_INC) $(LFSCK_OBJS) -o lfsck $(LUSTRE_LIB) -llustreapi $(DEPLIBS)
+
extend: extend.o
@echo " LD $@"
@$(LD) $(ALL_LDFLAGS) -o extend extend.o $(CHECKLIB)
-@@ -159,6 +181,9 @@
+@@ -181,6 +203,9 @@ profiled:
@PROFILE_CMT@ @echo " MKDIR $@"
@PROFILE_CMT@ @mkdir profiled
@@ -779,7 +757,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
e2fsck.8: $(DEP_SUBSTITUTE) $(srcdir)/e2fsck.8.in
@echo " SUBST $@"
@$(SUBSTITUTE_UPTIME) $(srcdir)/e2fsck.8.in e2fsck.8
-@@ -168,15 +193,19 @@
+@@ -190,15 +215,19 @@ e2fsck.conf.5: $(DEP_SUBSTITUTE) $(srcdi
@$(SUBSTITUTE_UPTIME) $(srcdir)/e2fsck.conf.5.in e2fsck.conf.5
installdirs:
@@ -802,7 +780,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
@echo " LINK $(root_sbindir)/fsck.ext2"
@$(LN) -f $(DESTDIR)$(root_sbindir)/e2fsck \
$(DESTDIR)$(root_sbindir)/fsck.ext2
-@@ -214,6 +243,9 @@
+@@ -248,6 +277,9 @@ uninstall:
for i in $(PROGS); do \
$(RM) -f $(DESTDIR)$(root_sbindir)/$$i; \
done
@@ -810,19 +788,19 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
+ $(RM) -f $(DESTDIR)$(sbindir)/$$i; \
+ done
$(RM) -f $(DESTDIR)$(root_sbindir)/fsck.ext2 \
- $(DESTDIR)$(root_sbindir)/fsck.ext3
- for i in $(MANPAGES); do \
-@@ -226,7 +258,7 @@
- $(DESTDIR)$(root_sbindir)/fsck.ext3
+ $(DESTDIR)$(root_sbindir)/fsck.ext3 \
+ $(DESTDIR)$(root_sbindir)/fsck.ext4 \
+@@ -264,7 +296,7 @@ uninstall:
+ $(DESTDIR)$(root_sbindir)/fsck.ext4dev
clean:
- $(RM) -f $(PROGS) \#* *\# *.s *.o *.a *~ core e2fsck.static \
+ $(RM) -f $(PROGS) $(USPROGS) \#* *\# *.s *.o *.a *~ core e2fsck.static \
- e2fsck.shared e2fsck.profiled flushb e2fsck.8
- $(RM) -rf profiled
-
-@@ -298,6 +330,13 @@
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ e2fsck.shared e2fsck.profiled flushb e2fsck.8 \
+ tst_problem tst_crc32 tst_region tst_refcount gen_crc32table \
+ crc32table.h e2fsck.conf.5 prof_err.c prof_err.h \
+@@ -354,6 +386,13 @@ pass5.o: $(srcdir)/pass5.c $(srcdir)/e2f
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(top_srcdir)/lib/blkid/blkid.h $(top_builddir)/lib/blkid/blkid_types.h \
$(srcdir)/profile.h prof_err.h $(srcdir)/problem.h
+pass6.o: $(srcdir)/pass6.c $(srcdir)/e2fsck.h \
@@ -835,21 +813,21 @@ Index: ldiskfsprogs-1.40.11/e2fsck/Makefile.in
journal.o: $(srcdir)/journal.c $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
-@@ -407,6 +446,9 @@
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+@@ -472,6 +511,9 @@ region.o: $(srcdir)/region.c $(srcdir)/e
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(top_srcdir)/lib/blkid/blkid.h $(top_builddir)/lib/blkid/blkid_types.h \
$(srcdir)/profile.h prof_err.h
+lfsck.o: $(srcdir)/lfsck.c $(srcdir)/lfsck.h $(srcdir)/lfsck_common.c \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_fs.h
- profile.o: $(srcdir)/profile.c $(srcdir)/profile.h prof_err.h \
- $(top_srcdir)/lib/et/com_err.h
+ profile.o: $(srcdir)/profile.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/profile.h prof_err.h
prof_err.o: prof_err.c
-Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.8.in
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.8.in
===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/e2fsck.8.in 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/e2fsck.8.in 2008-09-05 15:01:30.000000000 +0200
-@@ -332,6 +332,20 @@
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.8.in
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.8.in
+@@ -326,6 +326,20 @@ may not be specified at the same time as
or
.B \-p
options.
@@ -870,11 +848,11 @@ Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.8.in
.SH EXIT CODE
The exit code returned by
.B e2fsck
-Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.c
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.c
===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/e2fsck.c 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/e2fsck.c 2008-09-05 15:01:30.000000000 +0200
-@@ -183,8 +183,11 @@
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.c
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.c
+@@ -190,8 +190,11 @@ void e2fsck_free_context(e2fsck_t ctx)
typedef void (*pass_t)(e2fsck_t ctx);
pass_t e2fsck_passes[] = {
@@ -888,20 +866,20 @@ Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.c
#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
-Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.h
+Index: e2fsprogs-1.41.5/e2fsck/e2fsck.h
===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/e2fsck.h 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/e2fsck.h 2008-09-05 15:01:30.000000000 +0200
-@@ -155,6 +155,7 @@
- #define E2F_OPT_FORCE 0x0100
+--- e2fsprogs-1.41.5.orig/e2fsck/e2fsck.h
++++ e2fsprogs-1.41.5/e2fsck/e2fsck.h
+@@ -156,6 +156,7 @@ struct resource_track {
#define E2F_OPT_WRITECHECK 0x0200
#define E2F_OPT_COMPRESS_DIRS 0x0400
-+#define E2F_OPT_VERBOSE 0x8000
+ #define E2F_OPT_FRAGCHECK 0x0800
++#define E2F_OPT_VERBOSE 0x1000
/*
* E2fsck flags
-@@ -176,6 +177,13 @@
- #define E2F_FLAG_GOT_DEVSIZE 0x0800 /* Device size has been fetched */
+@@ -179,6 +180,13 @@ struct resource_track {
+ #define E2F_FLAG_EXITING 0x1000 /* E2fsck exiting due to errors */
#define E2F_FLAG_EXPAND_EISIZE 0x2000 /* Expand the inodes (i_extra_isize) */
+/* Defines for Lustre */
@@ -914,7 +892,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.h
/*
* Defines for indicating the e2fsck pass number
*/
-@@ -318,6 +326,12 @@
+@@ -324,6 +332,12 @@ struct e2fsck_struct {
io_channel journal_io;
char *journal_name;
@@ -927,7 +905,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.h
#ifdef RESOURCE_TRACK
/*
* For timing purposes
-@@ -401,6 +415,7 @@
+@@ -408,6 +422,7 @@ extern void e2fsck_pass2(e2fsck_t ctx);
extern void e2fsck_pass3(e2fsck_t ctx);
extern void e2fsck_pass4(e2fsck_t ctx);
extern void e2fsck_pass5(e2fsck_t ctx);
@@ -935,10 +913,371 @@ Index: ldiskfsprogs-1.40.11/e2fsck/e2fsck.h
/* e2fsck.c */
extern errcode_t e2fsck_allocate_context(e2fsck_t *ret);
-Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.8.in
+Index: e2fsprogs-1.41.5/e2fsck/pass1.c
+===================================================================
+--- e2fsprogs-1.41.5.orig/e2fsck/pass1.c
++++ e2fsprogs-1.41.5/e2fsck/pass1.c
+@@ -48,6 +48,7 @@
+
+ #include "e2fsck.h"
+ #include <ext2fs/ext2_ext_attr.h>
++#include "lfsck.h"
+
+ #include "problem.h"
+
+@@ -338,6 +339,9 @@ static void check_ea_in_inode(e2fsck_t c
+ goto fix;
+ }
+
++ e2fsck_lfsck_found_ea(ctx, pctx->ino, inode, entry,
++ start + entry->e_value_offs);
++
+ remain -= entry->e_value_size;
+
+ entry = EXT2_EXT_ATTR_NEXT(entry);
+@@ -833,6 +837,12 @@ void e2fsck_pass1(e2fsck_t ctx)
+ ext2fs_mark_block_bitmap(ctx->block_found_map,
+ fs->super->s_mmp_block);
+
++ if (!(ctx->options & E2F_OPT_READONLY) &&
++ (ctx->lustre_devtype & LUSTRE_TYPE) == LUSTRE_MDS) {
++ if (e2fsck_lfsck_remove_pending(ctx, NULL))
++ return;
++ }
++
+ while (1) {
+ if (ino % EXT2_MMP_INODE_INTERVAL == 0) {
+ errcode_t error;
+@@ -1359,6 +1369,9 @@ void e2fsck_pass1(e2fsck_t ctx)
+ }
+ e2fsck_pass1_dupblocks(ctx, block_buf);
+ }
++
++ e2fsck_lfsck_flush_ea(ctx);
++
+ ext2fs_free_mem(&inodes_to_process);
+ endit:
+ e2fsck_use_inode_shortcuts(ctx, 0);
+@@ -1769,6 +1782,14 @@ static int check_ext_attr(e2fsck_t ctx,
+ entry->e_hash = hash;
+ }
+
++ if (e2fsck_lfsck_found_ea(ctx, ino,
++ (struct ext2_inode_large *)inode,
++ entry,
++ block_buf + entry->e_value_offs)) {
++ if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
++ return 0;
++ }
++
+ entry = EXT2_EXT_ATTR_NEXT(entry);
+ }
+ if (region_allocate(region, (char *)entry - (char *)header, 4)) {
+Index: e2fsprogs-1.41.5/e2fsck/unix.c
+===================================================================
+--- e2fsprogs-1.41.5.orig/e2fsck/unix.c
++++ e2fsprogs-1.41.5/e2fsck/unix.c
+@@ -10,6 +10,7 @@
+ */
+
+ #define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */
++#define _GNU_SOURCE
+
+ #include <stdio.h>
+ #ifdef HAVE_STDLIB_H
+@@ -47,6 +48,9 @@ extern int optind;
+ #ifdef HAVE_DIRENT_H
+ #include <dirent.h>
+ #endif
++#ifdef HAVE_LIMITS_H
++#include <limits.h>
++#endif
+
+ #include "e2p/e2p.h"
+ #include "et/com_err.h"
+@@ -55,6 +59,17 @@ extern int optind;
+ #include "problem.h"
+ #include "../version.h"
+
++#include "lfsck.h"
++
++static struct option long_options[] = {
++#ifdef ENABLE_LFSCK
++ { "mdsdb", 1, NULL, 1 },
++ { "mdtdb", 1, NULL, 1 },
++ { "ostdb", 1, NULL, 2 },
++#endif
++ { 0, 0, 0, 0 }
++};
++
+ /* Command line options */
+ static int cflag; /* check disk */
+ static int show_version_only;
+@@ -333,6 +348,15 @@ static void check_if_skip(e2fsck_t ctx)
+ fs->super->s_checkinterval*2))
+ reason = 0;
+ }
++#ifdef ENABLE_LFSCK
++ if (ctx->lustre_devtype & LUSTRE_TYPE) {
++ if (!reason || ctx->options & E2F_OPT_READONLY)
++ ctx->lustre_devtype |= LUSTRE_ONLY;
++ if (!reason)
++ reason = _(" lustre database creation");
++ }
++#endif
++
+ if (reason) {
+ fputs(ctx->device_name, stdout);
+ printf(reason, reason_arg);
+@@ -366,6 +390,13 @@ static void check_if_skip(e2fsck_t ctx)
+ fputc('\n', stdout);
+ ext2fs_close(fs);
+ ctx->fs = NULL;
++ if (ctx->lustre_mdsdb)
++ free(ctx->lustre_mdsdb);
++ if (ctx->lustre_ostdb)
++ free(ctx->lustre_ostdb);
++ if (ctx->lfsck_oinfo)
++ e2fsck_lfsck_cleanupdb(ctx);
++
+ e2fsck_free_context(ctx);
+ exit(FSCK_OK);
+ }
+@@ -700,6 +731,31 @@ static void parse_extended_opts(e2fsck_t
+ }
+ }
+
++static char *my_dirname(char *path)
++{
++
++ if (path != NULL) {
++ char *tmp = strrchr(path, '/');
++ if (tmp != NULL) {
++ *tmp = '\0';
++ return path;
++ }
++ }
++
++ return ".";
++}
++
++static const char *my_basename(const char *path)
++{
++ if (path != NULL) {
++ char *tmp = strrchr(path, '/');
++ if (tmp != NULL)
++ return tmp + 1;
++ }
++
++ return path;
++}
++
+ static void syntax_err_report(const char *filename, long err, int line_num)
+ {
+ fprintf(stderr,
+@@ -714,6 +770,7 @@ static errcode_t PRS(int argc, char *arg
+ {
+ int flush = 0;
+ int c, fd;
++ int option_index;
+ #ifdef MTRACE
+ extern void *mallwatch;
+ #endif
+@@ -762,8 +819,73 @@ static errcode_t PRS(int argc, char *arg
+ ctx->inode_badness_threshold = BADNESS_THRESHOLD;
+ ctx->now_tolerance_val = 172800; /* Two days */
+
+- while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
++ ctx->lustre_devtype = LUSTRE_NULL;
++
++ while ((c = getopt_long(argc, argv,
++ "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk",
++ long_options, &option_index)) != EOF)
+ switch (c) {
++ case 1: {
++ char *dbpath, *tmp;
++
++ if (!optarg)
++ usage(ctx);
++
++ dbpath = malloc(PATH_MAX);
++ if (dbpath == NULL) {
++ fprintf(stderr, "Out of memory\n");
++ exit(1);
++ }
++ tmp = malloc(PATH_MAX);
++ if (tmp == NULL) {
++ fprintf(stderr, "Out of memory\n");
++ exit(1);
++ }
++
++ strcpy(tmp, optarg);
++ if (realpath(my_dirname(tmp), dbpath) == NULL) {
++ fprintf(stderr, "Failure to resolve path %s\n",
++ optarg);
++ exit(1);
++ }
++
++ strcpy(tmp, optarg);
++ sprintf(dbpath+strlen(dbpath), "/%s", my_basename(tmp));
++ ctx->lustre_mdsdb = dbpath;
++ ctx->lustre_devtype |= LUSTRE_MDS;
++
++ free(tmp);
++ break;
++ }
++ case 2: {
++ char *dbpath, *tmp;
++
++ dbpath = malloc(PATH_MAX);
++ if (dbpath == NULL) {
++ fprintf(stderr, "Out of memory\n");
++ exit(1);
++ }
++ tmp = malloc(PATH_MAX);
++ if (tmp == NULL) {
++ fprintf(stderr, "Out of memory\n");
++ exit(1);
++ }
++
++ strcpy(tmp, optarg);
++ if (realpath(my_dirname(tmp), dbpath) == NULL) {
++ fprintf(stderr, "Failure to resolve path %s\n",
++ optarg);
++ exit(1);
++ }
++
++ strcpy(tmp, optarg);
++ sprintf(dbpath+strlen(dbpath), "/%s", my_basename(tmp));
++ ctx->lustre_ostdb = dbpath;
++ ctx->lustre_devtype |= LUSTRE_OST;
++
++ free(tmp);
++ break;
++ }
+ case 'C':
+ ctx->progress = e2fsck_update_progress;
+ res = sscanf(optarg, "%d", &ctx->progress_fd);
+@@ -870,6 +992,7 @@ static errcode_t PRS(int argc, char *arg
+ break;
+ case 'v':
+ verbose = 1;
++ ctx->options |= E2F_OPT_VERBOSE;
+ break;
+ case 'V':
+ show_version_only = 1;
+@@ -888,6 +1011,14 @@ static errcode_t PRS(int argc, char *arg
+ default:
+ usage(ctx);
+ }
++ if (ctx->lustre_devtype) {
++ if ((ctx->lustre_devtype != LUSTRE_MDS) &&
++ ctx->lustre_devtype != (LUSTRE_MDS | LUSTRE_OST)) {
++ com_err(ctx->program_name, 0,
++ _("must specify --mdsdb with --ostdb"));
++ usage(ctx);
++ }
++ }
+ if (show_version_only)
+ return 0;
+ if (optind != argc - 1)
+@@ -1569,6 +1700,12 @@ no_journal:
+ ext2fs_close(fs);
+ ctx->fs = NULL;
+ free(ctx->journal_name);
++ if (ctx->lfsck_oinfo)
++ e2fsck_lfsck_cleanupdb(ctx);
++ if (ctx->lustre_mdsdb)
++ free(ctx->lustre_mdsdb);
++ if (ctx->lustre_ostdb)
++ free(ctx->lustre_ostdb);
+
+ e2fsck_free_context(ctx);
+ remove_error_table(&et_ext2_error_table);
+Index: e2fsprogs-1.41.5/misc/mke2fs.c
+===================================================================
+--- e2fsprogs-1.41.5.orig/misc/mke2fs.c
++++ e2fsprogs-1.41.5/misc/mke2fs.c
+@@ -1300,7 +1300,7 @@ static void PRS(int argc, char *argv[])
+ }
+ break;
+ case 'v':
+- verbose = 1;
++ verbose++;
+ break;
+ case 'F':
+ force++;
+Index: e2fsprogs-1.41.5/util/subst.conf.in
+===================================================================
+--- e2fsprogs-1.41.5.orig/util/subst.conf.in
++++ e2fsprogs-1.41.5/util/subst.conf.in
+@@ -5,6 +5,8 @@ SS_DIR @SS_DIR@
+ E2FSPROGS_MONTH @E2FSPROGS_MONTH@
+ E2FSPROGS_YEAR @E2FSPROGS_YEAR@
+ E2FSPROGS_VERSION @E2FSPROGS_VERSION@
++LFSCK_CMT @LFSCK_CMT@
++LFSCK_MAN @LFSCK_MAN@
+ SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@
+ SIZEOF_LONG @SIZEOF_LONG@
+ SIZEOF_INT @SIZEOF_INT@
+Index: e2fsprogs-1.41.5/e2fsprogs.spec.in
+===================================================================
+--- e2fsprogs-1.41.5.orig/e2fsprogs.spec.in
++++ e2fsprogs-1.41.5/e2fsprogs.spec.in
+@@ -10,17 +10,21 @@ Release: 0%{_vendor}
+ License: GPLv2
+ Group: System Environment/Base
+ Source: ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/e2fsprogs-%{version}.tar.gz
+-Url: http://e2fsprogs.sourceforge.net/
++Url: ftp://ftp.lustre.org/pub/lustre/other/e2fsprogs/
+ Prereq: /sbin/ldconfig
+ BuildRoot: %{_tmppath}/%{name}-root
+ %if %{_vendor} == "suse"
+ Group: System/Filesystems
+-Provides: e2fsbn ext2fs libcom_err = %{version}
++ at LFSCK_CMT@Requires: db >= @DB4VERSION@
++ at LFSCK_CMT@BuildRequires: db-devel >= 4.1 texinfo
++Provides: e2fsbn ext2fs libcom_err = %{version} ldiskfsprogs
+ Obsoletes: ext2fs libcom_err < %{version}
+ %else
+ Group: System Environment/Base
++ at LFSCK_CMT@Requires: db4 >= @DB4VERSION@
++ at LFSCK_CMT@BuildRequires: db4-devel >= 4.1 texinfo
+ Obsoletes: e2fsprogs-libs < %{version}
+-Provides: e2fsprogs-libs = %{version}
++Provides: e2fsprogs-libs = %{version} ldiskfsprogs
+ %endif
+
+ %description
+@@ -71,7 +75,7 @@ SMP systems.
+ %setup
+
+ %build
+-%configure --enable-elf-shlibs --enable-nls \
++%configure --enable-elf-shlibs --enable-nls @LFSCK_CMT@ --enable-lfsck \
+ %{?extra_config_flags:%extra_config_flags}
+ make
+ make check
+@@ -144,6 +148,7 @@ exit 0
+ %{_sbindir}/filefrag
+ %{_sbindir}/mklost+found
+ %{_sbindir}/e2freefrag
++ at LFSCK_CMT@%{_sbindir}/lfsck
+
+ %{_root_libdir}/libblkid.so.*
+ %{_root_libdir}/libcom_err.so.*
+@@ -169,6 +174,7 @@ exit 0
+ %{_mandir}/man8/debugfs.8*
+ %{_mandir}/man8/dumpe2fs.8*
+ %{_mandir}/man8/e2fsck.8*
++ at LFSCK_CMT@%{_mandir}/man8/lfsck.8*
+ %{_mandir}/man8/findfs.8*
+ %{_mandir}/man8/fsck.ext2.8*
+ %{_mandir}/man8/fsck.ext3.8*
+Index: e2fsprogs-1.41.5/e2fsck/lfsck.8.in
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ldiskfsprogs-1.40.11/e2fsck/lfsck.8.in 2008-09-05 15:01:30.000000000 +0200
+--- /dev/null
++++ e2fsprogs-1.41.5/e2fsck/lfsck.8.in
@@ -0,0 +1,78 @@
+.\" -*- nroff -*-
+.\" Copyright 2004 by Andreas Dilger. All Rights Reserved.
@@ -1009,7 +1348,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.8.in
+on each of the OST backing devices. These are required, unless an OST is
+unavailable, in which case all objects thereon will be considered missing.
+.SH REPORTING BUGS
-+Bugs should be reported to Cluster File Systems via Bugzilla:
++Bugs should be reported to Sun Microsystems, Inc. via Bugzilla:
+http://bugzilla.lustre.org/
+.SH AUTHOR
+This version of
@@ -1018,14 +1357,14 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.8.in
+and maintained by Andreas Dilger <adilger at clusterfs.com>
+.SH SEE ALSO
+.BR e2fsck (8)
-Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.c
+Index: e2fsprogs-1.41.5/e2fsck/lfsck.c
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ldiskfsprogs-1.40.11/e2fsck/lfsck.c 2008-09-05 15:01:30.000000000 +0200
+--- /dev/null
++++ e2fsprogs-1.41.5/e2fsck/lfsck.c
@@ -0,0 +1,1868 @@
+/*
+ * Copyright (c) 2004 Hewlett-Packard Co.
-+ * Copyright (c) 2005, 2006 Cluster File Systems, Inc.
++ * Copyright 2008 Sun Microsystems, Inc.
+ */
+/***********************************************************************
+ * This program takes as input files generated by running e2fsck on
@@ -1129,11 +1468,11 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.c
+char *mds_file;
+char lostandfounddir[PATH_MAX];
+char dupedir[PATH_MAX];
-+char *ost_files[MAX_OSTS];
++char *ost_files[LOV_MAX_OSTS];
+int num_ost_files;
+
-+struct obd_uuid lfsck_uuid[MAX_OSTS];
-+int lov_tgt_count = MAX_OSTS;
++struct obd_uuid lfsck_uuid[LOV_MAX_OSTS];
++int lov_tgt_count = LOV_MAX_OSTS;
+
+struct lfsck_saved_duplicates *lfsck_duplicates;
+int lfsck_dup_saved;
@@ -2874,7 +3213,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.c
+
+ if (mds_file)
+ free(mds_file);
-+ for (i = 0; i < MAX_OSTS; i++) {
++ for (i = 0; i < LOV_MAX_OSTS; i++) {
+ if (ost_files[i])
+ free(ost_files[i]);
+ }
@@ -2891,10 +3230,10 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.c
+ return !!fixed;
+ }
+}
-Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.h
+Index: e2fsprogs-1.41.5/e2fsck/lfsck.h
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ldiskfsprogs-1.40.11/e2fsck/lfsck.h 2008-09-05 15:01:30.000000000 +0200
+--- /dev/null
++++ e2fsprogs-1.41.5/e2fsck/lfsck.h
@@ -0,0 +1,221 @@
+#undef PACKAGE
+#undef VERSION
@@ -2962,10 +3301,10 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.h
+#define OBD_INCOMPAT_OST 0x00000002 /* this is an OST */
+#define OBD_INCOMPAT_MDT 0x00000004 /* this is an MDS */
+
-+/* XXX - Not permanent, change */
-+#define MAX_OSTS 1000
++#define LOV_MAX_OSTS 2048 /* XXX - Not permanent, change */
+#define LOV_EA_SIZE(lum, num) (sizeof(*lum) + num * sizeof(*lum->lmm_objects))
-+#define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, MAX_OSTS)
++#define LOV_MAX_STRIPE_COUNT 160
++#define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, LOV_MAX_STRIPE_COUNT)
+
+/*XXX*/
+#define STRTOUL strtoul
@@ -2998,9 +3337,9 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.h
+ __u64 mds_max_files;
+ __u32 mds_num_osts;
+ __u32 mds_unused;
-+ __u64 mds_max_ost_id[MAX_OSTS];
++ __u64 mds_max_ost_id[LOV_MAX_OSTS];
+ struct obd_uuid mds_uuid;
-+ struct obd_uuid mds_ost_info[MAX_OSTS];
++ struct obd_uuid mds_ost_info[LOV_MAX_OSTS];
+};
+
+struct lfsck_ost_hdr {
@@ -3117,10 +3456,10 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck.h
+#endif /* ENABLE_LFSCK */
+
+#endif /* LFSCK_H */
-Index: ldiskfsprogs-1.40.11/e2fsck/lfsck_common.c
+Index: e2fsprogs-1.41.5/e2fsck/lfsck_common.c
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ldiskfsprogs-1.40.11/e2fsck/lfsck_common.c 2008-09-05 15:01:30.000000000 +0200
+--- /dev/null
++++ e2fsprogs-1.41.5/e2fsck/lfsck_common.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004 Hewlett-Packard Co.
@@ -3445,71 +3784,11 @@ Index: ldiskfsprogs-1.40.11/e2fsck/lfsck_common.c
+ }
+}
+#endif
-Index: ldiskfsprogs-1.40.11/e2fsck/pass1.c
+Index: e2fsprogs-1.41.5/e2fsck/pass6.c
===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/pass1.c 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/pass1.c 2008-09-05 15:01:30.000000000 +0200
-@@ -49,6 +49,7 @@
- #include "e2fsck.h"
- #include <ext2fs/ext2_ext_attr.h>
- #include <ext2fs/ext3_extents.h>
-+#include "lfsck.h"
-
- #include "problem.h"
-
-@@ -310,6 +311,9 @@
- goto fix;
- }
-
-+ e2fsck_lfsck_found_ea(ctx, pctx->ino, inode, entry,
-+ start + entry->e_value_offs);
-+
- remain -= entry->e_value_size;
-
- entry = EXT2_EXT_ATTR_NEXT(entry);
-@@ -801,6 +805,12 @@
- ext2fs_mark_block_bitmap(ctx->block_found_map,
- fs->super->s_mmp_block);
-
-+ if (!(ctx->options & E2F_OPT_READONLY) &&
-+ (ctx->lustre_devtype & LUSTRE_TYPE) == LUSTRE_MDS) {
-+ if (e2fsck_lfsck_remove_pending(ctx, NULL))
-+ return;
-+ }
-+
- while (1) {
- if (ino % EXT2_MMP_INODE_INTERVAL == 0) {
- errcode_t error;
-@@ -1310,6 +1320,9 @@
- }
- e2fsck_pass1_dupblocks(ctx, block_buf);
- }
-+
-+ e2fsck_lfsck_flush_ea(ctx);
-+
- ext2fs_free_mem(&inodes_to_process);
- endit:
- e2fsck_use_inode_shortcuts(ctx, 0);
-@@ -1718,6 +1731,14 @@
- entry->e_hash = hash;
- }
-
-+ if (e2fsck_lfsck_found_ea(ctx, ino,
-+ (struct ext2_inode_large *)inode,
-+ entry,
-+ block_buf + entry->e_value_offs)) {
-+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-+ return 0;
-+ }
-+
- entry = EXT2_EXT_ATTR_NEXT(entry);
- }
- if (region_allocate(region, (char *)entry - (char *)header, 4)) {
-Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ ldiskfsprogs-1.40.11/e2fsck/pass6.c 2008-09-05 15:14:55.000000000 +0200
-@@ -0,0 +1,1451 @@
+--- /dev/null
++++ e2fsprogs-1.41.5/e2fsck/pass6.c
+@@ -0,0 +1,1454 @@
+/*
+ * Copyright (c) 2004 Hewlett-Packard Co.
+ */
@@ -3535,6 +3814,8 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+#include <limits.h>
+#include <stdlib.h>
+#include <assert.h>
++#include "ext2fs/ext2_fs.h"
++#include "ext2fs/ext2fs.h"
+
+#ifdef ENABLE_LFSCK
+#include "lfsck.h"
@@ -3612,7 +3893,8 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ if (rc)
+ goto out;
+
-+ lov_objids = e2fsck_allocate_memory(ctx, sizeof(*lov_objids) * MAX_OSTS,
++ lov_objids = e2fsck_allocate_memory(ctx,
++ sizeof(*lov_objids) * LOV_MAX_OSTS,
+ "lov_objids array");
+ if (lov_objids == NULL) {
+ rc = ENOMEM;
@@ -3624,7 +3906,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ goto out;
+
+ rc = ext2fs_file_read(e2_file, lov_objids,
-+ sizeof(*lov_objids) * MAX_OSTS, &got);
++ sizeof(*lov_objids) * LOV_MAX_OSTS, &got);
+ rc = ext2fs_file_close(e2_file);
+
+ outdb->ost_count = got / sizeof(*lov_objids);
@@ -3755,7 +4037,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ return rc;
+ }
+ memset(ctx->lfsck_oinfo, 0, sizeof(struct lfsck_outdb_info));
-+ rc = ext2fs_get_mem(sizeof(struct lfsck_ofile_ctx) * MAX_OSTS,
++ rc = ext2fs_get_mem(sizeof(struct lfsck_ofile_ctx)*LOV_MAX_OSTS,
+ &ctx->lfsck_oinfo->ofile_ctx);
+ if (rc) {
+ ext2fs_free_mem(&ctx->lfsck_oinfo);
@@ -3763,7 +4045,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ return rc;
+ }
+ memset(ctx->lfsck_oinfo->ofile_ctx, 0,
-+ sizeof(struct lfsck_ofile_ctx) * MAX_OSTS);
++ sizeof(struct lfsck_ofile_ctx) * LOV_MAX_OSTS);
+ if (lfsck_opendb(ctx->lustre_mdsdb, MDS_SIZEINFO,
+ &ctx->lfsck_oinfo->mds_sizeinfo_dbp, 0,
+ sizeof(mds_fid) + sizeof(szinfo), numfiles)) {
@@ -3813,8 +4095,8 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ &ctx->lfsck_oinfo->ofile_ctx[ost_idx];
+ __u64 objid = mds_md->lmm_objects[i].l_object_id;
+
-+ if (ost_idx >= MAX_OSTS) {
-+ fprintf(stderr, "bad OST index %u ino %u[%d]\n",
++ if (ost_idx >= LOV_MAX_OSTS) {
++ fprintf(stderr, "invalid OST index %u ino %u[%d]\n",
+ ost_idx, ino, i);
+ continue;
+ }
@@ -4123,14 +4405,14 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ if (rc != DB_KEYEXIST) {
+ fprintf(stderr,
+ "error adding MDS inode %.*s (inum %u): %s\n",
-+ dirent->name_len, dirent->name, dirent->inode,
++ dirent->name_len & 0xFF, dirent->name, dirent->inode,
+ db_strerror(rc));
+ lctx->ctx->flags |= E2F_FLAG_ABORT;
+ return (DIRENT_ABORT);
+ }
+ fprintf(stderr,
+ "warning MDS inode %.*s (inum %u): %s hard link?\n",
-+ dirent->name_len, dirent->name, dirent->inode,
++ dirent->name_len & 0xFF, dirent->name, dirent->inode,
+ db_strerror(rc));
+ }
+ if (dirent2->file_type == EXT2_FT_DIR) {
@@ -4830,7 +5112,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ goto out;
+ }
+ memset(ctx->lfsck_oinfo, 0, sizeof(struct lfsck_outdb_info));
-+ rc = ext2fs_get_mem(sizeof(struct lfsck_ofile_ctx) * MAX_OSTS,
++ rc = ext2fs_get_mem(sizeof(struct lfsck_ofile_ctx)*LOV_MAX_OSTS,
+ &ctx->lfsck_oinfo->ofile_ctx);
+ if (rc) {
+ ext2fs_free_mem(&ctx->lfsck_oinfo);
@@ -4839,7 +5121,7 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ goto out;
+ }
+ memset(ctx->lfsck_oinfo->ofile_ctx, 0,
-+ sizeof(struct lfsck_ofile_ctx) * MAX_OSTS);
++ sizeof(struct lfsck_ofile_ctx) * LOV_MAX_OSTS);
+ }
+
+ if (!(ctx->options & E2F_OPT_READONLY)) {
@@ -4961,296 +5243,3 @@ Index: ldiskfsprogs-1.40.11/e2fsck/pass6.c
+ return;
+}
+#endif /* ENABLE_LFSCK */
-Index: ldiskfsprogs-1.40.11/e2fsck/unix.c
-===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsck/unix.c 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsck/unix.c 2008-09-05 15:01:30.000000000 +0200
-@@ -45,6 +45,9 @@
- #ifdef HAVE_DIRENT_H
- #include <dirent.h>
- #endif
-+#ifdef HAVE_LIMITS_H
-+#include <limits.h>
-+#endif
-
- #include "e2p/e2p.h"
- #include "et/com_err.h"
-@@ -52,6 +55,17 @@
- #include "problem.h"
- #include "../version.h"
-
-+#include "lfsck.h"
-+
-+static struct option long_options[] = {
-+#ifdef ENABLE_LFSCK
-+ { "mdsdb", 1, NULL, 1 },
-+ { "mdtdb", 1, NULL, 1 },
-+ { "ostdb", 1, NULL, 2 },
-+#endif
-+ { 0, 0, 0, 0 }
-+};
-+
- /* Command line options */
- static int swapfs;
- static int normalize_swapfs;
-@@ -299,6 +313,15 @@
- fs->super->s_checkinterval*2))
- reason = 0;
- }
-+#ifdef ENABLE_LFSCK
-+ if (ctx->lustre_devtype & LUSTRE_TYPE) {
-+ if (!reason || ctx->options & E2F_OPT_READONLY)
-+ ctx->lustre_devtype |= LUSTRE_ONLY;
-+ if (!reason)
-+ reason = _(" lustre database creation");
-+ }
-+#endif
-+
- if (reason) {
- fputs(ctx->device_name, stdout);
- printf(reason, reason_arg);
-@@ -332,6 +355,13 @@
- fputc('\n', stdout);
- ext2fs_close(fs);
- ctx->fs = NULL;
-+ if (ctx->lustre_mdsdb)
-+ free(ctx->lustre_mdsdb);
-+ if (ctx->lustre_ostdb)
-+ free(ctx->lustre_ostdb);
-+ if (ctx->lfsck_oinfo)
-+ e2fsck_lfsck_cleanupdb(ctx);
-+
- e2fsck_free_context(ctx);
- exit(FSCK_OK);
- }
-@@ -662,6 +692,31 @@
- }
- }
-
-+static char *my_dirname(char *path)
-+{
-+
-+ if (path != NULL) {
-+ char *tmp = strrchr(path, '/');
-+ if (tmp != NULL) {
-+ *tmp = '\0';
-+ return path;
-+ }
-+ }
-+
-+ return ".";
-+}
-+
-+static const char *my_basename(const char *path)
-+{
-+ if (path != NULL) {
-+ char *tmp = strrchr(path, '/');
-+ if (tmp != NULL)
-+ return tmp + 1;
-+ }
-+
-+ return path;
-+}
-+
- static void syntax_err_report(const char *filename, long err, int line_num)
- {
- fprintf(stderr,
-@@ -676,6 +731,7 @@
- {
- int flush = 0;
- int c, fd;
-+ int option_index;
- #ifdef MTRACE
- extern void *mallwatch;
- #endif
-@@ -724,8 +780,73 @@
- ctx->inode_badness_threshold = BADNESS_THRESHOLD;
- ctx->now_tolerance_val = 172800; /* Two days */
-
-- while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
-+ ctx->lustre_devtype = LUSTRE_NULL;
-+
-+ while ((c = getopt_long(argc, argv,
-+ "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk",
-+ long_options, &option_index)) != EOF)
- switch (c) {
-+ case 1: {
-+ char *dbpath, *tmp;
-+
-+ if (!optarg)
-+ usage(ctx);
-+
-+ dbpath = malloc(PATH_MAX);
-+ if (dbpath == NULL) {
-+ fprintf(stderr, "Out of memory\n");
-+ exit(1);
-+ }
-+ tmp = malloc(PATH_MAX);
-+ if (tmp == NULL) {
-+ fprintf(stderr, "Out of memory\n");
-+ exit(1);
-+ }
-+
-+ strcpy(tmp, optarg);
-+ if (realpath(my_dirname(tmp), dbpath) == NULL) {
-+ fprintf(stderr, "Failure to resolve path %s\n",
-+ optarg);
-+ exit(1);
-+ }
-+
-+ strcpy(tmp, optarg);
-+ sprintf(dbpath+strlen(dbpath), "/%s", my_basename(tmp));
-+ ctx->lustre_mdsdb = dbpath;
-+ ctx->lustre_devtype |= LUSTRE_MDS;
-+
-+ free(tmp);
-+ break;
-+ }
-+ case 2: {
-+ char *dbpath, *tmp;
-+
-+ dbpath = malloc(PATH_MAX);
-+ if (dbpath == NULL) {
-+ fprintf(stderr, "Out of memory\n");
-+ exit(1);
-+ }
-+ tmp = malloc(PATH_MAX);
-+ if (tmp == NULL) {
-+ fprintf(stderr, "Out of memory\n");
-+ exit(1);
-+ }
-+
-+ strcpy(tmp, optarg);
-+ if (realpath(my_dirname(tmp), dbpath) == NULL) {
-+ fprintf(stderr, "Failure to resolve path %s\n",
-+ optarg);
-+ exit(1);
-+ }
-+
-+ strcpy(tmp, optarg);
-+ sprintf(dbpath+strlen(dbpath), "/%s", my_basename(tmp));
-+ ctx->lustre_ostdb = dbpath;
-+ ctx->lustre_devtype |= LUSTRE_OST;
-+
-+ free(tmp);
-+ break;
-+ }
- case 'C':
- ctx->progress = e2fsck_update_progress;
- res = sscanf(optarg, "%d", &ctx->progress_fd);
-@@ -832,6 +953,7 @@
- break;
- case 'v':
- verbose = 1;
-+ ctx->options |= E2F_OPT_VERBOSE;
- break;
- case 'V':
- show_version_only = 1;
-@@ -864,6 +986,14 @@
- default:
- usage(ctx);
- }
-+ if (ctx->lustre_devtype) {
-+ if ((ctx->lustre_devtype != LUSTRE_MDS) &&
-+ ctx->lustre_devtype != (LUSTRE_MDS | LUSTRE_OST)) {
-+ com_err(ctx->program_name, 0,
-+ _("must specify --mdsdb with --ostdb"));
-+ usage(ctx);
-+ }
-+ }
- if (show_version_only)
- return 0;
- if (optind != argc - 1)
-@@ -1559,6 +1689,12 @@
- ext2fs_close(fs);
- ctx->fs = NULL;
- free(ctx->journal_name);
-+ if (ctx->lfsck_oinfo)
-+ e2fsck_lfsck_cleanupdb(ctx);
-+ if (ctx->lustre_mdsdb)
-+ free(ctx->lustre_mdsdb);
-+ if (ctx->lustre_ostdb)
-+ free(ctx->lustre_ostdb);
-
- #ifdef RESOURCE_TRACK
- if (ctx->options & E2F_OPT_TIME)
-Index: ldiskfsprogs-1.40.11/misc/mke2fs.c
-===================================================================
---- ldiskfsprogs-1.40.11.orig/misc/mke2fs.c 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/misc/mke2fs.c 2008-09-05 15:01:30.000000000 +0200
-@@ -1166,7 +1166,7 @@
- }
- break;
- case 'v':
-- verbose = 1;
-+ verbose++;
- break;
- case 'F':
- force++;
-Index: ldiskfsprogs-1.40.11/util/subst.conf.in
-===================================================================
---- ldiskfsprogs-1.40.11.orig/util/subst.conf.in 2008-09-05 14:42:07.000000000 +0200
-+++ ldiskfsprogs-1.40.11/util/subst.conf.in 2008-09-05 15:14:55.000000000 +0200
-@@ -5,6 +5,8 @@
- E2FSPROGS_MONTH @E2FSPROGS_MONTH@
- E2FSPROGS_YEAR @E2FSPROGS_YEAR@
- E2FSPROGS_VERSION @E2FSPROGS_VERSION@
-+LFSCK_CMT @LFSCK_CMT@
-+LFSCK_MAN @LFSCK_MAN@
- SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@
- SIZEOF_LONG @SIZEOF_LONG@
- SIZEOF_INT @SIZEOF_INT@
-Index: ldiskfsprogs-1.40.11/e2fsprogs.spec.in
-===================================================================
---- ldiskfsprogs-1.40.11.orig/e2fsprogs.spec.in 2008-09-05 15:01:30.000000000 +0200
-+++ ldiskfsprogs-1.40.11/e2fsprogs.spec.in 2008-09-05 15:14:55.000000000 +0200
-@@ -10,17 +10,21 @@
- License: GPLv2
- Group: System Environment/Base
- Source: ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/e2fsprogs-%{version}.tar.gz
--Url: http://e2fsprogs.sourceforge.net/
-+Url: ftp://ftp.lustre.org/pub/lustre/other/e2fsprogs/
- Prereq: /sbin/ldconfig
- BuildRoot: %{_tmppath}/%{name}-root
- %if %{_vendor} == "suse"
- Group: System/Filesystems
--Provides: e2fsbn ext2fs libcom_err = %{version}
-+ at LFSCK_CMT@Requires: db >= @DB4VERSION@
-+ at LFSCK_CMT@BuildRequires: db-devel >= 4.1 texinfo
-+Provides: e2fsbn ext2fs libcom_err = %{version} ldiskfsprogs
- Obsoletes: ext2fs libcom_err < %{version}
- %else
- Group: System Environment/Base
-+ at LFSCK_CMT@Requires: db4 >= @DB4VERSION@
-+ at LFSCK_CMT@BuildRequires: db4-devel >= 4.1 texinfo
- Obsoletes: e2fsprogs-libs < %{version}
--Provides: e2fsprogs-libs = %{version}
-+Provides: e2fsprogs-libs = %{version} ldiskfsprogs
- %endif
-
- %description
-@@ -71,7 +75,7 @@
- %setup
-
- %build
--%configure --enable-elf-shlibs --enable-nls \
-+%configure --enable-elf-shlibs --enable-nls @LFSCK_CMT@ --enable-lfsck \
- %{?extra_config_flags:%extra_config_flags}
- make
- make check
-@@ -139,6 +143,7 @@
- %{_sbindir}/filefrag
- %{_sbindir}/mklost+found
- %{_sbindir}/e2freefrag
-+ at LFSCK_CMT@%{_sbindir}/lfsck
-
- %{_root_libdir}/libblkid.so.*
- %{_root_libdir}/libcom_err.so.*
-@@ -164,6 +169,7 @@
- %{_mandir}/man8/debugfs.8*
- %{_mandir}/man8/dumpe2fs.8*
- %{_mandir}/man8/e2fsck.8*
-+ at LFSCK_CMT@%{_mandir}/man8/lfsck.8*
- %{_mandir}/man8/findfs.8*
- %{_mandir}/man8/fsck.ext2.8*
- %{_mandir}/man8/fsck.ext3.8*
diff --git a/debian/patches/e2fsprogs-lts-make_rpms.patch b/debian/patches/e2fsprogs-lts-make_rpms.patch
deleted file mode 100644
index 3ebc4f1..0000000
--- a/debian/patches/e2fsprogs-lts-make_rpms.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-Allow "make rpm" to take some extra configure options from the build
-environment without having to patch the code.
-
-Build the tarball in a temporary directory instead of the e2fsprogs
-source directory.
-
-Signed-off-by: Michael MacDonald <Michael.Macdonald at Sun.COM>
-Signed-off-by: Andreas Dilger <adilger at sun.com>
-
-diff -Naur e2fsprogs-1.40.2/contrib/build-rpm e2fsprogs-1.40.2.new/contrib/build-rpm
---- e2fsprogs-1.40.2/contrib/build-rpm 2007-06-30 08:58:34.000000000 -0400
-+++ e2fsprogs-1.40.2.new/contrib/build-rpm 2007-12-21 12:49:43.000000000 -0500
-@@ -1,5 +1,10 @@
- #!/bin/sh
-
-+# enable xtrace output if requested
-+if [ -n ${ENABLE_XTRACE:-''} ]; then
-+ set -x
-+fi
-+
- # Build an e2fsprogs RPM from cvs
-
- pwd=`pwd`
-@@ -8,8 +13,11 @@
- pkgvers=`grep Version: e2fsprogs.spec | awk '{print $2;}'`
- builddir=${pkgname}-${pkgvers}
-
-+# ensure that $TMP is set to something
-+TMP=${TMP:-'/tmp'}
-+
- cd ..
--tmpdir=`mktemp -d rpmtmp.XXXXXX`
-+tmpdir=`mktemp -d ${RPM_TMPDIR:-$TMP}/rpmtmp.XXXXXX`
-
- # We need to build a tarball for the SRPM using $builddir as the
- # directory name (since that's what RPM will expect it to unpack
-@@ -25,10 +33,13 @@
- (cd $tmpdir && tar czfh ${builddir}.tar.gz $EXCLUDE $builddir)
-
- [ "`rpmbuild --version 2> /dev/null`" ] && RPM=rpmbuild || RPM=rpm
--$RPM --define "_sourcedir `pwd`/$tmpdir" -ba $currdir/e2fsprogs.spec
--
--ret=$?
--rm -rf $tmpdir
--exit $?
-
-+$RPM --define "_sourcedir $tmpdir" \
-+ --define "_topdir ${RPM_TOPDIR:-$(rpm -E %_topdir)}" \
-+ --define "_tmpdir ${RPM_TMPDIR:-$TMP}" \
-+ --define "extra_config_flags ${EXTRA_CONFIG_FLAGS:-''}" \
-+ -ba $currdir/e2fsprogs.spec
-
-+rpm_exit=$?
-+rm -rf $tmpdir
-+exit $rpm_exit
-diff -Naur e2fsprogs-1.40.2/e2fsprogs.spec.in e2fsprogs-1.40.2.new/e2fsprogs.spec.in
---- e2fsprogs-1.40.2/e2fsprogs.spec.in 2007-12-12 22:48:29.000000000 -0500
-+++ e2fsprogs-1.40.2.new/e2fsprogs.spec.in 2007-12-21 12:39:11.000000000 -0500
-@@ -50,7 +50,8 @@
- %setup
-
- %build
--%configure --enable-elf-shlibs --enable-nls
-+%configure --enable-elf-shlibs --enable-nls \
-+ %{?extra_config_flags:%extra_config_flags}
- make
-
- %install
diff --git a/debian/patches/e2fsprogs-misc.patch b/debian/patches/e2fsprogs-misc.patch
index cb5e43f..4cd8105 100644
--- a/debian/patches/e2fsprogs-misc.patch
+++ b/debian/patches/e2fsprogs-misc.patch
@@ -1,84 +1,10 @@
-For removing some warnings.
+For removing some warnings. And some fixes which are already upstream.
-Index: e2fsprogs-1.40.7/e2fsck/unix.c
+Index: e2fsprogs-1.41.6/lib/ext2fs/dblist.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.7/e2fsck/unix.c
-@@ -46,6 +46,7 @@ extern int optind;
- #include <dirent.h>
- #endif
-
-+#include "e2p/e2p.h"
- #include "et/com_err.h"
- #include "e2fsck.h"
- #include "problem.h"
-Index: e2fsprogs-cfs/e2fsck/problem.c
-===================================================================
---- e2fsprogs-cfs.orig/e2fsck/problem.c
-+++ e2fsprogs-cfs/e2fsck/problem.c
-@@ -591,12 +591,12 @@ static struct e2fsck_problem problem_tab
- N_("@A @b @B (%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
-- /* Error allocating icount structure */
-+ /* Error allocating icount link information */
- { PR_1_ALLOCATE_ICOUNT,
- N_("@A icount link information: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
-- /* Error allocating dbcount */
-+ /* Error allocating directory block array */
- { PR_1_ALLOCATE_DBCOUNT,
- N_("@A @d @b array: %m\n"),
- PROMPT_NONE, PR_FATAL },
-Index: e2fsprogs-1.40.7/e2fsck/super.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/super.c
-+++ e2fsprogs-1.40.7/e2fsck/super.c
-@@ -797,7 +797,6 @@ int check_backup_super_block(e2fsck_t ct
- {
- ext2_filsys fs = ctx->fs;
- ext2_filsys tfs = 0;
-- io_manager io_ptr;
- errcode_t retval;
- dgrp_t g;
- blk_t sb;
-Index: e2fsprogs-1.40.7/lib/blkid/read.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/blkid/read.c
-+++ e2fsprogs-1.40.7/lib/blkid/read.c
-@@ -10,6 +10,8 @@
- * %End-Header%
- */
-
-+#define _XOPEN_SOURCE 600 /* for inclusion of strtoull */
-+
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
-@@ -26,7 +28,6 @@
- #include "uuid/uuid.h"
-
- #ifdef HAVE_STRTOULL
--#define __USE_ISOC9X
- #define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */
- #else
- /* FIXME: need to support real strtoull here */
-@@ -319,8 +320,7 @@ static int parse_tag(blkid_cache cache,
- else if (!strcmp(name, "PRI"))
- dev->bid_pri = strtol(value, 0, 0);
- else if (!strcmp(name, "TIME"))
-- /* FIXME: need to parse a long long eventually */
-- dev->bid_time = strtol(value, 0, 0);
-+ dev->bid_time = STRTOULL(value, 0, 0);
- else
- ret = blkid_set_tag(dev, name, value, strlen(value));
-
-Index: e2fsprogs-cfs/lib/ext2fs/dblist.c
-===================================================================
---- e2fsprogs-cfs.orig/lib/ext2fs/dblist.c
-+++ e2fsprogs-cfs/lib/ext2fs/dblist.c
-@@ -168,7 +168,7 @@ errcode_t ext2fs_add_dir_block(ext2_dbli
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/dblist.c 2009-06-09 10:19:48.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/dblist.c 2009-06-09 10:19:54.000000000 -0400
+@@ -169,7 +169,7 @@ errcode_t ext2fs_add_dir_block(ext2_dbli
sizeof(struct ext2_db_entry),
&dblist->list);
if (retval) {
@@ -87,20 +13,20 @@ Index: e2fsprogs-cfs/lib/ext2fs/dblist.c
return retval;
}
}
-Index: e2fsprogs-1.40.7/misc/badblocks.c
+Index: e2fsprogs-1.41.6/misc/badblocks.c
===================================================================
---- e2fsprogs-1.40.7.orig/misc/badblocks.c
-+++ e2fsprogs-1.40.7/misc/badblocks.c
-@@ -825,7 +825,7 @@ int main (int argc, char ** argv)
+--- e2fsprogs-1.41.6.orig/misc/badblocks.c 2009-06-09 10:19:48.000000000 -0400
++++ e2fsprogs-1.41.6/misc/badblocks.c 2009-06-09 10:19:54.000000000 -0400
+@@ -969,7 +969,7 @@ int main (int argc, char ** argv)
FILE * in = NULL;
int block_size = 1024;
- unsigned long blocks_at_once = 64;
-- blk_t last_block, from_count;
-+ unsigned long last_block, from_count;
+ unsigned int blocks_at_once = 64;
+- blk_t last_block, first_block;
++ unsigned long last_block, first_block;
int num_passes = 0;
int passes_clean = 0;
int dev;
-@@ -973,9 +973,10 @@ int main (int argc, char ** argv)
+@@ -1109,9 +1109,10 @@ int main (int argc, char ** argv)
usage();
device_name = argv[optind++];
if (optind > argc - 1) {
@@ -112,53 +38,33 @@ Index: e2fsprogs-1.40.7/misc/badblocks.c
if (errcode == EXT2_ET_UNIMPLEMENTED) {
com_err(program_name, 0,
_("Couldn't determine device size; you "
-@@ -987,14 +988,15 @@ int main (int argc, char ** argv)
+@@ -1123,6 +1124,7 @@ int main (int argc, char ** argv)
_("while trying to determine device size"));
exit(1);
}
+ last_block = device_size;
} else {
errno = 0;
- last_block = strtoul (argv[optind], &tmp, 0);
- printf("last_block = %d (%s)\n", last_block, argv[optind]);
- if (*tmp || errno ||
- (last_block == ULONG_MAX && errno == ERANGE)) {
-- com_err (program_name, 0, _("invalid blocks count - %s"),
-- argv[optind]);
-+ com_err(program_name, 0, _("invalid blocks count - %s"),
-+ argv[optind]);
- exit (1);
- }
- last_block++;
-@@ -1006,14 +1008,15 @@ int main (int argc, char ** argv)
- printf("from_count = %d\n", from_count);
- if (*tmp || errno ||
- (from_count == ULONG_MAX && errno == ERANGE)) {
-- com_err (program_name, 0, _("invalid starting block - %s"),
-- argv[optind]);
-+ com_err(program_name, 0,
-+ _("invalid starting block - %s"), argv[optind]);
- exit (1);
- }
- } else from_count = 0;
- if (from_count >= last_block) {
-- com_err (program_name, 0, _("invalid starting block (%d): must be less than %lu"),
-- (unsigned long) from_count, (unsigned long) last_block);
-+ com_err(program_name, 0,
-+ _("invalid starting block (%lu): must be less than %lu"),
-+ from_count, last_block);
- exit (1);
- }
- if (w_flag)
-Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ last_block = parse_uint(argv[optind], _("last block"));
+Index: e2fsprogs-1.41.6/misc/tune2fs.c
===================================================================
---- e2fsprogs-1.40.7.orig/misc/tune2fs.c
-+++ e2fsprogs-1.40.7/misc/tune2fs.c
-@@ -311,7 +311,6 @@ static void update_mntopts(ext2_filsys f
- static void update_feature_set(ext2_filsys fs, char *features)
- {
- struct ext2_super_block *sb= fs->super;
-- __u32 old_compat, old_incompat, old_ro_compat;
- __u32 old_features[3];
- int type_err;
- unsigned int mask_err;
+--- e2fsprogs-1.41.6.orig/misc/tune2fs.c 2009-06-09 10:19:48.000000000 -0400
++++ e2fsprogs-1.41.6/misc/tune2fs.c 2009-06-09 10:19:54.000000000 -0400
+@@ -1570,6 +1570,17 @@ retry_open:
+ sb = fs->super;
+ fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
+
++ /* Warn if file system needs recovery and we have opened it for writing.
++ */
++ if ((open_flag & EXT2_FLAG_RW)
++ && (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)
++ && (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
++ fprintf(stderr, _("Warning: needs_recovery flag is set."
++ "You may wish to\n replay the journal then rerun "
++ "this command, otherwise any changes may\n"
++ "be overwritten by journal data later.\n"));
++ }
++
+ if (print_label) {
+ /* For e2label emulation */
+ printf("%.*s\n", (int) sizeof(sb->s_volume_name),
diff --git a/debian/patches/e2fsprogs-mmp.patch b/debian/patches/e2fsprogs-mmp.patch
index e1e49b4..1f3c5b7 100644
--- a/debian/patches/e2fsprogs-mmp.patch
+++ b/debian/patches/e2fsprogs-mmp.patch
@@ -13,41 +13,35 @@ information to the sysadmin in case of conflict.
Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-Index: e2fsprogs-1.40.7/lib/e2p/feature.c
+Index: e2fsprogs-1.41.6/lib/e2p/feature.c
===================================================================
---- e2fsprogs-1.40.7.orig/lib/e2p/feature.c
-+++ e2fsprogs-1.40.7/lib/e2p/feature.c
-@@ -67,6 +67,8 @@ static struct feature feature_list[] = {
- "extent" },
+--- e2fsprogs-1.41.6.orig/lib/e2p/feature.c 2009-02-14 08:49:08.000000000 -0500
++++ e2fsprogs-1.41.6/lib/e2p/feature.c 2009-06-10 08:02:29.000000000 -0400
+@@ -72,7 +72,9 @@ static struct feature feature_list[] = {
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
"64bit" },
-+ { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
+ { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
+- "flex_bg"},
++ "flex_bg"},
++ { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
+ "mmp" },
{ 0, 0, 0 },
};
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2_fs.h
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
-@@ -594,11 +594,11 @@ struct ext2_super_block {
- __u16 s_min_extra_isize; /* All inodes have at least # bytes */
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2_fs.h 2009-06-10 08:01:08.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2_fs.h 2009-06-10 08:02:29.000000000 -0400
+@@ -579,7 +579,7 @@ struct ext2_super_block {
__u16 s_want_extra_isize; /* New inodes should reserve # bytes */
__u32 s_flags; /* Miscellaneous flags */
-- __u16 s_raid_stride; /* RAID stride */
+ __u16 s_raid_stride; /* RAID stride */
- __u16 s_mmp_interval; /* # seconds to wait in MMP checking */
-- __u64 s_mmp_block; /* Block for multi-mount protection */
-- __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
-- __u32 s_reserved[163]; /* Padding to the end of the block */
-+ __u16 s_raid_stride; /* RAID stride */
-+ __u16 s_mmp_update_interval; /* # seconds to wait in MMP checking */
-+ __u64 s_mmp_block; /* Block for multi-mount protection */
-+ __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
-+ __u32 s_reserved[163]; /* Padding to the end of the block */
- };
-
- /*
-@@ -664,7 +664,8 @@ struct ext2_super_block {
++ __u16 s_mmp_update_interval; /* # seconds to wait in MMP checking */
+ __u64 s_mmp_block; /* Block for multi-mount protection */
+ __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
+ __u8 s_log_groups_per_flex; /* FLEX_BG group size */
+@@ -653,7 +653,8 @@ struct ext2_super_block {
#define EXT2_FEATURE_COMPAT_SUPP 0
@@ -57,7 +51,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
-@@ -744,26 +745,34 @@ struct ext2_dir_entry_2 {
+@@ -733,26 +734,34 @@ struct ext2_dir_entry_2 {
/*
* This structure will be used for multiple mount protection. It will be
* written into the block number saved in the s_mmp_block field in the
@@ -106,11 +100,11 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
+#define EXT2_MMP_MIN_CHECK_INTERVAL 5
#endif /* _LINUX_EXT2_FS_H */
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2fs.h
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-@@ -191,6 +191,8 @@ typedef struct ext2_file *ext2_file_t;
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2fs.h 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2fs.h 2009-06-10 08:02:29.000000000 -0400
+@@ -172,6 +172,8 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_EXCLUSIVE 0x4000
#define EXT2_FLAG_SOFTSUPP_FEATURES 0x8000
#define EXT2_FLAG_NOFREE_ON_ERROR 0x10000
@@ -119,7 +113,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
/*
* Special flag in the ext2 inode i_flag field that means that this is
-@@ -205,6 +207,15 @@ typedef struct ext2_file *ext2_file_t;
+@@ -186,6 +188,15 @@ typedef struct ext2_file *ext2_file_t;
*/
#define EXT2_MKJOURNAL_V1_SUPER 0x0000001
@@ -135,80 +129,86 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
struct struct_ext2_filsys {
errcode_t magic;
io_channel io;
-@@ -248,6 +259,16 @@ struct struct_ext2_filsys {
- */
- struct ext2_inode_cache *icache;
+@@ -231,6 +242,19 @@ struct struct_ext2_filsys {
io_channel image_io;
-+
-+ /*
+
+ /*
+ * Buffers for Multiple mount protection(MMP) block.
+ */
-+ char *mmp_buf;
-+ char *mmp_cmp;
++ void *mmp_buf;
++ void *mmp_unaligned_buf;
++ void *mmp_cmp;
++ int mmp_fd;
++
+ /*
+ * Time at which e2fsck last updated the MMP block.
+ */
+ long mmp_last_written;
- };
-
- #if EXT2_FLAT_INCLUDES
-@@ -463,14 +484,16 @@ typedef struct ext2_icount *ext2_icount_
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
++
++ /*
+ * More callback functions
+ */
+ errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal,
+@@ -528,14 +552,16 @@ typedef struct ext2_icount *ext2_icount_
EXT2_FEATURE_INCOMPAT_META_BG|\
EXT3_FEATURE_INCOMPAT_RECOVER|\
-- EXT3_FEATURE_INCOMPAT_EXTENTS)
-+ EXT3_FEATURE_INCOMPAT_EXTENTS|\
+ EXT3_FEATURE_INCOMPAT_EXTENTS|\
+- EXT4_FEATURE_INCOMPAT_FLEX_BG)
++ EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+ EXT4_FEATURE_INCOMPAT_MMP)
-
#else
#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
EXT2_FEATURE_INCOMPAT_META_BG|\
EXT3_FEATURE_INCOMPAT_RECOVER|\
-- EXT3_FEATURE_INCOMPAT_EXTENTS)
-+ EXT3_FEATURE_INCOMPAT_EXTENTS|\
+ EXT3_FEATURE_INCOMPAT_EXTENTS|\
+- EXT4_FEATURE_INCOMPAT_FLEX_BG)
++ EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+ EXT4_FEATURE_INCOMPAT_MMP)
#endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
-@@ -966,6 +989,15 @@ errcode_t ext2fs_link(ext2_filsys fs, ex
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
+@@ -1106,6 +1132,16 @@ errcode_t ext2fs_link(ext2_filsys fs, ex
errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
ext2_ino_t ino, int flags);
+/* mmp.c */
-+errcode_t ext2fs_mmp_read(ext2_filsys fs, blk_t mmp_blk, char *buf);
-+errcode_t ext2fs_mmp_write(ext2_filsys fs, blk_t mmp_blk, char *buf);
++errcode_t ext2fs_mmp_read(ext2_filsys fs, blk_t mmp_blk, void *buf);
++errcode_t ext2fs_mmp_write(ext2_filsys fs, blk_t mmp_blk, void *buf);
++errcode_t ext2fs_mmp_clear(ext2_filsys fs);
+errcode_t ext2fs_mmp_init(ext2_filsys fs);
+errcode_t ext2fs_mmp_start(ext2_filsys fs);
+errcode_t ext2fs_mmp_update(ext2_filsys fs);
+errcode_t ext2fs_mmp_stop(ext2_filsys fs);
-+long int ext2fs_mmp_new_seq();
++unsigned ext2fs_mmp_new_seq();
+
/* read_bb.c */
extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
ext2_badblocks_list *bb_list);
-@@ -1014,6 +1046,7 @@ extern void ext2fs_swap_inode(ext2_filsy
- extern void ext2fs_swap_extent_header(struct ext3_extent_header *eh);
- extern void ext2fs_swap_extent_index(struct ext3_extent_idx *ix);
- extern void ext2fs_swap_extent(struct ext3_extent *ex);
+@@ -1140,6 +1176,7 @@ extern void ext2fs_swap_inode_full(ext2_
+ int bufsize);
+ extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder);
+extern void ext2fs_swap_mmp(struct mmp_struct *mmp);
/* valid_blk.c */
extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
-Index: e2fsprogs-1.40.7/misc/tune2fs.c
+Index: e2fsprogs-1.41.6/misc/tune2fs.c
===================================================================
---- e2fsprogs-1.40.7.orig/misc/tune2fs.c
-+++ e2fsprogs-1.40.7/misc/tune2fs.c
-@@ -70,7 +70,7 @@ char * device_name;
- char * new_label, *new_last_mounted, *new_UUID;
- char * io_options;
+--- e2fsprogs-1.41.6.orig/misc/tune2fs.c 2009-06-09 10:19:54.000000000 -0400
++++ e2fsprogs-1.41.6/misc/tune2fs.c 2009-06-10 08:02:29.000000000 -0400
+@@ -64,8 +64,9 @@ char *device_name;
+ char *new_label, *new_last_mounted, *new_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, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
+static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag, p_flag;
+ static int I_flag;
++static int clear_mmp;
static time_t last_check_time;
static int print_label;
static int max_mount_count, mount_count, mount_flags;
-@@ -79,6 +79,7 @@ static double reserved_ratio;
+@@ -74,6 +75,7 @@ static double reserved_ratio;
static unsigned long resgid, resuid;
static unsigned short errors;
static int open_flag;
@@ -216,52 +216,36 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
static char *features_cmd;
static char *mntopts_cmd;
static int stride, stripe_width;
-@@ -95,16 +96,14 @@ void do_findfs(int argc, char **argv);
- static void usage(void)
- {
- fprintf(stderr,
-- _("Usage: %s [-c max_mounts_count] [-e errors_behavior] "
-- "[-g group]\n"
-- "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n"
-- "\t[-m reserved_blocks_percent] "
+@@ -106,7 +108,7 @@ static void usage(void)
+ "[-g group]\n"
+ "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n"
+ "\t[-m reserved_blocks_percent] "
- "[-o [^]mount_options[,...]] \n"
-- "\t[-r reserved_blocks_count] [-u user] [-C mount_count] "
-- "[-L volume_label]\n"
-- "\t[-M last_mounted_dir] [-O [^]feature[,...]]\n"
-- "\t[-E extended-option[,...]] [-T last_check_time] "
-- "[-U UUID] device\n"), program_name);
-+ _("Usage: %s [-c max_mounts_count] [-C mount_count]\n"
-+ "\t[-e errors_behavior] [-E extended-option[,...]] [-f] [-g group]\n"
-+ "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l] [-L volume_label]\n"
-+ "\t[-m reserved_blocks_percent] [-M last_mounted_dir]\n"
-+ "\t[-o [^]mount_options[,...]] [-O [^]feature[,...]]\n"
-+ "\t[-p mmp_update_interval] [-r reserved_blocks_count]\n"
-+ "\t[-T last_check_time] [-u user] [-U UUID] device\n"),
-+ program_name);
- exit (1);
- }
-
-@@ -113,7 +112,8 @@ static __u32 ok_features[3] = {
- EXT3_FEATURE_COMPAT_HAS_JOURNAL |
- EXT2_FEATURE_COMPAT_DIR_INDEX,
++ "[-o [^]mount_options[,...]] [-p mmp_update_interval]\n"
+ "\t[-r reserved_blocks_count] [-u user] [-C mount_count] "
+ "[-L volume_label]\n"
+ "\t[-M last_mounted_dir] [-O [^]feature[,...]]\n"
+@@ -122,7 +124,8 @@ static __u32 ok_features[3] = {
/* Incompat */
-- EXT2_FEATURE_INCOMPAT_FILETYPE,
-+ EXT2_FEATURE_INCOMPAT_FILETYPE |
+ EXT2_FEATURE_INCOMPAT_FILETYPE |
+ EXT3_FEATURE_INCOMPAT_EXTENTS |
+- EXT4_FEATURE_INCOMPAT_FLEX_BG,
++ EXT4_FEATURE_INCOMPAT_FLEX_BG |
+ EXT4_FEATURE_INCOMPAT_MMP,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
-@@ -127,7 +127,8 @@ static __u32 clear_ok_features[3] = {
- EXT2_FEATURE_COMPAT_RESIZE_INODE |
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+@@ -139,7 +142,8 @@ static __u32 clear_ok_features[3] = {
EXT2_FEATURE_COMPAT_DIR_INDEX,
/* Incompat */
-- EXT2_FEATURE_INCOMPAT_FILETYPE,
-+ EXT2_FEATURE_INCOMPAT_FILETYPE |
+ EXT2_FEATURE_INCOMPAT_FILETYPE |
+- EXT4_FEATURE_INCOMPAT_FLEX_BG,
++ EXT4_FEATURE_INCOMPAT_FLEX_BG |
+ EXT4_FEATURE_INCOMPAT_MMP,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK |
-@@ -137,7 +138,7 @@ static __u32 clear_ok_features[3] = {
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+@@ -151,7 +155,7 @@ static __u32 clear_ok_features[3] = {
/*
* Remove an external journal from the filesystem
*/
@@ -270,7 +254,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
{
char *journal_path;
ext2_filsys jfs;
-@@ -225,13 +226,15 @@ static void remove_journal_device(ext2_f
+@@ -240,13 +244,15 @@ static void remove_journal_device(ext2_f
no_valid_journal:
if (commit_remove_journal == 0) {
fputs(_("Journal NOT removed\n"), stderr);
@@ -287,7 +271,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
/* Helper function for remove_journal_inode */
-@@ -255,31 +258,31 @@ static int release_blocks_proc(ext2_fils
+@@ -269,7 +275,7 @@ static int release_blocks_proc(ext2_fils
/*
* Remove the journal inode from the filesystem
*/
@@ -296,10 +280,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
{
struct ext2_inode inode;
errcode_t retval;
- ino_t ino = fs->super->s_journal_inum;
--
-+
- retval = ext2fs_read_inode(fs, ino, &inode);
+@@ -279,14 +285,14 @@ static void remove_journal_inode(ext2_fi
if (retval) {
com_err(program_name, retval,
_("while reading journal inode"));
@@ -314,8 +295,9 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
- exit(1);
+ return retval;
}
- retval = ext2fs_block_iterate(fs, ino, 0, NULL,
- release_blocks_proc, NULL);
+ retval = ext2fs_block_iterate(fs, ino,
+ BLOCK_FLAG_READ_ONLY, NULL,
+@@ -294,7 +300,7 @@ static void remove_journal_inode(ext2_fi
if (retval) {
com_err(program_name, retval,
_("while clearing journal inode"));
@@ -324,7 +306,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
memset(&inode, 0, sizeof(inode));
ext2fs_mark_bb_dirty(fs);
-@@ -290,31 +293,35 @@ static void remove_journal_inode(ext2_fi
+@@ -305,31 +311,35 @@ static void remove_journal_inode(ext2_fi
if (retval) {
com_err(program_name, retval,
_("while writing journal inode"));
@@ -343,13 +325,13 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
-static void update_mntopts(ext2_filsys fs, char *mntopts)
+static int update_mntopts(ext2_filsys fs, char *mntopts)
{
- struct ext2_super_block *sb= fs->super;
+ struct ext2_super_block *sb = fs->super;
if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) {
fprintf(stderr, _("Invalid mount option set: %s\n"),
mntopts);
- exit(1);
-+ return 1;
++ return 1;
}
ext2fs_mark_super_dirty(fs);
+
@@ -362,9 +344,9 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
-static void update_feature_set(ext2_filsys fs, char *features)
+static int update_feature_set(ext2_filsys fs, char *features)
{
- struct ext2_super_block *sb= fs->super;
+ struct ext2_super_block *sb = fs->super;
__u32 old_features[3];
-@@ -349,7 +356,7 @@ static void update_feature_set(ext2_fils
+@@ -364,7 +374,7 @@ static void update_feature_set(ext2_fils
fprintf(stderr, _("Setting filesystem feature '%s' "
"not supported.\n"),
e2p_feature2string(type_err, mask_err));
@@ -373,7 +355,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
-@@ -359,22 +366,96 @@ static void update_feature_set(ext2_fils
+@@ -374,22 +384,89 @@ static void update_feature_set(ext2_fils
"cleared when the filesystem is\n"
"unmounted or mounted "
"read-only.\n"), stderr);
@@ -417,15 +399,17 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ return 1;
+ }
+
++ /*
++ * We want to update group desc with the new free blocks count
++ */
++ fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
++
+ printf(_("Multiple mount protection has been enabled "
+ "with update interval %ds.\n"),
+ sb->s_mmp_update_interval);
+ }
+
+ if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP)) {
-+ blk_t mmp_block;
-+ struct mmp_struct *mmp_s;
-+ char *buf;
+ int error;
+
+ if (mount_flags & EXT2_MF_READONLY) {
@@ -441,40 +425,31 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ return 1;
+ }
+
-+ mmp_block = sb->s_mmp_block;
-+
-+ error = ext2fs_get_mem(fs->blocksize, &buf);
++ error = ext2fs_mmp_read(fs, sb->s_mmp_block, NULL);
+ if (error) {
-+ fputs(_("Error allocating memory.\n"), stderr);
-+ return 1;
-+ }
++ struct mmp_struct *mmp_cmp = fs->mmp_cmp;
+
-+ mmp_s = (struct mmp_struct *) buf;
-+ error = ext2fs_mmp_read(fs, mmp_block, buf);
-+ if (error) {
+ if (error == EXT2_ET_MMP_MAGIC_INVALID)
+ printf(_("Magic number in MMP block does not "
+ "match. expected: %x, actual: %x\n"),
-+ EXT2_MMP_MAGIC, mmp_s->mmp_magic);
++ EXT2_MMP_MAGIC, mmp_cmp->mmp_magic);
+ else
+ com_err (program_name, error,
+ _("while reading MMP block."));
+ goto mmp_error;
+ }
+
-+ ext2fs_unmark_block_bitmap(fs->block_map, mmp_block);
-+ ext2fs_mark_bb_dirty(fs);
-+
++ /* We need to force out the group descriptors as well */
++ fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
++ ext2fs_block_alloc_stats(fs, sb->s_mmp_block, -1);
+mmp_error:
+ sb->s_mmp_block = 0;
+ sb->s_mmp_update_interval = 0;
-+ if (buf)
-+ ext2fs_free_mem(&buf);
+ }
if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
/*
-@@ -418,12 +499,14 @@ static void update_feature_set(ext2_fils
+@@ -457,12 +534,14 @@ static void update_feature_set(ext2_fils
(old_features[E2P_FEATURE_INCOMPAT] != sb->s_feature_incompat) ||
(old_features[E2P_FEATURE_RO_INCOMPAT] != sb->s_feature_ro_compat))
ext2fs_mark_super_dirty(fs);
@@ -490,7 +465,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
{
unsigned long journal_blocks;
errcode_t retval;
-@@ -477,7 +560,7 @@ static void add_journal(ext2_filsys fs)
+@@ -517,7 +596,7 @@ static void add_journal(ext2_filsys fs)
fprintf(stderr, "\n");
com_err(program_name, retval,
_("\n\twhile trying to create journal file"));
@@ -499,7 +474,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
} else
fputs(_("done\n"), stdout);
/*
-@@ -488,12 +571,12 @@ static void add_journal(ext2_filsys fs)
+@@ -528,11 +607,11 @@ static void add_journal(ext2_filsys fs)
fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
}
print_check_message(fs);
@@ -507,59 +482,58 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ return 0;
err:
- if (journal_device)
- free(journal_device);
+ free(journal_device);
- exit(1);
+ return 1;
}
-@@ -560,7 +643,7 @@ static void parse_tune2fs_options(int ar
- open_flag = EXT2_FLAG_SOFTSUPP_FEATURES;
+@@ -600,7 +679,7 @@ static void parse_tune2fs_options(int ar
+ open_flag = 0;
printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
-- while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:E:J:L:M:O:T:U:")) != EOF)
-+ while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:p:r:s:u:C:E:J:L:M:O:T:U:")) != EOF)
- switch (c)
- {
- case 'c':
-@@ -715,6 +798,26 @@ static void parse_tune2fs_options(int ar
- features_cmd = optarg;
- open_flag = EXT2_FLAG_RW;
- break;
-+ case 'p':
-+ mmp_update_interval = strtol (optarg, &tmp, 0);
-+ if (*tmp && mmp_update_interval < 0) {
-+ com_err (program_name, 0, _("invalid "
-+ "mmp update interval"));
-+ usage();
-+ }
-+ if (mmp_update_interval == 0)
-+ mmp_update_interval = EXT2_MMP_UPDATE_INTERVAL;
-+ if (mmp_update_interval > EXT2_MMP_UPDATE_INTERVAL) {
-+ com_err (program_name, 0,
-+ _("MMP update interval of %s "
-+ "seconds may be dangerous "
-+ "under high load. Consider "
-+ "decreasing it."),
-+ optarg);
-+ }
-+ p_flag = 1;
-+ open_flag = EXT2_FLAG_RW;
-+ break;
- case 'r':
- reserved_blocks = strtoul (optarg, &tmp, 0);
- if (*tmp) {
-@@ -804,7 +907,7 @@ void do_findfs(int argc, char **argv)
- * enabled for tune2fs, there needs to be an explicit test for them
- * here.
- */
+- while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:E:I:J:L:M:O:T:U:")) != EOF)
++ while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:p:r:s:u:C:E:I:J:L:M:O:T:U:")) != EOF)
+ switch (c) {
+ case 'c':
+ max_mount_count = strtol(optarg, &tmp, 0);
+@@ -755,6 +834,26 @@ static void parse_tune2fs_options(int ar
+ features_cmd = optarg;
+ open_flag = EXT2_FLAG_RW;
+ break;
++ case 'p':
++ mmp_update_interval = strtol (optarg, &tmp, 0);
++ if (*tmp && mmp_update_interval < 0) {
++ com_err (program_name, 0, _("invalid "
++ "mmp update interval"));
++ usage();
++ }
++ if (mmp_update_interval == 0)
++ mmp_update_interval = EXT2_MMP_UPDATE_INTERVAL;
++ if (mmp_update_interval > EXT2_MMP_UPDATE_INTERVAL) {
++ com_err (program_name, 0,
++ _("MMP update interval of %s "
++ "seconds may be dangerous "
++ "under high load. Consider "
++ "decreasing it."),
++ optarg);
++ }
++ p_flag = 1;
++ open_flag = EXT2_FLAG_RW;
++ break;
+ case 'r':
+ reserved_blocks = strtoul(optarg, &tmp, 0);
+ if (*tmp) {
+@@ -859,7 +958,7 @@ void do_findfs(int argc, char **argv)
+ }
+ #endif
+
-static void parse_extended_opts(ext2_filsys fs, const char *opts)
+static int parse_extended_opts(ext2_filsys fs, const char *opts)
{
char *buf, *token, *next, *p, *arg;
- int len;
-@@ -815,7 +918,7 @@ static void parse_extended_opts(ext2_fil
+ int len, hash_alg;
+@@ -870,7 +969,7 @@ static void parse_extended_opts(ext2_fil
if (!buf) {
fprintf(stderr,
_("Couldn't allocate memory to parse options!\n"));
@@ -568,7 +542,24 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
strcpy(buf, opts);
for (token = buf; token && *token; token = next) {
-@@ -881,10 +984,12 @@ static void parse_extended_opts(ext2_fil
+@@ -893,6 +992,9 @@ static void parse_extended_opts(ext2_fil
+ fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
+ printf("Clearing test filesystem flag\n");
+ ext2fs_mark_super_dirty(fs);
++ } else if (strcmp(token, "clear-mmp") == 0 ||
++ strcmp(token, "clear_mmp") == 0) {
++ clear_mmp = 1;
+ } else if (strcmp(token, "stride") == 0) {
+ if (!arg) {
+ r_usage++;
+@@ -950,15 +1052,18 @@ static void parse_extended_opts(ext2_fil
+ "and may take an argument which\n"
+ "\tis set off by an equals ('=') sign.\n\n"
+ "Valid extended options are:\n"
++ "\tclear-mmp\n"
+ "\tstride=<RAID per-disk chunk size in blocks>\n"
+ "\tstripe_width=<RAID stride*data disks in blocks>\n"
+ "\thash_alg=<hash algorithm>\n"
"\ttest_fs\n"
"\t^test_fs\n"));
free(buf);
@@ -576,50 +567,90 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ return 1;
}
free(buf);
--}
+
+ return 0;
-+}
-
+ }
- int main (int argc, char ** argv)
-@@ -893,6 +998,8 @@ int main (int argc, char ** argv)
+ /*
+@@ -1496,6 +1601,8 @@ int main(int argc, char **argv)
ext2_filsys fs;
struct ext2_super_block *sb;
- io_manager io_ptr;
+ io_manager io_ptr, io_ptr_orig = NULL;
+ int rc = 0;
+ int rc2;
#ifdef ENABLE_NLS
setlocale(LC_MESSAGES, "");
-@@ -917,6 +1024,9 @@ int main (int argc, char ** argv)
- #else
- io_ptr = unix_io_manager;
- #endif
+@@ -1525,15 +1632,24 @@ int main(int argc, char **argv)
+ io_ptr = unix_io_manager;
+
+ retry_open:
+ if ((open_flag & EXT2_FLAG_RW) == 0 || f_flag)
-+ open_flag |= EXT2_FLAG_SKIP_MMP;
++ open_flag |= EXT2_FLAG_SKIP_MMP;
+
- retval = ext2fs_open2(device_name, io_options, open_flag,
+ retval = ext2fs_open2(device_name, io_options, open_flag,
0, 0, io_ptr, &fs);
- if (retval) {
-@@ -933,21 +1043,23 @@ int main (int argc, char ** argv)
- fprintf(stderr,
- _("Filesystem %s has unsupported features enabled.\n"),
+ if (retval) {
+- com_err(program_name, retval,
+- _("while trying to open %s"),
++ com_err(program_name, retval,
++ _("while trying to open %s"),
device_name);
+- fprintf(stderr,
+- _("Couldn't find valid filesystem superblock.\n"));
- exit(1);
++ if (retval == EXT2_ET_MMP_FSCK_ON)
++ fprintf(stderr,
++ _("If you are sure e2fsck is not running then "
++ "use 'tune2fs -f -E clear_mmp {device}'\n"));
++ else if (retval != EXT2_ET_MMP_FAILED)
++ fprintf(stderr,
++ _("Couldn't find valid filesystem superblock.\n"));
+ rc = 1;
+ goto closefs;
}
- if (print_label) {
- /* For e2label emulation */
+
+ if (I_flag && !io_ptr_orig) {
+@@ -1545,12 +1661,14 @@ retry_open:
+ if (new_inode_size == EXT2_INODE_SIZE(fs->super)) {
+ fprintf(stderr, _("The inode size is already %lu\n"),
+ new_inode_size);
+- exit(1);
++ rc = 1;
++ goto closefs;
+ }
+ if (new_inode_size < EXT2_INODE_SIZE(fs->super)) {
+ fprintf(stderr, _("Shrinking the inode size is "
+ "not supported\n"));
+- exit(1);
++ rc = 1;
++ goto closefs;
+ }
+
+ /*
+@@ -1559,8 +1677,10 @@ retry_open:
+ */
+ io_ptr_orig = io_ptr;
+ retval = tune2fs_setup_tdb(device_name, &io_ptr);
+- if (retval)
+- exit(1);
++ if (retval) {
++ rc = 1;
++ goto closefs;
++ }
+ if (io_ptr != io_ptr_orig) {
+ ext2fs_close(fs);
+ goto retry_open;
+@@ -1586,7 +1706,7 @@ retry_open:
printf("%.*s\n", (int) sizeof(sb->s_volume_name),
sb->s_volume_name);
remove_error_table(&et_ext2_error_table);
- exit(0);
+ goto closefs;
}
+
retval = ext2fs_check_if_mounted(device_name, &mount_flags);
- if (retval) {
+@@ -1594,7 +1714,8 @@ retry_open:
com_err("ext2fs_check_if_mount", retval,
_("while determining whether %s is mounted."),
device_name);
@@ -629,9 +660,9 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
/* Normally we only need to write out the superblock */
fs->flags |= EXT2_FLAG_SUPER_ONLY;
-@@ -985,12 +1097,19 @@ int main (int argc, char ** argv)
- printf (_("Setting reserved blocks percentage to %g%% (%u blocks)\n"),
- reserved_ratio, sb->s_r_blocks_count);
+@@ -1634,12 +1755,19 @@ retry_open:
+ "(%u blocks)\n"),
+ reserved_ratio, sb->s_r_blocks_count);
}
+ if (p_flag) {
+ sb->s_mmp_update_interval = mmp_update_interval;
@@ -641,16 +672,16 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ }
if (r_flag) {
if (reserved_blocks >= sb->s_blocks_count/2) {
- com_err (program_name, 0,
- _("reserved blocks count is too big (%lu)"),
- reserved_blocks);
-- exit (1);
+ com_err(program_name, 0,
+ _("reserved blocks count is too big (%lu)"),
+ reserved_blocks);
+- exit(1);
+ rc = 1;
+ goto closefs;
}
sb->s_r_blocks_count = reserved_blocks;
ext2fs_mark_super_dirty(fs);
-@@ -1014,7 +1133,8 @@ int main (int argc, char ** argv)
+@@ -1663,7 +1791,8 @@ retry_open:
if (s_flag == 0) {
fputs(_("\nClearing the sparse superflag not supported.\n"),
stderr);
@@ -660,7 +691,7 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
}
if (T_flag) {
sb->s_lastcheck = last_check_time;
-@@ -1042,15 +1162,27 @@ int main (int argc, char ** argv)
+@@ -1691,14 +1820,30 @@ retry_open:
sizeof(sb->s_last_mounted));
ext2fs_mark_super_dirty(fs);
}
@@ -672,7 +703,6 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
- parse_extended_opts(fs, extended_cmd);
- if (journal_size || journal_device)
- add_journal(fs);
--
+ if (mntopts_cmd) {
+ rc = update_mntopts(fs, mntopts_cmd);
+ if (rc)
@@ -688,16 +718,19 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ if (rc)
+ goto closefs;
+ }
++ if (clear_mmp) {
++ rc = ext2fs_mmp_clear(fs);
++ goto closefs;
++ }
+ if (journal_size || journal_device) {
+ rc = add_journal(fs);
-+ if (rc)
++ if (rc);
+ goto closefs;
+ }
-+
+
if (U_flag) {
- if ((strcasecmp(new_UUID, "null") == 0) ||
- (strcasecmp(new_UUID, "clear") == 0)) {
-@@ -1061,7 +1193,8 @@ int main (int argc, char ** argv)
+ int set_csum = 0;
+@@ -1726,7 +1871,8 @@ retry_open:
uuid_generate(sb->s_uuid);
} else if (uuid_parse(new_UUID, sb->s_uuid)) {
com_err(program_name, 0, _("Invalid UUID format\n"));
@@ -705,30 +738,41 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.c
+ rc = 1;
+ goto closefs;
}
- ext2fs_mark_super_dirty(fs);
- }
-@@ -1079,5 +1212,11 @@ int main (int argc, char ** argv)
+ if (set_csum) {
+ for (i = 0; i < fs->group_desc_count; i++)
+@@ -1740,7 +1886,8 @@ retry_open:
+ fputs(_("The inode size may only be "
+ "changed when the filesystem is "
+ "unmounted.\n"), stderr);
+- exit(1);
++ rc = 1;
++ goto closefs;
+ }
+ if (fs->super->s_feature_incompat &
+ EXT4_FEATURE_INCOMPAT_FLEX_BG) {
+@@ -1778,5 +1925,12 @@ retry_open:
printf(_("Setting stripe width to %d\n"), stripe_width);
}
remove_error_table(&et_ext2_error_table);
++
+closefs:
+ if (rc) {
+ ext2fs_mmp_stop(fs);
+ exit(1);
+ }
+
- return (ext2fs_close (fs) ? 1 : 0);
+ return (ext2fs_close(fs) ? 1 : 0);
}
-Index: e2fsprogs-1.40.7/e2fsck/pass1.c
+Index: e2fsprogs-1.41.6/e2fsck/pass1.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass1.c
-+++ e2fsprogs-1.40.7/e2fsck/pass1.c
-@@ -795,7 +795,20 @@ void e2fsck_pass1(e2fsck_t ctx)
+--- e2fsprogs-1.41.6.orig/e2fsck/pass1.c 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/pass1.c 2009-06-10 12:08:54.000000000 -0400
+@@ -825,7 +825,20 @@ void e2fsck_pass1(e2fsck_t ctx)
(fs->super->s_mtime < fs->super->s_inodes_count))
busted_fs_time = 1;
+ if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
-+ !(fs->super->s_mmp_block < fs->super->s_first_data_block ||
++ !(fs->super->s_mmp_block <= fs->super->s_first_data_block ||
+ fs->super->s_mmp_block >= fs->super->s_blocks_count))
+ ext2fs_mark_block_bitmap(ctx->block_found_map,
+ fs->super->s_mmp_block);
@@ -742,13 +786,31 @@ Index: e2fsprogs-1.40.7/e2fsck/pass1.c
+ fatal_error(ctx, 0);
+ }
old_op = ehandler_operation(_("getting next inode from scan"));
- pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
+ pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
inode, inode_size);
-Index: e2fsprogs-1.40.7/e2fsck/unix.c
+Index: e2fsprogs-1.41.6/e2fsck/pass1b.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.7/e2fsck/unix.c
-@@ -1131,6 +1131,24 @@ restart:
+--- e2fsprogs-1.41.6.orig/e2fsck/pass1b.c 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/pass1b.c 2009-06-10 08:02:29.000000000 -0400
+@@ -283,6 +283,13 @@ static void pass1b(e2fsck_t ctx, char *b
+ pb.pctx = &pctx;
+ pctx.str = "pass1b";
+ while (1) {
++ if (ino % EXT2_MMP_INODE_INTERVAL == 0) {
++ errcode_t error;
++
++ error = e2fsck_mmp_update(fs);
++ if (error)
++ fatal_error(ctx, 0);
++ }
+ pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
+ continue;
+Index: e2fsprogs-1.41.6/e2fsck/unix.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/e2fsck/unix.c 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/unix.c 2009-06-10 12:08:53.000000000 -0400
+@@ -1177,6 +1177,19 @@ restart:
"to do a read-only\n"
"check of the device.\n"));
#endif
@@ -757,66 +819,60 @@ Index: e2fsprogs-1.40.7/e2fsck/unix.c
+ fs->super->s_mmp_block = 0;
+ ext2fs_mark_super_dirty(fs);
+ }
-+ }
-+ else if (retval == EXT2_ET_MMP_FAILED) {
-+ dump_mmp_msg((struct mmp_struct *)fs->mmp_buf,
-+ _("Device active on another node"));
-+ }
-+ else if (retval == EXT2_ET_MMP_FSCK_ON) {
-+ dump_mmp_msg((struct mmp_struct *)fs->mmp_buf,
-+ _("It seems that e2fsck is running on the "
-+ "filesystem.\nIf you are sure that e2fsck "
-+ "is not running then use "
-+ "'tune2fs -O ^mmp {device}'\n"
-+ "followed by 'tune2fs -O mmp {device}'"));
++ } else if (retval == EXT2_ET_MMP_FAILED) {
++ dump_mmp_msg(fs->mmp_buf, NULL);
++ } else if (retval == EXT2_ET_MMP_FSCK_ON) {
++ dump_mmp_msg(fs->mmp_buf,
++ _("If you are sure that e2fsck "
++ "is not running then use "
++ "'tune2fs -f -E clear_mmp {device}'\n"));
+ }
else
fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
fatal_error(ctx, 0);
-Index: e2fsprogs-1.40.7/e2fsck/problem.c
+Index: e2fsprogs-1.41.6/e2fsck/problem.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.7/e2fsck/problem.c
-@@ -389,6 +389,11 @@ static struct e2fsck_problem problem_tab
+--- e2fsprogs-1.41.6.orig/e2fsck/problem.c 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/problem.c 2009-06-10 08:02:29.000000000 -0400
+@@ -397,6 +397,11 @@ static struct e2fsck_problem problem_tab
+ N_("Disable extra_isize feature since @f has 128 byte inodes. "),
PROMPT_NONE, 0 },
-
+ /* Superblock has invalid MMP block. */
+ { PR_0_MMP_INVALID_BLK,
+ N_("@S has invalid MMP block. "),
+ PROMPT_CLEAR, PR_PREEN_OK },
+
+
/* Pass 1 errors */
- /* Pass 1: Checking inodes, blocks, and sizes */
-Index: e2fsprogs-1.40.7/e2fsck/problem.h
+Index: e2fsprogs-1.41.6/e2fsck/problem.h
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.7/e2fsck/problem.h
-@@ -222,6 +222,9 @@ struct problem_context {
- #define PR_0_CLEAR_EXTRA_ISIZE 0x00003C
-
+--- e2fsprogs-1.41.6.orig/e2fsck/problem.h 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/problem.h 2009-06-10 08:02:29.000000000 -0400
+@@ -227,6 +227,8 @@ struct problem_context {
+ /* Clear EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE flag */
+ #define PR_0_CLEAR_EXTRA_ISIZE 0x000042
+/* Superblock has invalid MMP block. */
-+#define PR_0_MMP_INVALID_BLK 0x00003A
-+
++#define PR_0_MMP_INVALID_BLK 0x000043
+
/*
* Pass 1 errors
- */
-Index: e2fsprogs-1.40.7/lib/ext2fs/swapfs.c
+Index: e2fsprogs-1.41.6/lib/ext2fs/swapfs.c
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/swapfs.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/swapfs.c
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/swapfs.c 2009-06-10 07:30:33.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/swapfs.c 2009-06-10 08:02:29.000000000 -0400
@@ -70,6 +70,8 @@ void ext2fs_swap_super(struct ext2_super
sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
sb->s_flags = ext2fs_swab32(sb->s_flags);
+ sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval);
+ sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block);
+ sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
for (i=0; i < 4; i++)
sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
- for (i=0; i < 17; i++)
-@@ -319,4 +321,12 @@ void ext2fs_swap_inode(ext2_filsys fs, s
+@@ -272,4 +274,12 @@ void ext2fs_swap_inode(ext2_filsys fs, s
sizeof(struct ext2_inode));
}
@@ -829,10 +885,40 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/swapfs.c
+}
+
#endif
-Index: e2fsprogs-1.40.7/lib/ext2fs/openfs.c
+Index: e2fsprogs-1.41.6/lib/ext2fs/ext2_err.et.in
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/openfs.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/openfs.c
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/ext2_err.et.in 2009-06-10 08:01:08.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/ext2_err.et.in 2009-06-10 08:02:29.000000000 -0400
+@@ -443,4 +443,25 @@ ec EXT2_ET_EA_NAME_NOT_FOUND,
+ ec EXT2_ET_EA_NAME_EXISTS,
+ "Extended attribute name already exists"
+
++ec EXT2_ET_MMP_MAGIC_INVALID,
++ "MMP: invalid magic number"
++
++ec EXT2_ET_MMP_FAILED,
++ "MMP: device currently active"
++
++ec EXT2_ET_MMP_FSCK_ON,
++ "MMP: fsck being run"
++
++ec EXT2_ET_MMP_BAD_BLOCK,
++ "MMP: block number beyond filesystem range"
++
++ec EXT2_ET_MMP_UNKNOWN_SEQ,
++ "MMP: undergoing an unknown operation"
++
++ec EXT2_ET_MMP_CHANGE_ABORT,
++ "MMP: filesystem still in use"
++
++ec EXT2_ET_MMP_OPEN_DIRECT,
++ "MMP: open with O_DIRECT failed"
++
+ end
+Index: e2fsprogs-1.41.6/lib/ext2fs/openfs.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/openfs.c 2009-04-23 00:01:56.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/openfs.c 2009-06-10 08:02:29.000000000 -0400
@@ -22,6 +22,9 @@
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -843,7 +929,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/openfs.c
#include "ext2_fs.h"
-@@ -77,6 +80,7 @@ errcode_t ext2fs_open(const char *name,
+@@ -76,6 +79,7 @@ errcode_t ext2fs_open(const char *name,
* EXT2_FLAG_FORCE - Open the filesystem even if some of the
* features aren't supported.
* EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
@@ -851,7 +937,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/openfs.c
*/
errcode_t ext2fs_open2(const char *name, const char *io_options,
int flags, int superblock,
-@@ -322,6 +326,14 @@ errcode_t ext2fs_open2(const char *name,
+@@ -353,6 +357,14 @@ errcode_t ext2fs_open2(const char *name,
fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs;
@@ -866,64 +952,27 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/openfs.c
return 0;
cleanup:
if (flags & EXT2_FLAG_NOFREE_ON_ERROR)
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_err.et.in
+Index: e2fsprogs-1.41.6/lib/ext2fs/closefs.c
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_err.et.in
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_err.et.in
-@@ -362,5 +362,23 @@ ec EXT2_ET_EA_NAME_NOT_FOUND,
- ec EXT2_ET_EA_NAME_EXISTS,
- "Extended attribute name already exists"
-
-+ec EXT2_ET_MMP_MAGIC_INVALID,
-+ "MMP: invalid magic number in header"
-+
-+ec EXT2_ET_MMP_FAILED,
-+ "MMP: device already active on another node"
-+
-+ec EXT2_ET_MMP_FSCK_ON,
-+ "MMP: appears fsck currently being run on the filesystem"
-+
-+ec EXT2_ET_MMP_BAD_BLOCK,
-+ "MMP: block number beyond filesystem range"
-+
-+ec EXT2_ET_MMP_UNKNOWN_SEQ,
-+ "MMP: seems to be undergoing an unknown operation"
-+
-+ec EXT2_ET_MMP_CHANGE_ABORT,
-+ "MMP: sequence changed - filesystem may be in use elsewhere"
-+
- end
-
-Index: e2fsprogs-1.40.7/lib/ext2fs/closefs.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/closefs.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/closefs.c
-@@ -373,11 +373,20 @@ errcode_t ext2fs_close(ext2_filsys fs)
- if (retval)
- return retval;
- }
-+
- if (fs->write_bitmaps) {
- retval = fs->write_bitmaps(fs);
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/closefs.c 2009-06-10 08:00:44.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/closefs.c 2009-06-10 08:02:29.000000000 -0400
+@@ -477,6 +477,11 @@ errcode_t ext2fs_close(ext2_filsys fs)
if (retval)
return retval;
}
+
-+ if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
-+ (fs->flags & EXT2_FLAG_RW) && !(fs->flags & EXT2_FLAG_SKIP_MMP)) {
-+ retval = ext2fs_mmp_stop(fs);
-+ if (retval)
-+ return retval;
-+ }
++ retval = ext2fs_mmp_stop(fs);
++ if (retval)
++ return retval;
+
ext2fs_free(fs);
return 0;
}
-Index: e2fsprogs-1.40.7/e2fsck/e2fsck.c
+Index: e2fsprogs-1.41.6/e2fsck/e2fsck.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/e2fsck.c
-+++ e2fsprogs-1.40.7/e2fsck/e2fsck.c
-@@ -186,6 +186,7 @@ int e2fsck_run(e2fsck_t ctx)
+--- e2fsprogs-1.41.6.orig/e2fsck/e2fsck.c 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/e2fsck.c 2009-06-10 12:08:53.000000000 -0400
+@@ -199,6 +199,7 @@ int e2fsck_run(e2fsck_t ctx)
{
int i;
pass_t e2fsck_pass;
@@ -931,7 +980,7 @@ Index: e2fsprogs-1.40.7/e2fsck/e2fsck.c
#ifdef HAVE_SETJMP_H
if (setjmp(ctx->abort_loc)) {
-@@ -198,6 +199,9 @@ int e2fsck_run(e2fsck_t ctx)
+@@ -211,6 +212,9 @@ int e2fsck_run(e2fsck_t ctx)
for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
if (ctx->flags & E2F_FLAG_RUN_RETURN)
break;
@@ -941,24 +990,77 @@ Index: e2fsprogs-1.40.7/e2fsck/e2fsck.c
e2fsck_pass(ctx);
if (ctx->progress)
(void) (ctx->progress)(ctx, 0, 0, 0);
-Index: e2fsprogs-1.40.7/e2fsck/e2fsck.h
+Index: e2fsprogs-1.41.6/e2fsck/e2fsck.h
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.7/e2fsck/e2fsck.h
-@@ -534,6 +534,8 @@ extern void mtrace_print(char *mesg);
- extern blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
+--- e2fsprogs-1.41.6.orig/e2fsck/e2fsck.h 2009-06-10 08:02:26.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/e2fsck.h 2009-06-10 12:08:53.000000000 -0400
+@@ -556,6 +556,8 @@ extern blk_t get_backup_sb(e2fsck_t ctx,
const char *name, io_manager manager);
extern int ext2_file_type(unsigned int mode);
+ extern int write_all(int fd, char *buf, size_t count);
+void dump_mmp_msg(struct mmp_struct *mmp, const char *msg);
+errcode_t e2fsck_mmp_update(ext2_filsys fs);
/* unix.c */
extern void e2fsck_clear_progbar(e2fsck_t ctx);
-Index: e2fsprogs-1.40.7/lib/ext2fs/Makefile.in
+Index: e2fsprogs-1.41.6/e2fsck/util.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/e2fsck/util.c 2009-05-28 10:00:12.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/util.c 2009-06-10 08:02:29.000000000 -0400
+@@ -48,6 +48,7 @@ void fatal_error(e2fsck_t ctx, const cha
+ if (msg)
+ fprintf (stderr, "e2fsck: %s\n", msg);
+ if (ctx->fs && ctx->fs->io) {
++ ext2fs_mmp_stop(ctx->fs);
+ if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
+ io_channel_flush(ctx->fs->io);
+ else
+@@ -709,3 +710,24 @@ int write_all(int fd, char *buf, size_t
+ }
+ return c;
+ }
++
++void dump_mmp_msg(struct mmp_struct *mmp, const char *msg)
++{
++ if (msg)
++ printf("MMP check failed: %s\n", msg);
++ printf("MMP failure info: last update time: %llu node: %s device: %s\n",
++ (long long)mmp->mmp_time, mmp->mmp_nodename, mmp->mmp_bdevname);
++}
++
++errcode_t e2fsck_mmp_update(ext2_filsys fs)
++{
++ errcode_t retval;
++
++ retval = ext2fs_mmp_update(fs);
++ if (retval == EXT2_ET_MMP_CHANGE_ABORT)
++ dump_mmp_msg(fs->mmp_cmp,
++ _("UNEXPECTED INCONSISTENCY: the filesystem is "
++ "being modified while fsck is running.\n"));
++
++ return retval;
++}
+Index: e2fsprogs-1.41.6/lib/ext2fs/freefs.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/freefs.c 2009-02-27 22:56:41.000000000 -0500
++++ e2fsprogs-1.41.6/lib/ext2fs/freefs.c 2009-06-10 08:02:29.000000000 -0400
+@@ -53,6 +53,11 @@ void ext2fs_free(ext2_filsys fs)
+ if (fs->icache)
+ ext2fs_free_inode_cache(fs->icache);
+
++ if (fs->mmp_buf)
++ ext2fs_free_mem(&fs->mmp_buf);
++ if (fs->mmp_unaligned_buf)
++ ext2fs_free_mem(&fs->mmp_unaligned_buf);
++
+ fs->magic = 0;
+
+ ext2fs_free_mem(&fs);
+Index: e2fsprogs-1.41.6/lib/ext2fs/Makefile.in
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/Makefile.in
-+++ e2fsprogs-1.40.7/lib/ext2fs/Makefile.in
-@@ -55,6 +55,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_O
+--- e2fsprogs-1.41.6.orig/lib/ext2fs/Makefile.in 2009-05-30 13:34:23.000000000 -0400
++++ e2fsprogs-1.41.6/lib/ext2fs/Makefile.in 2009-06-10 08:02:29.000000000 -0400
+@@ -61,6 +61,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_O
lookup.o \
mkdir.o \
mkjournal.o \
@@ -966,7 +1068,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/Makefile.in
native.o \
newdir.o \
openfs.o \
-@@ -117,6 +118,7 @@ SRCS= ext2_err.c \
+@@ -124,6 +125,7 @@ SRCS= ext2_err.c \
$(srcdir)/lookup.c \
$(srcdir)/mkdir.c \
$(srcdir)/mkjournal.c \
@@ -974,20 +1076,20 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/Makefile.in
$(srcdir)/namei.c \
$(srcdir)/native.c \
$(srcdir)/newdir.c \
-@@ -511,6 +513,8 @@ mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+@@ -622,6 +624,8 @@ mkjournal.o: $(srcdir)/mkjournal.c $(src
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/jfs_user.h $(srcdir)/kernel-jbd.h \
+ $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h
+mmp.o: $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h
- mkjournal.o: $(srcdir)/mkjournal.c $(srcdir)/ext2_fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/e2p/e2p.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h \
-Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ namei.o: $(srcdir)/namei.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+Index: e2fsprogs-1.41.6/lib/ext2fs/mmp.c
===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.7/lib/ext2fs/mmp.c
-@@ -0,0 +1,335 @@
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ e2fsprogs-1.41.6/lib/ext2fs/mmp.c 2009-06-10 08:02:29.000000000 -0400
+@@ -0,0 +1,413 @@
+/*
+ * Helper functions for multiple mount protection(MMP).
+ *
@@ -999,111 +1101,169 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ * %End-Header%
+ */
+
++#ifndef _GNU_SOURCE
++#define _GNU_SOURCE
++#endif
++
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/time.h>
+
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
+#include "ext2fs/ext2_fs.h"
+#include "ext2fs/ext2fs.h"
+
-+errcode_t ext2fs_mmp_read(ext2_filsys fs, blk_t mmp_blk, char *buf)
++static int mmp_pagesize(void)
+{
-+ struct mmp_struct *mmp_s;
-+ errcode_t retval;
++#ifdef _SC_PAGESIZE
++ int sysval = sysconf(_SC_PAGESIZE);
++ if (sysval > 0)
++ return sysval;
++#endif /* _SC_PAGESIZE */
++#ifdef HAVE_GETPAGESIZE
++ return getpagesize();
++#else
++ return 4096;
++#endif
++}
++
++#define ptr_align(ptr, size) (void *)(((unsigned long)(ptr) + (size) - 1) & \
++ ~((unsigned long)(size) - 1))
++
++errcode_t ext2fs_mmp_read(ext2_filsys fs, blk_t mmp_blk, void *buf)
++{
++ struct mmp_struct *mmp_cmp;
++ errcode_t retval = 0;
++ int fd;
+
-+ if ((mmp_blk < fs->super->s_first_data_block) ||
++ if ((mmp_blk <= fs->super->s_first_data_block) ||
+ (mmp_blk >= fs->super->s_blocks_count))
+ return EXT2_ET_MMP_BAD_BLOCK;
+
-+ /*
-+ * Make sure that we read direct from disk by reading only
-+ * sizeof(stuct mmp_struct) bytes.
-+ */
-+ retval = io_channel_read_blk(fs->io, mmp_blk,
-+ -(int)sizeof(struct mmp_struct), buf);
-+ if (retval)
-+ return retval;
++ if (fs->mmp_cmp == NULL) {
++ /* O_DIRECT in linux 2.4: page aligned
++ * O_DIRECT in linux 2.6: sector aligned
++ * A filesystem cannot be created with blocksize < sector size,
++ * or with blocksize > page_size. */
++ int bufsize = fs->blocksize;
++
++ if (bufsize < mmp_pagesize())
++ bufsize = mmp_pagesize();
++ retval = ext2fs_get_mem(bufsize * 2, &fs->mmp_unaligned_buf);
++ if (retval)
++ return retval;
++ fs->mmp_cmp = ptr_align(fs->mmp_unaligned_buf, bufsize);
++ }
++
++ /* ext2fs_open reserves fd0,1,2 to avoid stdio collision */
++ if (fs->mmp_fd <= 0) {
++ fs->mmp_fd = open(fs->device_name, O_RDWR | O_DIRECT);
++ if (fs->mmp_fd < 0) {
++ retval = EXT2_ET_MMP_OPEN_DIRECT;
++ goto out;
++ }
++ }
++
++ if (ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize, SEEK_SET) !=
++ mmp_blk * fs->blocksize) {
++ retval = EXT2_ET_LLSEEK_FAILED;
++ goto out;
++ }
+
-+ mmp_s = (struct mmp_struct *) buf;
++ if (read(fs->mmp_fd, fs->mmp_cmp, fs->blocksize) != fs->blocksize) {
++ retval = EXT2_ET_SHORT_READ;
++ goto out;
++ }
+
++ mmp_cmp = fs->mmp_cmp;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
-+ ext2fs_swap_mmp(mmp_s);
++ ext2fs_swap_mmp(mmp_cmp);
+#endif
+
-+ if (mmp_s->mmp_magic != EXT2_MMP_MAGIC)
-+ return EXT2_ET_MMP_MAGIC_INVALID;
++ if (buf != NULL && buf != fs->mmp_cmp)
++ memcpy(buf, fs->mmp_cmp, fs->blocksize);
+
-+ return 0;
++ if (mmp_cmp->mmp_magic != EXT2_MMP_MAGIC) {
++ retval = EXT2_ET_MMP_MAGIC_INVALID;
++ goto out;
++ }
++
++out:
++ return retval;
+}
+
-+errcode_t ext2fs_mmp_write(ext2_filsys fs, blk_t mmp_blk, char *buf)
++errcode_t ext2fs_mmp_write(ext2_filsys fs, blk_t mmp_blk, void *buf)
+{
-+ struct mmp_struct *mmp_s = (struct mmp_struct *) buf;
++ struct mmp_struct *mmp_s = buf;
+ struct timeval tv;
-+ int retval;
++ errcode_t retval = 0;
+
+ gettimeofday(&tv, 0);
+ mmp_s->mmp_time = tv.tv_sec;
++ fs->mmp_last_written = tv.tv_sec;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
+ ext2fs_swap_mmp(mmp_s);
+#endif
+
-+ retval = io_channel_write_blk(fs->io, mmp_blk,
-+ -(int)sizeof(struct mmp_struct), buf);
++ /* I was tempted to make this use O_DIRECT and the mmp_fd, but
++ * this caused no end of grief, while leaving it as-is works. */
++ retval = io_channel_write_blk(fs->io, mmp_blk, -fs->blocksize, buf);
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
+ ext2fs_swap_mmp(mmp_s);
+#endif
+
-+ /*
-+ * Make sure the block gets to disk quickly.
-+ */
++ /* Make sure the block gets to disk quickly */
+ io_channel_flush(fs->io);
+ return retval;
+}
+
-+long int ext2fs_mmp_new_seq()
++#ifdef HAVE_SRANDOM
++#define srand(x) srandom(x)
++#define rand() random()
++#endif
++
++unsigned ext2fs_mmp_new_seq()
+{
-+ long int new_seq;
++ unsigned new_seq;
++ struct timeval tv;
++
++ gettimeofday(&tv, 0);
++ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
++
++ gettimeofday(&tv, 0);
++ /* Crank the random number generator a few times */
++ for (new_seq = (tv.tv_sec ^ tv.tv_usec) & 0x1F; new_seq > 0; new_seq--)
++ rand();
+
+ do {
-+ new_seq = random();
++ new_seq = rand();
+ } while (new_seq > EXT2_MMP_SEQ_MAX);
+
+ return new_seq;
+}
+
-+errcode_t ext2fs_mmp_init(ext2_filsys fs)
++static errcode_t ext2fs_mmp_reset(ext2_filsys fs)
+{
-+ struct ext2_super_block *sb = fs->super;
+ struct mmp_struct *mmp_s = NULL;
-+ blk_t mmp_block;
-+ int error;
-+
-+ error = ext2fs_read_bitmaps(fs);
-+ if (error)
-+ goto out;
-+
-+ error = ext2fs_new_block(fs, 0, 0, &mmp_block);
-+ if (error)
-+ goto out;
-+
-+ ext2fs_block_alloc_stats(fs, mmp_block, +1);
-+ sb->s_mmp_block = mmp_block;
++ errcode_t retval = 0;
+
+ if (fs->mmp_buf == NULL) {
-+ error = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
-+ if (error)
++ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
++ if (retval)
+ goto out;
+ }
+
-+ mmp_s = (struct mmp_struct *)fs->mmp_buf;
-+ memset(mmp_s, 0, sizeof(struct mmp_struct));
++ memset(fs->mmp_buf, 0, fs->blocksize);
++ mmp_s = fs->mmp_buf;
+
+ mmp_s->mmp_magic = EXT2_MMP_MAGIC;
+ mmp_s->mmp_seq = EXT2_MMP_SEQ_CLEAN;
@@ -1116,19 +1276,55 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ strncpy(mmp_s->mmp_bdevname, fs->device_name,
+ sizeof(mmp_s->mmp_bdevname));
+
-+ mmp_s->mmp_check_interval = EXT2_MMP_MIN_CHECK_INTERVAL;
++ mmp_s->mmp_check_interval = fs->super->s_mmp_update_interval;
++ if (mmp_s->mmp_check_interval < EXT2_MMP_MIN_CHECK_INTERVAL)
++ mmp_s->mmp_check_interval = EXT2_MMP_MIN_CHECK_INTERVAL;
+
-+ error = ext2fs_mmp_write(fs, mmp_block, fs->mmp_buf);
-+ if (error) {
-+ ext2fs_free_mem(&fs->mmp_buf);
-+ fs->mmp_buf = NULL;
-+ goto out;
++ retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
++out:
++ return retval;
++}
++
++errcode_t ext2fs_mmp_clear(ext2_filsys fs)
++{
++ struct mmp_struct *mmp_s = NULL;
++ errcode_t retval = 0;
++
++ if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
++ !(fs->flags & EXT2_FLAG_RW))
++ return 0;
++
++ retval = ext2fs_mmp_reset(fs);
++
++ return retval;
++}
++
++errcode_t ext2fs_mmp_init(ext2_filsys fs)
++{
++ struct ext2_super_block *sb = fs->super;
++ struct mmp_struct *mmp_s = NULL;
++ blk_t mmp_block;
++ errcode_t retval;
++
++ if (fs->mmp_buf == NULL) {
++ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
++ if (retval)
++ goto out;
+ }
+
++ retval = ext2fs_alloc_block(fs, 0, fs->mmp_buf, &mmp_block);
++ if (retval)
++ goto out;
++
++ sb->s_mmp_block = mmp_block;
+ sb->s_mmp_update_interval = EXT2_MMP_UPDATE_INTERVAL;
+
++ retval = ext2fs_mmp_reset(fs);
++ if (retval)
++ goto out;
++
+out:
-+ return error;
++ return retval;
+}
+
+/*
@@ -1136,7 +1332,6 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ */
+errcode_t ext2fs_mmp_start(ext2_filsys fs)
+{
-+ blk_t mmp_blk = fs->super->s_mmp_block;
+ struct mmp_struct *mmp_s;
+ unsigned seq;
+ unsigned int mmp_check_interval;
@@ -1148,11 +1343,11 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ goto mmp_error;
+ }
+
-+ retval = ext2fs_mmp_read(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
-+ mmp_s = (struct mmp_struct *)fs->mmp_buf;
++ mmp_s = fs->mmp_buf;
+
+ mmp_check_interval = fs->super->s_mmp_update_interval;
+ if (mmp_check_interval < EXT2_MMP_MIN_CHECK_INTERVAL)
@@ -1180,7 +1375,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+
+ sleep(2 * mmp_check_interval + 1);
+
-+ retval = ext2fs_mmp_read(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
@@ -1199,13 +1394,13 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ strncpy(mmp_s->mmp_bdevname, fs->device_name,
+ sizeof(mmp_s->mmp_bdevname));
+
-+ retval = ext2fs_mmp_write(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
+ sleep(2 * mmp_check_interval + 1);
+
-+ retval = ext2fs_mmp_read(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
@@ -1215,7 +1410,7 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ }
+
+ mmp_s->mmp_seq = EXT2_MMP_SEQ_FSCK;
-+ retval = ext2fs_mmp_write(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
@@ -1233,46 +1428,39 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ */
+errcode_t ext2fs_mmp_stop(ext2_filsys fs)
+{
-+ blk_t mmp_blk = fs->super->s_mmp_block;
+ struct mmp_struct *mmp, *mmp_cmp;
-+ errcode_t retval;
++ errcode_t retval = 0;
+
-+ if (fs->mmp_cmp == NULL) {
-+ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_cmp);
-+ if (retval)
-+ goto mmp_error;
-+ }
++ if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
++ !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
++ goto mmp_error;
+
-+ retval = ext2fs_mmp_read(fs, mmp_blk, fs->mmp_cmp);
++ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto mmp_error;
+
-+ /*
-+ * This is important since we may come here just after when MMP feature
-+ * is set and fs->mmp_buf is NULL
-+ */
-+ if (fs->mmp_buf == NULL)
-+ goto check_skipped;
-+
-+ /*
-+ * Make sure that the MMP block is not changed.
-+ */
-+ mmp = (struct mmp_struct *)fs->mmp_buf;
-+ mmp_cmp = (struct mmp_struct *)fs->mmp_cmp;
-+ if (memcmp(mmp, mmp_cmp, sizeof(struct mmp_struct)))
++ /* Check if the MMP block is not changed. */
++ mmp = fs->mmp_buf;
++ mmp_cmp = fs->mmp_cmp;
++ if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp)))
+ return EXT2_ET_MMP_CHANGE_ABORT;
+
+check_skipped:
+ mmp_cmp->mmp_seq = EXT2_MMP_SEQ_CLEAN;
-+ retval = ext2fs_mmp_write(fs, mmp_blk, fs->mmp_cmp);
++ retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_cmp);
+
+mmp_error:
++ if (fs->mmp_fd > 0) {
++ close(fs->mmp_fd);
++ fs->mmp_fd = -1;
++ }
+ if (fs->mmp_buf) {
+ ext2fs_free_mem(&fs->mmp_buf);
+ fs->mmp_buf = NULL;
+ }
-+ if (fs->mmp_cmp) {
-+ ext2fs_free_mem(&fs->mmp_cmp);
++ if (fs->mmp_unaligned_buf) {
++ ext2fs_free_mem(&fs->mmp_unaligned_buf);
++ fs->mmp_unaligned_buf = NULL;
+ fs->mmp_cmp = NULL;
+ }
+
@@ -1286,10 +1474,9 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ */
+errcode_t ext2fs_mmp_update(ext2_filsys fs)
+{
-+ blk_t mmp_blk = fs->super->s_mmp_block;
+ struct mmp_struct *mmp, *mmp_cmp;
+ struct timeval tv;
-+ errcode_t retval;
++ errcode_t retval = 0;
+
+ if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
+ !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
@@ -1299,53 +1486,40 @@ Index: e2fsprogs-1.40.7/lib/ext2fs/mmp.c
+ if (tv.tv_sec - fs->mmp_last_written < EXT2_MIN_MMP_UPDATE_INTERVAL)
+ return 0;
+
-+ if (fs->mmp_cmp == NULL) {
-+ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_cmp);
-+ if (retval)
-+ goto mmp_error;
-+ }
-+
-+ retval = ext2fs_mmp_read(fs, mmp_blk, fs->mmp_cmp);
++ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, NULL);
+ if (retval)
+ goto mmp_error;
+
-+ mmp = (struct mmp_struct *)fs->mmp_buf;
-+ mmp_cmp = (struct mmp_struct *)fs->mmp_cmp;
++ mmp = fs->mmp_buf;
++ mmp_cmp = fs->mmp_cmp;
+
-+ if (memcmp(mmp, mmp_cmp, sizeof(struct mmp_struct)))
++ if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp)))
+ return EXT2_ET_MMP_CHANGE_ABORT;
+
+ mmp->mmp_time = tv.tv_sec;
-+ fs->mmp_last_written = tv.tv_sec;
+ mmp->mmp_seq = EXT2_MMP_SEQ_FSCK;
-+ retval = ext2fs_mmp_write(fs, mmp_blk, fs->mmp_buf);
++ retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+
+mmp_error:
+ return retval;
+}
-Index: e2fsprogs-1.40.7/e2fsck/pass1b.c
+Index: e2fsprogs-1.41.6/misc/tune2fs.8.in
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass1b.c
-+++ e2fsprogs-1.40.7/e2fsck/pass1b.c
-@@ -272,6 +272,13 @@ static void pass1b(e2fsck_t ctx, char *b
- pb.pctx = &pctx;
- pctx.str = "pass1b";
- while (1) {
-+ if (ino % EXT2_MMP_INODE_INTERVAL == 0) {
-+ errcode_t error;
-+
-+ error = e2fsck_mmp_update(fs);
-+ if (error)
-+ fatal_error(ctx, 0);
-+ }
- pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
- if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
- continue;
-Index: e2fsprogs-1.40.7/misc/tune2fs.8.in
-===================================================================
---- e2fsprogs-1.40.7.orig/misc/tune2fs.8.in
-+++ e2fsprogs-1.40.7/misc/tune2fs.8.in
-@@ -464,6 +464,11 @@ Setting the filesystem feature is equiva
+--- e2fsprogs-1.41.6.orig/misc/tune2fs.8.in 2009-05-30 12:17:35.000000000 -0400
++++ e2fsprogs-1.41.6/misc/tune2fs.8.in 2009-06-10 08:02:29.000000000 -0400
+@@ -161,6 +161,11 @@ separated, and may take an argument usin
+ The following extended options are supported:
+ .RS 1.2i
+ .TP
++.B clear-mmp
++Reset the MMP block (if any) back to the clean state. Use only if
++absolutely certain the device is not currently mounted or being
++fscked, or major filesystem corruption can result. Needs '-f'.
++.TP
+ .BI stride= stride-size
+ Configure the filesystem for a RAID array with
+ .I stride-size
+@@ -447,6 +452,11 @@ Setting the filesystem feature is equiva
.B \-j
option.
.TP
@@ -1357,9 +1531,9 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.8.in
.B sparse_super
Limit the number of backup superblocks to save space on large filesystems.
.TP
-@@ -501,6 +506,9 @@ feature,
- can be run to convert existing directories to the hashed B-tree format.
-
+@@ -489,6 +499,9 @@ and
+ .BR flex_bg
+ features are only supported by the ext4 filesystem.
.TP
+.BI \-p " mmp_check_interval"
+Set the desired MMP check interval in seconds. It is 5 seconds by default.
@@ -1367,21 +1541,21 @@ Index: e2fsprogs-1.40.7/misc/tune2fs.8.in
.BI \-r " reserved-blocks-count"
Set the number of reserved filesystem blocks.
.TP
-Index: e2fsprogs-1.40.7/misc/mke2fs.c
+Index: e2fsprogs-1.41.6/misc/mke2fs.c
===================================================================
---- e2fsprogs-1.40.7.orig/misc/mke2fs.c
-+++ e2fsprogs-1.40.7/misc/mke2fs.c
-@@ -925,7 +925,8 @@ static __u32 ok_features[3] = {
- /* Incompat */
- EXT2_FEATURE_INCOMPAT_FILETYPE|
+--- e2fsprogs-1.41.6.orig/misc/mke2fs.c 2009-06-10 08:00:44.000000000 -0400
++++ e2fsprogs-1.41.6/misc/mke2fs.c 2009-06-10 12:08:53.000000000 -0400
+@@ -841,7 +841,8 @@ static __u32 ok_features[3] = {
+ EXT3_FEATURE_INCOMPAT_EXTENTS|
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
-- EXT2_FEATURE_INCOMPAT_META_BG,
-+ EXT2_FEATURE_INCOMPAT_META_BG|
+ EXT2_FEATURE_INCOMPAT_META_BG|
+- EXT4_FEATURE_INCOMPAT_FLEX_BG,
++ EXT4_FEATURE_INCOMPAT_FLEX_BG|
+ EXT4_FEATURE_INCOMPAT_MMP,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
-@@ -1808,8 +1809,20 @@ int main (int argc, char *argv[])
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+@@ -2120,8 +2121,20 @@ int main (int argc, char *argv[])
}
no_journal:
@@ -1403,71 +1577,11 @@ Index: e2fsprogs-1.40.7/misc/mke2fs.c
if (!quiet)
printf(_("Writing superblocks and "
"filesystem accounting information: "));
-Index: e2fsprogs-1.40.7/e2fsck/util.c
+Index: e2fsprogs-1.41.6/lib/e2p/ls.c
===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/util.c
-+++ e2fsprogs-1.40.7/e2fsck/util.c
-@@ -577,3 +577,25 @@ errcode_t e2fsck_zero_blocks(ext2_filsys
- }
- return 0;
- }
-+
-+void dump_mmp_msg(struct mmp_struct *mmp, const char *msg)
-+{
-+ printf("MMP check failed: %s\n", msg);
-+ printf("MMP failure info: last update time: %llu node: %s device: %s\n",
-+ (long long)mmp->mmp_time, mmp->mmp_nodename, mmp->mmp_bdevname);
-+}
-+
-+errcode_t e2fsck_mmp_update(ext2_filsys fs)
-+{
-+ errcode_t retval;
-+
-+ retval = ext2fs_mmp_update(fs);
-+ if (retval == EXT2_ET_MMP_CHANGE_ABORT)
-+ dump_mmp_msg((struct mmp_struct *)fs->mmp_cmp,
-+ _("\n UNEXPECTED INCONSISTENCY: "
-+ "Unexpected MMP structure read from disk.\n"
-+ "It seems the filesystem is being modified while "
-+ "fsck is running.\n"));
-+
-+ return retval;
-+}
-Index: e2fsprogs-1.40.7/lib/ext2fs/bitops.h
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/bitops.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/bitops.h
-@@ -352,6 +352,12 @@ _INLINE_ __u32 ext2fs_swab32(__u32 val)
- ((val<<8)&0xFF0000) | (val<<24));
- }
-
-+_INLINE_ __u64 ext2fs_swab64(__u64 val)
-+{
-+ return (ext2fs_swab32(val >> 32) |
-+ (((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
-+}
-+
- #endif /* !_EXT2_HAVE_ASM_SWAB */
-
- #if !defined(_EXT2_HAVE_ASM_FINDBIT_)
-Index: e2fsprogs-1.40.7/debugfs/set_fields.c
-===================================================================
---- e2fsprogs-1.40.7.orig/debugfs/set_fields.c
-+++ e2fsprogs-1.40.7/debugfs/set_fields.c
-@@ -126,7 +126,7 @@ static struct field_set_info super_field
- { "flags", &set_sb.s_flags, 4, parse_uint },
- { "raid_stride", &set_sb.s_raid_stride, 2, parse_uint },
- { "min_extra_isize", &set_sb.s_min_extra_isize, 4, parse_uint },
-- { "mmp_interval", &set_sb.s_mmp_interval, 2, parse_uint },
-+ { "mmp_update_interval", &set_sb.s_mmp_update_interval, 2, parse_uint },
- { "mmp_block", &set_sb.s_mmp_block, 8, parse_uint },
- { "raid_stripe_width", &set_sb.s_raid_stripe_width, 4, parse_uint },
- { 0, 0, 0, 0 }
-Index: e2fsprogs-1.40.7/lib/e2p/ls.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/e2p/ls.c
-+++ e2fsprogs-1.40.7/lib/e2p/ls.c
-@@ -301,6 +301,12 @@ void list_super2(struct ext2_super_block
+--- e2fsprogs-1.41.6.orig/lib/e2p/ls.c 2009-03-05 17:05:21.000000000 -0500
++++ e2fsprogs-1.41.6/lib/e2p/ls.c 2009-06-10 08:02:29.000000000 -0400
+@@ -328,6 +328,12 @@ void list_super2(struct ext2_super_block
fprintf(f, "type %u\n", sb->s_jnl_backup_type);
}
}
@@ -1480,21 +1594,45 @@ Index: e2fsprogs-1.40.7/lib/e2p/ls.c
}
void list_super (struct ext2_super_block * s)
-Index: e2fsprogs-1.40.7/lib/ext2fs/freefs.c
+Index: e2fsprogs-1.41.6/debugfs/set_fields.c
===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/freefs.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/freefs.c
-@@ -52,7 +52,12 @@ void ext2fs_free(ext2_filsys fs)
-
- if (fs->icache)
- ext2fs_free_inode_cache(fs->icache);
--
-+
-+ if (fs->mmp_buf)
-+ ext2fs_free_mem(&fs->mmp_buf);
-+ if (fs->mmp_cmp)
-+ ext2fs_free_mem(&fs->mmp_cmp);
+--- e2fsprogs-1.41.6.orig/debugfs/set_fields.c 2009-06-10 08:00:44.000000000 -0400
++++ e2fsprogs-1.41.6/debugfs/set_fields.c 2009-06-10 08:02:29.000000000 -0400
+@@ -129,7 +129,7 @@ static struct field_set_info super_field
+ { "flags", &set_sb.s_flags, 4, parse_uint },
+ { "raid_stride", &set_sb.s_raid_stride, 2, parse_uint },
+ { "min_extra_isize", &set_sb.s_min_extra_isize, 4, parse_uint },
+- { "mmp_interval", &set_sb.s_mmp_interval, 2, parse_uint },
++ { "mmp_update_interval", &set_sb.s_mmp_update_interval, 2, parse_uint },
+ { "mmp_block", &set_sb.s_mmp_block, 8, parse_uint },
+ { "raid_stripe_width", &set_sb.s_raid_stripe_width, 4, parse_uint },
+ { "log_groups_per_flex", &set_sb.s_log_groups_per_flex, 1, parse_uint },
+Index: e2fsprogs-1.41.6/misc/util.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/misc/util.c 2009-04-22 22:19:29.000000000 -0400
++++ e2fsprogs-1.41.6/misc/util.c 2009-06-10 08:02:29.000000000 -0400
+@@ -287,3 +287,11 @@ void print_check_message(ext2_filsys fs)
+ fs->super->s_max_mnt_count,
+ (double)fs->super->s_checkinterval / (3600 * 24));
+ }
+
- fs->magic = 0;
-
- ext2fs_free_mem(&fs);
++void dump_mmp_msg(struct mmp_struct *mmp, const char *msg)
++{
++ if (msg)
++ printf("MMP check failed: %s\n", msg);
++ printf("MMP failure info: last update time: %llu node: %s device: %s\n",
++ (long long)mmp->mmp_time, mmp->mmp_nodename, mmp->mmp_bdevname);
++}
+Index: e2fsprogs-1.41.6/e2fsck/journal.c
+===================================================================
+--- e2fsprogs-1.41.6.orig/e2fsck/journal.c 2009-05-25 20:13:28.000000000 -0400
++++ e2fsprogs-1.41.6/e2fsck/journal.c 2009-06-10 12:18:39.000000000 -0400
+@@ -878,6 +878,8 @@ int 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;
++
++ ext2fs_mmp_stop(ctx->fs);
+ ext2fs_free(ctx->fs);
+ retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
+ ctx->superblock, blocksize, io_ptr,
diff --git a/debian/patches/e2fsprogs-new-opt-shrdblks.patch b/debian/patches/e2fsprogs-new-opt-shrdblks.patch
index cddd9af..2774568 100644
--- a/debian/patches/e2fsprogs-new-opt-shrdblks.patch
+++ b/debian/patches/e2fsprogs-new-opt-shrdblks.patch
@@ -32,16 +32,16 @@ In the config file:
Signed-off-by: Jim Garlick <garlick at llnl.gov>
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
+Index: e2fsprogs-1.41.4/e2fsck/e2fsck.h
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.h
-@@ -183,6 +183,17 @@ struct resource_track {
+--- e2fsprogs-1.41.4.orig/e2fsck/e2fsck.h
++++ e2fsprogs-1.41.4/e2fsck/e2fsck.h
+@@ -186,6 +186,17 @@ struct resource_track {
#define E2F_PASS_5 5
#define E2F_PASS_1B 6
-+typedef enum {
-+ E2F_SHARED_PRESERVE = 0,
++typedef enum {
++ E2F_SHARED_PRESERVE = 0,
+ E2F_SHARED_DELETE,
+ E2F_SHARED_LPF
+} shared_opt_t;
@@ -54,7 +54,7 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
/*
* Define the extended attribute refcount structure
*/
-@@ -333,6 +344,8 @@ struct e2fsck_struct {
+@@ -340,6 +351,8 @@ struct e2fsck_struct {
time_t now;
time_t time_fudge; /* For working around buggy init scripts */
int ext_attr_ver;
@@ -63,11 +63,11 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.h
profile_t profile;
int blocks_per_page;
-Index: e2fsprogs-1.40.4/e2fsck/unix.c
+Index: e2fsprogs-1.41.4/e2fsck/unix.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.4/e2fsck/unix.c
-@@ -515,6 +515,49 @@ static void signal_cancel(int sig EXT2FS
+--- e2fsprogs-1.41.4.orig/e2fsck/unix.c
++++ e2fsprogs-1.41.4/e2fsck/unix.c
+@@ -550,6 +550,49 @@ static void signal_cancel(int sig EXT2FS
}
#endif
@@ -77,18 +77,18 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
+
+ /* [options] shared=preserve|lost+found|delete */
+ tmp = NULL;
-+ ctx->shared = E2F_SHARED_PRESERVE;
++ ctx->shared = E2F_SHARED_PRESERVE;
+ profile_get_string(ctx->profile, "options", "shared", 0,
+ "preserve", &tmp);
+ if (tmp) {
+ if (strcmp(tmp, "preserve") == 0)
-+ ctx->shared = E2F_SHARED_PRESERVE;
++ ctx->shared = E2F_SHARED_PRESERVE;
+ else if (strcmp(tmp, "delete") == 0)
-+ ctx->shared = E2F_SHARED_DELETE;
++ ctx->shared = E2F_SHARED_DELETE;
+ else if (strcmp(tmp, "lost+found") == 0)
-+ ctx->shared = E2F_SHARED_LPF;
++ ctx->shared = E2F_SHARED_LPF;
+ else {
-+ com_err(ctx->program_name, 0,
++ com_err(ctx->program_name, 0,
+ _("configuration error: 'shared=%s'"), tmp);
+ fatal_error(ctx, 0);
+ }
@@ -106,7 +106,7 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
+ else if (strcmp(tmp, "zero") == 0)
+ ctx->clone = E2F_CLONE_ZERO;
+ else {
-+ com_err(ctx->program_name, 0,
++ com_err(ctx->program_name, 0,
+ _("configuration error: 'clone=%s'"), tmp);
+ fatal_error(ctx, 0);
+ }
@@ -117,10 +117,10 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
static void parse_extended_opts(e2fsck_t ctx, const char *opts)
{
char *buf, *token, *next, *p, *arg;
-@@ -548,6 +591,36 @@ static void parse_extended_opts(e2fsck_t
- extended_usage++;
- continue;
- }
+@@ -585,6 +628,36 @@ static void parse_extended_opts(e2fsck_t
+ } else if (strcmp(token, "fragcheck") == 0) {
+ ctx->options |= E2F_OPT_FRAGCHECK;
+ continue;
+ /* -E shared=preserve|lost+found|delete */
+ } else if (strcmp(token, "shared") == 0) {
+ if (!arg) {
@@ -154,16 +154,16 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
} else {
fprintf(stderr, _("Unknown extended option: %s\n"),
token);
-@@ -561,6 +634,8 @@ static void parse_extended_opts(e2fsck_t
- "and may take an argument which\n"
- "is set off by an equals ('=') sign. "
- "Valid extended options are:\n"
-+ "\tshared=<preserve|lost+found|delete>\n"
-+ "\tclone=<dup|zero>\n"
- "\tea_ver=<ea_version (1 or 2)>\n"
- "\n"), stderr);
+@@ -600,6 +673,8 @@ static void parse_extended_opts(e2fsck_t
+ "Valid extended options are:\n"), stderr);
+ fputs(("\tea_ver=<ea_version (1 or 2)>\n"), stderr);
+ fputs(("\tfragcheck\n"), stderr);
++ fputs(("\tshared=<preserve|lost+found|delete>\n"), stderr);
++ fputs(("\tclone=<dup|zero>\n"), stderr);
+ fputc('\n', stderr);
exit(1);
-@@ -623,6 +698,7 @@ static errcode_t PRS(int argc, char *arg
+ }
+@@ -662,6 +737,7 @@ static errcode_t PRS(int argc, char *arg
config_fn[0] = cp;
profile_set_syntax_err_cb(syntax_err_report);
profile_init(config_fn, &ctx->profile);
@@ -171,11 +171,11 @@ Index: e2fsprogs-1.40.4/e2fsck/unix.c
while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
switch (c) {
-Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
+Index: e2fsprogs-1.41.4/e2fsck/pass1b.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/pass1b.c
-+++ e2fsprogs-1.40.4/e2fsck/pass1b.c
-@@ -456,6 +456,9 @@ static void pass1d(e2fsck_t ctx, char *b
+--- e2fsprogs-1.41.4.orig/e2fsck/pass1b.c
++++ e2fsprogs-1.41.4/e2fsck/pass1b.c
+@@ -457,6 +457,9 @@ static void pass1d(e2fsck_t ctx, char *b
q = (struct dup_block *) dnode_get(m);
if (q->num_bad > 1)
file_ok = 0;
@@ -185,7 +185,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
if (check_if_fs_block(ctx, s->block)) {
file_ok = 0;
meta_data = 1;
-@@ -511,13 +514,26 @@ static void pass1d(e2fsck_t ctx, char *b
+@@ -512,13 +515,26 @@ static void pass1d(e2fsck_t ctx, char *b
fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
continue;
}
@@ -202,7 +202,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
+ }
+ if (ctx->shared == E2F_SHARED_LPF &&
+ fix_problem(ctx, PR_1D_DISCONNECT_QUESTION, &pctx)) {
-+ pctx.errcode = ext2fs_unlink(fs, p->dir,
++ pctx.errcode = ext2fs_unlink(fs, p->dir,
+ NULL, ino, 0);
+ if (pctx.errcode) {
+ fix_problem(ctx, PR_1D_DISCONNECT_ERROR,
@@ -216,26 +216,17 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
delete_file(ctx, ino, p, block_buf);
else
-@@ -534,7 +550,8 @@ static void decrement_badcount(e2fsck_t
+@@ -535,7 +551,8 @@ static void decrement_badcount(e2fsck_t
{
p->num_bad--;
if (p->num_bad <= 0 ||
- (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
-+ (p->num_bad == 1 && !check_if_fs_block(ctx, block) &&
++ (p->num_bad == 1 && !check_if_fs_block(ctx, block) &&
+ ctx->clone == E2F_CLONE_DUP))
ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
}
-@@ -572,7 +589,7 @@ static int delete_file_block(ext2_filsys
-
- return 0;
- }
--
-+
- static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
- struct dup_inode *dp, char* block_buf)
- {
-@@ -680,11 +697,15 @@ static int clone_file_block(ext2_filsys
+@@ -677,11 +694,15 @@ static int clone_file_block(ext2_filsys
printf("Cloning block %u to %u\n", *block_nr,
new_block);
#endif
@@ -256,7 +247,7 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
}
retval = io_channel_write_blk(fs->io, new_block, 1,
cs->buf);
-@@ -693,6 +714,11 @@ static int clone_file_block(ext2_filsys
+@@ -690,6 +711,11 @@ static int clone_file_block(ext2_filsys
return BLOCK_ABORT;
}
decrement_badcount(ctx, *block_nr, p);
@@ -268,30 +259,29 @@ Index: e2fsprogs-1.40.4/e2fsck/pass1b.c
*block_nr = new_block;
ext2fs_mark_block_bitmap(ctx->block_found_map,
new_block);
-Index: e2fsprogs-1.40.4/e2fsck/problem.h
+Index: e2fsprogs-1.41.4/e2fsck/problem.h
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.4/e2fsck/problem.h
-@@ -542,7 +542,13 @@ struct problem_context {
-
+--- e2fsprogs-1.41.4.orig/e2fsck/problem.h
++++ e2fsprogs-1.41.4/e2fsck/problem.h
+@@ -569,6 +569,13 @@ struct problem_context {
/* Couldn't clone file (error) */
#define PR_1D_CLONE_ERROR 0x013008
--
-+
+
+/* File with shared blocks found */
+#define PR_1D_DISCONNECT_QUESTION 0x013009
+
+/* Couldn't unlink file (error) */
+#define PR_1D_DISCONNECT_ERROR 0x01300A
+
++
/*
* Pass 2 errors
*/
-Index: e2fsprogs-1.40.4/e2fsck/problem.c
+Index: e2fsprogs-1.41.4/e2fsck/problem.c
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.4/e2fsck/problem.c
-@@ -917,6 +917,14 @@ static struct e2fsck_problem problem_tab
+--- e2fsprogs-1.41.4.orig/e2fsck/problem.c
++++ e2fsprogs-1.41.4/e2fsck/problem.c
+@@ -990,6 +990,14 @@ static struct e2fsck_problem problem_tab
{ PR_1D_CLONE_ERROR,
N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
@@ -306,15 +296,14 @@ Index: e2fsprogs-1.40.4/e2fsck/problem.c
/* Pass 2 errors */
/* Pass 2: Checking directory structure */
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.8.in
+Index: e2fsprogs-1.41.4/e2fsck/e2fsck.8.in
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.8.in
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.8.in
-@@ -178,6 +178,19 @@ following options are supported:
- separated, and may take an argument using the equals ('=') sign. The
+--- e2fsprogs-1.41.4.orig/e2fsck/e2fsck.8.in
++++ e2fsprogs-1.41.4/e2fsck/e2fsck.8.in
+@@ -184,6 +184,19 @@ separated, and may take an argument usin
following options are supported:
.RS 1.2i
-+.TP
+ .TP
+.BI clone= dup|zero
+Resolve files with shared blocks in pass 1D by giving each file a private
+copy of the blocks (dup);
@@ -327,17 +316,18 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.8.in
+cloned and then disconnected from their parent directory,
+then reconnected to /lost+found in pass 3 (lost+found);
+or simply deleted (delete). The default is preserve.
- .TP
++.TP
.BI ea_ver= extended_attribute_version
- Assume the format of the extended attribute blocks in the filesystem is
-Index: e2fsprogs-1.40.4/e2fsck/e2fsck.conf.5.in
+ Set the version of the extended attribute blocks which
+ .B e2fsck
+Index: e2fsprogs-1.41.4/e2fsck/e2fsck.conf.5.in
===================================================================
---- e2fsprogs-1.40.4.orig/e2fsck/e2fsck.conf.5.in
-+++ e2fsprogs-1.40.4/e2fsck/e2fsck.conf.5.in
-@@ -106,6 +106,20 @@ This boolean relation controls whether o
- filesystem checks (either based on time or number of mounts) should
- be doubled if the system is running on battery. It defaults to
- true.
+--- e2fsprogs-1.41.4.orig/e2fsck/e2fsck.conf.5.in
++++ e2fsprogs-1.41.4/e2fsck/e2fsck.conf.5.in
+@@ -107,6 +107,19 @@ This boolean relation controls whether o
+ will offer to clear
+ the test_fs flag if the ext4 filesystem is available on the system. It
+ defaults to true.
+.TP
+.I clone
+This string relation controls the default handling of shared blocks in pass 1D.
@@ -351,7 +341,6 @@ Index: e2fsprogs-1.40.4/e2fsck/e2fsck.conf.5.in
+or delete. See the
+.I "-E shared"
+option description in e2fsck(8).
-+
- .SH THE [problems] STANZA
- Each tag in the
- .I [problems]
+ .TP
+ .I defer_check_on_battery
+ This boolean relation controls whether or not the interval between
diff --git a/debian/patches/e2fsprogs-nlinks-flag.patch b/debian/patches/e2fsprogs-nlinks-flag.patch
deleted file mode 100644
index b350dd7..0000000
--- a/debian/patches/e2fsprogs-nlinks-flag.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-If there are any directories with > 65000 subdirectories, enable the
-DIR_NLINK feature in the superblock. If there are any directories
-that formerly had > 65000 subdirs (i_links_count == 1) but no longer
-do, don't consider this an error to alert the user about, but silently
-fix the link count to the currently counted link count.
-
-The DIR_NLINK feature is not disabled if set but no many-subdir directories
-are found, so that the kernel is not required to enable it on-the-fly. The
-admin should set it with tune2fs instead.
-
-Index: e2fsprogs-1.40.5/e2fsck/pass4.c
-===================================================================
---- e2fsprogs-1.40.5.orig/e2fsck/pass4.c
-+++ e2fsprogs-1.40.5/e2fsck/pass4.c
-@@ -101,6 +101,7 @@ void e2fsck_pass4(e2fsck_t ctx)
- struct problem_context pctx;
- __u16 link_count;
- __u32 link_counted;
-+ __u32 many_subdirs = 0;
- char *buf = 0;
- int group, maxgroup;
-
-@@ -182,7 +183,20 @@ void e2fsck_pass4(e2fsck_t ctx)
- e2fsck_write_inode(ctx, i, inode, "pass4");
- }
- }
-+ if (link_count == 1 && link_counted > EXT2_LINK_MAX)
-+ many_subdirs++;
- }
-+
-+ if (many_subdirs) {
-+ if (!(fs->super->s_feature_ro_compat &
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK) &&
-+ fix_problem(ctx, PR_4_FEATURE_DIR_NLINK, &pctx)) {
-+ fs->super->s_feature_ro_compat |=
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
-+ ext2fs_mark_super_dirty(fs);
-+ }
-+ }
-+
- ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
- ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
- ext2fs_free_inode_bitmap(ctx->inode_bb_map);
-Index: e2fsprogs-1.40.5/e2fsck/problem.c
-===================================================================
---- e2fsprogs-1.40.5.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.5/e2fsck/problem.c
-@@ -1371,6 +1371,11 @@ static struct e2fsck_problem problem_tab
- "They @s the same!\n"),
- PROMPT_NONE, 0 },
-
-+ /* DIR_NLINK flag not set but dirs with > 65000 subdirs found */
-+ { PR_4_FEATURE_DIR_NLINK,
-+ N_("@f has @d with > 65000 subdirs, but no DIR_NLINK flag in @S.\n"),
-+ PROMPT_FIX, 0 },
-+
- /* Pass 5 errors */
-
- /* Pass 5: Checking group summary information */
-Index: e2fsprogs-1.40.5/e2fsck/problem.h
-===================================================================
---- e2fsprogs-1.40.5.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.5/e2fsck/problem.h
-@@ -824,6 +824,10 @@ struct problem_context {
- /* Inconsistent inode count information cached */
- #define PR_4_INCONSISTENT_COUNT 0x040004
-
-+/* Directory with > EXT2_LINK_MAX subdirs found but
-+ * EXT4_FEATURE_RO_COMPAT_DIR_NLINK flag is not set */
-+#define PR_4_FEATURE_DIR_NLINK 0x040005
-+
- /*
- * Pass 5 errors
- */
diff --git a/debian/patches/e2fsprogs-nlinks.patch b/debian/patches/e2fsprogs-nlinks.patch
deleted file mode 100644
index 2c5299f..0000000
--- a/debian/patches/e2fsprogs-nlinks.patch
+++ /dev/null
@@ -1,394 +0,0 @@
-Add support for the DIR_NLINK feature.
-
-This patch includes the changes required to e2fsck to understand the
-nlink count changes made in the kernel. In pass2, while counting the
-links for a directory, if the link count exceeds 65000, its permanently
-set to EXT2_LINK_MAX + 10. In pass4, when the counted and actual nlink
-counts are compared, e2fsck does not flag an error if counted links =
-EXT2_NLINK_MAX + 10 and existing link count is 1.
-
-It also handles the case when a directory had more than 65000 subdirs
-and they were later deleted. The nlink count of such a directory remains
-1. In pass4 if counted links are 2 and if existing nlink count = 1,
-e2fsck corrects the nlink count without displaying any errors.
-
-The file hard link count is also increased to 65000, but this cannot be
-exceeded.
-
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-
-Index: e2fsprogs-1.40.7/e2fsck/pass2.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass2.c
-+++ e2fsprogs-1.40.7/e2fsck/pass2.c
-@@ -712,7 +712,7 @@ static int check_dir_block(ext2_filsys f
- blk_t block_nr = db->blk;
- ext2_ino_t ino = db->ino;
- ext2_ino_t subdir_parent;
-- __u16 links;
-+ __u32 links;
- struct check_dir_struct *cd;
- char *buf;
- e2fsck_t ctx;
-@@ -1019,9 +1019,11 @@ static int check_dir_block(ext2_filsys f
- dups_found++;
- } else
- dict_alloc_insert(&de_dict, dirent, dirent);
--
-- ext2fs_icount_increment(ctx->inode_count, dirent->inode,
-- &links);
-+
-+ ext2fs_icount_inc32(ctx->inode_count, dirent->inode, &links,
-+ ext2fs_test_inode_bitmap(ctx->inode_dir_map,
-+ dirent->inode) ?
-+ EXT2_LINK_MAX : (__u32)~0U);
- if (links > 1)
- ctx->fs_links_count++;
- ctx->fs_total_count++;
-Index: e2fsprogs-1.40.7/e2fsck/pass4.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass4.c
-+++ e2fsprogs-1.40.7/e2fsck/pass4.c
-@@ -99,7 +99,8 @@ void e2fsck_pass4(e2fsck_t ctx)
- struct resource_track rtrack;
- #endif
- struct problem_context pctx;
-- __u16 link_count, link_counted;
-+ __u16 link_count;
-+ __u32 link_counted;
- char *buf = 0;
- int group, maxgroup;
-
-@@ -145,7 +146,7 @@ void e2fsck_pass4(e2fsck_t ctx)
- ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
- continue;
- ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
-- ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
-+ ext2fs_icount_fetch32(ctx->inode_count, i, &link_counted);
- if (link_counted == 0) {
- if (!buf)
- buf = e2fsck_allocate_memory(ctx,
-@@ -156,10 +157,12 @@ void e2fsck_pass4(e2fsck_t ctx)
- continue;
- ext2fs_icount_fetch(ctx->inode_link_info, i,
- &link_count);
-- ext2fs_icount_fetch(ctx->inode_count, i,
-- &link_counted);
-+ ext2fs_icount_fetch32(ctx->inode_count, i,
-+ &link_counted);
- }
-- if (link_counted != link_count) {
-+ if (link_counted != link_count &&
-+ !(ext2fs_test_inode_bitmap(ctx->inode_dir_map, i) &&
-+ link_count == 1 && link_counted > EXT2_LINK_MAX)) {
- e2fsck_read_inode(ctx, i, inode, "pass4");
- pctx.ino = i;
- pctx.inode = inode;
-@@ -169,7 +172,12 @@ void e2fsck_pass4(e2fsck_t ctx)
- PR_4_INCONSISTENT_COUNT, &pctx);
- }
- pctx.num = link_counted;
-- if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
-+ /* i_link_count was previously exceeded, but no longer
-+ * is, fix this but don't consider it an error */
-+ if ((LINUX_S_ISDIR(inode->i_mode) && link_counted > 1 &&
-+ (inode->i_flags & EXT2_INDEX_FL) &&
-+ link_count == 1 && !(ctx->options & E2F_OPT_NO)) ||
-+ (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx))) {
- inode->i_links_count = link_counted;
- e2fsck_write_inode(ctx, i, inode, "pass4");
- }
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2_fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2_fs.h
-@@ -659,6 +659,7 @@ struct ext2_super_block {
- #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE)
- #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
- EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
-
- /*
-Index: e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.7/lib/ext2fs/ext2fs.h
-@@ -463,7 +463,8 @@ typedef struct ext2_icount *ext2_icount_
- EXT3_FEATURE_INCOMPAT_RECOVER)
- #endif
- #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
-- EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
-+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
-
- /*
- * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
-@@ -472,7 +473,6 @@ typedef struct ext2_icount *ext2_icount_
- #define EXT2_LIB_SOFTSUPP_INCOMPAT (EXT3_FEATURE_INCOMPAT_EXTENTS)
- #define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
-- EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
-
- /*
-@@ -796,12 +796,20 @@ extern errcode_t ext2fs_create_icount2(e
- extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags,
- unsigned int size,
- ext2_icount_t *ret);
-+extern errcode_t ext2fs_icount_fetch32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 *ret);
- extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-+extern errcode_t ext2fs_icount_inc32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 *ret, __u32 overflow);
- extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-+extern errcode_t ext2fs_icount_dec32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 *ret);
- extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-+extern errcode_t ext2fs_icount_store32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 count);
- extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
- __u16 count);
- extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
-Index: e2fsprogs-1.40.7/lib/ext2fs/icount.c
-===================================================================
---- e2fsprogs-1.40.7.orig/lib/ext2fs/icount.c
-+++ e2fsprogs-1.40.7/lib/ext2fs/icount.c
-@@ -43,7 +43,7 @@
-
- struct ext2_icount_el {
- ext2_ino_t ino;
-- __u16 count;
-+ __u32 count;
- };
-
- struct ext2_icount {
-@@ -398,16 +398,16 @@ static struct ext2_icount_el *get_icount
- }
-
- static errcode_t set_inode_count(ext2_icount_t icount, ext2_ino_t ino,
-- __u16 count)
-+ __u32 count)
- {
-- struct ext2_icount_el *el;
-+ struct ext2_icount_el *el;
- TDB_DATA key, data;
-
- if (icount->tdb) {
- key.dptr = (unsigned char *) &ino;
- key.dsize = sizeof(ext2_ino_t);
- data.dptr = (unsigned char *) &count;
-- data.dsize = sizeof(__u16);
-+ data.dsize = sizeof(__u32);
- if (count) {
- if (tdb_store(icount->tdb, key, data, TDB_REPLACE))
- return tdb_error(icount->tdb) +
-@@ -429,9 +429,9 @@ static errcode_t set_inode_count(ext2_ic
- }
-
- static errcode_t get_inode_count(ext2_icount_t icount, ext2_ino_t ino,
-- __u16 *count)
-+ __u32 *count)
- {
-- struct ext2_icount_el *el;
-+ struct ext2_icount_el *el;
- TDB_DATA key, data;
-
- if (icount->tdb) {
-@@ -444,7 +444,7 @@ static errcode_t get_inode_count(ext2_ic
- return tdb_error(icount->tdb) + EXT2_ET_TDB_SUCCESS;
- }
-
-- *count = *((__u16 *) data.dptr);
-+ *count = *((__u32 *) data.dptr);
- free(data.dptr);
- return 0;
- }
-@@ -481,7 +481,7 @@ errcode_t ext2fs_icount_validate(ext2_ic
- return ret;
- }
-
--errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
-+errcode_t ext2fs_icount_fetch32(ext2_icount_t icount, ext2_ino_t ino, __u32 *ret)
- {
- EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-
-@@ -501,10 +501,21 @@ errcode_t ext2fs_icount_fetch(ext2_icoun
- return 0;
- }
-
--errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-- __u16 *ret)
-+errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
- {
-- __u16 curr_value;
-+ __u32 ret32 = ret ? *ret : 0;
-+ errcode_t err;
-+
-+ err = ext2fs_icount_fetch32(icount, ino, &ret32);
-+ *ret = (__u16)ret32;
-+
-+ return err;
-+}
-+
-+errcode_t ext2fs_icount_inc32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 *ret, __u32 overflow)
-+{
-+ __u32 curr_value;
-
- EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-
-@@ -529,6 +540,8 @@ errcode_t ext2fs_icount_increment(ext2_i
- if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
- get_inode_count(icount, ino, &curr_value);
- curr_value++;
-+ if (curr_value >= overflow)
-+ curr_value = overflow + 10;
- if (set_inode_count(icount, ino, curr_value))
- return EXT2_ET_NO_MEMORY;
- } else {
-@@ -548,6 +561,8 @@ errcode_t ext2fs_icount_increment(ext2_i
- */
- get_inode_count(icount, ino, &curr_value);
- curr_value++;
-+ if (curr_value >= overflow)
-+ curr_value = overflow + 10;
- if (set_inode_count(icount, ino, curr_value))
- return EXT2_ET_NO_MEMORY;
- }
-@@ -558,10 +573,23 @@ errcode_t ext2fs_icount_increment(ext2_i
- return 0;
- }
-
--errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret)
- {
-- __u16 curr_value;
-+ __u32 ret32 = ret ? *ret : 0;
-+ errcode_t err;
-+
-+ err = ext2fs_icount_inc32(icount, ino, &ret32, (__u16)~0U);
-+ if (ret)
-+ *ret = ret32;
-+
-+ return err;
-+}
-+
-+errcode_t ext2fs_icount_dec32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 *ret)
-+{
-+ __u32 curr_value;
-
- if (!ino || (ino > icount->num_inodes))
- return EXT2_ET_INVALID_ARGUMENT;
-@@ -601,8 +629,21 @@ errcode_t ext2fs_icount_decrement(ext2_i
- return 0;
- }
-
--errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-- __u16 count)
-+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+ __u16 *ret)
-+{
-+ __u32 ret32 = ret ? *ret : 0;
-+ errcode_t err;
-+
-+ err = ext2fs_icount_dec32(icount, ino, &ret32);
-+ if (ret)
-+ *ret = ret32;
-+
-+ return err;
-+}
-+
-+errcode_t ext2fs_icount_store32(ext2_icount_t icount, ext2_ino_t ino,
-+ __u32 count)
- {
- if (!ino || (ino > icount->num_inodes))
- return EXT2_ET_INVALID_ARGUMENT;
-@@ -636,6 +677,12 @@ errcode_t ext2fs_icount_store(ext2_icoun
- return 0;
- }
-
-+errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-+ __u16 count)
-+{
-+ return ext2fs_icount_store32(icount, ino, count);
-+}
-+
- ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount)
- {
- if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
-Index: e2fsprogs-1.40.7/e2fsck/pass3.c
-===================================================================
---- e2fsprogs-1.40.7.orig/e2fsck/pass3.c
-+++ e2fsprogs-1.40.7/e2fsck/pass3.c
-@@ -580,19 +580,22 @@ errcode_t e2fsck_adjust_inode_count(e2fs
- #endif
-
- if (adj == 1) {
-- ext2fs_icount_increment(ctx->inode_count, ino, 0);
-+ ext2fs_icount_inc32(ctx->inode_count, ino, 0,
-+ ext2fs_test_inode_bitmap(ctx->inode_dir_map,
-+ ino) ?
-+ EXT2_LINK_MAX : ~0U);
- if (inode.i_links_count == (__u16) ~0)
- return 0;
- ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
- inode.i_links_count++;
- } else if (adj == -1) {
-- ext2fs_icount_decrement(ctx->inode_count, ino, 0);
-+ ext2fs_icount_dec32(ctx->inode_count, ino, 0);
- if (inode.i_links_count == 0)
- return 0;
- ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
- inode.i_links_count--;
- }
--
-+
- retval = ext2fs_write_inode(fs, ino, &inode);
- if (retval)
- return retval;
-Index: e2fsprogs-1.40.5/misc/tune2fs.8.in
-===================================================================
---- e2fsprogs-1.40.5.orig/misc/tune2fs.8.in
-+++ e2fsprogs-1.40.5/misc/tune2fs.8.in
-@@ -422,6 +422,10 @@ The following filesystem features can be
- .B dir_index
- Use hashed b-trees to speed up lookups in large directories.
- .TP
-+.B dir_nlink
-+Allow directories to have more than 65000 subdirectories (read-only
-+compatible).
-+.TP
- .B filetype
- Store file type information in directory entries.
- .TP
-Index: e2fsprogs-1.40.7/misc/tune2fs.c
-===================================================================
---- e2fsprogs-1.40.7.orig/misc/tune2fs.c
-+++ e2fsprogs-1.40.7/misc/tune2fs.c
-@@ -116,7 +116,8 @@ static __u32 ok_features[3] = {
- EXT2_FEATURE_INCOMPAT_FILETYPE,
- /* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
-- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
-+ EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK
- };
-
- static __u32 clear_ok_features[3] = {
-@@ -127,7 +128,8 @@ static __u32 clear_ok_features[3] = {
- /* Incompat */
- EXT2_FEATURE_INCOMPAT_FILETYPE,
- /* R/O compat */
-- EXT2_FEATURE_RO_COMPAT_LARGE_FILE
-+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK
- };
-
- /*
diff --git a/debian/patches/e2fsprogs-stride_option.patch b/debian/patches/e2fsprogs-stride_option.patch
deleted file mode 100644
index dcd9651..0000000
--- a/debian/patches/e2fsprogs-stride_option.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-Add support for setting the s_raid_stride and s_raid_stripe_width
-fields in the superblock via mke2fs and tune2fs.c. This is useful
-for mballoc to align block allocation on the RAID stripe boundaries.
-
-Signed-off-by: Rupesh Thakare <rupesh at clusterfs.com>
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-
-Index: e2fsprogs-1.40.7/misc/tune2fs.8.in
-===================================================================
---- e2fsprogs-1.40.7.orig/misc/tune2fs.8.in
-+++ e2fsprogs-1.40.7/misc/tune2fs.8.in
-@@ -181,6 +185,34 @@ Clear the test_fs flag, indicating the f
- using production-level filesystem code.
- .RE
- .TP
-+.BI \-E " extended-options"
-+Set extended options for the filesystem. Extended options are comma
-+separated, and may take an argument using the equals ('=') sign.
-+The following extended options are supported:
-+.RS 1.2i
-+.TP
-+.BI stride= stride-size
-+Configure the filesystem for a RAID array with
-+.I stride-size
-+filesystem blocks. This is the number of blocks read or written to disk
-+before moving to next disk. This mostly affects placement of filesystem
-+metadata like bitmaps at
-+.BR mke2fs (2)
-+time to avoid placing them on a single disk, which can hurt the performanace.
-+For example, if the RAID chunk size is 64kB and the filesystem blocksize is
-+4kB then the
-+.I stride-size
-+should be 16.
-+.TP
-+.BI stripe-width= stripe-width
-+Configure the filesystem for a RAID array with
-+.I stripe-width
-+filesystem blocks per stripe. This is typically be stride-size * N, where
-+N is the number of data disks in the RAID (e.g. RAID 5 N+1, RAID 6 N+2).
-+This allows the block allocator to prevent read-modify-write of the
-+parity in a RAID stripe if possible when the data is written.
-+.RE
-+.TP
- .B \-f
- Force the tune2fs operation to complete even in the face of errors. This
- option is useful when removing the
diff --git a/debian/patches/e2fsprogs-tests-f_random_corruption.patch b/debian/patches/e2fsprogs-tests-f_random_corruption.patch
index 413abca..9d93242 100644
--- a/debian/patches/e2fsprogs-tests-f_random_corruption.patch
+++ b/debian/patches/e2fsprogs-tests-f_random_corruption.patch
@@ -29,11 +29,11 @@ bug, this part of the test is not enabled by default.
Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-Index: e2fsprogs-1.40.4/tests/f_random_corruption/script
+Index: e2fsprogs-1.41.1/tests/f_random_corruption/script
===================================================================
--- /dev/null
-+++ e2fsprogs-1.40.4/tests/f_random_corruption/script
-@@ -0,0 +1,277 @@
++++ e2fsprogs-1.41.1/tests/f_random_corruption/script
+@@ -0,0 +1,271 @@
+# This is to make sure that if this test fails other tests can still be run
+# instead of doing an exit. We break before the end of the loop.
+export LOOP_COUNT=${LOOP_COUNT:-1}
@@ -98,16 +98,10 @@ Index: e2fsprogs-1.40.4/tests/f_random_corruption/script
+ HAVE_JOURNAL="-j"
+fi
+
-+# Experimental features should not be used too often.
-+LAZY_BG=$(( $RANDOM % 12 ))
-+if (( LAZY_BG == 0 )); then
-+ FEATURES=$FEATURES,lazy_bg
-+fi
-+
+# meta_bg and resize_inode features should not be enabled simultaneously
+META_BG=$(( $RANDOM % 12 ))
+if (( META_BG == 0 )); then
-+ FEATURES=$FEATURES,meta_bg
++ FEATURES=$FEATURES,meta_bg,^resize_inode
+else
+ FEATURES=$FEATURES,resize_inode
+fi
@@ -127,7 +121,7 @@ Index: e2fsprogs-1.40.4/tests/f_random_corruption/script
+if [ "$FS_TYPE" = "ext4dev" ]; then
+ UNINIT_GROUPS=$((RANDOM % 12 ))
+ if (( UNINIT_GROUPS == 0 )); then
-+ FEATURES=$FEATURES,uninit_groups
++ FEATURES=$FEATURES,uninit_bg
+ fi
+ EXPAND_ESIZE=$((RANDOM % 12 ))
+ if (( EXPAND_EISIZE == 0 )); then
@@ -311,12 +305,12 @@ Index: e2fsprogs-1.40.4/tests/f_random_corruption/script
+
+COUNT=$((COUNT + 1))
+done
-Index: e2fsprogs-1.40.4/tests/Makefile.in
+Index: e2fsprogs-1.41.1/tests/Makefile.in
===================================================================
---- e2fsprogs-1.40.4.orig/tests/Makefile.in
-+++ e2fsprogs-1.40.4/tests/Makefile.in
-@@ -24,6 +24,8 @@ test_script: test_script.in Makefile
- @chmod +x test_script
+--- e2fsprogs-1.41.1.orig/tests/Makefile.in
++++ e2fsprogs-1.41.1/tests/Makefile.in
+@@ -27,6 +27,8 @@ mke2fs.conf: $(srcdir)/../misc/mke2fs.co
+ sed -e 's/blocksize = -1/blocksize = 4096/' $(srcdir)/../misc/mke2fs.conf >mke2fs.conf
check:: test_script
+ @echo "Removing remnants of earlier tests..."
@@ -324,12 +318,12 @@ Index: e2fsprogs-1.40.4/tests/Makefile.in
@echo "Running e2fsprogs test suite..."
@echo " "
@./test_script
-@@ -63,7 +65,7 @@ testend: test_script ${TDIR}/image
+@@ -66,7 +68,7 @@ testend: test_script ${TDIR}/image
@echo "If all is well, edit ${TDIR}/name and rename ${TDIR}."
clean::
-- $(RM) -f *~ *.log *.new *.failed *.ok test.img test_script
-+ $(RM) -f *~ *.log *.new *.failed *.ok test.img* test_script
+- $(RM) -f *~ *.log *.new *.failed *.ok test.img test_script mke2fs.conf
++ $(RM) -f *~ *.log *.new *.failed *.ok test.img* test_script mke2fs.conf
distclean:: clean
$(RM) -f Makefile
diff --git a/debian/patches/e2fsprogs-uninit.patch b/debian/patches/e2fsprogs-uninit.patch
deleted file mode 100644
index b76c3ee..0000000
--- a/debian/patches/e2fsprogs-uninit.patch
+++ /dev/null
@@ -1,2583 +0,0 @@
-Support for the COMPAT_GDT_CSUM (uninit_groups) feature.
-
-Allows skipping uninitialized inode and block bitmap checks, and
-skipping unused parts of the inode table. Can dramatically speed
-up e2fsck on large filesystems where the inode table is mostly
-unused.
-
-Signed-off-by: Andreas Dilger <adilger at clusterfs.com>
-Signed-off-by: Girish Shilamkar <girish at clusterfs.com>
-Signed-off-by: Kalpak Shah <kalpak at clusterfs.com>
-
-Index: e2fsprogs-1.40.11/debugfs/debugfs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/debugfs.c
-+++ e2fsprogs-1.40.11/debugfs/debugfs.c
-@@ -286,7 +286,10 @@ void do_show_super_stats(int argc, char
- FILE *out;
- struct ext2_group_desc *gdp;
- int c, header_only = 0;
-- int numdirs = 0, first;
-+ int numdirs = 0, first, gdt_csum;
-+
-+ gdt_csum = EXT2_HAS_RO_COMPAT_FEATURE(current_fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
-
- reset_getopt();
- while ((c = getopt (argc, argv, "h")) != EOF) {
-@@ -322,7 +325,7 @@ void do_show_super_stats(int argc, char
- "inode table at %u\n"
- " %d free %s, "
- "%d free %s, "
-- "%d used %s\n",
-+ "%d used %s%s",
- i, gdp->bg_block_bitmap,
- gdp->bg_inode_bitmap, gdp->bg_inode_table,
- gdp->bg_free_blocks_count,
-@@ -331,12 +334,21 @@ void do_show_super_stats(int argc, char
- gdp->bg_free_inodes_count != 1 ? "inodes" : "inode",
- gdp->bg_used_dirs_count,
- gdp->bg_used_dirs_count != 1 ? "directories"
-- : "directory");
-+ : "directory", gdt_csum ? ", " : "\n");
-+ if (gdt_csum)
-+ fprintf(out, "%d unused %s\n",
-+ gdp->bg_itable_unused,
-+ gdp->bg_itable_unused != 1 ? "inodes":"inode");
- first = 1;
- print_bg_opts(gdp, EXT2_BG_INODE_UNINIT, "Inode not init",
- &first, out);
- print_bg_opts(gdp, EXT2_BG_BLOCK_UNINIT, "Block not init",
- &first, out);
-+ if (gdt_csum) {
-+ fprintf(out, "%sChecksum 0x%04x",
-+ first ? " [":", ", gdp->bg_checksum);
-+ first = 0;
-+ }
- if (!first)
- fputs("]\n", out);
- }
-Index: e2fsprogs-1.40.11/debugfs/set_fields.c
-===================================================================
---- e2fsprogs-1.40.11.orig/debugfs/set_fields.c
-+++ e2fsprogs-1.40.11/debugfs/set_fields.c
-@@ -39,6 +39,7 @@
- static struct ext2_super_block set_sb;
- static struct ext2_inode set_inode;
- static struct ext2_group_desc set_gd;
-+static dgrp_t set_bg;
- static ext2_ino_t set_ino;
- static int array_idx;
-
-@@ -60,6 +61,7 @@ static errcode_t parse_uuid(struct field
- static errcode_t parse_hashalg(struct field_set_info *info, char *arg);
- static errcode_t parse_time(struct field_set_info *info, char *arg);
- static errcode_t parse_bmap(struct field_set_info *info, char *arg);
-+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg);
-
- static struct field_set_info super_fields[] = {
- { "inodes_count", &set_sb.s_inodes_count, 4, parse_uint },
-@@ -175,7 +177,7 @@ static struct field_set_info ext2_bg_fie
- { "flags", &set_gd.bg_flags, 2, parse_uint },
- { "reserved", &set_gd.bg_reserved, 2, parse_uint, FLAG_ARRAY, 2 },
- { "itable_unused", &set_gd.bg_itable_unused, 2, parse_uint },
-- { "checksum", &set_gd.bg_checksum, 2, parse_uint },
-+ { "checksum", &set_gd.bg_checksum, 2, parse_gd_csum },
- { 0, 0, 0, 0 }
- };
-
-@@ -399,6 +401,17 @@ static errcode_t parse_bmap(struct field
- return retval;
- }
-
-+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg)
-+{
-+ __u16 *val = info->ptr;
-+
-+ if (strcmp(arg, "calc") == 0) {
-+ *val = ext2fs_group_desc_csum(&set_sb, set_bg, &set_gd);
-+ return 0;
-+ }
-+
-+ return parse_uint(info, arg);
-+}
-
- static void print_possible_fields(struct field_set_info *fields)
- {
-@@ -518,7 +531,6 @@ void do_set_block_group_descriptor(int a
- "\t\"set_block_group_descriptor -l\" will list the names of "
- "the fields in a block group descriptor\n\twhich can be set.";
- struct field_set_info *ss;
-- dgrp_t set_bg;
- char *end;
-
- if ((argc == 2) && !strcmp(argv[1], "-l")) {
-@@ -548,6 +560,7 @@ void do_set_block_group_descriptor(int a
- }
-
- set_gd = current_fs->group_desc[set_bg];
-+ set_sb = *current_fs->super;
-
- if (ss->func(ss, argv[3]) == 0) {
- current_fs->group_desc[set_bg] = set_gd;
-Index: e2fsprogs-1.40.11/e2fsck/journal.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/journal.c
-+++ e2fsprogs-1.40.11/e2fsck/journal.c
-@@ -988,6 +988,8 @@ void e2fsck_move_ext3_journal(e2fsck_t c
- ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
- ext2fs_mark_ib_dirty(fs);
- fs->group_desc[group].bg_free_inodes_count++;
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,&fs->group_desc[group]);
- fs->super->s_free_inodes_count++;
- return;
-
-Index: e2fsprogs-1.40.11/e2fsck/pass5.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/pass5.c
-+++ e2fsprogs-1.40.11/e2fsck/pass5.c
-@@ -121,7 +121,7 @@ static void check_block_bitmaps(e2fsck_t
- struct problem_context pctx;
- int problem, save_problem, fixit, had_problem;
- errcode_t retval;
-- int lazy_bg = 0;
-+ int lazy_flag, csum_flag;
- int skip_group = 0;
-
- clear_problem_context(&pctx);
-@@ -158,15 +158,16 @@ static void check_block_bitmaps(e2fsck_t
- goto errout;
- }
-
-- if (EXT2_HAS_COMPAT_FEATURE(fs->super, EXT2_FEATURE_COMPAT_LAZY_BG))
-- lazy_bg++;
--
-+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG);
-+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- redo_counts:
- had_problem = 0;
- save_problem = 0;
- pctx.blk = pctx.blk2 = NO_BLK;
-- if (lazy_bg && (fs->group_desc[group].bg_flags &
-- EXT2_BG_BLOCK_UNINIT))
-+ if ((lazy_flag || csum_flag) &&
-+ (fs->group_desc[group].bg_flags & EXT2_BG_BLOCK_UNINIT))
- skip_group++;
- super = fs->super->s_first_data_block;
- for (i = fs->super->s_first_data_block;
-@@ -206,6 +207,17 @@ redo_counts:
- * Block used, but not marked in use in the bitmap.
- */
- problem = PR_5_BLOCK_USED;
-+
-+ if (skip_group) {
-+ struct problem_context pctx2;
-+ pctx2.blk = i;
-+ pctx2.group = group;
-+ if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){
-+ fs->group_desc[group].bg_flags &=
-+ ~EXT2_BG_BLOCK_UNINIT;
-+ skip_group = 0;
-+ }
-+ }
- }
- if (pctx.blk == NO_BLK) {
- pctx.blk = pctx.blk2 = i;
-@@ -224,7 +236,7 @@ redo_counts:
- had_problem++;
-
- do_counts:
-- if (!bitmap && !skip_group) {
-+ if (!bitmap && (!skip_group || csum_flag)) {
- group_free++;
- free_blocks++;
- }
-@@ -241,7 +253,7 @@ redo_counts:
- if ((ctx->progress)(ctx, 5, group,
- fs->group_desc_count*2))
- goto errout;
-- if (lazy_bg &&
-+ if ((lazy_flag || csum_flag) &&
- (i != fs->super->s_blocks_count-1) &&
- (fs->group_desc[group].bg_flags &
- EXT2_BG_BLOCK_UNINIT))
-@@ -321,7 +333,7 @@ static void check_inode_bitmaps(e2fsck_t
- errcode_t retval;
- struct problem_context pctx;
- int problem, save_problem, fixit, had_problem;
-- int lazy_bg = 0;
-+ int lazy_flag, csum_flag;
- int skip_group = 0;
-
- clear_problem_context(&pctx);
-@@ -358,16 +370,16 @@ static void check_inode_bitmaps(e2fsck_t
- goto errout;
- }
-
-- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-- EXT2_FEATURE_COMPAT_LAZY_BG))
-- lazy_bg++;
--
-+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG);
-+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- redo_counts:
- had_problem = 0;
- save_problem = 0;
- pctx.ino = pctx.ino2 = 0;
-- if (lazy_bg && (fs->group_desc[group].bg_flags &
-- EXT2_BG_INODE_UNINIT))
-+ if ((lazy_flag || csum_flag) &&
-+ (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT))
- skip_group++;
-
- /* Protect loop from wrap-around if inodes_count is maxed */
-@@ -390,6 +402,21 @@ redo_counts:
- * Inode used, but not in bitmap
- */
- problem = PR_5_INODE_USED;
-+
-+ /* We should never hit this, because it means that
-+ * inodes were marked in use that weren't noticed
-+ * in pass1 or pass 2. It is easier to fix the problem
-+ * than to kill e2fsck and leave the user stuck. */
-+ if (skip_group) {
-+ struct problem_context pctx2;
-+ pctx2.blk = i;
-+ pctx2.group = group;
-+ if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){
-+ fs->group_desc[group].bg_flags &=
-+ ~EXT2_BG_INODE_UNINIT;
-+ skip_group = 0;
-+ }
-+ }
- }
- if (pctx.ino == 0) {
- pctx.ino = pctx.ino2 = i;
-@@ -411,7 +438,7 @@ do_counts:
- if (bitmap) {
- if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
- dirs_count++;
-- } else if (!skip_group) {
-+ } else if (!skip_group || csum_flag) {
- group_free++;
- free_inodes++;
- }
-@@ -430,7 +457,7 @@ do_counts:
- group + fs->group_desc_count,
- fs->group_desc_count*2))
- goto errout;
-- if (lazy_bg &&
-+ if ((lazy_flag || csum_flag) &&
- (i != fs->super->s_inodes_count) &&
- (fs->group_desc[group].bg_flags &
- EXT2_BG_INODE_UNINIT))
-Index: e2fsprogs-1.40.11/e2fsck/problem.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/problem.c
-+++ e2fsprogs-1.40.11/e2fsck/problem.c
-@@ -351,8 +351,33 @@ static struct e2fsck_problem problem_tab
- N_("Adding dirhash hint to @f.\n\n"),
- PROMPT_NONE, 0 },
-
-+ /* Group descriptor N checksum is invalid. */
-+ { PR_0_GDT_CSUM,
-+ N_("@g descriptor %g checksum is invalid. "),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Group descriptor N marked uninitialized without feature set. */
-+ { PR_0_GDT_UNINIT,
-+ N_("@g descriptor %g marked uninitialized without feature set.\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Group N block bitmap uninitialized but inode bitmap in use. */
-+ { PR_0_BB_UNINIT_IB_INIT,
-+ N_("@g %g @b @B uninitialized but @i @B in use.\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Group descriptor N has invalid unused inodes count. */
-+ { PR_0_GDT_ITABLE_UNUSED,
-+ N_("@g descriptor %g has invalid unused inodes count %b. "),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Last group block bitmap uninitialized. */
-+ { PR_0_BB_UNINIT_LAST,
-+ N_("last @g @b @B uninitialized. "),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
- /* Pass 1 errors */
--
-+
- /* Pass 1: Checking inodes, blocks, and sizes */
- { PR_1_PASS_HEADER,
- N_("Pass 1: Checking @is, @bs, and sizes\n"),
-@@ -1243,7 +1268,17 @@ static struct e2fsck_problem problem_tab
- /* Unexpected HTREE block */
- { PR_2_UNEXPECTED_HTREE_BLOCK,
- N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
--
-+
-+ /* Inode found in group where _INODE_UNINIT is set */
-+ { PR_2_INOREF_BG_INO_UNINIT,
-+ N_("@i %i found in @g %g where _INODE_UNINIT is set. "),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Inode found in group unused inodes area */
-+ { PR_2_INOREF_IN_UNUSED,
-+ N_("@i %i found in @g %g unused inodes area. "),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
- /* Pass 3 errors */
-
- /* Pass 3: Checking directory connectivity */
-@@ -1550,6 +1585,16 @@ static struct e2fsck_problem problem_tab
- " +(%i--%j)",
- PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
-+ /* Group N block(s) in use but group is marked BLOCK_UNINIT */
-+ { PR_5_BLOCK_UNINIT,
-+ N_("@g %g @b(s) in use but @g is marked BLOCK_UNINIT\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
-+ /* Group N inode(s) in use but group is marked INODE_UNINIT */
-+ { PR_5_INODE_UNINIT,
-+ N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"),
-+ PROMPT_FIX, PR_PREEN_OK },
-+
- /* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
- { PR_6_RECREATE_JOURNAL,
- N_("Recreate journal to make the filesystem ext3 again?\n"),
-Index: e2fsprogs-1.40.11/e2fsck/problem.h
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/problem.h
-+++ e2fsprogs-1.40.11/e2fsck/problem.h
-@@ -197,6 +197,21 @@ struct problem_context {
- /* Superblock hint for external journal incorrect */
- #define PR_0_DIRHASH_HINT 0x000034
-
-+/* Group descriptor N checksum is invalid */
-+#define PR_0_GDT_CSUM 0x000035
-+
-+/* Group descriptor N marked uninitialized without feature set. */
-+#define PR_0_GDT_UNINIT 0x000036
-+
-+/* Block bitmap is uninitialised but Inode bitmap in use. */
-+#define PR_0_BB_UNINIT_IB_INIT 0x000037
-+
-+/* Group descriptor N has invalid unused inodes count. */
-+#define PR_0_GDT_ITABLE_UNUSED 0x000038
-+
-+/* Last group block bitmap is uninitialized. */
-+#define PR_0_BB_UNINIT_LAST 0x000039
-+
- /*
- * Pass 1 errors
- */
-@@ -748,6 +763,12 @@ struct problem_context {
- /* Unexpected HTREE block */
- #define PR_2_UNEXPECTED_HTREE_BLOCK 0x020045
-
-+/* Inode found in group where _INODE_UNINIT is set */
-+#define PR_2_INOREF_BG_INO_UNINIT 0x020046
-+
-+/* Inode found in group unused inodes area */
-+#define PR_2_INOREF_IN_UNUSED 0x020047
-+
- /*
- * Pass 3 errors
- */
-@@ -936,10 +957,16 @@ struct problem_context {
-
- /* Inode range not used, but marked in bitmap */
- #define PR_5_INODE_RANGE_UNUSED 0x050016
--
-+
- /* Inode rangeused, but not marked used in bitmap */
- #define PR_5_INODE_RANGE_USED 0x050017
-
-+/* Block in use but group is marked BLOCK_UNINIT */
-+#define PR_5_BLOCK_UNINIT 0x050018
-+
-+/* Inode in use but group is marked INODE_UNINIT */
-+#define PR_5_INODE_UNINIT 0x050019
-+
- /*
- * Post-Pass 5 errors
- */
-Index: e2fsprogs-1.40.11/e2fsck/super.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/super.c
-+++ e2fsprogs-1.40.11/e2fsck/super.c
-@@ -468,6 +468,7 @@ void check_super_block(e2fsck_t ctx)
- blk_t should_be;
- struct problem_context pctx;
- __u32 free_blocks = 0, free_inodes = 0;
-+ int lazy_flag, csum_flag;
-
- inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
- ipg_max = inodes_per_block * (blocks_per_group - 4);
-@@ -576,6 +577,10 @@ void check_super_block(e2fsck_t ctx)
- */
- first_block = sb->s_first_data_block;
-
-+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG);
-+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
- pctx.group = i;
-
-@@ -621,6 +626,50 @@ void check_super_block(e2fsck_t ctx)
- (gd->bg_used_dirs_count > sb->s_inodes_per_group))
- ext2fs_unmark_valid(fs);
-
-+ if (!ext2fs_group_desc_csum_verify(sb, i, gd)) {
-+ if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
-+ gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
-+ EXT2_BG_INODE_UNINIT);
-+ gd->bg_itable_unused = 0;
-+ }
-+ ext2fs_unmark_valid(fs);
-+ }
-+
-+ if (!lazy_flag && !csum_flag &&
-+ (gd->bg_flags &(EXT2_BG_BLOCK_UNINIT|EXT2_BG_INODE_UNINIT)||
-+ gd->bg_itable_unused != 0)){
-+ if (fix_problem(ctx, PR_0_GDT_UNINIT, &pctx)) {
-+ gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
-+ EXT2_BG_INODE_UNINIT);
-+ gd->bg_itable_unused = 0;
-+ }
-+ ext2fs_unmark_valid(fs);
-+ }
-+
-+ if (i == fs->group_desc_count - 1 &&
-+ gd->bg_flags & EXT2_BG_BLOCK_UNINIT) {
-+ if (fix_problem(ctx, PR_0_BB_UNINIT_LAST, &pctx))
-+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
-+ ext2fs_unmark_valid(fs);
-+ }
-+
-+ if (gd->bg_flags & EXT2_BG_BLOCK_UNINIT &&
-+ !(gd->bg_flags & EXT2_BG_INODE_UNINIT)) {
-+ if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx))
-+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
-+ ext2fs_unmark_valid(fs);
-+ }
-+
-+ if (csum_flag &&
-+ (gd->bg_itable_unused > gd->bg_free_inodes_count ||
-+ gd->bg_itable_unused > sb->s_inodes_per_group)) {
-+ pctx.blk = gd->bg_itable_unused;
-+ if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx))
-+ gd->bg_itable_unused = 0;
-+ ext2fs_unmark_valid(fs);
-+ }
-+
-+ gd->bg_checksum = ext2fs_group_desc_csum(fs->super, i, gd);
- }
-
- /*
-Index: e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/Makefile.in
-+++ e2fsprogs-1.40.11/lib/ext2fs/Makefile.in
-@@ -67,7 +67,9 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_O
- unix_io.o \
- unlink.o \
- valid_blk.o \
-- version.o
-+ version.o \
-+ crc16.o \
-+ csum.o
-
- SRCS= ext2_err.c \
- $(srcdir)/alloc.c \
-@@ -127,6 +129,9 @@ SRCS= ext2_err.c \
- $(srcdir)/swapfs.c \
- $(srcdir)/tdb.c \
- $(srcdir)/test_io.c \
-+ $(srcdir)/tst_csum.c \
-+ $(srcdir)/crc16.c \
-+ $(srcdir)/csum.c \
- $(srcdir)/unix_io.c \
- $(srcdir)/unlink.c \
- $(srcdir)/valid_blk.c \
-@@ -191,11 +196,13 @@ ext2fs.pc: $(srcdir)/ext2fs.pc.in $(top_
- @cd $(top_builddir); CONFIG_FILES=lib/ext2fs/ext2fs.pc ./config.status
-
- tst_badblocks: tst_badblocks.o freefs.o \
-- read_bb_file.o write_bb_file.o badblocks.o
-+ read_bb_file.o write_bb_file.o badblocks.o csum.o \
-+ crc16.o $(STATIC_LIBEXT2FS)
- @echo " LD $@"
- @$(CC) -o tst_badblocks tst_badblocks.o freefs.o \
- read_bb_file.o write_bb_file.o badblocks.o \
-- inline.o bitops.o gen_bitmap.o $(LIBCOM_ERR)
-+ inline.o bitops.o gen_bitmap.o bitmaps.o csum.o crc16.o \
-+ $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
-
- tst_icount: icount.c initialize.o $(STATIC_LIBEXT2FS)
- @echo " LD $@"
-@@ -227,6 +234,11 @@ tst_bitops: tst_bitops.o inline.o $(STAT
- @$(CC) -o tst_bitops tst_bitops.o inline.o $(ALL_CFLAGS) \
- $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
-
-+tst_csum: tst_csum.o csum.o crc16.o $(STATIC_LIBEXT2FS) $(STATIC_LIBUUID)
-+ @echo " LD $@"
-+ @$(CC) -o tst_csum csum.o tst_csum.o crc16.o $(STATIC_LIBEXT2FS) \
-+ $(STATIC_LIBUUID) $(LIBCOM_ERR)
-+
- tst_getsectsize: tst_getsectsize.o getsectsize.o $(STATIC_LIBEXT2FS)
- @echo " LD $@"
- @$(CC) -o tst_sectgetsize tst_getsectsize.o getsectsize.o \
-@@ -249,7 +261,7 @@ mkjournal: mkjournal.c $(STATIC_LIBEXT2F
- @$(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
-
- check:: tst_bitops tst_badblocks tst_iscan @SWAPFS_CMT@ tst_byteswap \
-- tst_types tst_icount tst_super_size
-+ tst_types tst_icount tst_super_size tst_csum
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_bitops
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_badblocks
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_iscan
-@@ -257,6 +269,7 @@ check:: tst_bitops tst_badblocks tst_isc
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_types
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_icount
- LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_super_size
-+ LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_csum
-
- installdirs::
- @echo " MKINSTALLDIRS $(libdir) $(includedir)/ext2fs"
-@@ -368,6 +381,10 @@ cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-+crc16.o: $(srcdir)/crc16.c $(srcdir)/ext2_fs.h $(srcdir)/crc16.h \
-+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h
-+csum.o: $(srcdir)/csum.c $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h \
-+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_builddir)/lib/ext2fs/ext2_err.h
- dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2_fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
-@@ -582,6 +599,8 @@ tst_byteswap.o: $(srcdir)/tst_byteswap.c
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-+tst_csum.o: $(srcdir)/tst_csum.c $(srcdir)/ext2_fs.h \
-+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h
- tst_getsize.o: $(srcdir)/tst_getsize.c $(srcdir)/ext2_fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
-Index: e2fsprogs-1.40.11/lib/ext2fs/alloc_stats.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/alloc_stats.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/alloc_stats.c
-@@ -27,6 +27,27 @@ void ext2fs_inode_alloc_stats2(ext2_fils
- fs->group_desc[group].bg_free_inodes_count -= inuse;
- if (isdir)
- fs->group_desc[group].bg_used_dirs_count += inuse;
-+
-+ /* We don't strictly need to be clearing these if inuse < 0
-+ * (i.e. freeing inodes) but it also means something is bad. */
-+ fs->group_desc[group].bg_flags &= ~(EXT2_BG_INODE_UNINIT |
-+ EXT2_BG_BLOCK_UNINIT);
-+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-+ ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group -
-+ fs->group_desc[group].bg_itable_unused +
-+ group * fs->super->s_inodes_per_group + 1;
-+
-+ if (ino >= first_unused_inode)
-+ fs->group_desc[group].bg_itable_unused =
-+ group * fs->super->s_inodes_per_group +
-+ fs->super->s_inodes_per_group - ino;
-+
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,
-+ &fs->group_desc[group]);
-+ }
-+
- fs->super->s_free_inodes_count -= inuse;
- ext2fs_mark_super_dirty(fs);
- ext2fs_mark_ib_dirty(fs);
-@@ -46,6 +67,10 @@ void ext2fs_block_alloc_stats(ext2_filsy
- else
- ext2fs_unmark_block_bitmap(fs->block_map, blk);
- fs->group_desc[group].bg_free_blocks_count -= inuse;
-+ fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,&fs->group_desc[group]);
-+
- fs->super->s_free_blocks_count -= inuse;
- ext2fs_mark_super_dirty(fs);
- ext2fs_mark_bb_dirty(fs);
-Index: e2fsprogs-1.40.11/lib/ext2fs/alloc_tables.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/alloc_tables.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/alloc_tables.c
-@@ -95,13 +95,12 @@ errcode_t ext2fs_allocate_group_table(ex
- ext2fs_mark_block_bitmap(bmap, blk);
- fs->group_desc[group].bg_inode_table = new_blk;
- }
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,&fs->group_desc[group]);
-
--
- return 0;
- }
-
--
--
- errcode_t ext2fs_allocate_tables(ext2_filsys fs)
- {
- errcode_t retval;
-Index: e2fsprogs-1.40.11/lib/ext2fs/ext2_fs.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ext2_fs.h
-+++ e2fsprogs-1.40.11/lib/ext2fs/ext2_fs.h
-@@ -173,6 +173,7 @@ struct ext4_group_desc
-
- #define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
- #define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */
-+#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
-
- /*
- * Data structures used by the directory indexing feature
-Index: e2fsprogs-1.40.11/lib/ext2fs/ext2fs.h
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/ext2fs.h
-+++ e2fsprogs-1.40.11/lib/ext2fs/ext2fs.h
-@@ -344,6 +344,7 @@ typedef struct ext2_struct_inode_scan *e
- #define EXT2_SF_BAD_EXTRA_BYTES 0x0004
- #define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
- #define EXT2_SF_DO_LAZY 0x0010
-+#define EXT2_SF_DO_CSUM 0x0020
-
- /*
- * ext2fs_check_if_mounted flags
-@@ -467,7 +468,8 @@ typedef struct ext2_icount *ext2_icount_
- #endif
- #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
-- EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
-
- /*
- * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
-@@ -475,7 +477,6 @@ typedef struct ext2_icount *ext2_icount_
- */
- #define EXT2_LIB_SOFTSUPP_INCOMPAT (EXT3_FEATURE_INCOMPAT_EXTENTS)
- #define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
-- EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
-
- /*
-@@ -625,6 +626,12 @@ extern errcode_t ext2fs_check_desc(ext2_
- extern errcode_t ext2fs_close(ext2_filsys fs);
- extern errcode_t ext2fs_flush(ext2_filsys fs);
- extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
-+extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
-+ dgrp_t group,
-+ blk_t *ret_super_blk,
-+ blk_t *ret_old_desc_blk,
-+ blk_t *ret_new_desc_blk,
-+ blk_t *ret_used_blks);
- extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
- dgrp_t group,
- blk_t *ret_super_blk,
-@@ -639,6 +646,13 @@ extern errcode_t ext2fs_compare_block_bi
- extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
- ext2fs_inode_bitmap bm2);
-
-+/* csum.c */
-+extern __u16 ext2fs_group_desc_csum(struct ext2_super_block *sb, __u32 group,
-+ struct ext2_group_desc *desc);
-+extern int ext2fs_group_desc_csum_verify(struct ext2_super_block *sb,
-+ __u32 group, struct ext2_group_desc *desc);
-+extern void ext2fs_set_gdt_csum(ext2_filsys fs);
-+
- /* dblist.c */
-
- extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
-Index: e2fsprogs-1.40.11/lib/ext2fs/inode.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/inode.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/inode.c
-@@ -167,6 +167,9 @@ errcode_t ext2fs_open_inode_scan(ext2_fi
- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
- EXT2_FEATURE_COMPAT_LAZY_BG))
- scan->scan_flags |= EXT2_SF_DO_LAZY;
-+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
-+ scan->scan_flags |= EXT2_SF_DO_LAZY | EXT2_SF_DO_CSUM;
- *ret_scan = scan;
- return 0;
- }
-@@ -218,18 +221,29 @@ int ext2fs_inode_scan_flags(ext2_inode_s
- */
- static errcode_t get_next_blockgroup(ext2_inode_scan scan)
- {
-+ ext2_filsys fs = scan->fs;
-+
- scan->current_group++;
- scan->groups_left--;
--
-- scan->current_block = scan->fs->
-- group_desc[scan->current_group].bg_inode_table;
-+
-+ scan->current_block =fs->group_desc[scan->current_group].bg_inode_table;
-
- scan->current_inode = scan->current_group *
-- EXT2_INODES_PER_GROUP(scan->fs->super);
-+ EXT2_INODES_PER_GROUP(fs->super);
-
- scan->bytes_left = 0;
-- scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
-- scan->blocks_left = scan->fs->inode_blocks_per_group;
-+ scan->inodes_left = EXT2_INODES_PER_GROUP(fs->super);
-+ scan->blocks_left = fs->inode_blocks_per_group;
-+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-+ scan->inodes_left -=
-+ fs->group_desc[scan->current_group].bg_itable_unused;
-+ scan->blocks_left =
-+ (scan->inodes_left +
-+ (fs->blocksize / scan->inode_size - 1)) *
-+ scan->inode_size / fs->blocksize;
-+ }
-+
- return 0;
- }
-
-@@ -417,6 +431,8 @@ errcode_t ext2fs_get_next_inode_full(ext
- (scan->fs->group_desc[scan->current_group].bg_flags &
- EXT2_BG_INODE_UNINIT))
- goto force_new_group;
-+ if (scan->inodes_left == 0)
-+ goto force_new_group;
- if (scan->current_block == 0) {
- if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
- goto force_new_group;
-Index: e2fsprogs-1.40.11/lib/ext2fs/rw_bitmaps.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/rw_bitmaps.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/rw_bitmaps.c
-@@ -161,6 +161,36 @@ static errcode_t write_bitmaps(ext2_fils
- return 0;
- }
-
-+static void get_uninit_block_bitmap(ext2_filsys fs, dgrp_t group,
-+ char *block_bitmap)
-+{
-+ blk_t super_blk, old_desc_blk, new_desc_blk;
-+ int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+ int i;
-+
-+ memset(block_bitmap, 0, block_nbytes);
-+
-+ ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
-+ &old_desc_blk, &new_desc_blk, 0);
-+
-+ if (super_blk)
-+ ext2fs_mark_block_bitmap(fs->block_map, super_blk);
-+ if (old_desc_blk)
-+ for (i = 0; i < fs->desc_blocks +
-+ fs->super->s_reserved_gdt_blocks; i++)
-+ ext2fs_mark_block_bitmap(fs->block_map, old_desc_blk+i);
-+ if (new_desc_blk)
-+ ext2fs_mark_block_bitmap(fs->block_map, new_desc_blk);
-+
-+ ext2fs_mark_block_bitmap(fs->block_map,
-+ fs->group_desc[group].bg_block_bitmap);
-+ ext2fs_mark_block_bitmap(fs->block_map,
-+ fs->group_desc[group].bg_inode_bitmap);
-+ for (i = 0; i < fs->inode_blocks_per_group; i++)
-+ ext2fs_mark_block_bitmap(fs->block_map,
-+ fs->group_desc[group].bg_inode_table + i);
-+}
-+
- static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
- {
- dgrp_t i;
-@@ -176,8 +206,10 @@ static errcode_t read_bitmaps(ext2_filsy
-
- fs->write_bitmaps = ext2fs_write_bitmaps;
-
-- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-- EXT2_FEATURE_COMPAT_LAZY_BG))
-+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG) ||
-+ EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
- lazy_flag = 1;
-
- retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
-@@ -229,7 +261,9 @@ static errcode_t read_bitmaps(ext2_filsy
- if (block_bitmap) {
- blk = fs->group_desc[i].bg_block_bitmap;
- if (lazy_flag && fs->group_desc[i].bg_flags &
-- EXT2_BG_BLOCK_UNINIT)
-+ EXT2_BG_BLOCK_UNINIT &&
-+ ext2fs_group_desc_csum_verify(fs->super, i,
-+ &fs->group_desc[i]))
- blk = 0;
- if (blk) {
- retval = io_channel_read_blk(fs->io, blk,
-@@ -243,14 +277,23 @@ static errcode_t read_bitmaps(ext2_filsy
- (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
- ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes);
- #endif
-- } else
-- memset(block_bitmap, 0xff, block_nbytes);
-+ } else {
-+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG) &&
-+ !EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
-+ memset(block_bitmap, 0xff, block_nbytes);
-+ else
-+ get_uninit_block_bitmap(fs, i, block_bitmap);
-+ }
- block_bitmap += block_nbytes;
- }
- if (inode_bitmap) {
- blk = fs->group_desc[i].bg_inode_bitmap;
- if (lazy_flag && fs->group_desc[i].bg_flags &
-- EXT2_BG_INODE_UNINIT)
-+ EXT2_BG_INODE_UNINIT &&
-+ ext2fs_group_desc_csum_verify(fs->super, i,
-+ &fs->group_desc[i]))
- blk = 0;
- if (blk) {
- retval = io_channel_read_blk(fs->io, blk,
-@@ -264,8 +307,15 @@ static errcode_t read_bitmaps(ext2_filsy
- (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
- ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes);
- #endif
-- } else
-- memset(inode_bitmap, 0xff, inode_nbytes);
-+ } else {
-+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG) &&
-+ !EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
-+ memset(inode_bitmap, 0xff, inode_nbytes);
-+ else
-+ memset(inode_bitmap, 0, inode_nbytes);
-+ }
- inode_bitmap += inode_nbytes;
- }
- }
-Index: e2fsprogs-1.40.11/misc/dumpe2fs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/misc/dumpe2fs.c
-+++ e2fsprogs-1.40.11/misc/dumpe2fs.c
-@@ -112,7 +112,8 @@ static void print_bg_opts(ext2_filsys fs
- {
- int first = 1, bg_flags;
-
-- if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_LAZY_BG)
-+ if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_LAZY_BG ||
-+ fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
- bg_flags = fs->group_desc[i].bg_flags;
- else
- bg_flags = 0;
-@@ -204,11 +205,15 @@ static void list_desc (ext2_filsys fs)
- diff = fs->group_desc[i].bg_inode_table - first_block;
- if (diff > 0)
- printf(" (+%ld)", diff);
-- printf (_("\n %d free blocks, %d free inodes, "
-- "%d directories\n"),
-+ printf (_("\n %u free blocks, %u free inodes, "
-+ "%u directories%s"),
- fs->group_desc[i].bg_free_blocks_count,
- fs->group_desc[i].bg_free_inodes_count,
-- fs->group_desc[i].bg_used_dirs_count);
-+ fs->group_desc[i].bg_used_dirs_count,
-+ fs->group_desc[i].bg_itable_unused ? "" : "\n");
-+ if (fs->group_desc[i].bg_itable_unused)
-+ printf (_(", %u unused inodes\n"),
-+ fs->group_desc[i].bg_itable_unused);
- if (block_bitmap) {
- fputs(_(" Free blocks: "), stdout);
- print_free (i, block_bitmap,
-Index: e2fsprogs-1.40.11/misc/mke2fs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/misc/mke2fs.c
-+++ e2fsprogs-1.40.11/misc/mke2fs.c
-@@ -433,6 +433,8 @@ static void write_inode_tables(ext2_fils
- num, blk, error_message(retval));
- exit(1);
- }
-+ /* The kernel doesn't need to zero the itable blocks */
-+ fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
- }
- if (sync_kludge) {
- if (sync_kludge == 1)
-@@ -448,34 +450,49 @@ static void write_inode_tables(ext2_fils
- static void setup_lazy_bg(ext2_filsys fs)
- {
- dgrp_t i;
-- int blks;
-+ int blks, csum_flag;
- struct ext2_super_block *sb = fs->super;
- struct ext2_group_desc *bg = fs->group_desc;
-
-- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
-- EXT2_FEATURE_COMPAT_LAZY_BG)) {
-+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
-+ if (EXT2_HAS_COMPAT_FEATURE(fs->super, EXT2_FEATURE_COMPAT_LAZY_BG) ||
-+ csum_flag) {
- for (i = 0; i < fs->group_desc_count; i++, bg++) {
- if ((i == 0) ||
-- (i == fs->group_desc_count-1))
-+ (i == fs->group_desc_count - 1 && !csum_flag))
- continue;
- if (bg->bg_free_inodes_count ==
- sb->s_inodes_per_group) {
-- bg->bg_free_inodes_count = 0;
- bg->bg_flags |= EXT2_BG_INODE_UNINIT;
-- sb->s_free_inodes_count -=
-- sb->s_inodes_per_group;
-+ if (!csum_flag) {
-+ bg->bg_free_inodes_count = 0;
-+ sb->s_free_inodes_count -=
-+ sb->s_inodes_per_group;
-+ }
- }
-+
-+ /* Skip groups with GDT backups because the resize
-+ * inode has blocks allocated in them, and the last
-+ * group because it needs block bitmap padding. */
-+ if ((ext2fs_bg_has_super(fs, i) &&
-+ sb->s_reserved_gdt_blocks) ||
-+ i == fs->group_desc_count - 1)
-+ continue;
-+
- blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
-- if (bg->bg_free_blocks_count == blks) {
-- bg->bg_free_blocks_count = 0;
-+ if (bg->bg_free_blocks_count == blks &&
-+ bg->bg_flags & EXT2_BG_INODE_UNINIT) {
- bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
-- sb->s_free_blocks_count -= blks;
-+ if (!csum_flag) {
-+ bg->bg_free_blocks_count = 0;
-+ sb->s_free_blocks_count -= blks;
-+ }
- }
- }
- }
- }
-
--
- static void create_root_dir(ext2_filsys fs)
- {
- errcode_t retval;
-@@ -910,7 +927,8 @@ static __u32 ok_features[3] = {
- EXT2_FEATURE_INCOMPAT_META_BG,
- /* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
-- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
-+ EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM
- };
-
-
-@@ -1798,6 +1816,8 @@ int main (int argc, char *argv[])
- }
- no_journal:
-
-+ if (!super_only)
-+ ext2fs_set_gdt_csum(fs);
- if (!quiet)
- printf(_("Writing superblocks and "
- "filesystem accounting information: "));
-Index: e2fsprogs-1.40.11/misc/tune2fs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/misc/tune2fs.c
-+++ e2fsprogs-1.40.11/misc/tune2fs.c
-@@ -117,7 +117,8 @@ static __u32 ok_features[3] = {
- /* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
-- EXT4_FEATURE_RO_COMPAT_DIR_NLINK
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK |
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM
- };
-
- static __u32 clear_ok_features[3] = {
-@@ -129,7 +130,8 @@ static __u32 clear_ok_features[3] = {
- EXT2_FEATURE_INCOMPAT_FILETYPE,
- /* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
-- EXT4_FEATURE_RO_COMPAT_DIR_NLINK
-+ EXT4_FEATURE_RO_COMPAT_DIR_NLINK |
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM
- };
-
- /*
-@@ -244,6 +246,8 @@ static int release_blocks_proc(ext2_fils
- ext2fs_unmark_block_bitmap(fs->block_map,block);
- group = ext2fs_group_of_blk(fs, block);
- fs->group_desc[group].bg_free_blocks_count++;
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,&fs->group_desc[group]);
- fs->super->s_free_blocks_count++;
- return 0;
- }
-@@ -402,6 +406,8 @@ static void update_feature_set(ext2_fils
- EXT2_FEATURE_INCOMPAT_FILETYPE) ||
- FEATURE_CHANGED(E2P_FEATURE_COMPAT,
- EXT2_FEATURE_COMPAT_RESIZE_INODE) ||
-+ FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
- FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
- sb->s_state &= ~EXT2_VALID_FS;
-Index: e2fsprogs-1.40.11/misc/tune2fs.8.in
-===================================================================
---- e2fsprogs-1.40.11.orig/misc/tune2fs.8.in
-+++ e2fsprogs-1.40.11/misc/tune2fs.8.in
-@@ -438,6 +438,14 @@ option.
- .B sparse_super
- Limit the number of backup superblocks to save space on large filesystems.
- .TP
-+.B uninit_groups
-+Allow the kernel to initialize bitmaps and inode tables and keep a high
-+watermark for the unused inodes in a filesystem, to reduce
-+.BR e2fsck (8)
-+time. This first e2fsck run after enabling this feature will take the
-+full time, but subsequent e2fsck runs will take only a fraction of the
-+original time, depending on how full the file system is.
-+.TP
- .B resize_inode
- Reserve space so the block group descriptor table may grow in the
- future.
-@@ -447,6 +455,7 @@ only supports clearing this filesystem f
- .IP
- After setting or clearing
- .BR sparse_super ,
-+.BR uninit_groups ,
- .BR filetype ,
- or
- .B resize_inode
-@@ -461,6 +470,7 @@ if necessary. After setting the
- feature,
- .B e2fsck -D
- can be run to convert existing directories to the hashed B-tree format.
-+
- .TP
- .BI \-r " reserved-blocks-count"
- Set the number of reserved filesystem blocks.
-Index: e2fsprogs-1.40.11/resize/resize2fs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/resize/resize2fs.c
-+++ e2fsprogs-1.40.11/resize/resize2fs.c
-@@ -340,7 +340,9 @@ retry:
- numblocks = fs->super->s_blocks_per_group;
- i = old_fs->group_desc_count - 1;
- fs->group_desc[i].bg_free_blocks_count += (numblocks-old_numblocks);
--
-+ fs->group_desc[i].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, i, &fs->group_desc[i]);
-+
- /*
- * If the number of block groups is staying the same, we're
- * done and can exit now. (If the number block groups is
-@@ -416,6 +418,8 @@ retry:
- fs->group_desc[i].bg_free_inodes_count =
- fs->super->s_inodes_per_group;
- fs->group_desc[i].bg_used_dirs_count = 0;
-+ fs->group_desc[i].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, i,&fs->group_desc[i]);
-
- retval = ext2fs_allocate_group_table(fs, i, 0);
- if (retval) goto errout;
-@@ -1233,8 +1237,12 @@ static errcode_t inode_scan_and_fix(ext2
- if (retval) goto errout;
-
- group = (new_inode-1) / EXT2_INODES_PER_GROUP(rfs->new_fs->super);
-- if (LINUX_S_ISDIR(inode->i_mode))
-+ if (LINUX_S_ISDIR(inode->i_mode)) {
- rfs->new_fs->group_desc[group].bg_used_dirs_count++;
-+ rfs->new_fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(rfs->new_fs->super,group,
-+ &rfs->new_fs->group_desc[group]);
-+ }
-
- #ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_INODEMAP)
-@@ -1490,6 +1498,9 @@ static errcode_t move_itables(ext2_resiz
- ext2fs_unmark_block_bitmap(fs->block_map, blk);
-
- rfs->old_fs->group_desc[i].bg_inode_table = new_blk;
-+ rfs->old_fs->group_desc[i].bg_checksum =
-+ ext2fs_group_desc_csum(rfs->old_fs->super, i,
-+ &rfs->old_fs->group_desc[i]);
- ext2fs_mark_super_dirty(rfs->old_fs);
- ext2fs_flush(rfs->old_fs);
-
-@@ -1587,8 +1598,12 @@ static errcode_t ext2fs_calculate_summar
- count++;
- if ((count == fs->super->s_blocks_per_group) ||
- (blk == fs->super->s_blocks_count-1)) {
-- fs->group_desc[group++].bg_free_blocks_count =
-+ fs->group_desc[group].bg_free_blocks_count =
- group_free;
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,
-+ &fs->group_desc[group]);
-+ group++;
- count = 0;
- group_free = 0;
- }
-@@ -1612,8 +1627,12 @@ static errcode_t ext2fs_calculate_summar
- count++;
- if ((count == fs->super->s_inodes_per_group) ||
- (ino == fs->super->s_inodes_count)) {
-- fs->group_desc[group++].bg_free_inodes_count =
-+ fs->group_desc[group].bg_free_inodes_count =
- group_free;
-+ fs->group_desc[group].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, group,
-+ &fs->group_desc[group]);
-+ group++;
- count = 0;
- group_free = 0;
- }
-Index: e2fsprogs-1.40.11/lib/ext2fs/initialize.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/initialize.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/initialize.c
-@@ -377,6 +377,8 @@ ipg_retry:
- fs->group_desc[i].bg_free_inodes_count =
- fs->super->s_inodes_per_group;
- fs->group_desc[i].bg_used_dirs_count = 0;
-+ fs->group_desc[i].bg_checksum =
-+ ext2fs_group_desc_csum(fs->super, i,&fs->group_desc[i]);
- }
-
- c = (char) 255;
-Index: e2fsprogs-1.40.11/e2fsck/pass2.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/pass2.c
-+++ e2fsprogs-1.40.11/e2fsck/pass2.c
-@@ -151,7 +151,7 @@ void e2fsck_pass2(e2fsck_t ctx)
-
- cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
- &cd);
-- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
- return;
- if (cd.pctx.errcode) {
- fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
-@@ -737,7 +737,7 @@ static int check_dir_block(ext2_filsys f
- buf = cd->buf;
- ctx = cd->ctx;
-
-- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
- return DIRENT_ABORT;
-
- if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
-@@ -841,6 +841,9 @@ out_htree:
- dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
- prev = 0;
- do {
-+ int group;
-+ ext2_ino_t first_unused_inode;
-+
- problem = 0;
- dirent = (struct ext2_dir_entry *) (buf + offset);
- cd->pctx.dirent = dirent;
-@@ -890,12 +893,6 @@ out_htree:
- (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
- (dirent->inode > fs->super->s_inodes_count)) {
- problem = PR_2_BAD_INO;
-- } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
-- dirent->inode))) {
-- /*
-- * If the inode is unused, offer to clear it.
-- */
-- problem = PR_2_UNUSED_INODE;
- } else if (ctx->inode_bb_map &&
- (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
- dirent->inode))) {
-@@ -972,6 +969,67 @@ out_htree:
- return DIRENT_ABORT;
- }
-
-+ group = ext2fs_group_of_ino(fs, dirent->inode);
-+ first_unused_inode = group * fs->super->s_inodes_per_group +
-+ 1 + fs->super->s_inodes_per_group -
-+ fs->group_desc[group].bg_itable_unused;
-+ cd->pctx.group = group;
-+
-+ /*
-+ * Check if the inode was missed out because _INODE_UNINIT
-+ * flag was set or bg_itable_unused was incorrect.
-+ * If that is the case restart e2fsck.
-+ * XXX Optimisations TODO:
-+ * 1. only restart e2fsck once
-+ * 2. only exposed inodes are checked again.
-+ */
-+ if (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT) {
-+ if (fix_problem(ctx, PR_2_INOREF_BG_INO_UNINIT,
-+ &cd->pctx)){
-+ fs->group_desc[group].bg_flags &=
-+ ~EXT2_BG_INODE_UNINIT;
-+ ctx->flags |= E2F_FLAG_RESTART |
-+ E2F_FLAG_SIGNAL_MASK;
-+ } else {
-+ ext2fs_unmark_valid(fs);
-+ if (problem == PR_2_BAD_INO)
-+ goto next;
-+ }
-+ } else if (dirent->inode >= first_unused_inode) {
-+ if (fix_problem(ctx, PR_2_INOREF_IN_UNUSED, &cd->pctx)){
-+ fs->group_desc[group].bg_itable_unused = 0;
-+ fs->group_desc[group].bg_flags &=
-+ ~EXT2_BG_INODE_UNINIT;
-+ ext2fs_mark_super_dirty(fs);
-+ ctx->flags |= E2F_FLAG_RESTART;
-+ goto restart_fsck;
-+ } else {
-+ ext2fs_unmark_valid(fs);
-+ if (problem == PR_2_BAD_INO)
-+ goto next;
-+ }
-+ }
-+
-+ if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
-+ dirent->inode))) {
-+ /*
-+ * If the inode is unused, offer to clear it.
-+ */
-+ problem = PR_2_UNUSED_INODE;
-+ }
-+
-+ if (problem) {
-+ if (fix_problem(ctx, problem, &cd->pctx)) {
-+ dirent->inode = 0;
-+ dir_modified++;
-+ goto next;
-+ } else {
-+ ext2fs_unmark_valid(fs);
-+ if (problem == PR_2_BAD_INO)
-+ goto next;
-+ }
-+ }
-+
- if (check_name(ctx, dirent, ino, &cd->pctx))
- dir_modified++;
-
-@@ -1083,8 +1141,9 @@ out_htree:
- dict_free_nodes(&de_dict);
- return 0;
- abort_free_dict:
-- dict_free_nodes(&de_dict);
- ctx->flags |= E2F_FLAG_ABORT;
-+restart_fsck:
-+ dict_free_nodes(&de_dict);
- return DIRENT_ABORT;
- }
-
-Index: e2fsprogs-1.40.11/e2fsck/unix.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/unix.c
-+++ e2fsprogs-1.40.11/e2fsck/unix.c
-@@ -1461,6 +1461,10 @@ no_journal:
- }
- }
-
-+ if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM &&
-+ !(ctx->options & E2F_OPT_READONLY))
-+ ext2fs_set_gdt_csum(ctx->fs);
-+
- e2fsck_write_bitmaps(ctx);
-
- ext2fs_close(fs);
-Index: e2fsprogs-1.40.11/e2fsck/e2fsck.h
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/e2fsck.h
-+++ e2fsprogs-1.40.11/e2fsck/e2fsck.h
-@@ -483,6 +483,8 @@ extern void e2fsck_read_bitmaps(e2fsck_t
- extern void e2fsck_write_bitmaps(e2fsck_t ctx);
- extern void preenhalt(e2fsck_t ctx);
- extern char *string_copy(e2fsck_t ctx, const char *str, int len);
-+extern errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
-+ blk_t *ret_blk, int *ret_count);
- #ifdef RESOURCE_TRACK
- extern void print_resource_track(const char *desc,
- struct resource_track *track);
-Index: e2fsprogs-1.40.11/lib/ext2fs/csum.c
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/csum.c
-@@ -0,0 +1,150 @@
-+/*
-+ * csum.c --- checksumming of ext3 structures
-+ *
-+ * Copyright (C) 2006 Cluster File Systems, Inc.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "crc16.h"
-+#include <assert.h>
-+
-+#ifndef offsetof
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+#endif
-+
-+__u16 ext2fs_group_desc_csum(struct ext2_super_block *sb, __u32 group,
-+ struct ext2_group_desc *desc)
-+{
-+ crc16_t crc = 0;
-+
-+ if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
-+ int offset = offsetof(struct ext2_group_desc, bg_checksum);
-+
-+#ifdef WORDS_BIGENDIAN
-+ struct ext2_group_desc swabdesc = *desc;
-+
-+ /* Have to swab back to little-endian to do the checksum */
-+ ext2fs_swap_group_desc(&swabdesc);
-+ desc = &swabdesc;
-+
-+ group = ext2fs_swab32(group);
-+#endif
-+ crc = crc16(0xffff, sb->s_uuid, sizeof(sb->s_uuid));
-+ crc = crc16(crc, &group, sizeof(group));
-+ crc = crc16(crc, desc, offset);
-+ offset += sizeof(desc->bg_checksum); /* skip checksum */
-+ if (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT &&
-+ sb->s_desc_size != 0 && offset < sb->s_desc_size)
-+ crc = crc16(crc, (char *)desc + offset,
-+ sb->s_desc_size - offset);
-+ }
-+
-+ return crc;
-+}
-+
-+int ext2fs_group_desc_csum_verify(struct ext2_super_block *sb, __u32 group,
-+ struct ext2_group_desc *desc)
-+{
-+ if (desc->bg_checksum != ext2fs_group_desc_csum(sb, group, desc))
-+ return 0;
-+
-+ return 1;
-+}
-+
-+static __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap,
-+ __u32 inodes_per_grp, dgrp_t grp_no)
-+{
-+ ext2_ino_t i, start_ino, end_ino;
-+
-+ start_ino = grp_no * inodes_per_grp + 1;
-+ end_ino = start_ino + inodes_per_grp - 1;
-+
-+ for (i = end_ino; i >= start_ino; i--) {
-+ if (ext2fs_fast_test_inode_bitmap(bitmap, i))
-+ return i - start_ino + 1;
-+ }
-+ return inodes_per_grp;
-+}
-+
-+/* update the bitmap flags, set the itable high watermark, and calculate
-+ * checksums for the group descriptors */
-+void ext2fs_set_gdt_csum(ext2_filsys fs)
-+{
-+ struct ext2_super_block *sb = fs->super;
-+ struct ext2_group_desc *bg = fs->group_desc;
-+ int blks, csum_flag, dirty = 0;
-+ int inodes_per_group = sb->s_inodes_per_group;
-+ dgrp_t i;
-+
-+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
-+ if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
-+ EXT2_FEATURE_COMPAT_LAZY_BG) && !csum_flag)
-+ return;
-+
-+ for (i = 0; i < fs->group_desc_count; i++, bg++) {
-+ int old_csum = bg->bg_checksum;
-+ int old_unused = bg->bg_itable_unused;
-+ int old_flags = bg->bg_flags;
-+
-+ /* Even if it wasn't zeroed, by the time this function is
-+ * called by e2fsck we have already scanned and corrected
-+ * the whole inode table so we may as well not overwrite it.
-+ * This is just a hint to the kernel that it could do lazy
-+ * zeroing of the inode table if mke2fs didn't do it, to help
-+ * out if we need to do a full itable scan sometime later. */
-+ if (!(bg->bg_flags & (EXT2_BG_INODE_UNINIT |
-+ EXT2_BG_INODE_ZEROED))) {
-+ bg->bg_flags |= EXT2_BG_INODE_ZEROED;
-+ dirty = 1;
-+ }
-+
-+ if (bg->bg_free_inodes_count == inodes_per_group &&
-+ i > 0 && (i < fs->group_desc_count - 1 || csum_flag)) {
-+ if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT))
-+ bg->bg_flags |= EXT2_BG_INODE_UNINIT;
-+
-+ if (csum_flag)
-+ bg->bg_itable_unused = inodes_per_group;
-+
-+ } else if (csum_flag) {
-+ if (fs->inode_map)
-+ bg->bg_itable_unused = inodes_per_group -
-+ find_last_inode_ingrp(fs->inode_map,
-+ inodes_per_group,
-+ i);
-+ else if (bg->bg_flags & EXT2_BG_INODE_UNINIT)
-+ bg->bg_itable_unused = 0;
-+
-+ bg->bg_flags &= ~EXT2_BG_INODE_UNINIT;
-+ }
-+
-+ /* skip first and last groups, or groups with GDT backups
-+ * because the resize inode has blocks allocated in them. */
-+ if (i == 0 || i == fs->group_desc_count - 1 ||
-+ (ext2fs_bg_has_super(fs, i) && sb->s_reserved_gdt_blocks))
-+ goto checksum;
-+
-+ blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
-+ if (bg->bg_free_blocks_count == blks &&
-+ bg->bg_flags & EXT2_BG_INODE_UNINIT &&
-+ !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT))
-+ bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
-+checksum:
-+ bg->bg_checksum = ext2fs_group_desc_csum(fs->super, i, bg);
-+ if (old_flags != bg->bg_flags)
-+ dirty = 1;
-+ if (old_unused != bg->bg_itable_unused)
-+ dirty = 1;
-+ if (old_csum != bg->bg_checksum)
-+ dirty = 1;
-+ }
-+ if (dirty)
-+ ext2fs_mark_super_dirty(fs);
-+}
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc16.c
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc16.c
-@@ -0,0 +1,61 @@
-+/*
-+ * crc16.c
-+ *
-+ * This source code is licensed under the GNU General Public License,
-+ * Version 2. See the file COPYING for more details.
-+ */
-+
-+#include <linux/types.h>
-+#include "crc16.h"
-+
-+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
-+__u16 const crc16_table[256] = {
-+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
-+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
-+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
-+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
-+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
-+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
-+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
-+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
-+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
-+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
-+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
-+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
-+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
-+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
-+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
-+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
-+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
-+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
-+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
-+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
-+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
-+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
-+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
-+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
-+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
-+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
-+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
-+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
-+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
-+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
-+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
-+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
-+};
-+
-+/**
-+ * Compute the CRC-16 for the data buffer
-+ *
-+ * @param crc previous CRC value
-+ * @param buffer data pointer
-+ * @param len number of bytes in the buffer
-+ * @return the updated CRC value
-+ */
-+crc16_t crc16(crc16_t crc, void const *buffer, size_t len)
-+{
-+ const unsigned char *ptr = buffer;
-+ while (len--)
-+ crc = crc16_byte(crc, *ptr++);
-+ return crc;
-+}
-Index: e2fsprogs-1.40.11/lib/ext2fs/crc16.h
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/crc16.h
-@@ -0,0 +1,47 @@
-+/*
-+ * crc16.h - CRC-16 routine
-+ *
-+ * Implements the standard CRC-16:
-+ * Width 16
-+ * Poly 0x8005 (x^16 + x^15 + x^2 + 1)
-+ * Init 0
-+ *
-+ * Copyright (c) 2005 Ben Gardner <bgardner at wabtec.com>
-+ *
-+ * This source code is licensed under the GNU General Public License,
-+ * Version 2. See the file COPYING for more details.
-+ */
-+
-+#ifndef __CRC16_H
-+#define __CRC16_H
-+
-+#include <linux/types.h>
-+
-+extern __u16 const crc16_table[256];
-+
-+
-+#ifdef WORDS_BIGENDIAN
-+/* for an unknown reason, PPC treats __u16 as signed and keeps doing sign
-+ * extension on the value. Instead, use only the low 16 bits of an
-+ * unsigned int for holding the CRC value to avoid this.
-+ */
-+typedef unsigned crc16_t;
-+
-+static inline crc16_t crc16_byte(crc16_t crc, const unsigned char data)
-+{
-+ return (((crc >> 8) & 0xffU) ^ crc16_table[(crc ^ data) & 0xffU]) &
-+ 0x0000ffffU;
-+}
-+#else
-+typedef __u16 crc16_t;
-+
-+static inline crc16_t crc16_byte(crc16_t crc, const unsigned char data)
-+{
-+ return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
-+}
-+#endif
-+
-+extern crc16_t crc16(crc16_t crc, void const *buffer, size_t len);
-+
-+
-+#endif /* __CRC16_H */
-Index: e2fsprogs-1.40.11/lib/ext2fs/tst_csum.c
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/lib/ext2fs/tst_csum.c
-@@ -0,0 +1,140 @@
-+/*
-+ * This testing program verifies checksumming operations
-+ *
-+ * Copyright (C) 2006, 2007 by Andreas Dilger <adilger at clusterfs.com>
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include "ext2fs/ext2_fs.h"
-+#include "ext2fs/ext2fs.h"
-+#include "ext2fs/crc16.h"
-+#include "uuid/uuid.h"
-+
-+#ifndef offsetof
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+#endif
-+
-+void print_csum(const char *msg, struct ext2_super_block *sb,
-+ __u32 group, struct ext2_group_desc *desc)
-+{
-+ __u16 crc1, crc2, crc3;
-+ __u32 swabgroup;
-+ char uuid[40];
-+
-+#ifdef WORDS_BIGENDIAN
-+ struct ext2_group_desc swabdesc = *desc;
-+
-+ /* Have to swab back to little-endian to do the checksum */
-+ ext2fs_swap_group_desc(&swabdesc);
-+ desc = &swabdesc;
-+
-+ swabgroup = ext2fs_swab32(group);
-+#else
-+ swabgroup = group;
-+#endif
-+
-+ crc1 = crc16(0xffff, sb->s_uuid, sizeof(sb->s_uuid));
-+ crc2 = crc16(crc1, &swabgroup, sizeof(swabgroup));
-+ crc3 = crc16(crc2, desc, offsetof(struct ext2_group_desc, bg_checksum));
-+ uuid_unparse(sb->s_uuid, uuid);
-+ printf("%s: UUID %s=%04x, grp %u=%04x: %04x=%04x\n",
-+ msg, uuid, crc1, group, crc2, crc3,
-+ ext2fs_group_desc_csum(sb, group,desc));
-+}
-+
-+int main(int argc, char **argv)
-+{
-+ struct ext2_group_desc desc = { .bg_block_bitmap = 124,
-+ .bg_inode_bitmap = 125,
-+ .bg_inode_table = 126,
-+ .bg_free_blocks_count = 31119,
-+ .bg_free_inodes_count = 15701,
-+ .bg_used_dirs_count = 2,
-+ .bg_flags = 0,
-+ };
-+ struct ext2_super_block sb = { .s_feature_ro_compat =
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
-+ .s_uuid = { 0x4f, 0x25, 0xe8, 0xcf,
-+ 0xe7, 0x97, 0x48, 0x23,
-+ 0xbe, 0xfa, 0xa7, 0x88,
-+ 0x4b, 0xae, 0xec, 0xdb } };
-+ __u16 csum1, csum2, csum_known = 0xd3a4;
-+ char data[8] = { 0x10, 0x20, 0x30, 0x40, 0xf1, 0xb2, 0xc3, 0xd4 };
-+ __u16 data_crc[8] = { 0xcc01, 0x180c, 0x1118, 0xfa10,
-+ 0x483a, 0x6648, 0x6726, 0x85e6 };
-+ __u16 data_crc0[8] = { 0x8cbe, 0xa80d, 0xd169, 0xde10,
-+ 0x481e, 0x7d48, 0x673d, 0x8ea6 };
-+ int i;
-+
-+ for (i = 0; i < sizeof(data); i++) {
-+ csum1 = crc16(0, data, i + 1);
-+ printf("crc16(0): data[%d]: %04x=%04x\n", i, csum1,data_crc[i]);
-+ if (csum1 != data_crc[i]) {
-+ printf("error: crc16(0) for data[%d] should be %04x\n",
-+ i, data_crc[i]);
-+ exit(1);
-+ }
-+ }
-+
-+ for (i = 0; i < sizeof(data); i++) {
-+ csum1 = crc16(~0, data, i + 1);
-+ printf("crc16(~0): data[%d]: %04x=%04x\n",i,csum1,data_crc0[i]);
-+ if (csum1 != data_crc0[i]) {
-+ printf("error: crc16(~0) for data[%d] should be %04x\n",
-+ i, data_crc0[i]);
-+ exit(1);
-+ }
-+ }
-+
-+ csum1 = ext2fs_group_desc_csum(&sb, 0, &desc);
-+ print_csum("csum0000", &sb, 0, &desc);
-+
-+ if (csum1 != csum_known) {
-+ printf("checksum for group 0 should be %04x\n", csum_known);
-+ exit(1);
-+ }
-+ csum2 = ext2fs_group_desc_csum(&sb, 1, &desc);
-+ print_csum("csum0001", &sb, 1, &desc);
-+ if (csum1 == csum2) {
-+ printf("checksums for different groups shouldn't match\n");
-+ exit(1);
-+ }
-+ csum2 = ext2fs_group_desc_csum(&sb, 0xffff, &desc);
-+ print_csum("csumffff", &sb, 0xffff, &desc);
-+ if (csum1 == csum2) {
-+ printf("checksums for different groups shouldn't match\n");
-+ exit(1);
-+ }
-+ desc.bg_checksum = csum1;
-+ csum2 = ext2fs_group_desc_csum(&sb, 0, &desc);
-+ print_csum("csum_set", &sb, 0, &desc);
-+ if (csum1 != csum2) {
-+ printf("checksums should not depend on checksum field\n");
-+ exit(1);
-+ }
-+ if (!ext2fs_group_desc_csum_verify(&sb, 0, &desc)) {
-+ printf("checksums should verify against gd_checksum\n");
-+ exit(1);
-+ }
-+ memset(sb.s_uuid, 0x30, sizeof(sb.s_uuid));
-+ print_csum("new_uuid", &sb, 0, &desc);
-+ if (ext2fs_group_desc_csum_verify(&sb, 0, &desc) != 0) {
-+ printf("checksums for different filesystems shouldn't match\n");
-+ exit(1);
-+ }
-+ csum1 = desc.bg_checksum = ext2fs_group_desc_csum(&sb, 0, &desc);
-+ print_csum("csum_new", &sb, 0, &desc);
-+ desc.bg_free_blocks_count = 1;
-+ csum2 = ext2fs_group_desc_csum(&sb, 0, &desc);
-+ print_csum("csum_blk", &sb, 0, &desc);
-+ if (csum1 == csum2) {
-+ printf("checksums for different data shouldn't match\n");
-+ exit(1);
-+ }
-+
-+ return 0;
-+}
-Index: e2fsprogs-1.40.11/lib/e2p/feature.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/e2p/feature.c
-+++ e2fsprogs-1.40.11/lib/e2p/feature.c
-@@ -45,7 +45,7 @@ static struct feature feature_list[] = {
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
- "huge_file" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
-- "gdt_checksum" },
-+ "uninit_groups" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
- "dir_nlink" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
-Index: e2fsprogs-1.40.11/misc/mke2fs.8.in
-===================================================================
---- e2fsprogs-1.40.11.orig/misc/mke2fs.8.in
-+++ e2fsprogs-1.40.11/misc/mke2fs.8.in
-@@ -429,6 +429,12 @@ Store file type information in directory
- Create an ext3 journal (as if using the
- .B \-j
- option).
-+.TP
-+.B uninit_groups
-+Create a filesystem without initializing all of the groups. This can reduce
-+.BR e2fsck (8)
-+time dramatically. This feature causes the filesystem to be read-only in
-+older kernels is not supported in most Linux kernels, use with caution.
- @JDEV at .TP
- @JDEV at .B journal_dev
- @JDEV at Create an external ext3 journal on the given device
-Index: e2fsprogs-1.40.11/e2fsck/util.c
-===================================================================
---- e2fsprogs-1.40.11.orig/e2fsck/util.c
-+++ e2fsprogs-1.40.11/e2fsck/util.c
-@@ -29,6 +29,10 @@
- #include <malloc.h>
- #endif
-
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
- #include "e2fsck.h"
-
- extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
-@@ -516,3 +520,60 @@ int ext2_file_type(unsigned int mode)
-
- return 0;
- }
-+
-+#define STRIDE_LENGTH 8
-+/*
-+ * Helper function which zeros out _num_ blocks starting at _blk_. In
-+ * case of an error, the details of the error is returned via _ret_blk_
-+ * and _ret_count_ if they are non-NULL pointers. Returns 0 on
-+ * success, and an error code on an error.
-+ *
-+ * As a special case, if the first argument is NULL, then it will
-+ * attempt to free the static zeroizing buffer. (This is to keep
-+ * programs that check for memory leaks happy.)
-+ */
-+errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
-+ blk_t *ret_blk, int *ret_count)
-+{
-+ int j, count, next_update, next_update_incr;
-+ static char *buf;
-+ errcode_t retval;
-+
-+ /* If fs is null, clean up the static buffer and return */
-+ if (!fs) {
-+ if (buf) {
-+ free(buf);
-+ buf = 0;
-+ }
-+ return 0;
-+ }
-+ /* Allocate the zeroizing buffer if necessary */
-+ if (!buf) {
-+ buf = malloc(fs->blocksize * STRIDE_LENGTH);
-+ if (!buf) {
-+ com_err("malloc", ENOMEM,
-+ _("while allocating zeroizing buffer"));
-+ exit(1);
-+ }
-+ memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
-+ }
-+ /* OK, do the write loop */
-+ next_update = 0;
-+ next_update_incr = num / 100;
-+ if (next_update_incr < 1)
-+ next_update_incr = 1;
-+ for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
-+ count = num - j;
-+ if (count > STRIDE_LENGTH)
-+ count = STRIDE_LENGTH;
-+ retval = io_channel_write_blk(fs->io, blk, count, buf);
-+ if (retval) {
-+ if (ret_count)
-+ *ret_count = count;
-+ if (ret_blk)
-+ *ret_blk = blk;
-+ return retval;
-+ }
-+ }
-+ return 0;
-+}
-Index: e2fsprogs-1.40.11/resize/main.c
-===================================================================
---- e2fsprogs-1.40.11.orig/resize/main.c
-+++ e2fsprogs-1.40.11/resize/main.c
-@@ -298,6 +298,13 @@ int main (int argc, char ** argv)
- printf (_("Couldn't find valid filesystem superblock.\n"));
- exit (1);
- }
-+
-+ if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
-+ com_err(program_name, EXT2_ET_RO_UNSUPP_FEATURE,
-+ ":- uninit_groups");
-+ exit(1);
-+ }
-+
- /*
- * Check for compatibility with the feature sets. We need to
- * be more stringent than ext2fs_open().
-Index: e2fsprogs-1.40.11/tests/f_dupfsblks/expect.1
-===================================================================
---- e2fsprogs-1.40.11.orig/tests/f_dupfsblks/expect.1
-+++ e2fsprogs-1.40.11/tests/f_dupfsblks/expect.1
-@@ -44,7 +44,8 @@ Salvage? yes
- Directory inode 12, block 3, offset 0: directory corrupted
- Salvage? yes
-
--Entry '' in ??? (12) has deleted/unused inode 32. Clear? yes
-+Entry '' in ??? (12) has a zero-length name.
-+Clear? yes
-
- Directory inode 12, block 4, offset 100: directory corrupted
- Salvage? yes
-Index: e2fsprogs-1.40.11/tests/f_uninit_last_uninit/expect.1
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/f_uninit_last_uninit/expect.1
-@@ -0,0 +1,9 @@
-+last group block bitmap uninitialized. Fix? yes
-+
-+Pass 1: Checking inodes, blocks, and sizes
-+Pass 2: Checking directory structure
-+Pass 3: Checking directory connectivity
-+Pass 4: Checking reference counts
-+Pass 5: Checking group summary information
-+test_filesys: 11/32 files (9.1% non-contiguous), 105/10000 blocks
-+Exit status is 0
-Index: e2fsprogs-1.40.11/tests/f_uninit_last_uninit/expect.2
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/f_uninit_last_uninit/expect.2
-@@ -0,0 +1,7 @@
-+Pass 1: Checking inodes, blocks, and sizes
-+Pass 2: Checking directory structure
-+Pass 3: Checking directory connectivity
-+Pass 4: Checking reference counts
-+Pass 5: Checking group summary information
-+test_filesys: 11/32 files (9.1% non-contiguous), 105/10000 blocks
-+Exit status is 0
-Index: e2fsprogs-1.40.11/tests/f_uninit_last_uninit/name
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/f_uninit_last_uninit/name
-@@ -0,0 +1,2 @@
-+last group has BLOCK_UNINIT set
-+
-Index: e2fsprogs-1.40.11/tests/f_uninit_last_uninit/script
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/f_uninit_last_uninit/script
-@@ -0,0 +1,20 @@
-+SKIP_GUNZIP="true"
-+
-+touch $TMPFILE
-+$MKE2FS -N 32 -F -o Linux -O uninit_groups -b 1024 $TMPFILE 10000 > /dev/null 2>&1
-+$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
-+set_current_time 200704102100
-+set_super_value lastcheck 0
-+set_super_value hash_seed null
-+set_super_value mkfs_time 0
-+set_bg 1 flags 0x7
-+set_bg 1 checksum calc
-+q
-+EOF
-+
-+E2FSCK_TIME=200704102100
-+export E2FSCK_TIME
-+
-+. $cmd_dir/run_e2fsck
-+
-+unset E2FSCK_TIME
-Index: e2fsprogs-1.40.11/tests/m_lazy/expect.1
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_lazy/expect.1
-@@ -0,0 +1,158 @@
-+Filesystem label=
-+OS type: Linux
-+Block size=1024 (log=0)
-+Fragment size=1024 (log=0)
-+32768 inodes, 131072 blocks
-+6553 blocks (5.00%) reserved for the super user
-+First data block=1
-+16 block groups
-+8192 blocks per group, 8192 fragments per group
-+2048 inodes per group
-+Superblock backups stored on blocks:
-+ 8193, 24577, 40961, 57345, 73729
-+
-+Writing inode tables: done
-+Writing superblocks and filesystem accounting information: done
-+
-+Filesystem features: ext_attr dir_index lazy_bg filetype sparse_super
-+
-+Pass 1: Checking inodes, blocks, and sizes
-+Pass 2: Checking directory structure
-+Pass 3: Checking directory connectivity
-+Pass 4: Checking reference counts
-+Pass 5: Checking group summary information
-+test_filesys: 28683/32768 files (0.0% non-contiguous), 115220/131072 blocks
-+Exit status is 0
-+
-+Filesystem volume name: <none>
-+Last mounted on: <not available>
-+Filesystem magic number: 0xEF53
-+Filesystem revision #: 1 (dynamic)
-+Filesystem features: ext_attr dir_index lazy_bg filetype sparse_super
-+Default mount options: (none)
-+Filesystem state: clean
-+Errors behavior: Continue
-+Filesystem OS type: Linux
-+Inode count: 32768
-+Block count: 131072
-+Reserved block count: 6553
-+Free blocks: 15852
-+Free inodes: 4085
-+First block: 1
-+Block size: 1024
-+Fragment size: 1024
-+Blocks per group: 8192
-+Fragments per group: 8192
-+Inodes per group: 2048
-+Inode blocks per group: 256
-+Mount count: 0
-+Check interval: 15552000 (6 months)
-+Reserved blocks uid: 0
-+Reserved blocks gid: 0
-+First inode: 11
-+Inode size: 128
-+Default directory hash: tea
-+
-+
-+Group 0: (Blocks 1-8192)
-+ Primary superblock at 1, Group descriptors at 2-2
-+ Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
-+ Inode table at 5-260 (+4)
-+ 7919 free blocks, 2037 free inodes, 2 directories
-+ Free blocks: 274-8192
-+ Free inodes: 12-2048
-+Group 1: (Blocks 8193-16384) [Inode not init, Block not init]
-+ Backup superblock at 8193, Group descriptors at 8194-8194
-+ Block bitmap at 8195 (+2), Inode bitmap at 8196 (+3)
-+ Inode table at 8197-8452 (+4)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
-+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
-+ Inode table at 16387-16642 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 3: (Blocks 24577-32768) [Inode not init, Block not init]
-+ Backup superblock at 24577, Group descriptors at 24578-24578
-+ Block bitmap at 24579 (+2), Inode bitmap at 24580 (+3)
-+ Inode table at 24581-24836 (+4)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
-+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
-+ Inode table at 32771-33026 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 5: (Blocks 40961-49152) [Inode not init, Block not init]
-+ Backup superblock at 40961, Group descriptors at 40962-40962
-+ Block bitmap at 40963 (+2), Inode bitmap at 40964 (+3)
-+ Inode table at 40965-41220 (+4)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
-+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
-+ Inode table at 49155-49410 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 7: (Blocks 57345-65536) [Inode not init, Block not init]
-+ Backup superblock at 57345, Group descriptors at 57346-57346
-+ Block bitmap at 57347 (+2), Inode bitmap at 57348 (+3)
-+ Inode table at 57349-57604 (+4)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
-+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
-+ Inode table at 65539-65794 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 9: (Blocks 73729-81920) [Inode not init, Block not init]
-+ Backup superblock at 73729, Group descriptors at 73730-73730
-+ Block bitmap at 73731 (+2), Inode bitmap at 73732 (+3)
-+ Inode table at 73733-73988 (+4)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
-+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
-+ Inode table at 81923-82178 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
-+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
-+ Inode table at 90115-90370 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
-+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
-+ Inode table at 98307-98562 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
-+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
-+ Inode table at 106499-106754 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
-+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
-+ Inode table at 114691-114946 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 15: (Blocks 122881-131071)
-+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
-+ Inode table at 122883-123138 (+2)
-+ 7933 free blocks, 2048 free inodes, 0 directories
-+ Free blocks: 123139-131071
-+ Free inodes: 30721-32768
-Index: e2fsprogs-1.40.11/tests/m_lazy/script
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_lazy/script
-@@ -0,0 +1,4 @@
-+DESCRIPTION="lazy group feature"
-+FS_SIZE=131072
-+MKE2FS_OPTS="-O ^resize_inode,lazy_bg"
-+. $cmd_dir/run_mke2fs
-Index: e2fsprogs-1.40.11/tests/m_lazy_resize/expect.1
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_lazy_resize/expect.1
-@@ -0,0 +1,166 @@
-+Filesystem label=
-+OS type: Linux
-+Block size=1024 (log=0)
-+Fragment size=1024 (log=0)
-+32768 inodes, 131072 blocks
-+6553 blocks (5.00%) reserved for the super user
-+First data block=1
-+Maximum filesystem blocks=67371008
-+16 block groups
-+8192 blocks per group, 8192 fragments per group
-+2048 inodes per group
-+Superblock backups stored on blocks:
-+ 8193, 24577, 40961, 57345, 73729
-+
-+Writing inode tables: done
-+Writing superblocks and filesystem accounting information: done
-+
-+Filesystem features: ext_attr resize_inode dir_index lazy_bg filetype sparse_super
-+
-+Pass 1: Checking inodes, blocks, and sizes
-+Pass 2: Checking directory structure
-+Pass 3: Checking directory connectivity
-+Pass 4: Checking reference counts
-+Pass 5: Checking group summary information
-+test_filesys: 28683/32768 files (0.0% non-contiguous), 77097/131072 blocks
-+Exit status is 0
-+
-+Filesystem volume name: <none>
-+Last mounted on: <not available>
-+Filesystem magic number: 0xEF53
-+Filesystem revision #: 1 (dynamic)
-+Filesystem features: ext_attr resize_inode dir_index lazy_bg filetype sparse_super
-+Default mount options: (none)
-+Filesystem state: clean
-+Errors behavior: Continue
-+Filesystem OS type: Linux
-+Inode count: 32768
-+Block count: 131072
-+Reserved block count: 6553
-+Free blocks: 53975
-+Free inodes: 4085
-+First block: 1
-+Block size: 1024
-+Fragment size: 1024
-+Reserved GDT blocks: 256
-+Blocks per group: 8192
-+Fragments per group: 8192
-+Inodes per group: 2048
-+Inode blocks per group: 256
-+Mount count: 0
-+Check interval: 15552000 (6 months)
-+Reserved blocks uid: 0
-+Reserved blocks gid: 0
-+First inode: 11
-+Inode size: 128
-+Default directory hash: tea
-+
-+
-+Group 0: (Blocks 1-8192)
-+ Primary superblock at 1, Group descriptors at 2-2
-+ Reserved GDT blocks at 3-258
-+ Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
-+ Inode table at 261-516 (+260)
-+ 7662 free blocks, 2037 free inodes, 2 directories
-+ Free blocks: 531-8192
-+ Free inodes: 12-2048
-+Group 1: (Blocks 8193-16384) [Inode not init]
-+ Backup superblock at 8193, Group descriptors at 8194-8194
-+ Reserved GDT blocks at 8195-8450
-+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
-+ Inode table at 8453-8708 (+260)
-+ 7676 free blocks, 0 free inodes, 0 directories
-+ Free blocks: 8709-16384
-+ Free inodes:
-+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
-+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
-+ Inode table at 16387-16642 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 3: (Blocks 24577-32768) [Inode not init]
-+ Backup superblock at 24577, Group descriptors at 24578-24578
-+ Reserved GDT blocks at 24579-24834
-+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
-+ Inode table at 24837-25092 (+260)
-+ 7676 free blocks, 0 free inodes, 0 directories
-+ Free blocks: 25093-32768
-+ Free inodes:
-+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
-+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
-+ Inode table at 32771-33026 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 5: (Blocks 40961-49152) [Inode not init]
-+ Backup superblock at 40961, Group descriptors at 40962-40962
-+ Reserved GDT blocks at 40963-41218
-+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
-+ Inode table at 41221-41476 (+260)
-+ 7676 free blocks, 0 free inodes, 0 directories
-+ Free blocks: 41477-49152
-+ Free inodes:
-+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
-+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
-+ Inode table at 49155-49410 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 7: (Blocks 57345-65536) [Inode not init]
-+ Backup superblock at 57345, Group descriptors at 57346-57346
-+ Reserved GDT blocks at 57347-57602
-+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
-+ Inode table at 57605-57860 (+260)
-+ 7676 free blocks, 0 free inodes, 0 directories
-+ Free blocks: 57861-65536
-+ Free inodes:
-+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
-+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
-+ Inode table at 65539-65794 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 9: (Blocks 73729-81920) [Inode not init]
-+ Backup superblock at 73729, Group descriptors at 73730-73730
-+ Reserved GDT blocks at 73731-73986
-+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
-+ Inode table at 73989-74244 (+260)
-+ 7676 free blocks, 0 free inodes, 0 directories
-+ Free blocks: 74245-81920
-+ Free inodes:
-+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
-+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
-+ Inode table at 81923-82178 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
-+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
-+ Inode table at 90115-90370 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
-+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
-+ Inode table at 98307-98562 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
-+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
-+ Inode table at 106499-106754 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
-+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
-+ Inode table at 114691-114946 (+2)
-+ 0 free blocks, 0 free inodes, 0 directories
-+ Free blocks:
-+ Free inodes:
-+Group 15: (Blocks 122881-131071)
-+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
-+ Inode table at 122883-123138 (+2)
-+ 7933 free blocks, 2048 free inodes, 0 directories
-+ Free blocks: 123139-131071
-+ Free inodes: 30721-32768
-Index: e2fsprogs-1.40.11/tests/m_lazy_resize/script
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_lazy_resize/script
-@@ -0,0 +1,4 @@
-+DESCRIPTION="lazy group feature with resize_inode"
-+FS_SIZE=131072
-+MKE2FS_OPTS="-O resize_inode,lazy_bg"
-+. $cmd_dir/run_mke2fs
-Index: e2fsprogs-1.40.11/tests/m_uninit/expect.1
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_uninit/expect.1
-@@ -0,0 +1,166 @@
-+Filesystem label=
-+OS type: Linux
-+Block size=1024 (log=0)
-+Fragment size=1024 (log=0)
-+32768 inodes, 131072 blocks
-+6553 blocks (5.00%) reserved for the super user
-+First data block=1
-+Maximum filesystem blocks=67371008
-+16 block groups
-+8192 blocks per group, 8192 fragments per group
-+2048 inodes per group
-+Superblock backups stored on blocks:
-+ 8193, 24577, 40961, 57345, 73729
-+
-+Writing inode tables: done
-+Writing superblocks and filesystem accounting information: done
-+
-+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super uninit_groups
-+
-+Pass 1: Checking inodes, blocks, and sizes
-+Pass 2: Checking directory structure
-+Pass 3: Checking directory connectivity
-+Pass 4: Checking reference counts
-+Pass 5: Checking group summary information
-+test_filesys: 11/32768 files (9.1% non-contiguous), 5691/131072 blocks
-+Exit status is 0
-+
-+Filesystem volume name: <none>
-+Last mounted on: <not available>
-+Filesystem magic number: 0xEF53
-+Filesystem revision #: 1 (dynamic)
-+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super uninit_groups
-+Default mount options: (none)
-+Filesystem state: clean
-+Errors behavior: Continue
-+Filesystem OS type: Linux
-+Inode count: 32768
-+Block count: 131072
-+Reserved block count: 6553
-+Free blocks: 125381
-+Free inodes: 32757
-+First block: 1
-+Block size: 1024
-+Fragment size: 1024
-+Reserved GDT blocks: 256
-+Blocks per group: 8192
-+Fragments per group: 8192
-+Inodes per group: 2048
-+Inode blocks per group: 256
-+Mount count: 0
-+Check interval: 15552000 (6 months)
-+Reserved blocks uid: 0
-+Reserved blocks gid: 0
-+First inode: 11
-+Inode size: 128
-+Default directory hash: tea
-+
-+
-+Group 0: (Blocks 1-8192)
-+ Primary superblock at 1, Group descriptors at 2-2
-+ Reserved GDT blocks at 3-258
-+ Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
-+ Inode table at 261-516 (+260)
-+ 7662 free blocks, 2037 free inodes, 2 directories, 2037 unused inodes
-+ Free blocks: 531-8192
-+ Free inodes: 12-2048
-+Group 1: (Blocks 8193-16384) [Inode not init]
-+ Backup superblock at 8193, Group descriptors at 8194-8194
-+ Reserved GDT blocks at 8195-8450
-+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
-+ Inode table at 8453-8708 (+260)
-+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 8709-16384
-+ Free inodes: 2049-4096
-+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
-+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
-+ Inode table at 16387-16642 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 16643-24576
-+ Free inodes: 4097-6144
-+Group 3: (Blocks 24577-32768) [Inode not init]
-+ Backup superblock at 24577, Group descriptors at 24578-24578
-+ Reserved GDT blocks at 24579-24834
-+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
-+ Inode table at 24837-25092 (+260)
-+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 25093-32768
-+ Free inodes: 6145-8192
-+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
-+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
-+ Inode table at 32771-33026 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 33027-40960
-+ Free inodes: 8193-10240
-+Group 5: (Blocks 40961-49152) [Inode not init]
-+ Backup superblock at 40961, Group descriptors at 40962-40962
-+ Reserved GDT blocks at 40963-41218
-+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
-+ Inode table at 41221-41476 (+260)
-+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 41477-49152
-+ Free inodes: 10241-12288
-+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
-+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
-+ Inode table at 49155-49410 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 49411-57344
-+ Free inodes: 12289-14336
-+Group 7: (Blocks 57345-65536) [Inode not init]
-+ Backup superblock at 57345, Group descriptors at 57346-57346
-+ Reserved GDT blocks at 57347-57602
-+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
-+ Inode table at 57605-57860 (+260)
-+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 57861-65536
-+ Free inodes: 14337-16384
-+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
-+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
-+ Inode table at 65539-65794 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 65795-73728
-+ Free inodes: 16385-18432
-+Group 9: (Blocks 73729-81920) [Inode not init]
-+ Backup superblock at 73729, Group descriptors at 73730-73730
-+ Reserved GDT blocks at 73731-73986
-+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
-+ Inode table at 73989-74244 (+260)
-+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 74245-81920
-+ Free inodes: 18433-20480
-+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
-+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
-+ Inode table at 81923-82178 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 82179-90112
-+ Free inodes: 20481-22528
-+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
-+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
-+ Inode table at 90115-90370 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 90371-98304
-+ Free inodes: 22529-24576
-+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
-+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
-+ Inode table at 98307-98562 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 98563-106496
-+ Free inodes: 24577-26624
-+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
-+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
-+ Inode table at 106499-106754 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 106755-114688
-+ Free inodes: 26625-28672
-+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
-+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
-+ Inode table at 114691-114946 (+2)
-+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 114947-122880
-+ Free inodes: 28673-30720
-+Group 15: (Blocks 122881-131071) [Inode not init]
-+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
-+ Inode table at 122883-123138 (+2)
-+ 7933 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-+ Free blocks: 123139-131071
-+ Free inodes: 30721-32768
-Index: e2fsprogs-1.40.11/tests/m_uninit/script
-===================================================================
---- /dev/null
-+++ e2fsprogs-1.40.11/tests/m_uninit/script
-@@ -0,0 +1,4 @@
-+DESCRIPTION="uninitialized group feature"
-+FS_SIZE=131072
-+MKE2FS_OPTS="-O uninit_groups"
-+. $cmd_dir/run_mke2fs
-Index: e2fsprogs-1.40.11/lib/ext2fs/openfs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/openfs.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/openfs.c
-@@ -304,6 +304,21 @@ errcode_t ext2fs_open2(const char *name,
- }
-
- fs->stride = fs->super->s_raid_stride;
-+ /*
-+ * If recovery is from backup superblock, Clear _UNININT flags &
-+ * reset bg_itable_unused to zero
-+ */
-+ if (superblock > 1 && EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
-+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-+ struct ext2_group_desc *gd;
-+ for (i = 0, gd = fs->group_desc; i < fs->group_desc_count;
-+ i++, gd++) {
-+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
-+ gd->bg_flags &= ~EXT2_BG_INODE_UNINIT;
-+ gd->bg_itable_unused = 0;
-+ }
-+ ext2fs_mark_super_dirty(fs);
-+ }
-
- fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
- *ret_fs = fs;
-Index: e2fsprogs-1.40.11/lib/ext2fs/closefs.c
-===================================================================
---- e2fsprogs-1.40.11.orig/lib/ext2fs/closefs.c
-+++ e2fsprogs-1.40.11/lib/ext2fs/closefs.c
-@@ -45,6 +45,87 @@ int ext2fs_bg_has_super(ext2_filsys fs,
- return 0;
- }
-
-+/*
-+ * ext2fs_super_and_bgd_loc2()
-+ * @fs: ext2 fs pointer
-+ * @group given block group
-+ * @ret_super_blk: if !NULL, returns super block location
-+ * @ret_old_desc_blk: if !NULL, returns location of the old block
-+ * group descriptor
-+ * @ret_new_desc_blk: if !NULL, returns location of meta_bg block
-+ * group descriptor
-+ * @ret_used_blks: if !NULL, returns number of blocks used by
-+ * super block and group_descriptors.
-+ *
-+ * Returns errcode_t of 0
-+ *
-+ * ret_used_blks returns the number of blocks used by the superblock and
-+ * group descriptors and unlike ext2fs_uper_and_bgd_loc2() it does not make the
-+ * assumption that inode table and bitmaps will be in the same group.
-+ *
-+ * XXX: Remove this when we upgrade our e2fsprogs patches. Also blk64_t has been
-+ * changed to blk_t here since this version does not have 64-bit support.
-+ */
-+errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
-+ dgrp_t group,
-+ blk_t *ret_super_blk,
-+ blk_t *ret_old_desc_blk,
-+ blk_t *ret_new_desc_blk,
-+ blk_t *ret_used_blks)
-+{
-+ blk_t group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0;
-+ unsigned int meta_bg, meta_bg_size;
-+ blk_t numblocks = 0;
-+ blk_t old_desc_blocks;
-+ int has_super;
-+
-+ group_block = fs->super->s_first_data_block +
-+ (group * fs->super->s_blocks_per_group);
-+
-+ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+ old_desc_blocks = fs->super->s_first_meta_bg;
-+ else
-+ old_desc_blocks =
-+ fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-+
-+ has_super = ext2fs_bg_has_super(fs, group);
-+
-+ if (has_super) {
-+ super_blk = group_block;
-+ numblocks++;
-+ }
-+ meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
-+ meta_bg = group / meta_bg_size;
-+
-+ if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
-+ (meta_bg < fs->super->s_first_meta_bg)) {
-+ if (has_super) {
-+ old_desc_blk = group_block + 1;
-+ numblocks += old_desc_blocks;
-+ }
-+ } else {
-+ if (((group % meta_bg_size) == 0) ||
-+ ((group % meta_bg_size) == 1) ||
-+ ((group % meta_bg_size) == (meta_bg_size-1))) {
-+ if (has_super)
-+ has_super = 1;
-+ new_desc_blk = group_block + has_super;
-+ numblocks++;
-+ }
-+ }
-+
-+ if (ret_super_blk)
-+ *ret_super_blk = super_blk;
-+ if (ret_old_desc_blk)
-+ *ret_old_desc_blk = old_desc_blk;
-+ if (ret_new_desc_blk)
-+ *ret_new_desc_blk = new_desc_blk;
-+ if (ret_used_blks)
-+ *ret_used_blks = numblocks;
-+
-+ return 0;
-+}
-+
- int ext2fs_super_and_bgd_loc(ext2_filsys fs,
- dgrp_t group,
- blk_t *ret_super_blk,
diff --git a/debian/patches/e2fsprogs-version.patch b/debian/patches/e2fsprogs-version.patch
index 5c80d0d..42fdfef 100644
--- a/debian/patches/e2fsprogs-version.patch
+++ b/debian/patches/e2fsprogs-version.patch
@@ -1,13 +1,14 @@
-change to Sun version number
+Change to Sun version number
-Index: e2fsprogs-1.40.11/version.h
+Index: e2fsprogs-1.41.6/version.h
===================================================================
---- e2fsprogs-1.40.11.orig/version.h
-+++ e2fsprogs-1.40.11/version.h
-@@ -7,5 +7,5 @@
+--- e2fsprogs-1.41.6.orig/version.h 2009-05-30 10:51:35.000000000 -0400
++++ e2fsprogs-1.41.6/version.h 2009-06-09 10:17:58.000000000 -0400
+@@ -7,5 +7,6 @@
* redistributed under the GNU Public License.
*/
--#define E2FSPROGS_VERSION "1.40.11"
-+#define E2FSPROGS_VERSION "1.40.11.sun1"
- #define E2FSPROGS_DATE "17-June-2008"
+-#define E2FSPROGS_VERSION "1.41.6"
++#define E2FSPROGS_VERSION "1.41.6.sun1"
++/* don't forget to update patches/ChangeLog */
+ #define E2FSPROGS_DATE "30-May-2009"
diff --git a/debian/patches/fix-patches.patch b/debian/patches/fix-patches.patch
deleted file mode 100644
index 5e4ba81..0000000
--- a/debian/patches/fix-patches.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff -Nurwd rebuild-clean/e2fsprogs-1.40.11/e2fsck/pass6.c e2fsprogs-1.40.11-0+lustre/e2fsck/pass6.c
---- e2fsprogs-1.40.11/e2fsck/pass6.c 2008-09-01 14:30:02.000000000 +0200
-+++ e2fsprogs-1.40.11-0+lustre/e2fsck/pass6.c 2008-08-27 17:01:09.000000000 +0200
-@@ -23,6 +23,8 @@
- #include <limits.h>
- #include <stdlib.h>
- #include <assert.h>
-+#include "ext2fs/ext2_fs.h"
-+#include "ext2fs/ext2fs.h"
-
- #ifdef ENABLE_LFSCK
- #include "lfsck.h"
-diff -Nurwd rebuild-clean/e2fsprogs-1.40.11/lib/ext2fs/crc16.h e2fsprogs-1.40.11-0+lustre/lib/ext2fs/crc16.h
---- e2fsprogs-1.40.11/lib/ext2fs/crc16.h 2008-09-01 14:30:01.000000000 +0200
-+++ e2fsprogs-1.40.11-0+lustre/lib/ext2fs/crc16.h 2008-08-27 14:44:10.000000000 +0200
-@@ -15,6 +15,7 @@
- #ifndef __CRC16_H
- #define __CRC16_H
-
-+#include <stddef.h>
- #include <linux/types.h>
-
- extern __u16 const crc16_table[256];
diff --git a/debian/patches/series b/debian/patches/series
index 5d3ef6b..c4d0f4a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,32 +1,64 @@
-e2fsprogs-version.patch
+e2fsprogs-version.patch
e2fsprogs-misc.patch
-e2fsprogs-disp-htree-bad-depth.patch
+e2fsprogs-bad-ininode-ea.patch
e2fsprogs-blkid-zfs.patch
+e2fsprogs-count_wrong_valid.patch
e2fsprogs-specdotin.patch
-e2fsprogs-eacheck.patch
e2fsprogs-extended_ops.patch
-e2fsprogs-nlinks.patch
-e2fsprogs-extents.patch
+e2fsprogs-tests-f_many_subdirs.patch
+e2fsprogs-extents.patch
+e2fsprogs-tests-f_bad_ea_value.patch
+e2fsprogs-tests-f_extents_bad_blk.patch
+e2fsprogs-tests-f_extents_ee_block.patch
+e2fsprogs-tests-f_extents_ee_len.patch
+e2fsprogs-tests-f_extents_ee_start.patch
+e2fsprogs-tests-f_extents_eh_depth.patch
+e2fsprogs-tests-f_extents_eh_entries.patch
+e2fsprogs-tests-f_extents_eh_magic.patch
+e2fsprogs-tests-f_extents_eh_max.patch
+e2fsprogs-tests-f_extents_ei_block.patch
+e2fsprogs-tests-f_extents_ei_leaf.patch
+e2fsprogs-tests-f_extents_imbalanced_tree.patch
+e2fsprogs-tests-f_extents_inrlevel-incons.patch
+e2fsprogs-tests-f_extents_orphan_blks.patch
+e2fsprogs-tests-f_extents_overlap.patch
+e2fsprogs-tests-f_extents_res_blk.patch
+e2fsprogs-tests-f_extents_shrd_blk.patch
+e2fsprogs-tests-f_extents_unsorted.patch
+e2fsprogs-tests-f_extents_split.patch
+e2fsprogs-skip-extent-tests.patch
e2fsprogs-config-before-cmdline.patch
-e2fsprogs-new-opt-shrdblks.patch
+e2fsprogs-new-opt-shrdblks.patch
sles/e2fsprogs-SLES10--m-support.patch
sles/libcom_err-no-static-buffer.patch
sles/libcom_err-no-init_error_table.patch
-sles/libcom_err-mutex.patch
-e2fsprogs-uninit.patch
+e2fsprogs-uninit-fixes.patch
+e2fsprogs-tests-f_uninit_enable.patch
+e2fsprogs-tests-f_uninit_disable.patch
+e2fsprogs-tests-f_uninit_blks-used_blk-uninit-not-set.patch
+e2fsprogs-tests-f_uninit_blk-uninit-set_inode-uninit-not-set.patch
+e2fsprogs-tests-f_uninit_checksum_invalid.patch
+e2fsprogs-tests-f_uninit_incorrect_free_inodes_count.patch
+e2fsprogs-tests-f_uninit_ino-ref_beyond_bg-itable-unused.patch
+e2fsprogs-tests-f_uninit_restart_fsck.patch
e2fsprogs-expand-extra-isize.patch
-e2fsprogs-ibadness-counter.patch
-e2fsprogs-stride_option.patch
+e2fsprogs-tests-f_expisize.patch
+e2fsprogs-tests-f_expisize_ea_del.patch
+e2fsprogs-ibadness-counter.patch
+e2fsprogs-tests-f_ibadness.patch
+e2fsprogs-tests-f_ibadness_bad_extents.patch
+e2fsprogs-tests-f_random_corruption.patch
e2fsprogs-mmp.patch
-e2fsprogs-journal_chksum.patch
+e2fsprogs-tests-f_mmp.patch
+e2fsprogs-tests-f_jchksum_bblk.patch
+e2fsprogs-tests-f_jchksum_blast_trans.patch
+e2fsprogs-tests-f_jchksum_remount.patch
e2fsprogs-i_size-corruption.patch
-e2fsprogs-fiemap.patch
-e2fsprogs-debugfs-supported_features.patch
-e2fsprogs-disp-i_version.patch
-e2fsprogs-lts-make_rpms.patch
+e2fsprogs-fiemap-lustre.patch
+e2fsprogs-disp-extent_header.patch
e2fsprogs-e2freefrag.patch
e2fsprogs-lustre_ismounted.patch
e2fsprogs-lfsck.patch
e2fsprogs-add-io_channel_readahead.patch
-e2fsprogs-e2scan.patch
-fix-patches.patch
+e2fsprogs-e2scan.patch
+e2fsprogs-tests-s_basic_scan.patch
diff --git a/debian/patches/sles/libcom_err-mutex.patch b/debian/patches/sles/libcom_err-mutex.patch
deleted file mode 100644
index 0631769..0000000
--- a/debian/patches/sles/libcom_err-mutex.patch
+++ /dev/null
@@ -1,472 +0,0 @@
-SLES upstream patch to add et_list_lock() and et_list_unlock() functions
-for kerberos use.
-
-Index: e2fsprogs-1.40.4/lib/et/com_err.pc.in
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/com_err.pc.in
-+++ e2fsprogs-1.40.4/lib/et/com_err.pc.in
-@@ -7,5 +7,5 @@ Name: com_err
- Description: Common error description library
- Version: @E2FSPROGS_VERSION@
- Requires:
--Cflags: -I${includedir}
--Libs: -L${libdir} -lcom_err
-+Cflags: -I${includedir} -pthread
-+Libs: -L${libdir} -lcom_err -pthread
-Index: e2fsprogs-1.40.4/lib/et/error_message.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/error_message.c
-+++ e2fsprogs-1.40.4/lib/et/error_message.c
-@@ -20,6 +20,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-+#include <pthread.h>
- #ifdef HAVE_SYS_PRCTL_H
- #include <sys/prctl.h>
- #else
-@@ -41,6 +42,17 @@
- struct et_list * _et_list = (struct et_list *) NULL;
- struct et_list * _et_dynamic_list = (struct et_list *) NULL;
-
-+static pthread_mutex_t _et_lock = PTHREAD_MUTEX_INITIALIZER;
-+
-+int et_list_lock()
-+{
-+ return pthread_mutex_lock(&_et_lock);
-+}
-+
-+int et_list_unlock()
-+{
-+ return pthread_mutex_unlock(&_et_lock);
-+}
-
- const char * error_message (errcode_t code)
- {
-@@ -66,22 +78,32 @@ const char * error_message (errcode_t co
- goto oops;
- #endif
- }
-+ et_list_lock();
- for (et = _et_list; et; et = et->next) {
- if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
- /* This is the right table */
-- if (et->table->n_msgs <= offset)
-- goto oops;
-- return(et->table->msgs[offset]);
-+ if (et->table->n_msgs <= offset) {
-+ break;
-+ } else {
-+ const char *msg = et->table->msgs[offset];
-+ et_list_unlock();
-+ return(msg);
-+ }
- }
- }
- for (et = _et_dynamic_list; et; et = et->next) {
- if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
- /* This is the right table */
-- if (et->table->n_msgs <= offset)
-- goto oops;
-- return(et->table->msgs[offset]);
-+ if (et->table->n_msgs <= offset) {
-+ break;
-+ } else {
-+ const char *msg = et->table->msgs[offset];
-+ et_list_unlock();
-+ return(msg);
-+ }
- }
- }
-+ et_list_unlock();
- oops:
- return "Unknown code";
- }
-@@ -150,10 +172,14 @@ errcode_t add_error_table(const struct e
- if (!(el = (struct et_list *) malloc(sizeof(struct et_list))))
- return ENOMEM;
-
-+ if( 0 != et_list_lock())
-+ return errno;
-+
- el->table = et;
- el->next = _et_dynamic_list;
- _et_dynamic_list = el;
-
-+ et_list_unlock();
- init_debug();
- if (debug_mask & DEBUG_ADDREMOVE)
- fprintf(debug_f, "add_error_table: %s (0x%p)\n",
-@@ -168,9 +194,13 @@ errcode_t add_error_table(const struct e
- */
- errcode_t remove_error_table(const struct error_table * et)
- {
-- struct et_list *el = _et_dynamic_list;
-+ struct et_list *el;
- struct et_list *el2 = 0;
-
-+ if( 0 != et_list_lock())
-+ return ENOENT;
-+
-+ el = _et_dynamic_list;
- init_debug();
- while (el) {
- if (el->table->base == et->base) {
-@@ -179,6 +209,7 @@ errcode_t remove_error_table(const struc
- else
- _et_dynamic_list = el->next;
- (void) free(el);
-+ et_list_unlock();
- if (debug_mask & DEBUG_ADDREMOVE)
- fprintf(debug_f,
- "remove_error_table: %s (0x%p)\n",
-@@ -193,6 +224,7 @@ errcode_t remove_error_table(const struc
- fprintf(debug_f, "remove_error_table FAILED: %s (0x%p)\n",
- error_table_name(et->base),
- (const void *) et);
-+ et_list_unlock();
- return ENOENT;
- }
-
-Index: e2fsprogs-1.40.4/lib/et/error_table.h
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/error_table.h
-+++ e2fsprogs-1.40.4/lib/et/error_table.h
-@@ -19,6 +19,8 @@ struct et_list {
- const struct error_table *table;
- };
- extern struct et_list * _et_list;
-+extern int et_list_lock(void);
-+extern int et_list_unlock(void);
-
- #define ERRCODE_RANGE 8 /* # of bits to shift table number */
- #define BITS_PER_CHAR 6 /* # bits to shift per character in name */
-Index: e2fsprogs-1.40.4/lib/et/et_c.awk
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/et_c.awk
-+++ e2fsprogs-1.40.4/lib/et/et_c.awk
-@@ -225,6 +225,8 @@ END {
- print " const struct error_table * table;" > outfile
- print "};" > outfile
- print "extern struct et_list *_et_list;" > outfile
-+ print "extern int et_list_lock();" > outfile
-+ print "extern int et_list_unlock();" > outfile
- print "" > outfile
- if (tab_base_high == 0) {
- print "const struct error_table et_" table_name "_error_table = { text, " \
-@@ -242,7 +244,22 @@ END {
- print "void initialize_" table_name "_error_table(void);" > outfile
- print "" > outfile
- print "void initialize_" table_name "_error_table(void) {" > outfile
-- print " initialize_" table_name "_error_table_r(&_et_list);" > outfile
-+ print " if(0 == et_list_lock()) {" > outfile
-+ print " if ( !link.table) {" > outfile
-+ print " struct et_list *el = _et_list;" > outfile
-+ print " while (el) {" > outfile
-+ print " if (el->table->base == et_" table_name "_error_table.base) {" > outfile
-+ print " et_list_unlock();" > outfile
-+ print " return;" > outfile
-+ print " }" > outfile
-+ print " el = el->next;" > outfile
-+ print " }" > outfile
-+ print " link.next = _et_list;" > outfile
-+ print " link.table = &et_" table_name "_error_table;" > outfile
-+ print " _et_list = &link;" > outfile
-+ print " }" > outfile
-+ print " et_list_unlock();" > outfile
-+ print " }" > outfile
- print "}" > outfile
- print "" > outfile
- print "/* For Heimdal compatibility */" > outfile
-@@ -255,9 +272,6 @@ END {
- print " return;" > outfile
- print " et = malloc(sizeof(struct et_list));" > outfile
- print " if (et == 0) {" > outfile
-- print " if (!link.table)" > outfile
-- print " et = &link;" > outfile
-- print " else" > outfile
- print " return;" > outfile
- print " }" > outfile
- print " et->table = &et_" table_name "_error_table;" > outfile
-Index: e2fsprogs-1.40.4/lib/et/test_cases/continuation.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/continuation.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/continuation.c
-@@ -20,6 +20,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_ovk_error_table = { text, 43787520L, 1 };
-
-@@ -29,7 +31,22 @@ void initialize_ovk_error_table_r(struct
- void initialize_ovk_error_table(void);
-
- void initialize_ovk_error_table(void) {
-- initialize_ovk_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_ovk_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_ovk_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -42,9 +59,6 @@ void initialize_ovk_error_table_r(struct
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_ovk_error_table;
-Index: e2fsprogs-1.40.4/lib/et/test_cases/heimdal2.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/heimdal2.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/heimdal2.c
-@@ -87,6 +87,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_kadm_error_table = { text, -1783126272L, 68 };
-
-@@ -96,7 +98,22 @@ void initialize_kadm_error_table_r(struc
- void initialize_kadm_error_table(void);
-
- void initialize_kadm_error_table(void) {
-- initialize_kadm_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_kadm_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_kadm_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -109,9 +126,6 @@ void initialize_kadm_error_table_r(struc
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_kadm_error_table;
-Index: e2fsprogs-1.40.4/lib/et/test_cases/heimdal3.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/heimdal3.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/heimdal3.c
-@@ -21,6 +21,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_h3test_error_table = { text, 43787520L, 2 };
-
-@@ -30,7 +32,22 @@ void initialize_h3test_error_table_r(str
- void initialize_h3test_error_table(void);
-
- void initialize_h3test_error_table(void) {
-- initialize_h3test_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_h3test_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_h3test_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -43,9 +60,6 @@ void initialize_h3test_error_table_r(str
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_h3test_error_table;
-Index: e2fsprogs-1.40.4/lib/et/test_cases/heimdal.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/heimdal.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/heimdal.c
-@@ -101,6 +101,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_krb_error_table = { text, 39525376L, 82 };
-
-@@ -110,7 +112,22 @@ void initialize_krb_error_table_r(struct
- void initialize_krb_error_table(void);
-
- void initialize_krb_error_table(void) {
-- initialize_krb_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_krb_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_krb_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -123,9 +140,6 @@ void initialize_krb_error_table_r(struct
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_krb_error_table;
-Index: e2fsprogs-1.40.4/lib/et/test_cases/imap_err.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/imap_err.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/imap_err.c
-@@ -49,6 +49,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_imap_error_table = { text, -1904809472L, 30 };
-
-@@ -58,7 +60,22 @@ void initialize_imap_error_table_r(struc
- void initialize_imap_error_table(void);
-
- void initialize_imap_error_table(void) {
-- initialize_imap_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_imap_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_imap_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -71,9 +88,6 @@ void initialize_imap_error_table_r(struc
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_imap_error_table;
-Index: e2fsprogs-1.40.4/lib/et/test_cases/simple.c
-===================================================================
---- e2fsprogs-1.40.4.orig/lib/et/test_cases/simple.c
-+++ e2fsprogs-1.40.4/lib/et/test_cases/simple.c
-@@ -41,6 +41,8 @@ struct et_list {
- const struct error_table * table;
- };
- extern struct et_list *_et_list;
-+extern int et_list_lock();
-+extern int et_list_unlock();
-
- const struct error_table et_krb_error_table = { text, 39525376L, 22 };
-
-@@ -50,7 +52,22 @@ void initialize_krb_error_table_r(struct
- void initialize_krb_error_table(void);
-
- void initialize_krb_error_table(void) {
-- initialize_krb_error_table_r(&_et_list);
-+ if(0 == et_list_lock()) {
-+ if ( !link.table) {
-+ struct et_list *el = _et_list;
-+ while (el) {
-+ if (el->table->base == et_krb_error_table.base) {
-+ et_list_unlock();
-+ return;
-+ }
-+ el = el->next;
-+ }
-+ link.next = _et_list;
-+ link.table = &et_krb_error_table;
-+ _et_list = &link;
-+ }
-+ et_list_unlock();
-+ }
- }
-
- /* For Heimdal compatibility */
-@@ -63,9 +80,6 @@ void initialize_krb_error_table_r(struct
- return;
- et = malloc(sizeof(struct et_list));
- if (et == 0) {
-- if (!link.table)
-- et = &link;
-- else
- return;
- }
- et->table = &et_krb_error_table;
diff --git a/debian/patches/sles/libcom_err-no-init_error_table.patch b/debian/patches/sles/libcom_err-no-init_error_table.patch
index cc0d074..dbeadca 100644
--- a/debian/patches/sles/libcom_err-no-init_error_table.patch
+++ b/debian/patches/sles/libcom_err-no-init_error_table.patch
@@ -4,7 +4,7 @@ SLES upstream patch to remove init_error_table() (not thread safe).
+++ e2fsprogs-1.38/lib/et/com_err.h
@@ -41,7 +41,10 @@
(const char *, long, const char *, va_list);
- extern void (*reset_com_err_hook (void)) (const char *, long,
+ extern void (*reset_com_err_hook (void)) (const char *, long,
const char *, va_list);
+#if 0
extern int init_error_table(const char * const *msgs, long base, int count);
diff --git a/debian/patches/sles/libcom_err-no-static-buffer.patch b/debian/patches/sles/libcom_err-no-static-buffer.patch
index 7ce82b2..08f0e2c 100644
--- a/debian/patches/sles/libcom_err-no-static-buffer.patch
+++ b/debian/patches/sles/libcom_err-no-static-buffer.patch
@@ -4,9 +4,9 @@ Index: e2fsprogs-1.40.7/lib/et/error_message.c
===================================================================
--- e2fsprogs-1.40.7.orig/lib/et/error_message.c
+++ e2fsprogs-1.40.7/lib/et/error_message.c
-@@ -91,25 +91,7 @@ const char * error_message (errcode_t co
- }
+@@ -92,25 +92,7 @@ const char * error_message (errcode_t co
}
+ et_list_unlock();
oops:
- strcpy (buffer, "Unknown code ");
- if (table_num) {
--
Repository for maintaining lidskfsprogs
More information about the Pkg-lustre-svn-commit
mailing list