[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1107599: marked as done (pre-unblock: e2fsprogs/1.47.2-3)



Your message dated Wed, 18 Jun 2025 09:56:12 +0000
with message-id <aFKNPG2SlaQZtA5U@debian.org>
and subject line Re: Bug#1107599: pre-unblock: e2fsprogs/1.47.2-3
has caused the Debian Bug report #1107599,
regarding pre-unblock: e2fsprogs/1.47.2-3
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1107599: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1107599
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: e2fsprogs@packages.debian.org
Control: affects -1 + src:e2fsprogs
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package e2fsprogs

[ Reason ]

I had hoped to get e2fsprogs 1.47.3 out the door ahead of the Debian
stable release, but life intervened, and there were a number of data
corruption bugs I wanted to root cause and fix before I released 1.47.3.
There is a 1.47.3-rc1 which is in experimental, but there were a few
final serious bugs that will be in the 1.47.3-rc2.   Given where we were
in the release cycle, I decided to backport the most critical and lowest
risk bug fixes to 1.47.2, which is this release.   The bug fixes fall in
to the following categories:

Copyright / license compliance issues:

  * Add a Built-Using field to the e2fsck-static man page to honor a LGPL
    requirement documenting which version of glibc was used to build the
    e2fsck.static binary (Closes: #1106799)  <---- Severity Serious
  * Remove the physical address of the FSF from the debian/copyright
    file, addressing a Lintian warning.

Data corruption issues:

  * Fix integer overflow bug which resulted in fuse2fs failing to delete
    very large files and crashing mid-delete (Closes: #1106241)
  * Fix an extent corruption bug which in very rare cases could result in
    data loss when resizing a file system or when fuse2fs is operating on
    that file system
  * Fix fuse2fs to reject renameat2 RENAME_EXCHANGE/RENAME_WHITEOUT
    instead of treating the request (wrongly) as a normal rename
  * Optimize ext2fs_extent_set_bmap() to avoid fragmenting the extent
    tree.  This fixes a problem where resize2fs is trying to relocate
    all of the blocks in a file leading to the extent tree doubling in
    size, and potentially leading to a corrupted extent tree.
  * Fix "e2fsck -n" to not abort when it trips across an EA inode which
    is not referenced by any inodes in the file system.
  * Fix fuse2fs to handle the encoding of POSIX acl's correctly
  * Fix fuse2fs to refuse mounting a file system with file system features
    that it doesn't know how to handle

Functional correctness issues:

  * Fix "e2fsck -E unshare_blocks" to clear the shared_blocks flag when
    there are no shared blocks to clear
  * Fix mke2fs to disallow the verity feature without extents
  * Fix fuse2fs to set the timestamps for the new inode created by a mkdir
    or symlink request
  * Fix fuse2fs to clamp the timestamps written to the file system to fix
    a Y2038 bug as tested by fstests generic/402
  * Fix fuse2fs to return EOPNOTSUPP when a fallocate(2) mode is not supported
  * Fix debugfs's dump and rdump commands to avoid looping forever when
    it runs across an I/O error or corupt filesystem metadata.
  * Fix debugfs's dirsearch command on big-endian systems.

Minor fixes:

  * Various man page cleanups
  * Fix bug in debugfs when user passes invalid arguments to the
    e2freefrag command
  * Add range checks to "mke2fs -E <desc_size>"
  * Check to make the invalid value of 0 is not passed to "e2freefrag -c"

[ Impact ]

The impact if e2fsprogs 1.47.2-2 is not accepted into Stable include:

* The e2fsck-static will be out of compliance with the LGPL (but to be
  fair, no one has noticed for well over a decade, and it really doesn't
  impact user freedoms --- but it is a technical license gap).

* Users attempting to shrink file systems using resize2fs, or to access
  files using fuse2fs (which has become more common for security
  concerns) may end up corrupting their file system and leading to data
  loss.

* Users run into random minor bugs, some of which might result in
  mke2fs or debugfs crashing, and fuse2fs not fully handling some edge
  cases that were noticed when using fstests to validate its correctness.

[ Tests ]

E2fsprogs has a very comprehensive test suite upstream, which exercises
e2fsck and libext2fs extensively.   External to e2fsprogs, we have
autopkgtests in Debian, and in addition, very recently, Darrick Wong has
adapted using fstests to test fuse2fs.   Many of the bug fixes in this
update were found by this test setup, including a number of data
corruption fixes.

I also test e2fsprogs by running the regression test using Clang's
Address Sanitizer and Undefinied Behaviour Sanitizer, and am regularly
checking Coverity's static code analysis (as well as Clang and GCC's
-Wall).  There is also portability testing for MacOS and Windows is done
using Github Actions, and I also work with the FreeBSD port maintainer
for e2fsprogs to assure portability (and sometimes functional bugs get
found and fixed as a result of this portability testing).


[ Risks ]

E2fsprogs is a key package, so this does increase the risk.

That being said, each patch is small --- most changing less than 10 LOC,
with one changing 2 dozen LOC, and one changing 3 dozen LOC, exclusive
of regression test changes.   (See debian/patches/0000-cover-letter.txt
for the breakdown).

If the release team doesn't want to take this for the initial Trixie
release, this update could wait until post Trixie, and e2fsprogs
1.47.2-2 could land as a Proposed Stable Update.

Also, the full set of fixes in 1.47.3 will be released shortly (some
fixes were dropped because there were more complicated than I was
comfortable asking for at this point); e2fsprogs 1.47.3 will also have a
number of performance improvements in fuse2fs and mke2fs -d.  So for
people who are advanced user of resize2fs, fuse2fs, and mke2fs can use
e2fsprogs 1.47.3 once it gets backported to Trixie-backports.
Unfortunately, people who don't realize that trixie-bacports might be
needed if they are aggresively using fuse2fs or resize2fs to shrink file
systems might get hit with corrupted file systems, or worse, data loss.

[ Checklist ]
  [X] all changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in testing

[ Other info ]

n/a


unblock e2fsprogs/1.47.2-2
diff -Nru e2fsprogs-1.47.2/debian/changelog e2fsprogs-1.47.2/debian/changelog
--- e2fsprogs-1.47.2/debian/changelog	2025-01-01 00:30:02.000000000 -0500
+++ e2fsprogs-1.47.2/debian/changelog	2025-06-09 20:49:10.000000000 -0400
@@ -1,3 +1,45 @@
+e2fsprogs (1.47.2-2) unstable; urgency=medium
+
+  * Fix integer overflow bug which resulted in fuse2fs failing to delete
+    very large files (Closes: #1106241)
+  * Fix an extent corruption bug which in very rare cases could result in
+    data loss when resizing a file system or when fuse2fs is operating on
+    that file system
+  * Various man page cleanups
+  * Add a Built-Using field to the e2fsck-static man page to honor a LGPL
+    requirement documenting which version of glibc was used to build the
+    e2fsck.static binary (Closes: #1106799)
+  * Remove the physical address of the FSF from the debian/copyright
+    file, addressing a Lintian warning.
+  * Fix bug in debugfs when user passes invalid arguments to the
+    e2freefrag command
+  * Add range checks to "mke2fs -E <desc_size>"
+  * Check to make the invalid value of 0 is not passed to "e2freefrag -c"
+  * Fix "e2fsck -E unshare_blocks" to clear the shared_blocks flag when
+    there are no shared blocks to clear
+  * Fix mke2fs to disallow the verity feature without extents
+  * Fix fuse2fs to reject renameat2 RENAME_EXCHANGE/RENAME_WHITEOUT
+    instead of treating the request (wrongly) as a normal rename
+  * Fix fuse2fs to set the timestamps for the new inode created by a mkdir
+    or symlink request
+  * Fix fuse2fs to clamp the timestamps written to the file system to fix
+    a Y2038 bug as tested by fstests generic/402
+  * Fix fuse2fs to handle the encoding of POSIX acl's correctly
+  * Fix fuse2fs to return EOPNOTSUPP when a fallocate(2) mode is not supported
+  * Fix fuse2fs to refuse mounting a file system with file system features
+    that it doesn't know how to handle
+  * Fix debugfs's dump and rdump commands to avoid looping forever when
+    it runs across an I/O error or corupt filesystem metadata.
+  * Fix debugfs's dirsearch command on big-endian systems.
+  * Optimize ext2fs_extent_set_bmap() to avoid fragmenting the extent
+    tree.  This fixes a problem where resize2fs is trying to relocate
+    all of the blocks in a file leading to the extent tree doubling in
+    size, and potentially leading to a corrupted extent tree.
+  * Fix "e2fsck -n" to not abort when it trips across an EA inode which
+    is not referenced by any inodes in the file system.
+
+ -- Theodore Y. Ts'o <tytso@mit.edu>  Mon, 09 Jun 2025 20:49:10 -0400
+
 e2fsprogs (1.47.2-1) unstable; urgency=medium
 
   * New upstream version
diff -Nru e2fsprogs-1.47.2/debian/control e2fsprogs-1.47.2/debian/control
--- e2fsprogs-1.47.2/debian/control	2025-01-01 00:30:02.000000000 -0500
+++ e2fsprogs-1.47.2/debian/control	2025-06-09 20:49:10.000000000 -0400
@@ -46,6 +46,7 @@
 
 Package: e2fsck-static
 Build-Profiles: <!pkg.e2fsprogs.no-static>
+Built-Using: ${misc:Built-Using}
 Priority: optional
 Depends: ${misc:Depends}
 Recommends: sash | bash-static | zsh-static | busybox-static
diff -Nru e2fsprogs-1.47.2/debian/copyright e2fsprogs-1.47.2/debian/copyright
--- e2fsprogs-1.47.2/debian/copyright	2025-01-01 00:30:02.000000000 -0500
+++ e2fsprogs-1.47.2/debian/copyright	2025-06-09 20:49:10.000000000 -0400
@@ -375,9 +375,7 @@
  General Public License for more details.
  .
  You should have received a copy of the GNU General Public License
- along with this texinfo.tex file; see the file COPYING.  If not, write
- to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  As a special exception, when this file is read by TeX when processing
  a Texinfo source document, you may use the result without
@@ -492,9 +490,7 @@
  GNU General Public License for more details.
  .
  You should have received a copy of the GNU General Public License
- along with this program (in the main directory of the fuse-ext2
- distribution in the file COPYING); if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
 Comment:
  On Debian systems, the complete text of the GNU General
  Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
diff -Nru e2fsprogs-1.47.2/debian/patches/0000-cover-letter.patch e2fsprogs-1.47.2/debian/patches/0000-cover-letter.patch
--- e2fsprogs-1.47.2/debian/patches/0000-cover-letter.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0000-cover-letter.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,68 @@
+From c4dad69036bbc060265931416a1b963d79c60a15 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 9 Jun 2025 20:55:12 -0400
+Subject: [PATCH 00/22] *** SUBJECT HERE ***
+
+*** BLURB HERE ***
+
+Allison Karlitskaya (1):
+  mke2fs: disallow -O verity without extents
+
+Benno Schulenberg (1):
+  mke2fs: fix a misindentation in the man page
+
+Brian Foster (1):
+  debugfs: byteswap dirsearch dirent buf on big endian systems
+
+Darrick J. Wong (6):
+  fuse2fs: refuse unsupported features
+  fuse2fs: return -EOPNOTSUPP when we don't recognize a fallocate mode
+  fuse2fs: remove posix acl translation
+  fuse2fs: clamp timestamps that are being written to disk
+  fuse2fs: update new child timestamps during mkdir/symlink
+  fuse2fs: disable renameat2
+
+Jakub Wilk (1):
+  e2image.8: add missing comma
+
+Theodore Ts'o (12):
+  e2fsck: fix logic bug when there are no references to an EA inode
+  test: fix expect files which changed after EA bugfix
+  libext2fs: teach ext2fs_extent_set_bmap() to update extents more
+    optimally
+  debugfs: abort reading a file on failure when dumping out a file
+  e2fsck: fix e2fsck -E unshare_blocks when there are no shared blocks
+  e2freefrag: require that the chunksize must be greater than 0
+  mke2fs: add range checks for -E desc_size
+  debugfs: return after printing the usage message in the e2freefrag
+    command
+  debian: remove physical address of the FSF from the copyright file
+  debian: add a Built-Using field to the e2fsck-static package
+  libext2fs: fix a extent tree corruption bug in
+    ext2fs_extent_set_bmap()
+  libext2fs: fix integer overflow in ext2fs_punch() when releasing more
+    than 2**31 blocks
+
+ debian/control                         |   1 +
+ debian/copyright                       |   8 +-
+ debian/rules                           |   2 +-
+ debugfs/dump.c                         |   4 +-
+ debugfs/htree.c                        |   6 +
+ e2fsck/pass1.c                         |   5 +
+ e2fsck/pass4.c                         |   2 +-
+ lib/ext2fs/ext2_fs.h                   |   4 +
+ lib/ext2fs/extent.c                    |  43 +++-
+ lib/ext2fs/punch.c                     |   8 +-
+ misc/e2freefrag.c                      |  11 +-
+ misc/e2image.8.in                      |   2 +-
+ misc/fuse2fs.c                         | 336 +++++--------------------
+ misc/mke2fs.8.in                       |   2 +-
+ misc/mke2fs.c                          |  13 +-
+ tests/f_badcluster/expect              |   8 +-
+ tests/f_ea_inode_disconnected/expect.1 |   2 +
+ tests/f_ea_inode_self_ref/expect.1     |   2 -
+ 18 files changed, 155 insertions(+), 304 deletions(-)
+
+-- 
+2.47.2
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch e2fsprogs-1.47.2/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch
--- e2fsprogs-1.47.2/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,36 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch e2fsprogs-1.47.2/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch
--- e2fsprogs-1.47.2/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,44 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch e2fsprogs-1.47.2/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch
--- e2fsprogs-1.47.2/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,123 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0004-e2image.8-add-missing-comma.patch e2fsprogs-1.47.2/debian/patches/0004-e2image.8-add-missing-comma.patch
--- e2fsprogs-1.47.2/debian/patches/0004-e2image.8-add-missing-comma.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0004-e2image.8-add-missing-comma.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,21 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch e2fsprogs-1.47.2/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch
--- e2fsprogs-1.47.2/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,40 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch e2fsprogs-1.47.2/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch
--- e2fsprogs-1.47.2/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,45 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch e2fsprogs-1.47.2/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch
--- e2fsprogs-1.47.2/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,28 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch e2fsprogs-1.47.2/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch
--- e2fsprogs-1.47.2/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,347 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch e2fsprogs-1.47.2/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch
--- e2fsprogs-1.47.2/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,107 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch e2fsprogs-1.47.2/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch
--- e2fsprogs-1.47.2/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,34 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0011-fuse2fs-disable-renameat2.patch e2fsprogs-1.47.2/debian/patches/0011-fuse2fs-disable-renameat2.patch
--- e2fsprogs-1.47.2/debian/patches/0011-fuse2fs-disable-renameat2.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0011-fuse2fs-disable-renameat2.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,33 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch e2fsprogs-1.47.2/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch
--- e2fsprogs-1.47.2/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,36 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch e2fsprogs-1.47.2/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch
--- e2fsprogs-1.47.2/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,34 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch e2fsprogs-1.47.2/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch
--- e2fsprogs-1.47.2/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,33 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch e2fsprogs-1.47.2/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch
--- e2fsprogs-1.47.2/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,28 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch e2fsprogs-1.47.2/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch
--- e2fsprogs-1.47.2/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,30 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch e2fsprogs-1.47.2/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch
--- e2fsprogs-1.47.2/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,45 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch e2fsprogs-1.47.2/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch
--- e2fsprogs-1.47.2/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,26 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch e2fsprogs-1.47.2/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch
--- e2fsprogs-1.47.2/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,66 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch e2fsprogs-1.47.2/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch
--- e2fsprogs-1.47.2/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,46 @@
+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
+
diff -Nru e2fsprogs-1.47.2/debian/patches/series e2fsprogs-1.47.2/debian/patches/series
--- e2fsprogs-1.47.2/debian/patches/series	1969-12-31 19:00:00.000000000 -0500
+++ e2fsprogs-1.47.2/debian/patches/series	2025-06-09 20:49:10.000000000 -0400
@@ -0,0 +1,20 @@
+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
diff -Nru e2fsprogs-1.47.2/debian/rules e2fsprogs-1.47.2/debian/rules
--- e2fsprogs-1.47.2/debian/rules	2025-01-01 00:30:02.000000000 -0500
+++ e2fsprogs-1.47.2/debian/rules	2025-06-09 20:49:10.000000000 -0400
@@ -195,7 +195,7 @@
 override_dh_gencontrol:
 	dh_gencontrol -pcomerr-dev -- -v${COMERR_VERSION}-${DEB_VERSION} -VmainBinary=${DEB_VERSION}
 	dh_gencontrol -pss-dev -- -v${SS_VERSION}-${DEB_VERSION} -VmainBinary=${DEB_VERSION}
-	dh_gencontrol --remaining-packages
+	dh_gencontrol --remaining-packages -- -Vmisc:Built-Using="$(shell dpkg-query -f '$${source:Package} (= $${source:Version})' -W libc-dev-bin)"
 
 override_dh_auto_test:
 ifeq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS)))

--- End Message ---
--- Begin Message ---
Hi,

On Fri, Jun 13, 2025 at 05:41:52PM -0230, Theodore Ts'o wrote:
> So this is now a heads up for a pre-unblock for e2fsprogs/1.47.2-3
> once the migration delay is complete.

OK. I unblocked it and set the migration delay to 10 days.

Thanks,

Ivo

--- End Message ---

Reply to: