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 @@ -15645,9 +15645,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="#" 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 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 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 Wed, 01 May 2024 00:50:49 -0400 + -- Theodore Y. Ts'o 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 -Build-Depends: dpkg-dev (>= 1.22.5), gettext, texinfo, pkg-config, libarchive-dev, libfuse3-dev [linux-any kfreebsd-any] , 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] , 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, "a_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 @@ static int check_dir_block(ext2_filsys fs, 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 + /* 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 +#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 Binary files /dev/null and b/tests/f_ea_inode_dir_ref/image.gz 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 Binary files /dev/null and b/tests/f_ea_inode_disconnected/image 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 Binary files /dev/null and b/tests/f_ea_inode_disconnected/image.gz 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 Binary files /dev/null and b/tests/f_ea_inode_no_feature/image.gz 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 Binary files /dev/null and b/tests/f_ea_inode_spurious_flag_dir/image 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 Binary files /dev/null and b/tests/f_ea_inode_spurious_flag_dir/image.gz 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"