--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: e2fsck: fix logic bug when there are no references to an EA inode
+
+There was a boolean logic error which, among other things, could cause
+an attempt to modify an inode in e2fsck -n mode:
+
+e2fsck 1.47.2 (1-Jan-2025)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+ext2fs_write_inode: Attempt to write to filesystem opened read-only while writing inode 14 in pass4
+e2fsck: aborted
+
+Fixes: 849a9e6e133a ("e2fsck: add more checks for ea inode consistency")
+Origin: https://github.com/tytso/e2fsprogs/commit/92b6e93936d7a0f6d7ce7a9f142e2c0ee9afbeaf
+---
+ e2fsck/pass4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
+index cf0cf7c47..cee3be64b 100644
+--- a/e2fsck/pass4.c
++++ b/e2fsck/pass4.c
+@@ -120,7 +120,7 @@ static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
+ * will get attached to lost+found so clear EA_INODE_FL.
+ * Otherwise this is likely a spuriously set flag so clear it.
+ */
+- if (*link_counted == 0 ||
++ if (*link_counted == 0 &&
+ fix_problem(ctx, PR_4_EA_INODE_SPURIOUS_FLAG, &pctx)) {
+ /* Clear EA_INODE_FL (likely a normal file) */
+ inode->i_flags &= ~EXT4_EA_INODE_FL;
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: test: fix expect files which changed after EA bugfix
+
+The logic bug which was fixed in commit 92b6e93936d7 ("e2fsck: fix
+logic bug when there are no references...") resulted in some silent
+fixes that were never logged, and in some cases, corruption that was
+not cleaned up. Fix the tests so that they pass as expected.
+
+Fixes: 92b6e93936d7 ("e2fsck: fix logic bug when there are no references..."
+Origin: https://github.com/tytso/e2fsprogs/commit/ddd4f796d9dfdb80e5639ca8411e8e4891d3c7f1
+---
+ tests/f_ea_inode_disconnected/expect.1 | 2 ++
+ tests/f_ea_inode_self_ref/expect.1 | 2 --
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/f_ea_inode_disconnected/expect.1 b/tests/f_ea_inode_disconnected/expect.1
+index afc77aea6..539dc5ef9 100644
+--- a/tests/f_ea_inode_disconnected/expect.1
++++ b/tests/f_ea_inode_disconnected/expect.1
+@@ -2,6 +2,8 @@ Pass 1: Checking inodes, blocks, and sizes
+ Pass 2: Checking directory structure
+ Pass 3: Checking directory connectivity
+ Pass 4: Checking reference counts
++Regular filesystem inode 13 has EA_INODE flag set. Clear? yes
++
+ Unattached inode 13
+ Connect to /lost+found? yes
+
+diff --git a/tests/f_ea_inode_self_ref/expect.1 b/tests/f_ea_inode_self_ref/expect.1
+index 35bea1417..f94c04d96 100644
+--- a/tests/f_ea_inode_self_ref/expect.1
++++ b/tests/f_ea_inode_self_ref/expect.1
+@@ -7,8 +7,6 @@ Clear? yes
+ Pass 2: Checking directory structure
+ Pass 3: Checking directory connectivity
+ Pass 4: Checking reference counts
+-Regular filesystem inode 16 has EA_INODE flag set. Clear? yes
+-
+ Pass 5: Checking group summary information
+ Block bitmap differences: -20
+ Fix? yes
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: libext2fs: teach ext2fs_extent_set_bmap() to update extents more optimally
+
+When programs like resize2fs or e2fsck relocates all of the blocks in
+an extent one at a time, the ext2fs_extent_set_bmap() works by
+initially adding a new extent and then moving mapping from the old
+extent to the new extent. For example:
+
+t=1 EXTENTS: (0-2) 1152-1154
+
+t=2 EXTENTS: (0) 1136, (1-2) 1153-1154
+
+t=3 EXTENTS: (0-1) 1136-1137, (2) 1154
+
+Unfortunately, previously, when the last block is updated, the
+resulting extent tree will have two extents instead of one, like this:
+
+t=4 EXTENTS: (0-1) 1136-1137, (2) 1138
+
+With this commit, the resulting extent tree will be more optimally
+represented with a single extent:
+
+t=4 EXTENTS: (0-2) 1136-1138
+
+The optimization in this commit solves the prolem reproted at:
+https://github.com/tytso/e2fsprogs/issues/146
+
+In that case, the file had a very large, complex (fragmented) extent
+tree, and resize2fs needed to relcate all of its blocks as part of a
+off-line shrink, the lack of the optimization led to an extent block
+overflowing, resulting in the old extent (the one which originally
+mapped logical block 2507128 to physical block 389065080) and the new
+extent landing in two different leaf blocks:
+
+ 2/ 2 1/ 1 2507128 - 2507128 640097 - 640097 1
+ 2/ 2 1/135 2507128 - 2507128 389065080 - 389065080 1
+
+This resulted a corrupted extent tree block and data loss.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/ea825a53bcb214de7356c2ebd8a10d005613bec3
+---
+ lib/ext2fs/extent.c | 25 ++++++++++++++++++++++++-
+ tests/f_badcluster/expect | 8 ++++----
+ 2 files changed, 28 insertions(+), 5 deletions(-)
+
+diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
+index 82e75ccd7..c4b95741e 100644
+--- a/lib/ext2fs/extent.c
++++ b/lib/ext2fs/extent.c
+@@ -1444,8 +1444,31 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
+ printf("(re/un)mapping only block in extent\n");
+ #endif
+ if (physical) {
+- retval = ext2fs_extent_replace(handle, 0, &newextent);
++ if (has_prev &&
++ (logical == (prev_extent.e_lblk +
++ prev_extent.e_len)) &&
++ (physical == (prev_extent.e_pblk +
++ prev_extent.e_len)) &&
++ (new_uninit == prev_uninit) &&
++ ((int) prev_extent.e_len < max_len-1)) {
++ retval = ext2fs_extent_get(handle,
++ EXT2_EXTENT_PREV_LEAF, &prev_extent);
++ if (retval)
++ goto done;
++ prev_extent.e_len++;
++ retval = ext2fs_extent_replace(handle, 0,
++ &prev_extent);
++ retval = ext2fs_extent_get(handle,
++ EXT2_EXTENT_NEXT_LEAF,
++ &extent);
++ if (retval)
++ goto done;
++ goto delete_node;
++
++ } else
++ retval = ext2fs_extent_replace(handle, 0, &newextent);
+ } else {
++ delete_node:
+ retval = ext2fs_extent_delete(handle, 0);
+ if (retval)
+ goto done;
+diff --git a/tests/f_badcluster/expect b/tests/f_badcluster/expect
+index b44e65d00..fe1c1718f 100644
+--- a/tests/f_badcluster/expect
++++ b/tests/f_badcluster/expect
+@@ -119,7 +119,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ EXTENTS:
+-(0-1):1136-1137, (2):1138
++(0-2):1136-1138
+ debugfs: stat /b
+ Inode: 13 Type: regular Mode: 0644 Flags: 0x80000
+ Generation: 1117152158 Version: 0x00000001
+@@ -143,7 +143,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ EXTENTS:
+-(0-1):1216-1217, (2):1218
++(0-2):1216-1218
+ debugfs: stat /d
+ Inode: 15 Type: regular Mode: 0644 Flags: 0x80000
+ Generation: 1117152160 Version: 0x00000001
+@@ -178,7 +178,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ EXTENTS:
+-(0):1232, (1):1233, (2):1234
++(0-2):1232-1234
+ debugfs: stat /g
+ Inode: 18 Type: regular Mode: 0644 Flags: 0x80000
+ Generation: 1117152163 Version: 0x00000001
+@@ -190,5 +190,5 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
+ EXTENTS:
+-(0-2):1680-1682, (3):1683
++(0-3):1680-1683
+ debugfs: quit
+--
+2.47.2
+
--- /dev/null
+From: Jakub Wilk <jwilk@jwilk.net>
+Subject: e2image.8: add missing comma
+Origin: https://github.com/tytso/e2fsprogs/commit/5a6ec683252be78ccda7dec7dac530f2ebc46ce6
+---
+ misc/e2image.8.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/e2image.8.in b/misc/e2image.8.in
+index 384ef3023..0be1c751e 100644
+--- a/misc/e2image.8.in
++++ b/misc/e2image.8.in
+@@ -326,5 +326,5 @@ http://e2fsprogs.sourceforge.net.
+
+ .SH SEE ALSO
+ .BR dumpe2fs (8),
+-.BR debugfs (8)
++.BR debugfs (8),
+ .BR e2fsck (8)
+--
+2.47.2
+
--- /dev/null
+From: Brian Foster <bfoster@redhat.com>
+Subject: debugfs: byteswap dirsearch dirent buf on big endian systems
+
+fstests test ext4/048 fails on big endian systems due to broken
+debugfs dirsearch functionality. On an s390x system and 4k block
+size, the dirsearch command seems to hang indefinitely. On the same
+system with a 1k block size, the command fails to locate an existing
+entry and causes the test to fail due to unexpected results.
+
+The cause of the dirsearch failure is lack of byte swapping of the
+on-disk (little endian) dirent buffer before attempting to iterate
+entries in the given block. This leads to garbage record and name
+length values, for example. To resolve this problem, byte swap the
+directory buffer on big endian systems.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/4be42019388d76c933e3b2ea80284aaf5b8eaecb
+---
+ debugfs/htree.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/debugfs/htree.c b/debugfs/htree.c
+index a10081507..4ea8f30b3 100644
+--- a/debugfs/htree.c
++++ b/debugfs/htree.c
+@@ -482,6 +482,12 @@ static int search_dir_block(ext2_filsys fs, blk64_t *blocknr,
+ return BLOCK_ABORT;
+ }
+
++#ifdef WORDS_BIGENDIAN
++ errcode = ext2fs_dirent_swab_in(fs, p->buf, 0);
++ if (errcode)
++ return BLOCK_ABORT;
++#endif
++
+ while (offset < fs->blocksize) {
+ dirent = (struct ext2_dir_entry *) (p->buf + offset);
+ errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: refuse unsupported features
+
+Don't mount a filesystem with superblock features that we don't actually
+know how to support.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/ccbc6f24fed095b28f9faa7b575159e49787fae0
+---
+ misc/fuse2fs.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index a6390ab5d..2e0463201 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -3863,6 +3863,26 @@ int main(int argc, char *argv[])
+
+ ret = 3;
+
++ if (ext2fs_has_feature_quota(global_fs->super)) {
++ printf(_("%s: quotas not supported."), fctx.device);
++ goto out;
++ }
++ if (ext2fs_has_feature_verity(global_fs->super)) {
++ printf(_("%s: verity not supported."), fctx.device);
++ goto out;
++ }
++ if (ext2fs_has_feature_encrypt(global_fs->super)) {
++ printf(_("%s: encryption not supported."), fctx.device);
++ goto out;
++ }
++ if (ext2fs_has_feature_casefold(global_fs->super)) {
++ printf(_("%s: casefolding not supported."), fctx.device);
++ goto out;
++ }
++
++ if (ext2fs_has_feature_shared_blocks(global_fs->super))
++ fctx.ro = 1;
++
+ if (ext2fs_has_feature_journal_needs_recovery(global_fs->super)) {
+ if (fctx.norecovery) {
+ printf(_("%s: mounting read-only without "
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: return -EOPNOTSUPP when we don't recognize a fallocate mode
+
+If we don't recognize a set bit in the mode parameter to fallocate,
+return EOPNOTSUPP to communicate that we don't support that mode instead
+of EINVAL. This avoids unnecessary failures in generic/521.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/7775293c08d2255e90b1e003ee532d826af52d95
+---
+ misc/fuse2fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index 2e0463201..1ec7cd22f 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -3616,7 +3616,7 @@ static int op_fallocate(const char *path EXT2FS_ATTR((unused)), int mode,
+
+ /* Catch unknown flags */
+ if (mode & ~(FL_PUNCH_HOLE_FLAG | FL_KEEP_SIZE_FLAG))
+- return -EINVAL;
++ return -EOPNOTSUPP;
+
+ pthread_mutex_lock(&ff->bfl);
+ if (!fs_writeable(fs)) {
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: remove posix acl translation
+
+Remove the POSIX ACL format translation since libext2fs takes care of
+that now.
+
+Fixes: 0ee1eaf70c257e ("libext2fs: translate internal ext4 acl to Posix ACL in ext2fs_xattr_[sg]et()")
+Origin: https://github.com/tytso/e2fsprogs/commit/0111bdb70a9c460052387111414a2e2dc8c06822
+---
+ misc/fuse2fs.c | 267 +------------------------------------------------
+ 1 file changed, 4 insertions(+), 263 deletions(-)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index 1ec7cd22f..eeb496d1b 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -17,12 +17,6 @@
+ # include <linux/fs.h>
+ # include <linux/falloc.h>
+ # include <linux/xattr.h>
+-# ifdef HAVE_SYS_ACL_H
+-# define TRANSLATE_LINUX_ACLS
+-# endif
+-#endif
+-#ifdef TRANSLATE_LINUX_ACLS
+-# include <sys/acl.h>
+ #endif
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+@@ -119,206 +113,6 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fs);
+ int journal_enable_debug = -1;
+ #endif
+
+-/* ACL translation stuff */
+-#ifdef TRANSLATE_LINUX_ACLS
+-/*
+- * Copied from acl_ea.h in libacl source; ACLs have to be sent to and from fuse
+- * in this format... at least on Linux.
+- */
+-#define ACL_EA_ACCESS "system.posix_acl_access"
+-#define ACL_EA_DEFAULT "system.posix_acl_default"
+-
+-#define ACL_EA_VERSION 0x0002
+-
+-typedef struct {
+- u_int16_t e_tag;
+- u_int16_t e_perm;
+- u_int32_t e_id;
+-} acl_ea_entry;
+-
+-typedef struct {
+- u_int32_t a_version;
+-#if __GNUC_PREREQ (4, 8)
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wpedantic"
+-#endif
+- acl_ea_entry a_entries[0];
+-#if __GNUC_PREREQ (4, 8)
+-#pragma GCC diagnostic pop
+-#endif
+-} acl_ea_header;
+-
+-static inline size_t acl_ea_size(int count)
+-{
+- return sizeof(acl_ea_header) + count * sizeof(acl_ea_entry);
+-}
+-
+-static inline int acl_ea_count(size_t size)
+-{
+- if (size < sizeof(acl_ea_header))
+- return -1;
+- size -= sizeof(acl_ea_header);
+- if (size % sizeof(acl_ea_entry))
+- return -1;
+- return size / sizeof(acl_ea_entry);
+-}
+-
+-/*
+- * ext4 ACL structures, copied from fs/ext4/acl.h.
+- */
+-#define EXT4_ACL_VERSION 0x0001
+-
+-typedef struct {
+- __u16 e_tag;
+- __u16 e_perm;
+- __u32 e_id;
+-} ext4_acl_entry;
+-
+-typedef struct {
+- __u16 e_tag;
+- __u16 e_perm;
+-} ext4_acl_entry_short;
+-
+-typedef struct {
+- __u32 a_version;
+-} ext4_acl_header;
+-
+-static inline size_t ext4_acl_size(int count)
+-{
+- if (count <= 4) {
+- return sizeof(ext4_acl_header) +
+- count * sizeof(ext4_acl_entry_short);
+- } else {
+- return sizeof(ext4_acl_header) +
+- 4 * sizeof(ext4_acl_entry_short) +
+- (count - 4) * sizeof(ext4_acl_entry);
+- }
+-}
+-
+-static inline int ext4_acl_count(size_t size)
+-{
+- ssize_t s;
+-
+- size -= sizeof(ext4_acl_header);
+- s = size - 4 * sizeof(ext4_acl_entry_short);
+- if (s < 0) {
+- if (size % sizeof(ext4_acl_entry_short))
+- return -1;
+- return size / sizeof(ext4_acl_entry_short);
+- }
+- if (s % sizeof(ext4_acl_entry))
+- return -1;
+- return s / sizeof(ext4_acl_entry) + 4;
+-}
+-
+-static errcode_t fuse_to_ext4_acl(acl_ea_header *facl, size_t facl_sz,
+- ext4_acl_header **eacl, size_t *eacl_sz)
+-{
+- int i, facl_count;
+- ext4_acl_header *h;
+- size_t h_sz;
+- ext4_acl_entry *e;
+- acl_ea_entry *a;
+- unsigned char *hptr;
+- errcode_t err;
+-
+- facl_count = acl_ea_count(facl_sz);
+- h_sz = ext4_acl_size(facl_count);
+- if (facl_count < 0 || facl->a_version != ACL_EA_VERSION)
+- return EXT2_ET_INVALID_ARGUMENT;
+-
+- err = ext2fs_get_mem(h_sz, &h);
+- if (err)
+- return err;
+-
+- h->a_version = ext2fs_cpu_to_le32(EXT4_ACL_VERSION);
+- hptr = (unsigned char *) (h + 1);
+- for (i = 0, a = facl->a_entries; i < facl_count; i++, a++) {
+- e = (ext4_acl_entry *) hptr;
+- e->e_tag = ext2fs_cpu_to_le16(a->e_tag);
+- e->e_perm = ext2fs_cpu_to_le16(a->e_perm);
+-
+- switch (a->e_tag) {
+- case ACL_USER:
+- case ACL_GROUP:
+- e->e_id = ext2fs_cpu_to_le32(a->e_id);
+- hptr += sizeof(ext4_acl_entry);
+- break;
+- case ACL_USER_OBJ:
+- case ACL_GROUP_OBJ:
+- case ACL_MASK:
+- case ACL_OTHER:
+- hptr += sizeof(ext4_acl_entry_short);
+- break;
+- default:
+- err = EXT2_ET_INVALID_ARGUMENT;
+- goto out;
+- }
+- }
+-
+- *eacl = h;
+- *eacl_sz = h_sz;
+- return err;
+-out:
+- ext2fs_free_mem(&h);
+- return err;
+-}
+-
+-static errcode_t ext4_to_fuse_acl(acl_ea_header **facl, size_t *facl_sz,
+- ext4_acl_header *eacl, size_t eacl_sz)
+-{
+- int i, eacl_count;
+- acl_ea_header *f;
+- ext4_acl_entry *e;
+- acl_ea_entry *a;
+- size_t f_sz;
+- unsigned char *hptr;
+- errcode_t err;
+-
+- eacl_count = ext4_acl_count(eacl_sz);
+- f_sz = acl_ea_size(eacl_count);
+- if (eacl_count < 0 ||
+- eacl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION))
+- return EXT2_ET_INVALID_ARGUMENT;
+-
+- err = ext2fs_get_mem(f_sz, &f);
+- if (err)
+- return err;
+-
+- f->a_version = ACL_EA_VERSION;
+- hptr = (unsigned char *) (eacl + 1);
+- for (i = 0, a = f->a_entries; i < eacl_count; i++, a++) {
+- e = (ext4_acl_entry *) hptr;
+- a->e_tag = ext2fs_le16_to_cpu(e->e_tag);
+- a->e_perm = ext2fs_le16_to_cpu(e->e_perm);
+-
+- switch (a->e_tag) {
+- case ACL_USER:
+- case ACL_GROUP:
+- a->e_id = ext2fs_le32_to_cpu(e->e_id);
+- hptr += sizeof(ext4_acl_entry);
+- break;
+- case ACL_USER_OBJ:
+- case ACL_GROUP_OBJ:
+- case ACL_MASK:
+- case ACL_OTHER:
+- hptr += sizeof(ext4_acl_entry_short);
+- break;
+- default:
+- err = EXT2_ET_INVALID_ARGUMENT;
+- goto out;
+- }
+- }
+-
+- *facl = f;
+- *facl_sz = f_sz;
+- return err;
+-out:
+- ext2fs_free_mem(&f);
+- return err;
+-}
+-#endif /* TRANSLATE_LINUX_ACLS */
+-
+ /*
+ * ext2_file_t contains a struct inode, so we can't leave files open.
+ * Use this as a proxy instead.
+@@ -2432,30 +2226,6 @@ static int op_statfs(const char *path EXT2FS_ATTR((unused)),
+ return 0;
+ }
+
+-typedef errcode_t (*xattr_xlate_get)(void **cooked_buf, size_t *cooked_sz,
+- const void *raw_buf, size_t raw_sz);
+-typedef errcode_t (*xattr_xlate_set)(const void *cooked_buf, size_t cooked_sz,
+- const void **raw_buf, size_t *raw_sz);
+-struct xattr_translate {
+- const char *prefix;
+- xattr_xlate_get get;
+- xattr_xlate_set set;
+-};
+-
+-#define XATTR_TRANSLATOR(p, g, s) \
+- {.prefix = (p), \
+- .get = (xattr_xlate_get)(g), \
+- .set = (xattr_xlate_set)(s)}
+-
+-static struct xattr_translate xattr_translators[] = {
+-#ifdef TRANSLATE_LINUX_ACLS
+- XATTR_TRANSLATOR(ACL_EA_ACCESS, ext4_to_fuse_acl, fuse_to_ext4_acl),
+- XATTR_TRANSLATOR(ACL_EA_DEFAULT, ext4_to_fuse_acl, fuse_to_ext4_acl),
+-#endif
+- XATTR_TRANSLATOR(NULL, NULL, NULL),
+-};
+-#undef XATTR_TRANSLATOR
+-
+ static int op_getxattr(const char *path, const char *key, char *value,
+ size_t len)
+ {
+@@ -2463,9 +2233,8 @@ static int op_getxattr(const char *path, const char *key, char *value,
+ struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data;
+ ext2_filsys fs;
+ struct ext2_xattr_handle *h;
+- struct xattr_translate *xt;
+- void *ptr, *cptr;
+- size_t plen, clen;
++ void *ptr;
++ size_t plen;
+ ext2_ino_t ino;
+ errcode_t err;
+ int ret = 0;
+@@ -2507,17 +2276,6 @@ static int op_getxattr(const char *path, const char *key, char *value,
+ goto out2;
+ }
+
+- for (xt = xattr_translators; xt->prefix != NULL; xt++) {
+- if (strncmp(key, xt->prefix, strlen(xt->prefix)) == 0) {
+- err = xt->get(&cptr, &clen, ptr, plen);
+- if (err)
+- goto out3;
+- ext2fs_free_mem(&ptr);
+- ptr = cptr;
+- plen = clen;
+- }
+- }
+-
+ if (!len) {
+ ret = plen;
+ } else if (len < plen) {
+@@ -2527,7 +2285,6 @@ static int op_getxattr(const char *path, const char *key, char *value,
+ ret = plen;
+ }
+
+-out3:
+ ext2fs_free_mem(&ptr);
+ out2:
+ err = ext2fs_xattrs_close(&h);
+@@ -2645,9 +2402,6 @@ static int op_setxattr(const char *path EXT2FS_ATTR((unused)),
+ struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data;
+ ext2_filsys fs;
+ struct ext2_xattr_handle *h;
+- struct xattr_translate *xt;
+- const void *cvalue;
+- size_t clen;
+ ext2_ino_t ino;
+ errcode_t err;
+ int ret = 0;
+@@ -2686,26 +2440,13 @@ static int op_setxattr(const char *path EXT2FS_ATTR((unused)),
+ goto out2;
+ }
+
+- cvalue = value;
+- clen = len;
+- for (xt = xattr_translators; xt->prefix != NULL; xt++) {
+- if (strncmp(key, xt->prefix, strlen(xt->prefix)) == 0) {
+- err = xt->set(value, len, &cvalue, &clen);
+- if (err)
+- goto out3;
+- }
+- }
+-
+- err = ext2fs_xattr_set(h, key, cvalue, clen);
++ err = ext2fs_xattr_set(h, key, value, len);
+ if (err) {
+ ret = translate_error(fs, ino, err);
+- goto out3;
++ goto out2;
+ }
+
+ ret = update_ctime(fs, ino, NULL);
+-out3:
+- if (cvalue != value)
+- ext2fs_free_mem(&cvalue);
+ out2:
+ err = ext2fs_xattrs_close(&h);
+ if (!ret && err)
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: clamp timestamps that are being written to disk
+
+Clamp the timestamps that we write to disk to the minimum and maximum
+values permitted given the ondisk format. This fixes y2038 support, as
+tested by generic/402.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/e13395876d63cebf008101b934ee9e5cdaae0150
+---
+ lib/ext2fs/ext2_fs.h | 4 ++++
+ misc/fuse2fs.c | 39 ++++++++++++++++++++++++++++++++-------
+ 2 files changed, 36 insertions(+), 7 deletions(-)
+
+diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
+index 3a5eb7387..fcd420556 100644
+--- a/lib/ext2fs/ext2_fs.h
++++ b/lib/ext2fs/ext2_fs.h
+@@ -801,6 +801,10 @@ struct ext2_super_block {
+
+ #define EXT2_GOOD_OLD_INODE_SIZE 128
+
++#define EXT4_EXTRA_TIMESTAMP_MAX (((int64_t)1 << 34) - 1 + INT32_MIN)
++#define EXT4_NON_EXTRA_TIMESTAMP_MAX INT32_MAX
++#define EXT4_TIMESTAMP_MIN INT32_MIN
++
+ /*
+ * Journal inode backup types
+ */
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index eeb496d1b..238804dd4 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -209,21 +209,43 @@ static inline void ext4_decode_extra_time(struct timespec *time, __u32 extra)
+ time->tv_nsec = ((extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
+ }
+
++#define EXT4_CLAMP_TIMESTAMP(xtime, timespec, raw_inode) \
++do { \
++ if ((timespec)->tv_sec < EXT4_TIMESTAMP_MIN) \
++ (timespec)->tv_sec = EXT4_TIMESTAMP_MIN; \
++ if ((timespec)->tv_sec < EXT4_TIMESTAMP_MIN) \
++ (timespec)->tv_sec = EXT4_TIMESTAMP_MIN; \
++ \
++ if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) { \
++ if ((timespec)->tv_sec > EXT4_EXTRA_TIMESTAMP_MAX) \
++ (timespec)->tv_sec = EXT4_EXTRA_TIMESTAMP_MAX; \
++ } else { \
++ if ((timespec)->tv_sec > EXT4_NON_EXTRA_TIMESTAMP_MAX) \
++ (timespec)->tv_sec = EXT4_NON_EXTRA_TIMESTAMP_MAX; \
++ } \
++} while (0)
++
+ #define EXT4_INODE_SET_XTIME(xtime, timespec, raw_inode) \
+ do { \
+- (raw_inode)->xtime = (timespec)->tv_sec; \
++ typeof(*(timespec)) _ts = *(timespec); \
++ \
++ EXT4_CLAMP_TIMESTAMP(xtime, &_ts, raw_inode); \
++ (raw_inode)->xtime = _ts.tv_sec; \
+ if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) \
+ (raw_inode)->xtime ## _extra = \
+- ext4_encode_extra_time(timespec); \
++ ext4_encode_extra_time(&_ts); \
+ } while (0)
+
+ #define EXT4_EINODE_SET_XTIME(xtime, timespec, raw_inode) \
+ do { \
++ typeof(*(timespec)) _ts = *(timespec); \
++ \
++ EXT4_CLAMP_TIMESTAMP(xtime, &_ts, raw_inode); \
+ if (EXT4_FITS_IN_INODE(raw_inode, xtime)) \
+- (raw_inode)->xtime = (timespec)->tv_sec; \
++ (raw_inode)->xtime = _ts.tv_sec; \
+ if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) \
+ (raw_inode)->xtime ## _extra = \
+- ext4_encode_extra_time(timespec); \
++ ext4_encode_extra_time(&_ts); \
+ } while (0)
+
+ #define EXT4_INODE_GET_XTIME(xtime, timespec, raw_inode) \
+@@ -2843,7 +2865,10 @@ static int op_utimens(const char *path, const struct timespec ctv[2]
+ ret = translate_error(fs, 0, err);
+ goto out;
+ }
+- dbg_printf("%s: ino=%d\n", __func__, ino);
++ dbg_printf("%s: ino=%d atime=%lld.%ld mtime=%lld.%ld\n", __func__,
++ ino,
++ (long long int)ctv[0].tv_sec, ctv[0].tv_nsec,
++ (long long int)ctv[1].tv_sec, ctv[1].tv_nsec);
+
+ ret = check_inum_access(fs, ino, W_OK);
+ if (ret)
+@@ -2867,9 +2892,9 @@ static int op_utimens(const char *path, const struct timespec ctv[2]
+ #endif /* UTIME_NOW */
+ #ifdef UTIME_OMIT
+ if (tv[0].tv_nsec != UTIME_OMIT)
+- EXT4_INODE_SET_XTIME(i_atime, tv, &inode);
++ EXT4_INODE_SET_XTIME(i_atime, &tv[0], &inode);
+ if (tv[1].tv_nsec != UTIME_OMIT)
+- EXT4_INODE_SET_XTIME(i_mtime, tv + 1, &inode);
++ EXT4_INODE_SET_XTIME(i_mtime, &tv[1], &inode);
+ #endif /* UTIME_OMIT */
+ ret = update_ctime(fs, ino, &inode);
+ if (ret)
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: update new child timestamps during mkdir/symlink
+
+These two file creation functions fail to update the timestamps of the
+new child file, unlike the others (mknod/creat). Fix that.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/f73fbf8e2cee1f2d49f4e7573eadb9f1cf141879
+---
+ misc/fuse2fs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index 238804dd4..d123eebb1 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -976,6 +976,7 @@ static int op_mkdir(const char *path, mode_t mode)
+ inode.i_mode = LINUX_S_IFDIR | (mode & ~S_ISUID) |
+ parent_sgid;
+ inode.i_generation = ff->next_generation++;
++ init_times(&inode);
+
+ err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
+ sizeof(inode));
+@@ -1349,6 +1350,7 @@ static int op_symlink(const char *src, const char *dest)
+ inode.i_gid = ctxt->gid;
+ ext2fs_set_i_gid_high(inode, ctxt->gid >> 16);
+ inode.i_generation = ff->next_generation++;
++ init_times(&inode);
+
+ err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode,
+ sizeof(inode));
+--
+2.47.2
+
--- /dev/null
+From: "Darrick J. Wong" <djwong@kernel.org>
+Subject: fuse2fs: disable renameat2
+
+Apparently fuse munged rename and renameat2 together into the same
+upcall, so we actually have to filter out nonzero flags because
+otherwise we do a regular rename for a RENAME_EXCHANGE/WHITEOUT, which
+is not what the user asked for.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/b431abbc8fe0fd1de4e414aae3520c4c19411048
+---
+ misc/fuse2fs.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
+index d123eebb1..36e1173e2 100644
+--- a/misc/fuse2fs.c
++++ b/misc/fuse2fs.c
+@@ -1405,6 +1405,12 @@ static int op_rename(const char *from, const char *to
+ struct update_dotdot ud;
+ int ret = 0;
+
++#if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
++ /* renameat2 is not supported */
++ if (flags)
++ return -ENOSYS;
++#endif
++
+ FUSE2FS_CHECK_CONTEXT(ff);
+ fs = ff->fs;
+ dbg_printf("%s: renaming %s to %s\n", __func__, from, to);
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: debugfs: abort reading a file on failure when dumping out a file
+
+If ext2fs_file_read() fails --- perhaps due to a corrupted file
+system, or an I/O error --- avoid looping forever in dump_file().
+
+This issue was pointed out in [1] by Quentin Kaiser but the commit
+description was too confusing and specific to the user's particular
+situation.
+
+[1] https://github.com/tytso/e2fsprogs/pull/149
+
+Origin: https://github.com/tytso/e2fsprogs/commit/51d68472456d22b6e64159244be63bce51473691
+---
+ debugfs/dump.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/debugfs/dump.c b/debugfs/dump.c
+index 4ab7cadcb..cc81a5086 100644
+--- a/debugfs/dump.c
++++ b/debugfs/dump.c
+@@ -122,8 +122,10 @@ static void dump_file(const char *cmdname, ext2_ino_t ino, int fd,
+ }
+ while (1) {
+ retval = ext2fs_file_read(e2_file, buf, blocksize, &got);
+- if (retval)
++ if (retval) {
+ com_err(cmdname, retval, "while reading ext2 file");
++ return;
++ }
+ if (got == 0)
+ break;
+ nbytes = write(fd, buf, got);
+--
+2.47.2
+
--- /dev/null
+From: Allison Karlitskaya <allison.karlitskaya@redhat.com>
+Subject: mke2fs: disallow -O verity without extents
+
+Similar to 64-bit support, fs-verity support requires extents, so don't
+allow to create a filesystem that has -O verity unless it also supports
+extents.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/03fa1a5ee55d0653f5931cea3cab760599bab216
+---
+ misc/mke2fs.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/misc/mke2fs.c b/misc/mke2fs.c
+index f24076bc1..017838d43 100644
+--- a/misc/mke2fs.c
++++ b/misc/mke2fs.c
+@@ -2385,6 +2385,14 @@ profile_error:
+ exit(1);
+ }
+
++ /* fs-verity support requires extents */
++ if (ext2fs_has_feature_verity(&fs_param) &&
++ !ext2fs_has_feature_extents(&fs_param)) {
++ printf("%s", _("Extents MUST be enabled for fs-verity "
++ "support. Pass -O extents to rectify.\n"));
++ exit(1);
++ }
++
+ /* Set first meta blockgroup via an environment variable */
+ /* (this is mostly for debugging purposes) */
+ if (ext2fs_has_feature_meta_bg(&fs_param) &&
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: e2fsck: fix e2fsck -E unshare_blocks when there are no shared blocks
+
+If there are no shared blocks in a ext4 file system, e2fsck -E
+unshare_blocks will not actually clear the shared_blocks feature flag
+since e2fsck_pass1_dupblocks() is never called. Fix this by adding a
+check in e2fsck_pass1() to clear the shared blocks flag.
+
+Bug: https://github.com/tytso/e2fsprogs/issues/218
+Origin: https://github.com/tytso/e2fsprogs/commit/707af4359e132bc415c3f6339f4ced9f23b28c0b
+---
+ e2fsck/pass1.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
+index eb73922d3..e7d5d0ae9 100644
+--- a/e2fsck/pass1.c
++++ b/e2fsck/pass1.c
+@@ -2169,6 +2169,11 @@ void e2fsck_pass1(e2fsck_t ctx)
+ fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
+ }
+ e2fsck_pass1_dupblocks(ctx, block_buf);
++ } else if ((ctx->options & E2F_OPT_UNSHARE_BLOCKS) &&
++ ext2fs_has_feature_shared_blocks(fs->super) &&
++ !(ctx->options & E2F_OPT_NO)) {
++ ext2fs_clear_feature_shared_blocks(fs->super);
++ ext2fs_mark_super_dirty(fs);
+ }
+ ctx->flags |= E2F_FLAG_ALLOC_OK;
+ endit:
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: e2freefrag: require that the chunksize must be greater than 0
+
+"e2freefrag -c 0" doesn't make much sense, so abort with an error
+message if the user specifies a zero chunksize.
+
+Addresses-Coverity-Bug: 1633767
+Origin: https://github.com/tytso/e2fsprogs/commit/3e059df08de94abde1ddd82008d0658584a35e5e
+---
+ misc/e2freefrag.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/e2freefrag.c b/misc/e2freefrag.c
+index 63a3d4351..c66e8f22f 100644
+--- a/misc/e2freefrag.c
++++ b/misc/e2freefrag.c
+@@ -405,7 +405,7 @@ int main(int argc, char *argv[])
+ switch (c) {
+ case 'c':
+ chunk_info.chunkbytes = strtoull(optarg, &end, 0);
+- if (*end != '\0') {
++ if (*end != '\0' || chunk_info.chunkbytes == 0) {
+ fprintf(stderr, "%s: bad chunk size '%s'\n",
+ progname, optarg);
+ usage(progname);
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: mke2fs: add range checks for -E desc_size
+
+Prevent the user from specifying group descriptor that result in
+invalid/corrupted file systems.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/326e8ab43503dd9f44338754c84cb03a725ecc49
+---
+ misc/mke2fs.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/misc/mke2fs.c b/misc/mke2fs.c
+index 017838d43..1b7399a51 100644
+--- a/misc/mke2fs.c
++++ b/misc/mke2fs.c
+@@ -883,7 +883,10 @@ static void parse_extended_opts(struct ext2_super_block *param,
+ continue;
+ }
+ ulong = strtoul(arg, &p, 0);
+- if (*p || (ulong & (ulong - 1))) {
++ if (*p ||
++ (ulong < EXT2_MIN_DESC_SIZE_64BIT) ||
++ (ulong > EXT2_MAX_DESC_SIZE) ||
++ (ulong & (ulong - 1))) {
+ fprintf(stderr,
+ _("Invalid desc_size: '%s'\n"), arg);
+ r_usage++;
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: debugfs: return after printing the usage message in the e2freefrag command
+
+Origin: https://github.com/tytso/e2fsprogs/commit/0c675a67c5684252e3a228c824b0accb9f3ab5d7
+---
+ misc/e2freefrag.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/misc/e2freefrag.c b/misc/e2freefrag.c
+index c66e8f22f..05f703966 100644
+--- a/misc/e2freefrag.c
++++ b/misc/e2freefrag.c
+@@ -409,6 +409,9 @@ int main(int argc, char *argv[])
+ fprintf(stderr, "%s: bad chunk size '%s'\n",
+ progname, optarg);
+ usage(progname);
++#ifdef DEBUFS
++ return;
++#endif
+ }
+ if (chunk_info.chunkbytes &
+ (chunk_info.chunkbytes - 1)) {
+@@ -421,6 +424,9 @@ int main(int argc, char *argv[])
+ case 'h':
+ default:
+ usage(progname);
++#ifdef DEBUGFS
++ return;
++#endif
+ break;
+ }
+ }
+@@ -429,6 +435,9 @@ int main(int argc, char *argv[])
+ if (optind == argc) {
+ fprintf(stderr, "%s: missing device name.\n", progname);
+ usage(progname);
++#ifdef DEBUGFS
++ return;
++#endif
+ }
+
+ device_name = argv[optind];
+--
+2.47.2
+
--- /dev/null
+From: Benno Schulenberg <bensberg@telfort.nl>
+Subject: mke2fs: fix a misindentation in the man page
+
+Problem existed since commit 3c22bf7e70 from twelve years ago.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/4d6cfa2557de7d0878fed3203ac36d3e91df183f
+---
+ misc/mke2fs.8.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
+index 4ff564baa..13ddef47b 100644
+--- a/misc/mke2fs.8.in
++++ b/misc/mke2fs.8.in
+@@ -714,7 +714,7 @@ by commas, that are to be enabled. To disable a feature, simply
+ prefix the feature name with a caret ('^') character.
+ Features with dependencies will not be removed successfully.
+ The pseudo-file system feature "none" will clear all file system features.
+-.TP
++.sp
+ For more information about the features which can be set, please see
+ the manual page
+ .BR ext4 (5).
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: libext2fs: fix a extent tree corruption bug in ext2fs_extent_set_bmap()
+
+In the case where we are moving a particular logical block mapping
+from a particular extent tree entry, to the immediately precending
+entry (when the physical block or uninitialized flag is changing so it
+can be coalesced with the precending entry) and the precending entry
+is in a different extent tree block, the resulting extent tree can get
+corrupted.
+
+Fix this by removing the original logical block mapping before adding
+the new logical block mapping. Per the warning in the comments before
+ext2fs_extents_fix_parents():
+
+ Note a subtlety of this function -- if there happen to be two extents
+ mapping the same lblk and someone calls fix_parents on the second of
+ the two extents, the position of the extent handle after the call will
+ be the second extent if nothing happened, or the first extent if
+ something did. A caller in this situation must use
+ ext2fs_extent_goto() after calling this function. Or simply don't map
+ the same lblk with two extents, ever.
+
+Origin: https://github.com/tytso/e2fsprogs/commit/b914701223255c116745a11f30563652c9fdbb4b
+---
+ lib/ext2fs/extent.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
+index c4b95741e..1b2b84f23 100644
+--- a/lib/ext2fs/extent.c
++++ b/lib/ext2fs/extent.c
+@@ -1531,6 +1531,15 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
+ #ifdef DEBUG
+ printf("(re/un)mapping first block in extent\n");
+ #endif
++ extent.e_pblk++;
++ extent.e_lblk++;
++ extent.e_len--;
++ retval = ext2fs_extent_replace(handle, 0, &extent);
++ if (retval)
++ goto done;
++ retval = ext2fs_extent_fix_parents(handle);
++ if (retval)
++ goto done;
+ if (physical) {
+ if (has_prev &&
+ (logical == (prev_extent.e_lblk +
+@@ -1560,15 +1569,6 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
+ if (retval)
+ goto done;
+ }
+- extent.e_pblk++;
+- extent.e_lblk++;
+- extent.e_len--;
+- retval = ext2fs_extent_replace(handle, 0, &extent);
+- if (retval)
+- goto done;
+- retval = ext2fs_extent_fix_parents(handle);
+- if (retval)
+- goto done;
+ } else {
+ __u32 save_length;
+ blk64_t save_lblk;
+--
+2.47.2
+
--- /dev/null
+From: Theodore Ts'o <tytso@mit.edu>
+Subject: libext2fs: fix integer overflow in ext2fs_punch() when releasing more than 2**31 blocks
+Origin: https://github.com/tytso/e2fsprogs/commit/34b2a4a1f9794498ca403393003cc5840c240d42
+Bug-Debian: http://bugs.debian.org/1106241
+---
+ lib/ext2fs/punch.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/lib/ext2fs/punch.c b/lib/ext2fs/punch.c
+index e2543e1e7..80c699eb0 100644
+--- a/lib/ext2fs/punch.c
++++ b/lib/ext2fs/punch.c
+@@ -193,10 +193,10 @@ static void dbg_print_extent(char *desc, struct ext2fs_extent *extent)
+ static errcode_t punch_extent_blocks(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ blk64_t lfree_start, blk64_t free_start,
+- __u32 free_count, int *freed)
++ __u32 free_count, blk64_t *freed)
+ {
+ blk64_t pblk;
+- int freed_now = 0;
++ __u32 freed_now = 0;
+ __u32 cluster_freed;
+ errcode_t retval = 0;
+
+@@ -271,7 +271,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
+ errcode_t retval;
+ blk64_t free_start, next, lfree_start;
+ __u32 free_count, newlen;
+- int freed = 0;
++ blk64_t freed = 0;
+ int op;
+
+ retval = ext2fs_extent_open2(fs, ino, inode, &handle);
+@@ -442,7 +442,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
+ if (retval)
+ goto errout;
+ }
+- dbg_printf("Freed %d blocks\n", freed);
++ dbg_printf("Freed %llu blocks\n", freed);
+ retval = ext2fs_iblk_sub_blocks(fs, inode, freed);
+ errout:
+ ext2fs_extent_free(handle);
+--
+2.47.2
+
--- /dev/null
+0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch
+0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch
+0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch
+0004-e2image.8-add-missing-comma.patch
+0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch
+0006-fuse2fs-refuse-unsupported-features.patch
+0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch
+0008-fuse2fs-remove-posix-acl-translation.patch
+0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch
+0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch
+0011-fuse2fs-disable-renameat2.patch
+0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch
+0013-mke2fs-disallow-O-verity-without-extents.patch
+0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch
+0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch
+0016-mke2fs-add-range-checks-for-E-desc_size.patch
+0017-debugfs-return-after-printing-the-usage-message-in-t.patch
+0020-mke2fs-fix-a-misindentation-in-the-man-page.patch
+0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch
+0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch