aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2024-05-20 23:13:33 -0400
committerTheodore Ts'o <tytso@mit.edu>2024-05-20 23:13:33 -0400
commit1d356bc77c2036138b858b1a2db4a2d7f120e2a3 (patch)
tree1124ba59a207f232099acd42d580191a01bd9daf
parent14c2e67f8764203531c024b1b81c4604287b03bc (diff)
parent950a0d69c82b585aba30118f01bf80151deffe8c (diff)
downloade2fsprogs-debian/master.tar.gz
Merge tag 'v1.47.1' into debian/masterdebian/1.47.1-1archive/debian/1.47.1-1debian/master
v1.47.1
-rw-r--r--Android.bp4
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac3
-rw-r--r--contrib/android/Android.bp1
-rw-r--r--contrib/android/e2fsdroid.c5
-rw-r--r--contrib/android/ext2simg.c123
-rw-r--r--debian/changelog21
-rw-r--r--debian/control2
-rw-r--r--debugfs/Makefile.in18
-rw-r--r--doc/RelNotes/v1.47.1.txt21
-rw-r--r--e2fsck/e2fsck.h6
-rw-r--r--e2fsck/pass1.c84
-rw-r--r--e2fsck/pass2.c15
-rw-r--r--e2fsck/pass4.c53
-rw-r--r--e2fsck/problem.c18
-rw-r--r--e2fsck/problem.h12
-rw-r--r--e2fsck/super.c4
-rw-r--r--e2fsprogs.lsm2
-rw-r--r--lib/blkid/Android.bp3
-rw-r--r--lib/e2p/Android.bp1
-rw-r--r--lib/et/Android.bp1
-rw-r--r--lib/ext2fs/Android.bp1
-rw-r--r--lib/ext2fs/e2image.h5
-rw-r--r--lib/ext2fs/qcow2.h2
-rw-r--r--lib/ext2fs/rbtree.h2
-rw-r--r--lib/ext2fs/rw_bitmaps.c2
-rw-r--r--lib/support/Android.bp1
-rw-r--r--lib/support/Makefile.in9
-rw-r--r--lib/support/print_fs_flags.c1
-rw-r--r--lib/support/quotaio.h8
-rw-r--r--lib/uuid/Android.bp3
-rw-r--r--misc/Android.bp7
-rw-r--r--misc/Makefile.in17
-rw-r--r--misc/e2image.c8
-rw-r--r--misc/e4defrag.c5
-rw-r--r--misc/ext4.5.in1
-rw-r--r--misc/lsattr.1.in4
-rw-r--r--misc/mklost+found.8.in6
-rw-r--r--tests/f_bad_disconnected_inode/expect.18
-rw-r--r--tests/f_bad_fname/expect.12
-rw-r--r--tests/f_ea_inode_dir_ref/expect.112
-rw-r--r--tests/f_ea_inode_dir_ref/expect.27
-rw-r--r--tests/f_ea_inode_dir_ref/image.gzbin0 -> 1822 bytes
-rw-r--r--tests/f_ea_inode_dir_ref/name1
-rw-r--r--tests/f_ea_inode_disconnected/expect.123
-rw-r--r--tests/f_ea_inode_disconnected/expect.27
-rw-r--r--tests/f_ea_inode_disconnected/imagebin0 -> 1048576 bytes
-rw-r--r--tests/f_ea_inode_disconnected/image.gzbin0 -> 1779 bytes
-rw-r--r--tests/f_ea_inode_disconnected/name1
-rw-r--r--tests/f_ea_inode_no_feature/expect.112
-rw-r--r--tests/f_ea_inode_no_feature/expect.27
-rw-r--r--tests/f_ea_inode_no_feature/image.gzbin0 -> 1817 bytes
-rw-r--r--tests/f_ea_inode_no_feature/name1
-rw-r--r--tests/f_ea_inode_self_ref/expect.12
-rw-r--r--tests/f_ea_inode_spurious_flag_dir/expect.111
-rw-r--r--tests/f_ea_inode_spurious_flag_dir/expect.27
-rw-r--r--tests/f_ea_inode_spurious_flag_dir/imagebin0 -> 1048576 bytes
-rw-r--r--tests/f_ea_inode_spurious_flag_dir/image.gzbin0 -> 1598 bytes
-rw-r--r--tests/f_ea_inode_spurious_flag_dir/name1
-rw-r--r--tests/progs/Makefile.in9
-rw-r--r--util/android_config.h3
-rw-r--r--version.h4
62 files changed, 464 insertions, 136 deletions
diff --git a/Android.bp b/Android.bp
index 1e6aa1a58..46f63348c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -62,6 +62,10 @@ cc_defaults {
"libdl",
],
},
+ darwin: {
+ // This matches what the upstream CI uses
+ cflags: ["-Wno-error=deprecated-declarations"],
+ },
windows: {
include_dirs: ["external/e2fsprogs/include/mingw"],
},
diff --git a/configure b/configure
index 2b712e5d3..cba3191c2 100755
--- a/configure
+++ b/configure
@@ -15646,9 +15646,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
-if test "$enable_fuzzer" = "yes" && test "$have_fuzzer" != "yes"; then
- as_fn_error $? "Fuzzing not supported by compiler." "$LINENO" 5
-fi
LINUX_CMT="#"
CYGWIN_CMT="#"
diff --git a/configure.ac b/configure.ac
index e00e8d0e0..131caef38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1664,9 +1664,6 @@ if test "$enable_fuzzing" = "yes" || test "$enable_fuzzing" = "probe"; then
AC_SUBST(fuzzer_cflags)
AC_SUBST(fuzzer_ldflags)
fi
-if test "$enable_fuzzer" = "yes" && test "$have_fuzzer" != "yes"; then
- AC_MSG_ERROR([Fuzzing not supported by compiler.])
-fi
AC_SUBST(FUZZING_CMT)
dnl
dnl OS-specific uncomment control
diff --git a/contrib/android/Android.bp b/contrib/android/Android.bp
index 6c9dd5c5d..650824ce3 100644
--- a/contrib/android/Android.bp
+++ b/contrib/android/Android.bp
@@ -16,6 +16,7 @@ cc_binary {
name: "e2fsdroid",
host_supported: true,
recovery_available: true,
+ vendor_available: true,
defaults: ["e2fsprogs-defaults"],
srcs: [
diff --git a/contrib/android/e2fsdroid.c b/contrib/android/e2fsdroid.c
index 6e5141409..82bd3408e 100644
--- a/contrib/android/e2fsdroid.c
+++ b/contrib/android/e2fsdroid.c
@@ -22,6 +22,11 @@
#define UID_GID_MAP_MAX_EXTENTS 340
#endif
+// disable leak detection, breaks host asan build
+const char *__asan_default_options() {
+ return "detect_leaks=0";
+}
+
static char *prog_name = "e2fsdroid";
static char *in_file;
static char *block_list;
diff --git a/contrib/android/ext2simg.c b/contrib/android/ext2simg.c
index 017e16ff7..2bf76b91a 100644
--- a/contrib/android/ext2simg.c
+++ b/contrib/android/ext2simg.c
@@ -24,16 +24,14 @@
#include <sparse/sparse.h>
struct {
- int crc;
- int sparse;
- int gzip;
+ bool crc;
+ bool sparse;
+ bool gzip;
char *in_file;
char *out_file;
bool overwrite_input;
} params = {
- .crc = 0,
- .sparse = 1,
- .gzip = 0,
+ .sparse = true,
};
#define ext2fs_fatal(Retval, Format, ...) \
@@ -60,39 +58,41 @@ static void usage(char *path)
static struct buf_item {
struct buf_item *next;
- void *buf[0];
+ void *buf[];
} *buf_list;
-static void add_chunk(ext2_filsys fs, struct sparse_file *s, blk_t chunk_start, blk_t chunk_end)
+/*
+ * Add @num_blks blocks, starting at index @chunk_start, of the filesystem @fs
+ * to the sparse file @s.
+ */
+static void add_chunk(ext2_filsys fs, struct sparse_file *s,
+ blk_t chunk_start, int num_blks)
{
+ uint64_t len = (uint64_t)num_blks * fs->blocksize;
+ int64_t offset = (int64_t)chunk_start * fs->blocksize;
+ struct buf_item *bi;
int retval;
- unsigned int nb_blk = chunk_end - chunk_start;
- size_t len = nb_blk * fs->blocksize;
- int64_t offset = (int64_t)chunk_start * (int64_t)fs->blocksize;
- if (params.overwrite_input == false) {
+ if (!params.overwrite_input) {
if (sparse_file_add_file(s, params.in_file, offset, len, chunk_start) < 0)
sparse_fatal("adding data to the sparse file");
- } else {
- /*
- * The input file will be overwritten, make a copy of
- * the blocks
- */
- struct buf_item *bi = calloc(1, sizeof(struct buf_item) + len);
- if (buf_list == NULL)
- buf_list = bi;
- else {
- bi->next = buf_list;
- buf_list = bi;
- }
+ return;
+ }
- retval = io_channel_read_blk64(fs->io, chunk_start, nb_blk, bi->buf);
- if (retval < 0)
- ext2fs_fatal(retval, "reading block %u - %u", chunk_start, chunk_end);
+ /* The input file will be overwritten, so make a copy of the blocks. */
+ if (len > SIZE_MAX - sizeof(*bi))
+ sparse_fatal("filesystem is too large");
+ bi = calloc(1, sizeof(*bi) + len);
+ if (!bi)
+ sparse_fatal("out of memory");
+ bi->next = buf_list;
+ buf_list = bi;
+ retval = io_channel_read_blk64(fs->io, chunk_start, num_blks, bi->buf);
+ if (retval)
+ ext2fs_fatal(retval, "reading data from %s", params.in_file);
- if (sparse_file_add_data(s, bi->buf, len, chunk_start) < 0)
- sparse_fatal("adding data to the sparse file");
- }
+ if (sparse_file_add_data(s, bi->buf, len, chunk_start) < 0)
+ sparse_fatal("adding data to the sparse file");
}
static void free_chunks(void)
@@ -106,13 +106,23 @@ static void free_chunks(void)
}
}
+static blk_t fs_blocks_count(ext2_filsys fs)
+{
+ blk64_t blks = ext2fs_blocks_count(fs->super);
+
+ /* libsparse assumes 32-bit block numbers. */
+ if ((blk_t)blks != blks)
+ sparse_fatal("filesystem is too large");
+ return blks;
+}
+
static struct sparse_file *ext_to_sparse(const char *in_file)
{
errcode_t retval;
ext2_filsys fs;
struct sparse_file *s;
int64_t chunk_start = -1;
- blk_t first_blk, last_blk, nb_blk, cur_blk;
+ blk_t fs_blks, cur_blk;
retval = ext2fs_open(in_file, 0, 0, 0, unix_io_manager, &fs);
if (retval)
@@ -122,11 +132,9 @@ static struct sparse_file *ext_to_sparse(const char *in_file)
if (retval)
ext2fs_fatal(retval, "while reading block bitmap of %s", in_file);
- first_blk = ext2fs_get_block_bitmap_start2(fs->block_map);
- last_blk = ext2fs_get_block_bitmap_end2(fs->block_map);
- nb_blk = last_blk - first_blk + 1;
+ fs_blks = fs_blocks_count(fs);
- s = sparse_file_new(fs->blocksize, (uint64_t)fs->blocksize * (uint64_t)nb_blk);
+ s = sparse_file_new(fs->blocksize, (uint64_t)fs_blks * fs->blocksize);
if (!s)
sparse_fatal("creating sparse file");
@@ -138,24 +146,39 @@ static struct sparse_file *ext_to_sparse(const char *in_file)
* larger than INT32_MAX (32-bit _and_ 64-bit systems).
* Make sure we do not create chunks larger than this limit.
*/
- int64_t max_blk_per_chunk = (INT32_MAX - 12) / fs->blocksize;
+ int32_t max_blk_per_chunk = (INT32_MAX - 12) / fs->blocksize;
- /* Iter on the blocks to merge contiguous chunk */
- for (cur_blk = first_blk; cur_blk <= last_blk; ++cur_blk) {
+ /*
+ * Iterate through the filesystem's blocks, identifying "chunks" that
+ * are contiguous ranges of blocks that are in-use by the filesystem.
+ * Add each chunk to the sparse_file.
+ */
+ for (cur_blk = ext2fs_get_block_bitmap_start2(fs->block_map);
+ cur_blk < fs_blks; ++cur_blk) {
if (ext2fs_test_block_bitmap2(fs->block_map, cur_blk)) {
+ /*
+ * @cur_blk is in-use. Append it to the pending chunk
+ * if there is one, otherwise start a new chunk.
+ */
if (chunk_start == -1) {
chunk_start = cur_blk;
} else if (cur_blk - chunk_start + 1 == max_blk_per_chunk) {
- add_chunk(fs, s, chunk_start, cur_blk);
+ /*
+ * Appending @cur_blk to the pending chunk made
+ * it reach the maximum length, so end it.
+ */
+ add_chunk(fs, s, chunk_start, max_blk_per_chunk);
chunk_start = -1;
}
} else if (chunk_start != -1) {
- add_chunk(fs, s, chunk_start, cur_blk);
+ /* @cur_blk is not in-use, so end the pending chunk. */
+ add_chunk(fs, s, chunk_start, cur_blk - chunk_start);
chunk_start = -1;
}
}
+ /* If there's still a pending chunk, end it. */
if (chunk_start != -1)
- add_chunk(fs, s, chunk_start, cur_blk - 1);
+ add_chunk(fs, s, chunk_start, cur_blk - chunk_start);
ext2fs_free(fs);
return s;
@@ -165,14 +188,14 @@ static bool same_file(const char *in, const char *out)
{
struct stat st1, st2;
- if (access(out, F_OK) == -1)
- return false;
-
- if (lstat(in, &st1) == -1)
+ if (stat(in, &st1) == -1)
ext2fs_fatal(errno, "stat %s\n", in);
- if (lstat(out, &st2) == -1)
+ if (stat(out, &st2) == -1) {
+ if (errno == ENOENT)
+ return false;
ext2fs_fatal(errno, "stat %s\n", out);
- return st1.st_ino == st2.st_ino;
+ }
+ return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino;
}
int main(int argc, char *argv[])
@@ -184,13 +207,13 @@ int main(int argc, char *argv[])
while ((opt = getopt(argc, argv, "czS")) != -1) {
switch(opt) {
case 'c':
- params.crc = 1;
+ params.crc = true;
break;
case 'z':
- params.gzip = 1;
+ params.gzip = true;
break;
case 'S':
- params.sparse = 0;
+ params.sparse = false;
break;
default:
usage(argv[0]);
diff --git a/debian/changelog b/debian/changelog
index 6265c395d..7d8ba53d5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,24 @@
+e2fsprogs (1.47.1-1) unstable; urgency=medium
+
+ * New upstream version
+ * Clarify the lsattr and mklost+found man pages that they are applicable
+ for ext2, ext3, and ext4 file systems and not just for ext2. (Closes:
+ #1041115)
+ * Replace the build-depend on pkg-config with pkgconf to fix a Lintian
+ warning.
+ * E2fsck will now perform more consistency checks on EA (extended
+ attribute value) inodes.
+ * Fix a big where e2fsck could potentially leak an acl block when
+ releasing an orphan inode.
+ * Avoid a divide by zero crash in libext2fs if the container
+ infrastructure, such as lxcfs, reports that the system has zero CPU's
+ via sysconf(_SC_NPROCESSORS_CONF).
+
+ -- Theodore Y. Ts'o <tytso@mit.edu> Mon, 20 May 2024 15:28:06 -0400
+
e2fsprogs (1.47.1~rc2-1) unstable; urgency=medium
+ * New upstream version
* Update Chinese, Czech, French, Polish Romainian, Swedish, and
Ukrainian translations
* Fix libarchive support in mke2fs on mips64el (Closes: #1070042)
@@ -7,7 +26,7 @@ e2fsprogs (1.47.1~rc2-1) unstable; urgency=medium
systemd. (Closes: #1070107)
* Update to standards 4.7.0
- -- Theodore Y. Ts'o <tytso@mit.edu> Wed, 01 May 2024 00:50:49 -0400
+ -- Theodore Y. Ts'o <tytso@mit.edu> Mon, 20 May 2024 15:24:47 -0400
e2fsprogs (1.47.1~rc1-3) unstable; urgency=medium
diff --git a/debian/control b/debian/control
index e3712d402..e641b3712 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: e2fsprogs
Section: admin
Priority: required
Maintainer: Theodore Y. Ts'o <tytso@mit.edu>
-Build-Depends: dpkg-dev (>= 1.22.5), gettext, texinfo, pkg-config, libarchive-dev, libfuse3-dev [linux-any kfreebsd-any] <!pkg.e2fsprogs.no-fuse2fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], systemd-dev [linux-any], cron [linux-any], dh-sequence-movetousr
+Build-Depends: dpkg-dev (>= 1.22.5), gettext, texinfo, pkgconf, libarchive-dev, libfuse3-dev [linux-any kfreebsd-any] <!pkg.e2fsprogs.no-fuse2fs>, debhelper-compat (= 12), dh-exec, libblkid-dev, uuid-dev, m4, udev [linux-any], systemd [linux-any], systemd-dev [linux-any], cron [linux-any], dh-sequence-movetousr
Rules-Requires-Root: no
Standards-Version: 4.7.0
Homepage: http://e2fsprogs.sourceforge.net
diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index b845a6f02..50a21e528 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -363,16 +363,18 @@ create_inode.o: $(srcdir)/../misc/create_inode.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/fiemap.h \
$(srcdir)/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
- $(top_srcdir)/lib/support/nls-enable.h
+ $(top_srcdir)/lib/support/nls-enable.h \
+ $(srcdir)/../misc/create_inode_libarchive.h
create_inode_libarchive.o: $(srcdir)/../misc/create_inode_libarchive.c \
- $(top_builddir)/lib/config.h $(srcdir)/../misc/create_inode_libarchive.h \
- $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
- $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/../misc/create_inode.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/fiemap.h \
- $(srcdir)/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(srcdir)/../misc/create_inode_libarchive.h \
$(top_srcdir)/lib/support/nls-enable.h
xattrs.o: $(srcdir)/xattrs.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/support/cstring.h \
diff --git a/doc/RelNotes/v1.47.1.txt b/doc/RelNotes/v1.47.1.txt
index ccc46d68d..4e7d4557d 100644
--- a/doc/RelNotes/v1.47.1.txt
+++ b/doc/RelNotes/v1.47.1.txt
@@ -1,5 +1,5 @@
-E2fsprogs 1.47.1 (May 1, 2024)
-==============================
+E2fsprogs 1.47.1 (May 20, 2024)
+===============================
Updates/Fixes since v1.47.0:
@@ -60,6 +60,16 @@ In the case where e2fsck comes across an orphan file which is empty but
the orphan_present feature is set, in preen mode, e2fsck will now clear
the orphan_present feature flag silently.
+E2fsck will now perform more consistency checks on EA (extended
+attribute value) inodes.
+
+Fix a big where e2fsck could potentially leak an acl block when
+releasing an orphan inode.
+
+Avoid a divide by zero crash in libext2fs if the container
+infrastructure, such as lxcfs, reports that the system has zero CPU's
+via sysconf(_SC_NPROCESSORS_CONF).
+
When resize2fs is performing an online resize, it's possible for reading
the superblock can race with a kernel modifying the superblock with the
checksum being invalid and causing the resize to fail with an bad
@@ -123,7 +133,8 @@ systemd. (Addresses Debian Bug #1070107)
Fixed/improved various Debian packaging issues.
-Update and clarify various man pages. (Addresses Debian Bug #1038286)
+Update and clarify various man pages. (Addresses Debian Bugs #1038286,
+#1041115)
@@ -169,6 +180,10 @@ Fix various portability problems in the regression test suite.
Fix various sanitizer, static code analysis, and compiler warnings.
+Synchronized changes from Android's AOSP e2fsprogs tree.
+
+Updated config.guess and config.sub with newer versions from the FSF.
+
Add Romainian translation.
Update Chinese, Czech, French, Malay, Polish, Swedish, and Ukrainian
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 55738fdc1..ae1273dc0 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -533,6 +533,12 @@ extern struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx,
typedef __u64 ea_key_t;
typedef __u64 ea_value_t;
+/*
+ * Special refcount value we use for inodes which have EA_INODE flag set but we
+ * do not yet know about any references.
+ */
+#define EA_INODE_NO_REFS (~(ea_value_t)0)
+
extern errcode_t ea_refcount_create(size_t size, ext2_refcount_t *ret);
extern void ea_refcount_free(ext2_refcount_t refcount);
extern errcode_t ea_refcount_fetch(ext2_refcount_t refcount, ea_key_t ea_key,
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 8b6238e84..eb73922d3 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -387,34 +387,71 @@ static problem_t check_large_ea_inode(e2fsck_t ctx,
return 0;
}
+static int alloc_ea_inode_refs(e2fsck_t ctx, struct problem_context *pctx)
+{
+ pctx->errcode = ea_refcount_create(0, &ctx->ea_inode_refs);
+ if (pctx->errcode) {
+ pctx->num = 4;
+ fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ return 0;
+ }
+ return 1;
+}
+
static void inc_ea_inode_refs(e2fsck_t ctx, struct problem_context *pctx,
struct ext2_ext_attr_entry *first, void *end)
{
struct ext2_ext_attr_entry *entry = first;
struct ext2_ext_attr_entry *np = EXT2_EXT_ATTR_NEXT(entry);
+ ea_value_t refs;
while ((void *) entry < end && (void *) np < end &&
!EXT2_EXT_IS_LAST_ENTRY(entry)) {
if (!entry->e_value_inum)
goto next;
- if (!ctx->ea_inode_refs) {
- pctx->errcode = ea_refcount_create(0,
- &ctx->ea_inode_refs);
- if (pctx->errcode) {
- pctx->num = 4;
- fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
- ea_refcount_increment(ctx->ea_inode_refs, entry->e_value_inum,
- 0);
+ if (!ctx->ea_inode_refs && !alloc_ea_inode_refs(ctx, pctx))
+ return;
+ ea_refcount_fetch(ctx->ea_inode_refs, entry->e_value_inum,
+ &refs);
+ if (refs == EA_INODE_NO_REFS)
+ refs = 1;
+ else
+ refs += 1;
+ ea_refcount_store(ctx->ea_inode_refs, entry->e_value_inum, refs);
next:
entry = np;
np = EXT2_EXT_ATTR_NEXT(entry);
}
}
+/*
+ * Make sure inode is tracked as EA inode. We use special EA_INODE_NO_REFS
+ * value if we didn't find any xattrs referencing this inode yet.
+ */
+static int track_ea_inode(e2fsck_t ctx, struct problem_context *pctx,
+ ext2_ino_t ino)
+{
+ ea_value_t refs;
+
+ if (!ctx->ea_inode_refs && !alloc_ea_inode_refs(ctx, pctx))
+ return 0;
+
+ ea_refcount_fetch(ctx->ea_inode_refs, ino, &refs);
+ if (refs > 0)
+ return 1;
+
+ pctx->errcode = ea_refcount_store(ctx->ea_inode_refs, ino,
+ EA_INODE_NO_REFS);
+ if (pctx->errcode) {
+ pctx->num = 5;
+ fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
+ ctx->flags |= E2F_FLAG_ABORT;
+ return 0;
+ }
+ return 1;
+}
+
static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx,
struct ea_quota *ea_ibody_quota)
{
@@ -510,6 +547,12 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx,
} else {
blk64_t quota_blocks;
+ if (!ext2fs_has_feature_ea_inode(sb) &&
+ fix_problem(ctx, PR_1_EA_INODE_FEATURE, pctx)) {
+ ext2fs_set_feature_ea_inode(sb);
+ ext2fs_mark_super_dirty(ctx->fs);
+ }
+
problem = check_large_ea_inode(ctx, entry, pctx,
&quota_blocks);
if (problem != 0)
@@ -1502,6 +1545,17 @@ void e2fsck_pass1(e2fsck_t ctx)
e2fsck_write_inode(ctx, ino, inode, "pass1");
}
+ if (inode->i_flags & EXT4_EA_INODE_FL) {
+ if (!LINUX_S_ISREG(inode->i_mode) &&
+ fix_problem(ctx, PR_1_EA_INODE_NONREG, &pctx)) {
+ inode->i_flags &= ~EXT4_EA_INODE_FL;
+ e2fsck_write_inode(ctx, ino, inode, "pass1");
+ }
+ if (inode->i_flags & EXT4_EA_INODE_FL)
+ if (!track_ea_inode(ctx, &pctx, ino))
+ continue;
+ }
+
/* Conflicting inlinedata/extents inode flags? */
if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
(inode->i_flags & EXT4_EXTENTS_FL)) {
@@ -2622,6 +2676,12 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
problem_t problem;
blk64_t entry_quota_blocks;
+ if (!ext2fs_has_feature_ea_inode(fs->super) &&
+ fix_problem(ctx, PR_1_EA_INODE_FEATURE, pctx)) {
+ ext2fs_set_feature_ea_inode(fs->super);
+ ext2fs_mark_super_dirty(fs);
+ }
+
problem = check_large_ea_inode(ctx, entry, pctx,
&entry_quota_blocks);
if (problem && fix_problem(ctx, problem, pctx))
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 08ab40fa8..036c0022d 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1501,6 +1501,21 @@ skip_checksum:
problem = PR_2_NULL_NAME;
}
+ /*
+ * Check if inode was tracked as EA inode and has actual
+ * references from xattrs. In that case dir entry is likely
+ * bogus and we want to clear it. The case of EA inode without
+ * references from xattrs will be handled in pass 4.
+ */
+ if (!problem && ctx->ea_inode_refs) {
+ ea_value_t refs;
+
+ ea_refcount_fetch(ctx->ea_inode_refs, dirent->inode,
+ &refs);
+ if (refs && refs != EA_INODE_NO_REFS)
+ problem = PR_2_EA_INODE_DIR_LINK;
+ }
+
if (problem) {
if (fix_problem(ctx, problem, &cd->pctx)) {
dirent->inode = 0;
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
index d2dda02a9..cf0cf7c47 100644
--- a/e2fsck/pass4.c
+++ b/e2fsck/pass4.c
@@ -96,9 +96,10 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
* an xattr inode at all. Return immediately if EA_INODE flag is not set.
*/
static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
- struct ext2_inode_large *inode, __u16 *link_counted)
+ struct ext2_inode_large *inode, __u16 *link_counted,
+ ea_value_t actual_refs)
{
- __u64 actual_refs = 0;
+ struct problem_context pctx;
__u64 ref_count;
if (*last_ino != i) {
@@ -107,13 +108,26 @@ static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
"pass4: check_ea_inode");
*last_ino = i;
}
- if (!(inode->i_flags & EXT4_EA_INODE_FL))
- return;
- if (ctx->ea_inode_refs)
- ea_refcount_fetch(ctx->ea_inode_refs, i, &actual_refs);
- if (!actual_refs)
+ clear_problem_context(&pctx);
+ pctx.ino = i;
+ pctx.inode = EXT2_INODE(inode);
+
+ /* No references to the inode from xattrs? */
+ if (actual_refs == EA_INODE_NO_REFS) {
+ /*
+ * No references from directory hierarchy either? Inode will
+ * 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 ||
+ 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;
+ e2fsck_write_inode(ctx, i, EXT2_INODE(inode), "pass4");
+ }
return;
+ }
/*
* There are some attribute references, link_counted is now considered
@@ -127,10 +141,6 @@ static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
* However, their i_ctime and i_atime should be the same.
*/
if (ref_count != actual_refs && inode->i_ctime != inode->i_atime) {
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
- pctx.ino = i;
pctx.num = ref_count;
pctx.num2 = actual_refs;
if (fix_problem(ctx, PR_4_EA_INODE_REF_COUNT, &pctx)) {
@@ -188,6 +198,7 @@ void e2fsck_pass4(e2fsck_t ctx)
/* Protect loop from wrap-around if s_inodes_count maxed */
for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
ext2_ino_t last_ino = 0;
+ ea_value_t ea_refs;
int isdir;
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
@@ -211,13 +222,19 @@ void e2fsck_pass4(e2fsck_t ctx)
ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
- if (link_counted == 0) {
- /*
- * link_counted is expected to be 0 for an ea_inode.
- * check_ea_inode() will update link_counted if
- * necessary.
- */
- check_ea_inode(ctx, i, &last_ino, inode, &link_counted);
+ if (ctx->ea_inode_refs) {
+ ea_refcount_fetch(ctx->ea_inode_refs, i, &ea_refs);
+ if (ea_refs) {
+ /*
+ * Final consolidation of EA inodes. We either
+ * decide the inode is fine and set link_counted
+ * to one, or we decide this is actually a
+ * normal file and clear EA_INODE flag, or
+ * decide the inode should just be deleted.
+ */
+ check_ea_inode(ctx, i, &last_ino, inode,
+ &link_counted, ea_refs);
+ }
}
if (link_counted == 0) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 207ebbb34..e433281fa 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1309,6 +1309,16 @@ static struct e2fsck_problem problem_table[] = {
N_("Orphan file @i %i is not in use, but contains data. "),
PROMPT_CLEAR, PR_PREEN_OK },
+ /* EA_INODE flag set on a non-regular file */
+ { PR_1_EA_INODE_NONREG,
+ N_("@i %i has the ea_inode flag set but is not a regular file. "),
+ PROMPT_CLEAR_FLAG, 0, 0, 0, 0 },
+
+ /* EA_INODE present but the file system is missing the ea_inode feature */
+ { PR_1_EA_INODE_FEATURE,
+ N_("@i %i references EA inode but @S is missing EA_INODE feature\n"),
+ PROMPT_FIX, PR_PREEN_OK, 0, 0, 0 },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
@@ -1860,6 +1870,10 @@ static struct e2fsck_problem problem_table[] = {
N_("Duplicate filename @E found. "),
PROMPT_CLEAR, 0, 0, 0, 0 },
+ /* Directory filename is null */
+ { PR_2_EA_INODE_DIR_LINK,
+ N_("@E references EA @i %Di.\n"),
+ PROMPT_CLEAR, 0, 0, 0, 0 },
/* Pass 3 errors */
@@ -2102,6 +2116,10 @@ static struct e2fsck_problem problem_table[] = {
N_("@d @i %i ref count set to overflow but could be exact value %N. "),
PROMPT_FIX, PR_PREEN_OK, 0, 0, 0 },
+ { PR_4_EA_INODE_SPURIOUS_FLAG,
+ N_("Regular @f @i %i has EA_INODE flag set. "),
+ PROMPT_CLEAR, PR_PREEN_OK, 0, 0, 0 },
+
/* Pass 5 errors */
/* Pass 5: Checking group summary information */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index b47b0c630..ef15b8c84 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -734,6 +734,12 @@ struct problem_context {
/* Orphan file inode is not in use, but contains data */
#define PR_1_ORPHAN_FILE_NOT_CLEAR 0x010090
+/* Inode has EA_INODE_FL set but is not a regular file */
+#define PR_1_EA_INODE_NONREG 0x010091
+
+/* Inode references EA inode but ea_inode feature is not enabled */
+#define PR_1_EA_INODE_FEATURE 0x010092
+
/*
* Pass 1b errors
*/
@@ -1061,6 +1067,9 @@ struct problem_context {
/* Non-unique filename found, but can't rename */
#define PR_2_NON_UNIQUE_FILE_NO_RENAME 0x020054
+/* EA inode referenced from directory */
+#define PR_2_EA_INODE_DIR_LINK 0x020055
+
/*
* Pass 3 errors
*/
@@ -1203,6 +1212,9 @@ struct problem_context {
/* Directory ref count set to overflow but it doesn't have to be */
#define PR_4_DIR_OVERFLOW_REF_COUNT 0x040007
+/* EA_INODE_FL set on normal file linked from directory hierarchy */
+#define PR_4_EA_INODE_SPURIOUS_FLAG 0x040008
+
/*
* Pass 5 errors
*/
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 60c690c22..04d6ddee6 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -196,7 +196,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
__u32 count;
if (!ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(inode)))
- return 0;
+ goto release_acl;
pb.buf = block_buf + 3 * ctx->fs->blocksize;
pb.ctx = ctx;
@@ -235,7 +235,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
if (pb.truncated_blocks)
ext2fs_iblk_sub_blocks(fs, EXT2_INODE(inode),
pb.truncated_blocks);
-
+release_acl:
blk = ext2fs_file_acl_block(fs, EXT2_INODE(inode));
if (blk) {
retval = ext2fs_adjust_ea_refcount3(fs, blk, block_buf, -1,
diff --git a/e2fsprogs.lsm b/e2fsprogs.lsm
index 116edf6c8..645a3fec6 100644
--- a/e2fsprogs.lsm
+++ b/e2fsprogs.lsm
@@ -1,7 +1,7 @@
Begin3
Title: EXT2 Filesystem utilities
Version: 1.47.1
-Entered-date: 2024-05-01
+Entered-date: 2024-05-20
Description: The filesystem utilities for the EXT2, EXT3, and EXT4
filesystems, including e2fsck, mke2fs, dumpe2fs, and others.
Keywords: utilities, filesystem, Ext2fs, ext3, ext4
diff --git a/lib/blkid/Android.bp b/lib/blkid/Android.bp
index 891c74a3a..89e39ab09 100644
--- a/lib/blkid/Android.bp
+++ b/lib/blkid/Android.bp
@@ -38,6 +38,9 @@ cc_library {
shared_libs: ["libext2_uuid"],
target: {
+ darwin: {
+ enabled: true,
+ },
windows: {
enabled: true,
},
diff --git a/lib/e2p/Android.bp b/lib/e2p/Android.bp
index bed92c120..02825cdb9 100644
--- a/lib/e2p/Android.bp
+++ b/lib/e2p/Android.bp
@@ -15,6 +15,7 @@ cc_library {
host_supported: true,
ramdisk_available: true,
vendor_ramdisk_available: true,
+ vendor_available: true,
recovery_available: true,
unique_host_soname: true,
defaults: ["e2fsprogs-defaults"],
diff --git a/lib/et/Android.bp b/lib/et/Android.bp
index 565feb594..5d4a129d2 100644
--- a/lib/et/Android.bp
+++ b/lib/et/Android.bp
@@ -18,6 +18,7 @@ cc_library {
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
+ vendor_available: true,
unique_host_soname: true,
defaults: ["e2fsprogs-defaults"],
srcs: [
diff --git a/lib/ext2fs/Android.bp b/lib/ext2fs/Android.bp
index db8b3b7e7..af4c2db94 100644
--- a/lib/ext2fs/Android.bp
+++ b/lib/ext2fs/Android.bp
@@ -19,6 +19,7 @@ cc_library {
host_supported: true,
ramdisk_available: true,
vendor_ramdisk_available: true,
+ vendor_available: true,
recovery_available: true,
unique_host_soname: true,
defaults: ["e2fsprogs-defaults"],
diff --git a/lib/ext2fs/e2image.h b/lib/ext2fs/e2image.h
index 53b20cc73..143e0dc6c 100644
--- a/lib/ext2fs/e2image.h
+++ b/lib/ext2fs/e2image.h
@@ -26,8 +26,9 @@ struct ext2_image_hdr {
__u32 image_device; /* Device number of image file */
__u32 image_inode; /* Inode number of image file */
- __u32 image_time; /* Time of image creation */
- __u32 image_reserved[8];
+ __u32 image_time_lo; /* Time of image creation */
+ __u32 image_time_hi; /* High bits of image test creation */
+ __u32 image_reserved[7];
__u32 offset_super; /* Byte offset of the sb and descriptors */
__u32 offset_inode; /* Byte offset of the inode table */
diff --git a/lib/ext2fs/qcow2.h b/lib/ext2fs/qcow2.h
index b649c9cf4..343e85ab0 100644
--- a/lib/ext2fs/qcow2.h
+++ b/lib/ext2fs/qcow2.h
@@ -24,6 +24,8 @@
* %End-Header%
*/
+#include <ext2fs/ext2_types.h>
+
/* Number of l2 tables in memory before writeback */
#define L2_CACHE_PREALLOC 512
diff --git a/lib/ext2fs/rbtree.h b/lib/ext2fs/rbtree.h
index 790f5c1c7..b96e6f2c2 100644
--- a/lib/ext2fs/rbtree.h
+++ b/lib/ext2fs/rbtree.h
@@ -163,7 +163,7 @@ extern struct rb_node *ext2fs_rb_first(const struct rb_root *);
extern struct rb_node *ext2fs_rb_last(const struct rb_root *);
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
-extern void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new,
+extern void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new_,
struct rb_root *root);
static inline void ext2fs_rb_link_node(struct rb_node * node,
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index 1fe65f744..1da75e4a0 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -557,7 +557,7 @@ errcode_t ext2fs_rw_bitmaps(ext2_filsys fs, int flags, int num_threads)
* MacOS, FreeBSD, etc.
* ref: https://stackoverflow.com/questions/150355
*/
- if (num_threads < 0)
+ if (num_threads <= 0)
num_threads = 4;
if ((unsigned) num_threads > fs->group_desc_count)
diff --git a/lib/support/Android.bp b/lib/support/Android.bp
index af9b28df6..ded3d4018 100644
--- a/lib/support/Android.bp
+++ b/lib/support/Android.bp
@@ -15,6 +15,7 @@ cc_library {
host_supported: true,
ramdisk_available: true,
vendor_ramdisk_available: true,
+ vendor_available: true,
recovery_available: true,
unique_host_soname: true,
defaults: ["e2fsprogs-defaults"],
diff --git a/lib/support/Makefile.in b/lib/support/Makefile.in
index b6229091f..3f26cd301 100644
--- a/lib/support/Makefile.in
+++ b/lib/support/Makefile.in
@@ -137,10 +137,11 @@ plausible.o: $(srcdir)/plausible.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/nls-enable.h
print_fs_flags.o: $(srcdir)/print_fs_flags.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
- $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/print_fs_flags.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
$(top_srcdir)/lib/ext2fs/bitops.h
profile.o: $(srcdir)/profile.c $(top_builddir)/lib/config.h \
diff --git a/lib/support/print_fs_flags.c b/lib/support/print_fs_flags.c
index f47cd6653..093820f14 100644
--- a/lib/support/print_fs_flags.c
+++ b/lib/support/print_fs_flags.c
@@ -14,6 +14,7 @@
#include "config.h"
#include <stdio.h>
+#include "print_fs_flags.h"
#include "ext2fs/ext2fs.h"
struct flags_name {
diff --git a/lib/support/quotaio.h b/lib/support/quotaio.h
index 390f7dc92..6152416fb 100644
--- a/lib/support/quotaio.h
+++ b/lib/support/quotaio.h
@@ -101,8 +101,8 @@ struct quotafile_ops;
/* Generic information about quotafile */
struct util_dqinfo {
- time_t dqi_bgrace; /* Block grace time for given quotafile */
- time_t dqi_igrace; /* Inode grace time for given quotafile */
+ __u32 dqi_bgrace; /* Block grace time for given quotafile */
+ __u32 dqi_igrace; /* Inode grace time for given quotafile */
union {
struct v2_mem_dqinfo v2_mdqi;
} u; /* Format specific info about quotafile */
@@ -137,8 +137,8 @@ struct util_dqblk {
qsize_t dqb_bhardlimit;
qsize_t dqb_bsoftlimit;
qsize_t dqb_curspace;
- time_t dqb_btime;
- time_t dqb_itime;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
union {
struct v2_mem_dqblk v2_mdqb;
} u; /* Format specific dquot information */
diff --git a/lib/uuid/Android.bp b/lib/uuid/Android.bp
index 3e6048d09..279592bd6 100644
--- a/lib/uuid/Android.bp
+++ b/lib/uuid/Android.bp
@@ -40,6 +40,9 @@ cc_library {
"uuid_time.c",
],
target: {
+ darwin: {
+ enabled: true,
+ },
windows: {
enabled: true,
},
diff --git a/misc/Android.bp b/misc/Android.bp
index 0656bf484..4edac23e2 100644
--- a/misc/Android.bp
+++ b/misc/Android.bp
@@ -18,6 +18,7 @@ cc_library {
name: "libext2_misc",
host_supported: true,
recovery_available: true,
+ vendor_available: true,
defaults: ["e2fsprogs-defaults"],
target: {
@@ -58,6 +59,7 @@ cc_defaults {
cc_binary {
name: "mke2fs",
host_supported: true,
+ vendor_available: true,
defaults: ["mke2fs_defaults"],
target: {
host: {
@@ -126,7 +128,7 @@ cc_binary {
symlinks: ["mkfs.ext4.microdroid"],
},
},
- installable: false,
+ no_full_install: true,
stem: "mke2fs",
visibility: ["//packages/modules/Virtualization/microdroid"],
}
@@ -191,9 +193,8 @@ cc_library_static {
//########################################################################
// Build badblocks
-cc_binary {
+cc_binary_host {
name: "badblocks",
- host_supported: true,
defaults: ["e2fsprogs-defaults"],
srcs: ["badblocks.c"],
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 37c269991..8769620a9 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -107,6 +107,7 @@ SRCS= $(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c $(srcdir)/
$(srcdir)/filefrag.c $(srcdir)/base_device.c \
$(srcdir)/ismounted.c $(srcdir)/e2undo.c \
$(srcdir)/e2freefrag.c $(srcdir)/create_inode.c \
+ $(srcdir)/create_inode_libarchive.c \
$(srcdir)/fuse2fs.c $(srcdir)/e2fuzz.c \
$(srcdir)/check_fuzzer.c \
$(srcdir)/../debugfs/journal.c $(srcdir)/../e2fsck/revoke.c \
@@ -857,16 +858,16 @@ create_inode.o: $(srcdir)/create_inode.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/fiemap.h \
$(srcdir)/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
- $(top_srcdir)/lib/support/nls-enable.h
+ $(top_srcdir)/lib/support/nls-enable.h $(srcdir)/create_inode_libarchive.h
create_inode_libarchive.o: $(srcdir)/create_inode_libarchive.c \
- $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
- $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/create_inode.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/fiemap.h \
- $(srcdir)/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/create_inode_libarchive.h \
$(top_srcdir)/lib/support/nls-enable.h
fuse2fs.o: $(srcdir)/fuse2fs.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
diff --git a/misc/e2image.c b/misc/e2image.c
index 1ae03001f..a92672464 100644
--- a/misc/e2image.c
+++ b/misc/e2image.c
@@ -239,6 +239,7 @@ static void write_image_file(ext2_filsys fs, int fd)
struct ext2_image_hdr hdr;
struct stat st;
errcode_t retval;
+ time_t now = time(0);
write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
memset(&hdr, 0, sizeof(struct ext2_image_hdr));
@@ -292,7 +293,12 @@ static void write_image_file(ext2_filsys fs, int fd)
}
memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
- hdr.image_time = ext2fs_cpu_to_le32(time(0));
+ hdr.image_time_lo = ext2fs_cpu_to_le32(now & 0xFFFFFFFF);
+#if (SIZEOF_TIME_T > 4)
+ hdr.image_time_hi = ext2fs_cpu_to_le32(now >> 32);
+#else
+ hdr.image_time_hi = 0;
+#endif
write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
}
diff --git a/misc/e4defrag.c b/misc/e4defrag.c
index e3011d7cd..5bfa6ff14 100644
--- a/misc/e4defrag.c
+++ b/misc/e4defrag.c
@@ -1206,9 +1206,8 @@ static int file_statistic(const char *file, const struct stat64 *buf,
if (mode_flag & DETAIL) {
/* Print statistic info */
- sprintf(msg_buffer, "[%u/%u]%.*s",
- defraged_file_count, total_count,
- PATH_MAX, file);
+ snprintf(msg_buffer, sizeof(msg_buffer), "[%u/%u]%.*s",
+ defraged_file_count, total_count, PATH_MAX, file);
if (current_uid == ROOT_UID) {
if (strlen(msg_buffer) > 40)
printf("\033[79;0H\033[K%s\n"
diff --git a/misc/ext4.5.in b/misc/ext4.5.in
index c835a3441..6fb67ebf8 100644
--- a/misc/ext4.5.in
+++ b/misc/ext4.5.in
@@ -1,3 +1,4 @@
+'\" t
.\" -*- nroff -*-
.\" Copyright 1993, 1994, 1995 by Theodore Ts'o. All Rights Reserved.
.\" This file may be copied under the terms of the GNU Public License.
diff --git a/misc/lsattr.1.in b/misc/lsattr.1.in
index 4d02a95a3..9884a4d6b 100644
--- a/misc/lsattr.1.in
+++ b/misc/lsattr.1.in
@@ -1,7 +1,7 @@
.\" -*- nroff -*-
.TH LSATTR 1 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
.SH NAME
-lsattr \- list file attributes on a Linux second extended file system
+lsattr \- list ext2/ext3/ext4 file attributes
.SH SYNOPSIS
.B lsattr
[
@@ -12,7 +12,7 @@ lsattr \- list file attributes on a Linux second extended file system
]
.SH DESCRIPTION
.B lsattr
-lists the file attributes on a second extended file system. See
+lists the file attributes on an ext2/ext3/ext4 file system. See
.BR chattr (1)
for a description of the attributes and what they mean.
.SH OPTIONS
diff --git a/misc/mklost+found.8.in b/misc/mklost+found.8.in
index d33823948..59b7e761c 100644
--- a/misc/mklost+found.8.in
+++ b/misc/mklost+found.8.in
@@ -4,15 +4,15 @@
.\"
.TH MKLOST+FOUND 8 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
.SH NAME
-mklost+found \- create a lost+found directory on a mounted Linux
-second extended file system
+mklost+found \- create a lost+found directory on a mounted
+ext2/ext3/ext4 file system
.SH SYNOPSIS
.B mklost+found
.SH DESCRIPTION
.B mklost+found
is used to create a
.I lost+found
-directory in the current working directory on a Linux second extended
+directory in the current working directory on an ext2/ext3/ext4
file system. There is normally a
.I lost+found
directory in the root directory of each file system.
diff --git a/tests/f_bad_disconnected_inode/expect.1 b/tests/f_bad_disconnected_inode/expect.1
index d1479cef2..39c6958cf 100644
--- a/tests/f_bad_disconnected_inode/expect.1
+++ b/tests/f_bad_disconnected_inode/expect.1
@@ -1,11 +1,17 @@
Pass 1: Checking inodes, blocks, and sizes
+Inode 1 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
Inode 1 has EXTENTS_FL flag set on filesystem without extents support.
Clear? yes
Inode 9 has the casefold flag set but is not a directory. Clear flag? yes
+Inode 10 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
Inode 14 has the casefold flag set but is not a directory. Clear flag? yes
+Inode 14 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
Inode 14 has INLINE_DATA_FL flag on filesystem without inline data support.
Clear? yes
@@ -14,6 +20,8 @@ Clear? yes
Inode 16 has the casefold flag set but is not a directory. Clear flag? yes
+Inode 16 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
Inode 16 has INLINE_DATA_FL flag on filesystem without inline data support.
Clear? yes
diff --git a/tests/f_bad_fname/expect.1 b/tests/f_bad_fname/expect.1
index 66f87df2b..60f64f67d 100644
--- a/tests/f_bad_fname/expect.1
+++ b/tests/f_bad_fname/expect.1
@@ -1,4 +1,6 @@
Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
Pass 2: Checking directory structure
Entry 'AM-^?' in /ci_dir (12) has illegal UTF-8 characters in its name.
Fix? yes
diff --git a/tests/f_ea_inode_dir_ref/expect.1 b/tests/f_ea_inode_dir_ref/expect.1
new file mode 100644
index 000000000..fa6a872b8
--- /dev/null
+++ b/tests/f_ea_inode_dir_ref/expect.1
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Entry 'xlink' in / (2) references EA inode 13.
+Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 13/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 1
diff --git a/tests/f_ea_inode_dir_ref/expect.2 b/tests/f_ea_inode_dir_ref/expect.2
new file mode 100644
index 000000000..24d059a30
--- /dev/null
+++ b/tests/f_ea_inode_dir_ref/expect.2
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 13/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 0
diff --git a/tests/f_ea_inode_dir_ref/image.gz b/tests/f_ea_inode_dir_ref/image.gz
new file mode 100644
index 000000000..483cc725e
--- /dev/null
+++ b/tests/f_ea_inode_dir_ref/image.gz
Binary files differ
diff --git a/tests/f_ea_inode_dir_ref/name b/tests/f_ea_inode_dir_ref/name
new file mode 100644
index 000000000..e43cd6950
--- /dev/null
+++ b/tests/f_ea_inode_dir_ref/name
@@ -0,0 +1 @@
+true ea inode referenced from a directory
diff --git a/tests/f_ea_inode_disconnected/expect.1 b/tests/f_ea_inode_disconnected/expect.1
new file mode 100644
index 000000000..afc77aea6
--- /dev/null
+++ b/tests/f_ea_inode_disconnected/expect.1
@@ -0,0 +1,23 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Unattached inode 13
+Connect to /lost+found? yes
+
+Inode 13 ref count is 2, should be 1. Fix? yes
+
+Pass 5: Checking group summary information
+Inode bitmap differences: -12
+Fix? yes
+
+Free inodes count wrong for group #0 (115, counted=116).
+Fix? yes
+
+Free inodes count wrong (115, counted=116).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 12/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 1
diff --git a/tests/f_ea_inode_disconnected/expect.2 b/tests/f_ea_inode_disconnected/expect.2
new file mode 100644
index 000000000..a67f94450
--- /dev/null
+++ b/tests/f_ea_inode_disconnected/expect.2
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 12/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 0
diff --git a/tests/f_ea_inode_disconnected/image b/tests/f_ea_inode_disconnected/image
new file mode 100644
index 000000000..f24547c26
--- /dev/null
+++ b/tests/f_ea_inode_disconnected/image
Binary files differ
diff --git a/tests/f_ea_inode_disconnected/image.gz b/tests/f_ea_inode_disconnected/image.gz
new file mode 100644
index 000000000..f440f2052
--- /dev/null
+++ b/tests/f_ea_inode_disconnected/image.gz
Binary files differ
diff --git a/tests/f_ea_inode_disconnected/name b/tests/f_ea_inode_disconnected/name
new file mode 100644
index 000000000..ce04192e8
--- /dev/null
+++ b/tests/f_ea_inode_disconnected/name
@@ -0,0 +1 @@
+ea inode that is not connected anywhere
diff --git a/tests/f_ea_inode_no_feature/expect.1 b/tests/f_ea_inode_no_feature/expect.1
new file mode 100644
index 000000000..f6a232bfc
--- /dev/null
+++ b/tests/f_ea_inode_no_feature/expect.1
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 references EA inode but superblock is missing EA_INODE feature
+Fix? yes
+
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 13/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 1
diff --git a/tests/f_ea_inode_no_feature/expect.2 b/tests/f_ea_inode_no_feature/expect.2
new file mode 100644
index 000000000..24d059a30
--- /dev/null
+++ b/tests/f_ea_inode_no_feature/expect.2
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 13/128 files (0.0% non-contiguous), 63/1024 blocks
+Exit status is 0
diff --git a/tests/f_ea_inode_no_feature/image.gz b/tests/f_ea_inode_no_feature/image.gz
new file mode 100644
index 000000000..596d69a1c
--- /dev/null
+++ b/tests/f_ea_inode_no_feature/image.gz
Binary files differ
diff --git a/tests/f_ea_inode_no_feature/name b/tests/f_ea_inode_no_feature/name
new file mode 100644
index 000000000..b357afb47
--- /dev/null
+++ b/tests/f_ea_inode_no_feature/name
@@ -0,0 +1 @@
+inode with ea inode but EA_INODE feature is not set
diff --git a/tests/f_ea_inode_self_ref/expect.1 b/tests/f_ea_inode_self_ref/expect.1
index f94c04d96..35bea1417 100644
--- a/tests/f_ea_inode_self_ref/expect.1
+++ b/tests/f_ea_inode_self_ref/expect.1
@@ -7,6 +7,8 @@ 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
diff --git a/tests/f_ea_inode_spurious_flag_dir/expect.1 b/tests/f_ea_inode_spurious_flag_dir/expect.1
new file mode 100644
index 000000000..19999ab79
--- /dev/null
+++ b/tests/f_ea_inode_spurious_flag_dir/expect.1
@@ -0,0 +1,11 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 2 has the ea_inode flag set but is not a regular file. Clear flag? yes
+
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/128 files (0.0% non-contiguous), 58/1024 blocks
+Exit status is 1
diff --git a/tests/f_ea_inode_spurious_flag_dir/expect.2 b/tests/f_ea_inode_spurious_flag_dir/expect.2
new file mode 100644
index 000000000..a35477094
--- /dev/null
+++ b/tests/f_ea_inode_spurious_flag_dir/expect.2
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/128 files (0.0% non-contiguous), 58/1024 blocks
+Exit status is 0
diff --git a/tests/f_ea_inode_spurious_flag_dir/image b/tests/f_ea_inode_spurious_flag_dir/image
new file mode 100644
index 000000000..f323b6131
--- /dev/null
+++ b/tests/f_ea_inode_spurious_flag_dir/image
Binary files differ
diff --git a/tests/f_ea_inode_spurious_flag_dir/image.gz b/tests/f_ea_inode_spurious_flag_dir/image.gz
new file mode 100644
index 000000000..af19132ce
--- /dev/null
+++ b/tests/f_ea_inode_spurious_flag_dir/image.gz
Binary files differ
diff --git a/tests/f_ea_inode_spurious_flag_dir/name b/tests/f_ea_inode_spurious_flag_dir/name
new file mode 100644
index 000000000..8ae52ccf0
--- /dev/null
+++ b/tests/f_ea_inode_spurious_flag_dir/name
@@ -0,0 +1 @@
+ea inode flag set on a directory
diff --git a/tests/progs/Makefile.in b/tests/progs/Makefile.in
index 47d7adfa9..1a8e9299a 100644
--- a/tests/progs/Makefile.in
+++ b/tests/progs/Makefile.in
@@ -73,6 +73,15 @@ distclean: clean
# Makefile dependencies follow. This must be the last section in
# the Makefile.in file
#
+test_icount.o: $(srcdir)/test_icount.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/ss/ss.h $(top_builddir)/lib/ss/ss_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/hashmap.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/irel.h \
+ $(top_srcdir)/lib/ext2fs/brel.h $(srcdir)/test_icount.h
test_rel.o: $(srcdir)/test_rel.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ss/ss.h $(top_builddir)/lib/ss/ss_err.h \
diff --git a/util/android_config.h b/util/android_config.h
index 90b8f8a8f..c2288602e 100644
--- a/util/android_config.h
+++ b/util/android_config.h
@@ -54,6 +54,9 @@
# define HAVE_SYS_SELECT_H 1
# define HAVE_SYS_WAIT_H 1
#endif
+#ifdef __APPLE__
+# define HAVE_GETMNTINFO 1
+#endif
#if defined(__linux__)
# define HAVE_EXT2_IOCTLS 1
# define HAVE_FALLOCATE 1
diff --git a/version.h b/version.h
index 6753cc7e8..af575f4da 100644
--- a/version.h
+++ b/version.h
@@ -9,5 +9,5 @@
* License v2.
*/
-#define E2FSPROGS_VERSION "1.47.1-rc2"
-#define E2FSPROGS_DATE "01-May-2024"
+#define E2FSPROGS_VERSION "1.47.1"
+#define E2FSPROGS_DATE "20-May-2024"