All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3
@ 2014-08-05  1:04 Darrick J. Wong
  2014-08-05  1:05 ` [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux Darrick J. Wong
                   ` (20 more replies)
  0 siblings, 21 replies; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:04 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Hi all,

This is part 3 of the July e2fsprogs patchset (even though it is
August) that fixes e2fsck failures with filesystems containing the
inline data feature.  e2fuzz helped me to find the failures.

The first patch fixes build problems with e2fuzz on i386 Linux and
Mac OSX, and the second patch fixes an error message introduced in
the previous patchbomb.

Patches 3-8 fix library functions such that we won't read off the end
of the EA buffer when parsing keys; some places where we neglect to
handle byte-swapping on big-endian systems correctly; remove the EA
part of inline data if it's not necessary; and fix a memory leak.

Patches 9-11 fix problems I found in libext2fs: there's a patch to add
to e2fsck the ability to find overlapping blobs in the inode EA area;
to truncate inline data files if the EA cannot be found; and to check
inline data symlinks.

Patches 12-13 fix a few bugs where e2fsck would abort unnecessarily
due to finding an inode with the inline data flag set.

Patches 14-15 try to fix inodes that shouldn't have inline_data set,
and to resolve conflicts if both extents and inline_data are set on an
inode.

Patches 16-20 deal with repair of inline data directories, since
containing directory data adds extra constraints on what constitutes a
valid inode that e2fsck should be able to fix.

Patch 21 adds test cases for the bugs I found in the inline data
repair code, and exercises the sanity tests in e2fsck.

I've tested these e2fsprogs changes against the -next branch as of
8/4.  That's not much testing, but most of the changes between 7/29
and today on that branch have been to add the patches that were in the
previous patch bomb.  As I stated in the part 1 introduction, I use
several VMs, each with 32M-1G ramdisks to test with; the test process
is "misc/e2fuzz.sh -B <fuzz> -s <size>", where fuzz is anything from 2
bytes to "0.1%" of metadata bytes.

Comments and questions are, as always, welcome.

--D

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:16   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error Darrick J. Wong
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Fix clang warnings about forgotten header files, dead code, and pwrite
support on OS X.  The unistd.h inclusion also fixes a parameter
truncation bug on i386.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 misc/e2fuzz.c |   21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)


diff --git a/misc/e2fuzz.c b/misc/e2fuzz.c
index 8c989dd..91aafe5 100644
--- a/misc/e2fuzz.c
+++ b/misc/e2fuzz.c
@@ -18,6 +18,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdint.h>
+#include <unistd.h>
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif
@@ -31,6 +32,16 @@ static int metadata_only = 1;
 static unsigned long long user_corrupt_bytes = 0;
 static double user_corrupt_pct = 0.0;
 
+#ifndef HAVE_PWRITE
+ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+	if (lseek(fd, offset, SEEK_SET) < 0)
+		return 0;
+
+	return write(fd, buf, count);
+}
+#endif /* HAVE_PWRITE */
+
 int getseed(void)
 {
 	int r;
@@ -70,7 +81,7 @@ errcode_t find_metadata_blocks(ext2_filsys fs, ext2fs_block_bitmap bmap,
 			       off_t *corrupt_bytes)
 {
 	dgrp_t i;
-	blk64_t b, c, d, j, old_desc_blocks;
+	blk64_t b, c;
 	ext2_inode_scan scan;
 	ext2_ino_t ino;
 	struct ext2_inode inode;
@@ -79,12 +90,6 @@ errcode_t find_metadata_blocks(ext2_filsys fs, ext2fs_block_bitmap bmap,
 
 	*corrupt_bytes = 0;
 	fb.corrupt_blocks = 0;
-	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
-				      EXT2_FEATURE_INCOMPAT_META_BG))
-		old_desc_blocks = fs->super->s_first_meta_bg;
-	else
-		old_desc_blocks = fs->desc_blocks +
-				  fs->super->s_reserved_gdt_blocks;
 
 	/* Construct bitmaps of super/descriptor blocks */
 	for (i = 0; i < fs->group_desc_count; i++) {
@@ -271,7 +276,7 @@ int process_fs(const char *fsname)
 			       off % fs->blocksize, off / fs->blocksize, c);
 		if (dryrun)
 			continue;
-		if (pwrite64(fd, &c, sizeof(c), off) != sizeof(c)) {
+		if (pwrite(fd, &c, sizeof(c), off) != sizeof(c)) {
 			perror(fsname);
 			goto fail3;
 		}


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
  2014-08-05  1:05 ` [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:16   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 03/21] libext2fs: check EA value offset Darrick J. Wong
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

In pass 3, convert the "delete files and re-run e2fsck" message to a
proper error code for more consistent error reporting and to make
translation easier.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass3.c                    |    4 ++--
 e2fsck/problem.c                  |    5 +++++
 e2fsck/problem.h                  |    3 +++
 tests/f_nospc_create_lnf/expect.1 |    3 ++-
 tests/f_nospc_create_lnf/expect.2 |    3 ++-
 5 files changed, 14 insertions(+), 4 deletions(-)


diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 0b02961..63b1d70 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -452,7 +452,7 @@ unlink:
 	retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 	if (retval == EXT2_ET_BLOCK_ALLOC_FAIL &&
 	    fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
-		printf("Delete some files and re-run e2fsck.\n\n");
+		fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
 		ctx->lost_and_found = EXT2_ROOT_INO;
 		return 0;
 	}
@@ -472,7 +472,7 @@ skip_new_block:
 				  ctx->inode_used_map, &ino);
 	if (retval == EXT2_ET_INODE_ALLOC_FAIL &&
 	    fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
-		printf("Delete some files and re-run e2fsck.\n\n");
+		fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
 		ctx->lost_and_found = EXT2_ROOT_INO;
 		return 0;
 	}
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 452137a..2d29c35 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1619,6 +1619,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("Cannot allocate space for /@l.\nPlace lost files in root directory instead"),
 	  PROMPT_NULL, 0 },
 
+	/* Delete some files and re-run e2fsck. */
+	{ PR_3_NO_SPACE_TO_RECOVER,
+	  N_("Insufficient space to recover lost files!\nMove data off the @f and re-run e2fsck.\n\n"),
+	  PROMPT_NONE, 0 },
+
 	/* Pass 3A Directory Optimization	*/
 
 	/* Pass 3A: Optimizing directories */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 72cfc4d..89146ec 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -967,6 +967,9 @@ struct problem_context {
 /* Cannot allocate lost+found */
 #define PR_3_LPF_NO_SPACE		0x030019
 
+/* Insufficient space to recover lost files */
+#define PR_3_NO_SPACE_TO_RECOVER	0x03001A
+
 /*
  * Pass 3a --- rehashing diretories
  */
diff --git a/tests/f_nospc_create_lnf/expect.1 b/tests/f_nospc_create_lnf/expect.1
index fc20628..986fe12 100644
--- a/tests/f_nospc_create_lnf/expect.1
+++ b/tests/f_nospc_create_lnf/expect.1
@@ -6,7 +6,8 @@ Pass 3: Checking directory connectivity
 Cannot allocate space for /lost+found.
 Place lost files in root directory instead? yes
 
-Delete some files and re-run e2fsck.
+Insufficient space to recover lost files!
+Move data off the filesystem and re-run e2fsck.
 
 Pass 3A: Optimizing directories
 Pass 4: Checking reference counts
diff --git a/tests/f_nospc_create_lnf/expect.2 b/tests/f_nospc_create_lnf/expect.2
index 5a44649..e9757f8 100644
--- a/tests/f_nospc_create_lnf/expect.2
+++ b/tests/f_nospc_create_lnf/expect.2
@@ -6,7 +6,8 @@ Pass 3: Checking directory connectivity
 Cannot allocate space for /lost+found.
 Place lost files in root directory instead? yes
 
-Delete some files and re-run e2fsck.
+Insufficient space to recover lost files!
+Move data off the filesystem and re-run e2fsck.
 
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 03/21] libext2fs: check EA value offset
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
  2014-08-05  1:05 ` [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux Darrick J. Wong
  2014-08-05  1:05 ` [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:21   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block Darrick J. Wong
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Perform a little more sanity checking of EA value offsets so that we
don't crash while trying to load things from the filesystem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/ext2_err.et.in |    3 +++
 lib/ext2fs/ext_attr.c     |    5 +++++
 2 files changed, 8 insertions(+)


diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 2194a18..6b6d8b8 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -518,4 +518,7 @@ ec	EXT2_ET_MAGIC_EA_HANDLE,
 ec	EXT2_ET_INODE_IS_GARBAGE,
 	"Inode seems to contain garbage"
 
+ec	EXT2_ET_EA_BAD_VALUE_OFFSET,
+	"Extended attribute has an invalid value offset"
+
 	end
diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
index f3fba96..96530f8 100644
--- a/lib/ext2fs/ext_attr.c
+++ b/lib/ext2fs/ext_attr.c
@@ -624,6 +624,8 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle,
 	void *ptr;
 	unsigned int remain, prefix_len;
 	errcode_t err;
+	unsigned int values_size = storage_size +
+			((char *)entries - (char *)value_start);
 
 	x = handle->attrs;
 	while (x->name)
@@ -648,6 +650,9 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle,
 		if (entry->e_value_size > remain)
 			return EXT2_ET_EA_BAD_VALUE_SIZE;
 
+		if (entry->e_value_offs + entry->e_value_size > values_size)
+			return EXT2_ET_EA_BAD_VALUE_OFFSET;
+
 		/* e_value_block must be 0 in inode's ea */
 		if (entry->e_value_block != 0)
 			return EXT2_ET_BAD_EA_BLOCK_NUM;


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (2 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 03/21] libext2fs: check EA value offset Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:22   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 05/21] misc: fix various endianness problems with inline_data Darrick J. Wong
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

When we're (a) reading EAs into a buffer; (b) byte-swapping EA
entries; or (c) checking EA data, be careful not to run off the end of
the memory buffer, because this causes invalid memory accesses and
e2fsck crashes.  This can happen if we encounter a specially crafted
FS image.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c        |    3 ++-
 lib/ext2fs/ext_attr.c |    3 ++-
 lib/ext2fs/swapfs.c   |    4 +++-
 3 files changed, 7 insertions(+), 3 deletions(-)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 5c72f48..6c79eed 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -302,7 +302,8 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 	/* take finish entry 0UL into account */
 	remain = storage_size - sizeof(__u32);
 
-	while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
+	while (remain >= sizeof(struct ext2_ext_attr_entry) &&
+	       !EXT2_EXT_IS_LAST_ENTRY(entry)) {
 		__u32 hash;
 
 		/* header eats this space */
diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
index 96530f8..5732ca6 100644
--- a/lib/ext2fs/ext_attr.c
+++ b/lib/ext2fs/ext_attr.c
@@ -633,7 +633,8 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle,
 
 	entry = entries;
 	remain = storage_size;
-	while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
+	while (remain >= sizeof(struct ext2_ext_attr_entry) &&
+	       !EXT2_EXT_IS_LAST_ENTRY(entry)) {
 		__u32 hash;
 
 		/* header eats this space */
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index f08859b..e2aa41d 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -196,7 +196,9 @@ void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
 		to_entry   = (struct ext2_ext_attr_entry *)to_header;
 	}
 
-	while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
+	while ((char *)from_entry < from_end &&
+	       (char *)EXT2_EXT_ATTR_NEXT(from_entry) <= from_end &&
+	       *(__u32 *)from_entry) {
 		ext2fs_swap_ext_attr_entry(to_entry, from_entry);
 		from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
 		to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 05/21] misc: fix various endianness problems with inline_data
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (3 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:23   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC Darrick J. Wong
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

The inline data code fails to perform endianness conversions correctly
or at all in a number of places, so fix this so that big-endian
machines function properly.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass2.c           |   25 +++++++++++++++++++++++--
 lib/ext2fs/inline_data.c |    5 ++++-
 lib/ext2fs/newdir.c      |    9 +++++++++
 3 files changed, 36 insertions(+), 3 deletions(-)


diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index e968831..38bf37a 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -870,11 +870,21 @@ static int check_dir_block(ext2_filsys fs,
 #endif
 
 	ehandler_operation(_("reading directory block"));
-	if (inline_data_size)
+	if (inline_data_size) {
 		cd->pctx.errcode = ext2fs_inline_data_get(fs, ino, 0, buf, 0);
-	else
+		if (cd->pctx.errcode)
+			goto inline_read_fail;
+#ifdef WORDS_BIGENDIAN
+		*((__u32 *)buf) = ext2fs_le32_to_cpu(*((__u32 *)buf));
+		cd->pctx.errcode = ext2fs_dirent_swab_in2(fs,
+				buf + EXT4_INLINE_DATA_DOTDOT_SIZE,
+				inline_data_size - EXT4_INLINE_DATA_DOTDOT_SIZE,
+				0);
+#endif
+	} else
 		cd->pctx.errcode = ext2fs_read_dir_block4(fs, block_nr,
 							  buf, 0, ino);
+inline_read_fail:
 	ehandler_operation(0);
 	if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
 		cd->pctx.errcode = 0; /* We'll handle this ourselves */
@@ -1311,6 +1321,17 @@ write_and_fix:
 			ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
 		}
 		if (inline_data_size) {
+#ifdef WORDS_BIGENDIAN
+			*((__u32 *)buf) = ext2fs_le32_to_cpu(*((__u32 *)buf));
+			cd->pctx.errcode = ext2fs_dirent_swab_out2(fs,
+					buf + EXT4_INLINE_DATA_DOTDOT_SIZE,
+					inline_data_size -
+					EXT4_INLINE_DATA_DOTDOT_SIZE,
+					0);
+			if (cd->pctx.errcode &&
+			    !fix_problem(ctx, PR_2_WRITE_DIRBLOCK, &cd->pctx))
+				goto abort_free_dict;
+#endif
 			cd->pctx.errcode =
 				ext2fs_inline_data_set(fs, ino, 0, buf,
 						       inline_data_size);
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 19248a0..c188d75 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -361,13 +361,16 @@ ext2fs_inline_data_dir_expand(ext2_filsys fs, ext2_ino_t ino,
 		return retval;
 
 #ifdef WORDS_BIGENDIAN
-	retval = ext2fs_dirent_swab_in2(fs, buf, size, 0);
+	retval = ext2fs_dirent_swab_in2(fs, buf + EXT4_INLINE_DATA_DOTDOT_SIZE,
+					size, 0);
 	if (retval)
 		goto errout;
 #endif
 
 	/* Adjust the rec_len */
 	retval = ext2fs_inline_data_convert_dir(fs, ino, blk_buf, buf, size);
+	if (retval)
+		goto errout;
 	/* Allocate a new block */
 	retval = ext2fs_new_block2(fs, 0, 0, &blk);
 	if (retval)
diff --git a/lib/ext2fs/newdir.c b/lib/ext2fs/newdir.c
index cd32d0a..506d609 100644
--- a/lib/ext2fs/newdir.c
+++ b/lib/ext2fs/newdir.c
@@ -115,6 +115,15 @@ errcode_t ext2fs_new_dir_inline_data(ext2_filsys fs, ext2_ino_t dir_ino,
 	dir->inode = 0;
 	rec_len = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DATA_DOTDOT_SIZE;
 	retval = ext2fs_set_rec_len(fs, rec_len, dir);
+	if (retval)
+		goto errout;
+
+#ifdef WORDS_BIGENDIAN
+	retval = ext2fs_dirent_swab_out2(fs, (char *)dir, rec_len, 0);
+	if (retval)
+		goto errout;
+#endif
 
+errout:
 	return retval;
 }


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (4 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 05/21] misc: fix various endianness problems with inline_data Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:27   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 07/21] libext2fs: remove EA when inline data is less than 60 bytes Darrick J. Wong
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If we're doing a strict overwrite (same data size) of data in an
inline data file, we should be able to skip the size check.  If the
in-core EA representation is fine but the on-disk EA is slightly
corrupt (this happens when fixing minor errors in an inline dir), the
ext2fs_xattr_inode_max_size() call, which reads the disk EA, can lead
us to think that there's no space when in reality there is no issue
with doing a strict overwrite.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/inline_data.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index c188d75..b9bda50 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -574,7 +574,8 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
 	else
 		free_inode_size = 0;
 
-	if (size > existing_size + free_ea_size + free_inode_size)
+	if (size != existing_size &&
+	    size > existing_size + free_ea_size + free_inode_size)
 		return EXT2_ET_INLINE_DATA_NO_SPACE;
 
 	memcpy((void *)inode->i_block, buf, EXT4_MIN_INLINE_DATA_SIZE);


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 07/21] libext2fs: remove EA when inline data is less than 60 bytes
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (5 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-08 22:46   ` [PATCH v2 07/21] libext2fs: don't fail inline data operations if there's no EA Darrick J. Wong
  2014-08-05  1:05 ` [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory Darrick J. Wong
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If we write less than 60 bytes of inline data, remove the EA.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/inline_data.c |    3 +++
 1 file changed, 3 insertions(+)


diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index b9bda50..8a71d18 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -557,6 +557,9 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
 	}
 
 	if (size <= EXT4_MIN_INLINE_DATA_SIZE) {
+		retval = ext2fs_inline_data_ea_remove(fs, ino);
+		if (retval)
+			return retval;
 		memcpy((void *)inode->i_block, buf, size);
 		return ext2fs_write_inode(fs, ino, inode);
 	}


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (6 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 07/21] libext2fs: remove EA when inline data is less than 60 bytes Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-10 22:32   ` Theodore Ts'o
  2014-08-05  1:05 ` [PATCH 09/21] e2fsck: check ea-in-inode regions for overlap Darrick J. Wong
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

The xattr_get method returns to us a pointer to a buffer containing
the EA value.  If for some reason we decide to fail out of iterating
the EA part of an inline-data directory, we must free the buffer that
xattr_get passed to us (via inline_data_ea_get).

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/inline_data.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 8a71d18..aeef329 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -214,7 +214,7 @@ int ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino,
 		goto out;
 	}
 	if (data.ea_size <= 0)
-		goto out;
+		goto out1;
 
 	ctx->buf = data.ea_data;
 	ctx->buflen = data.ea_size;
@@ -222,7 +222,7 @@ int ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino,
 	ctx->errcode = ext2fs_dirent_swab_in2(fs, ctx->buf, ctx->buflen, 0);
 	if (ctx->errcode) {
 		ret |= BLOCK_ABORT;
-		goto out;
+		goto out1;
 	}
 #endif
 


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 09/21] e2fsck: check ea-in-inode regions for overlap
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (7 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory Darrick J. Wong
@ 2014-08-05  1:05 ` Darrick J. Wong
  2014-08-08 22:43   ` [PATCH v2 " Darrick J. Wong
  2014-08-05  1:06 ` [PATCH 10/21] e2fsck: clear inline_data inode flag if EA missing Darrick J. Wong
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:05 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Ensure that the various blobs in the in-inode EA region do not overlap.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c                      |   41 ++++++++++++++++++++++++++++++++---
 e2fsck/problem.c                    |    5 ++++
 e2fsck/problem.h                    |    3 +++
 tests/f_inode_ea_collision/expect.1 |   15 +++++++++++++
 tests/f_inode_ea_collision/expect.2 |    7 ++++++
 tests/f_inode_ea_collision/image.gz |  Bin
 tests/f_inode_ea_collision/name     |    1 +
 7 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 tests/f_inode_ea_collision/expect.1
 create mode 100644 tests/f_inode_ea_collision/expect.2
 create mode 100644 tests/f_inode_ea_collision/image.gz
 create mode 100644 tests/f_inode_ea_collision/name


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 6c79eed..172d664 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -286,15 +286,17 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 	struct ext2_super_block *sb = ctx->fs->super;
 	struct ext2_inode_large *inode;
 	struct ext2_ext_attr_entry *entry;
-	char *start;
+	char *start, *header;
 	unsigned int storage_size, remain;
 	problem_t problem = 0;
+	region_t region = 0;
 
 	inode = (struct ext2_inode_large *) pctx->inode;
 	storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
 		inode->i_extra_isize;
-	start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
-		inode->i_extra_isize + sizeof(__u32);
+	header = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
+		 inode->i_extra_isize;
+	start = header + sizeof(__u32);
 	entry = (struct ext2_ext_attr_entry *) start;
 
 	/* scan all entry's headers first */
@@ -302,10 +304,28 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 	/* take finish entry 0UL into account */
 	remain = storage_size - sizeof(__u32);
 
+	region = region_create(0, storage_size);
+	if (!region) {
+		fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
+		problem = 0;
+		ctx->flags |= E2F_FLAG_ABORT;
+		return;
+	}
+	if (region_allocate(region, 0, sizeof(__u32))) {
+		problem = PR_1_INODE_EA_ALLOC_COLLISION;
+		goto fix;
+	}
+
 	while (remain >= sizeof(struct ext2_ext_attr_entry) &&
 	       !EXT2_EXT_IS_LAST_ENTRY(entry)) {
 		__u32 hash;
 
+		if (region_allocate(region, (char *)entry - (char *)header,
+				    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
+			problem = PR_1_INODE_EA_ALLOC_COLLISION;
+			goto fix;
+		}
+
 		/* header eats this space */
 		remain -= sizeof(struct ext2_ext_attr_entry);
 
@@ -333,6 +353,13 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 			goto fix;
 		}
 
+		if (entry->e_value_size &&
+		    region_allocate(region, sizeof(__u32) + entry->e_value_offs,
+				    EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
+			problem = PR_1_INODE_EA_ALLOC_COLLISION;
+			goto fix;
+		}
+
 		hash = ext2fs_ext_attr_hash_entry(entry,
 						  start + entry->e_value_offs);
 
@@ -347,7 +374,15 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 
 		entry = EXT2_EXT_ATTR_NEXT(entry);
 	}
+
+	if (region_allocate(region, (char *)entry - (char *)header,
+			    sizeof(__u32))) {
+		problem = PR_1_INODE_EA_ALLOC_COLLISION;
+		goto fix;
+	}
 fix:
+	if (region)
+		region_free(region);
 	/*
 	 * it seems like a corruption. it's very unlikely we could repair
 	 * EA(s) in automatic fashion -bzzz
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 2d29c35..b982a27 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -977,6 +977,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@i %i passes checks, but checksum does not match @i.  "),
 	  PROMPT_FIX, PR_PREEN_OK },
 
+	/* Inode extended attribute is corrupt (allocation collision) */
+	{ PR_1_INODE_EA_ALLOC_COLLISION,
+	  N_("@i %i @a is corrupt (allocation collision).  "),
+	  PROMPT_CLEAR, 0},
+
 	/*
 	 * Inode extent block passes checks, but checksum does not match
 	 * extent
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 89146ec..f051c11 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -577,6 +577,9 @@ struct problem_context {
 /* inode passes checks, but checksum does not match inode */
 #define PR_1_INODE_ONLY_CSUM_INVALID   0x010068
 
+/* Inode EA allocation collision */
+#define PR_1_INODE_EA_ALLOC_COLLISION	0x010069
+
 /* extent block passes checks, but checksum does not match extent block */
 #define PR_1_EXTENT_ONLY_CSUM_INVALID  0x01006A
 
diff --git a/tests/f_inode_ea_collision/expect.1 b/tests/f_inode_ea_collision/expect.1
new file mode 100644
index 0000000..a67a5f1
--- /dev/null
+++ b/tests/f_inode_ea_collision/expect.1
@@ -0,0 +1,15 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 extended attribute is corrupt (allocation collision).  Clear? yes
+
+Inode 13 extended attribute is corrupt (allocation collision).  Clear? yes
+
+Inode 14 extended attribute is corrupt (allocation collision).  Clear? 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: 14/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 1
diff --git a/tests/f_inode_ea_collision/expect.2 b/tests/f_inode_ea_collision/expect.2
new file mode 100644
index 0000000..5a7ca86
--- /dev/null
+++ b/tests/f_inode_ea_collision/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: 14/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 0
diff --git a/tests/f_inode_ea_collision/image.gz b/tests/f_inode_ea_collision/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..5217f6503404864944a88bfc36b7d75a305aafb8
GIT binary patch
literal 2602
zcmb2|=3rRTdo!4c`Ry(1jNn8Oh6n%E1ihnk1;sZu?eJW<NUv+f#j`7&rz`1+%6Chx
z=yzP$zj61~h22d*Bw~&@hIDCYH8poTn;&#Na(uyTr@!x&7j4w~mb&)7_&M9}GoL+C
zGk@+c%=BTul$ZKafv}@r^f(vpkBHY&x}B)u->fWbo2immwCQ=R(4%*W3VPSyYikyH
zZ``1|?Dt2%b4UJs`SxP5`rf<qk6jPBKPPtAKflM1ZxnpF(YbTo*E?sW`@hG%t1C!M
z`g-u=^W<936>Zmo_PxDrmFDffM>TlO`Xe_UFJ)&q5I<qte(j_+r+@wbw<G4~uC?|#
zcOOVHF)%dL-%klvt<gLGpn`#cA>p9+|Nr-;CIy9`sOP>Q<+XI(x<BT7w4IAzdc6J7
zdCqz3<l}rxZf~lc+-s<>{mlI69-Cu#x2fEG^I8O`IbuST)Up5aw?BQf2l6(Y*iy{}
zq!0X%2a*Q=*nuRGpkb%!&drIEK-Cc?HOxRqk_!&ZmynqGV&(DwA>VJu7G9cn-9Ex)
z-%^=bo9>7_cgpxTq2-kMan+l0#@7WOyMF(gCH3|5gR2~8+7~{w*cm?e(XaU;*Z057
z&W!M@EBc%LN2Vw&q3(|N@A<Dn{>E#r(fu{w!1aHyW|G;j`TKwV+ix=G`9b+#`+r?s
zr8ztMpTXa%^)Y*{{yhEf{nO2F^^e8ndMp3^ovC;3;OnAI>tDDPw`Xk)@T=PVQ}yVs
zzqQN%|1gw&XD!<Qdj9lZ>;J9$x8;BAuL5_e$iIgFSN+p<{rgaU<^NmnU)kI5+HJ>n
z;+6g}CVTt;_t($%{7Y`ojOrT=fzc2c4S~@R7!85Z5Fii&8zgEO|2Qt4#K54y004(2
BL%09{

literal 0
HcmV?d00001

diff --git a/tests/f_inode_ea_collision/name b/tests/f_inode_ea_collision/name
new file mode 100644
index 0000000..b64119e
--- /dev/null
+++ b/tests/f_inode_ea_collision/name
@@ -0,0 +1 @@
+collisions in the inode ea area


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 10/21] e2fsck: clear inline_data inode flag if EA missing
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (8 preceding siblings ...)
  2014-08-05  1:05 ` [PATCH 09/21] e2fsck: check ea-in-inode regions for overlap Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-08 22:44   ` [PATCH v2 " Darrick J. Wong
  2014-08-05  1:06 ` [PATCH 11/21] e2fsck: handle inline data symlinks Darrick J. Wong
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If i_size indicates that an inode requires a system.data extended
attribute to hold overflow from i_blocks but the EA cannot be found,
offer to truncate the file.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c   |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 e2fsck/problem.c |    5 +++++
 e2fsck/problem.h |    3 +++
 3 files changed, 64 insertions(+)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 172d664..74c70ca 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -959,6 +959,62 @@ void e2fsck_pass1(e2fsck_t ctx)
 			}
 		}
 
+		/* Test for inline data flag but no attr */
+		if ((inode->i_flags & EXT4_INLINE_DATA_FL) && inlinedata_fs &&
+		    EXT2_I_SIZE(inode) > EXT4_MIN_INLINE_DATA_SIZE &&
+		    (ino >= EXT2_FIRST_INODE(fs->super))) {
+			size_t size = 0;
+			errcode_t err;
+			int flags;
+
+			flags = fs->flags;
+			if (failed_csum)
+				fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+			err = ext2fs_inline_data_size(fs, ino, &size);
+			fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
+				    (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
+
+			switch (err) {
+			case 0:
+				/* Everything is awesome... */
+				break;
+			case EXT2_ET_BAD_EA_BLOCK_NUM:
+			case EXT2_ET_BAD_EA_HASH:
+			case EXT2_ET_BAD_EA_HEADER:
+			case EXT2_ET_EA_BAD_NAME_LEN:
+			case EXT2_ET_EA_BAD_VALUE_SIZE:
+			case EXT2_ET_EA_KEY_NOT_FOUND:
+			case EXT2_ET_EA_NO_SPACE:
+			case EXT2_ET_MISSING_EA_FEATURE:
+			case EXT2_ET_INLINE_DATA_CANT_ITERATE:
+			case EXT2_ET_INLINE_DATA_NO_BLOCK:
+			case EXT2_ET_INLINE_DATA_NO_SPACE:
+			case EXT2_ET_NO_INLINE_DATA:
+			case EXT2_ET_EXT_ATTR_CSUM_INVALID:
+			case EXT2_ET_EA_BAD_VALUE_OFFSET:
+				/* no system.data attr, so truncate file */
+				if (fix_problem(ctx, PR_1_INLINE_DATA_NO_ATTR,
+						&pctx)) {
+					err = ext2fs_inode_size_set(fs, inode,
+							sizeof(inode->i_block));
+					if (err) {
+						pctx.errcode = err;
+						ctx->flags |= E2F_FLAG_ABORT;
+						goto endit;
+					}
+					e2fsck_write_inode(ctx, ino, inode,
+							   "pass1");
+					failed_csum = 0;
+				}
+				break;
+			default:
+				/* Some other kind of non-xattr error? */
+				pctx.errcode = err;
+				ctx->flags |= E2F_FLAG_ABORT;
+				goto endit;
+			}
+		}
+
 		/*
 		 * Test for incorrect extent flag settings.
 		 *
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index b982a27..9081277 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1045,6 +1045,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@i %i logical @b %b (physical @b %c) violates cluster allocation rules.\nWill fix in pass 1B.\n"),
 	  PROMPT_NONE, 0 },
 
+	/* Inode has INLINE_DATA_FL flag but extended attribute not found */
+	{ PR_1_INLINE_DATA_NO_ATTR,
+	  N_("@i %i has INLINE_DATA_FL flag but @a not found.  "),
+	  PROMPT_TRUNCATE, 0 },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index f051c11..1f0be2d 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -609,6 +609,9 @@ struct problem_context {
 /* Inode logical block is misaligned */
 #define PR_1_MISALIGNED_CLUSTER		0x010074
 
+/* Inode has INLINE_DATA_FL flag but extended attribute not found */
+#define PR_1_INLINE_DATA_NO_ATTR	0x010075
+
 /*
  * Pass 1b errors
  */


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 11/21] e2fsck: handle inline data symlinks
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (9 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 10/21] e2fsck: clear inline_data inode flag if EA missing Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:38   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 12/21] e2fsck: check inline directory data "block" first Darrick J. Wong
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Perform some basic checks on inline-data symlinks.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 74c70ca..f7c1fbb 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -183,6 +183,8 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
 		return 0;
 
 	if (inode->i_flags & EXT4_EXTENTS_FL) {
+		if (inode->i_flags & EXT4_INLINE_DATA_FL)
+			return 0;
 		if (inode->i_size > fs->blocksize)
 			return 0;
 		if (ext2fs_extent_open2(fs, ino, inode, &handle))
@@ -217,6 +219,8 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
 
 	blocks = ext2fs_inode_data_blocks2(fs, inode);
 	if (blocks) {
+		if (inode->i_flags & EXT4_INLINE_DATA_FL)
+			return 0;
 		if ((inode->i_size >= fs->blocksize) ||
 		    (blocks != fs->blocksize >> 9) ||
 		    (inode->i_block[0] < fs->super->s_first_data_block) ||
@@ -233,6 +237,27 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
 		len = strnlen(buf, fs->blocksize);
 		if (len == fs->blocksize)
 			return 0;
+	} else if (inode->i_flags & EXT4_INLINE_DATA_FL) {
+		char *inline_buf = NULL;
+		size_t inline_sz = 0;
+
+		if (ext2fs_inline_data_size(fs, ino, &inline_sz))
+			return 0;
+		if (inode->i_size != inline_sz)
+			return 0;
+		if (ext2fs_get_mem(inline_sz + 1, &inline_buf))
+			return 0;
+		i = 0;
+		if (ext2fs_inline_data_get(fs, ino, inode, inline_buf, NULL))
+			goto exit_inline;
+		inline_buf[inline_sz] = 0;
+		len = strnlen(inline_buf, inline_sz);
+		if (len != inline_sz)
+			goto exit_inline;
+		i = 1;
+exit_inline:
+		ext2fs_free_mem(&inline_buf);
+		return i;
 	} else {
 		if (inode->i_size >= sizeof(inode->i_block))
 			return 0;


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 12/21] e2fsck: check inline directory data "block" first
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (10 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 11/21] e2fsck: handle inline data symlinks Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:40   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it Darrick J. Wong
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Since the inline data flag will cause the extent/block map iteration
code to abort fsck early, move the test for the inode flag and the
actual block check call further forward in check_blocks.  This
eliminates an e2fsck abort on an inline data symlink when the file ACL
block is set.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c |    8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index f7c1fbb..8bd08ee 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -2596,7 +2596,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		pb.num_blocks++;
 	}
 
-	if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
+	if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL))
+		check_blocks_inline_data(ctx, pctx, &pb);
+	else if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
 		if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
 			check_blocks_extents(ctx, pctx, &pb);
 		else {
@@ -2632,10 +2634,6 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 			fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
 				    (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
 		}
-	} else {
-		/* check inline data */
-		if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL))
-			check_blocks_inline_data(ctx, pctx, &pb);
 	}
 	end_problem_latch(ctx, PR_LATCH_BLOCK);
 	end_problem_latch(ctx, PR_LATCH_TOOBIG);


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (11 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 12/21] e2fsck: check inline directory data "block" first Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:40   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes Darrick J. Wong
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Inodes with inline_data set do not have iterable blocks, so don't try
to iterate the blocks, because that will just fail, causing e2fsck to
abort.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass2.c |    4 ++++
 1 file changed, 4 insertions(+)


diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 38bf37a..d56b4c8 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1441,6 +1441,10 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
 	if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
 		goto clear_inode;
 
+	/* Inline data inodes don't have blocks to iterate */
+	if (inode.i_flags & EXT4_INLINE_DATA_FL)
+		goto clear_inode;
+
 	if (LINUX_S_ISREG(inode.i_mode) &&
 	    ext2fs_needs_large_file_feature(EXT2_I_SIZE(&inode)))
 		ctx->large_files--;


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (12 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:41   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 15/21] e2fsck: fix conflicting extents|inlinedata inode flags Darrick J. Wong
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Since fifo, socket, and device inodes cannot have inline data or
extents, strip off these flags if we find them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c           |   22 ++++++++++++++++++++++
 e2fsck/problem.c         |    6 ++++++
 e2fsck/problem.h         |    3 +++
 tests/f_extents/expect.1 |    3 +++
 4 files changed, 34 insertions(+)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 8bd08ee..d41b230 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -272,6 +272,24 @@ exit_inline:
 }
 
 /*
+ * If the extents or inlinedata flags are set on the inode, offer to clear 'em.
+ */
+#define BAD_SPECIAL_FLAGS (EXT4_EXTENTS_FL | EXT4_INLINE_DATA_FL)
+static void check_extents_inlinedata(e2fsck_t ctx,
+				     struct problem_context *pctx)
+{
+	if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
+		return;
+
+	if (!fix_problem(ctx, PR_1_SPECIAL_EXTENTS_IDATA, pctx))
+		return;
+
+	pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
+	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
+}
+#undef BAD_SPECIAL_FLAGS
+
+/*
  * If the immutable (or append-only) flag is set on the inode, offer
  * to clear it.
  */
@@ -1396,11 +1414,13 @@ void e2fsck_pass1(e2fsck_t ctx)
 			ctx->fs_regular_count++;
 		} else if (LINUX_S_ISCHR (inode->i_mode) &&
 			   e2fsck_pass1_check_device_inode(fs, inode)) {
+			check_extents_inlinedata(ctx, &pctx);
 			check_immutable(ctx, &pctx);
 			check_size(ctx, &pctx);
 			ctx->fs_chardev_count++;
 		} else if (LINUX_S_ISBLK (inode->i_mode) &&
 			   e2fsck_pass1_check_device_inode(fs, inode)) {
+			check_extents_inlinedata(ctx, &pctx);
 			check_immutable(ctx, &pctx);
 			check_size(ctx, &pctx);
 			ctx->fs_blockdev_count++;
@@ -1421,11 +1441,13 @@ void e2fsck_pass1(e2fsck_t ctx)
 		}
 		else if (LINUX_S_ISFIFO (inode->i_mode) &&
 			 e2fsck_pass1_check_device_inode(fs, inode)) {
+			check_extents_inlinedata(ctx, &pctx);
 			check_immutable(ctx, &pctx);
 			check_size(ctx, &pctx);
 			ctx->fs_fifo_count++;
 		} else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
 			   e2fsck_pass1_check_device_inode(fs, inode)) {
+			check_extents_inlinedata(ctx, &pctx);
 			check_immutable(ctx, &pctx);
 			check_size(ctx, &pctx);
 			ctx->fs_sockets_count++;
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 9081277..26ee51b 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1050,6 +1050,12 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@i %i has INLINE_DATA_FL flag but @a not found.  "),
 	  PROMPT_TRUNCATE, 0 },
 
+	/* Extents/inlinedata flag set on a device or socket inode */
+	{ PR_1_SPECIAL_EXTENTS_IDATA,
+	  N_("Special (@v/socket/fifo) file (@i %i) has extents\n"
+	     "or inline-data flag set.  "),
+	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 1f0be2d..3c5e11a 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -612,6 +612,9 @@ struct problem_context {
 /* Inode has INLINE_DATA_FL flag but extended attribute not found */
 #define PR_1_INLINE_DATA_NO_ATTR	0x010075
 
+/* extents/inlinedata set on fifo/socket/device */
+#define PR_1_SPECIAL_EXTENTS_IDATA	0x010076
+
 /*
  * Pass 1b errors
  */
diff --git a/tests/f_extents/expect.1 b/tests/f_extents/expect.1
index 2abe32e..953162c 100644
--- a/tests/f_extents/expect.1
+++ b/tests/f_extents/expect.1
@@ -22,6 +22,9 @@ Clear inode? yes
 
 Inode 18, i_blocks is 2, should be 0.  Fix? yes
 
+Special (device/socket/fifo) file (inode 19) has extents
+or inline-data flag set.  Clear? yes
+
 Pass 2: Checking directory structure
 Entry 'fbad-flag' in / (2) has deleted/unused inode 18.  Clear? yes
 


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 15/21] e2fsck: fix conflicting extents|inlinedata inode flags
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (13 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-08 16:24   ` [PATCH v2 " Darrick J. Wong
  2014-08-05  1:06 ` [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories Darrick J. Wong
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If we come across an inode with the inline data and extents inode flag
set, try to figure out the correct flag settings from the contents of
i_block and i_size.  If i_blocks looks like an extent tree head, we'll
make it an extent inode; if it's small enough for inline data, set it
to that.  This leaves the weird gray area where there's no extent
tree but it's too big for the inode -- if /could/ be a block map,
change it to that; otherwise, just clear the inode.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c                     |  114 ++++++++++++++++++++++++++++++++++++
 e2fsck/problem.c                   |   20 ++++++
 e2fsck/problem.h                   |   12 ++++
 tests/f_idata_and_extents/expect.1 |   35 +++++++++++
 tests/f_idata_and_extents/expect.2 |    7 ++
 tests/f_idata_and_extents/image.gz |  Bin
 tests/f_idata_and_extents/name     |    1 
 7 files changed, 189 insertions(+)
 create mode 100644 tests/f_idata_and_extents/expect.1
 create mode 100644 tests/f_idata_and_extents/expect.2
 create mode 100644 tests/f_idata_and_extents/image.gz
 create mode 100644 tests/f_idata_and_extents/name


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index d41b230..b214f72 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -735,6 +735,108 @@ static void finish_processing_inode(e2fsck_t ctx, ext2_ino_t ino,
 			return; \
 	} while (0)
 
+static int could_be_block_map(ext2_filsys fs, struct ext2_inode *inode)
+{
+	__u32 x;
+	int i;
+
+	for (i = 0; i < EXT2_N_BLOCKS; i++) {
+		x = inode->i_block[i];
+#ifdef WORDS_BIGENDIAN
+		x = ext2fs_swab32(x);
+#endif
+		if (x >= ext2fs_blocks_count(fs->super))
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Figure out what to do with an inode that has both extents and inline data
+ * inode flags set.  Returns -1 if we decide to erase the inode, 0 otherwise.
+ */
+static int fix_inline_data_extents_file(e2fsck_t ctx,
+					ext2_ino_t ino,
+					struct ext2_inode *inode,
+					int inode_size,
+					struct problem_context *pctx)
+{
+	size_t max_inline_ea_size;
+	ext2_filsys fs = ctx->fs;
+	int dirty = 0;
+
+	/* Both feature flags not set?  Just run the regular checks */
+	if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				       EXT3_FEATURE_INCOMPAT_EXTENTS) &&
+	    !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_INCOMPAT_INLINE_DATA))
+		return 0;
+
+	/* Clear both flags if it's a special file */
+	if (LINUX_S_ISCHR(inode->i_mode) ||
+	    LINUX_S_ISBLK(inode->i_mode) ||
+	    LINUX_S_ISFIFO(inode->i_mode) ||
+	    LINUX_S_ISSOCK(inode->i_mode)) {
+		check_extents_inlinedata(ctx, pctx);
+		return 0;
+	}
+
+	/* If it looks like an extent tree, try to clear inlinedata */
+	if (ext2fs_extent_header_verify(inode->i_block,
+				 sizeof(inode->i_block)) == 0 &&
+	    fix_problem(ctx, PR_1_CLEAR_INLINE_DATA_FOR_EXTENT, pctx)) {
+		inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+		dirty = 1;
+		goto out;
+	}
+
+	/* If it looks short enough to be inline data, try to clear extents */
+	if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
+		max_inline_ea_size = EXT2_INODE_SIZE(fs->super) -
+				     (EXT2_GOOD_OLD_INODE_SIZE +
+				      ((struct ext2_inode_large *)inode)->i_extra_isize);
+	else
+		max_inline_ea_size = 0;
+	if (EXT2_I_SIZE(inode) <
+	    EXT4_MIN_INLINE_DATA_SIZE + max_inline_ea_size &&
+	    fix_problem(ctx, PR_1_CLEAR_EXTENT_FOR_INLINE_DATA, pctx)) {
+		inode->i_flags &= ~EXT4_EXTENTS_FL;
+		dirty = 1;
+		goto out;
+	}
+
+	/*
+	 * Too big for inline data, but no evidence of extent tree -
+	 * maybe it's a block map file?  If the mappings all look valid?
+	 */
+	if (could_be_block_map(fs, inode) &&
+	    fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS, pctx)) {
+		int i;
+
+#ifdef WORDS_BIGENDIAN
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			inode->i_block[i] = ext2fs_swab32(inode->i_block[i]);
+#endif
+
+		inode->i_flags &= ~(EXT4_EXTENTS_FL | EXT4_INLINE_DATA_FL);
+		dirty = 1;
+		goto out;
+	}
+
+	/* Oh well, just clear the busted inode. */
+	if (fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_INODE, pctx)) {
+		e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+		return -1;
+	}
+
+out:
+	if (dirty)
+		e2fsck_write_inode(ctx, ino, inode, "pass1");
+
+	return 0;
+}
+
 void e2fsck_pass1(e2fsck_t ctx)
 {
 	int	i;
@@ -983,6 +1085,18 @@ void e2fsck_pass1(e2fsck_t ctx)
 			}
 		}
 
+		/* Conflicting inlinedata/extents inode flags? */
+		if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
+		    (inode->i_flags & EXT4_EXTENTS_FL)) {
+			int res = fix_inline_data_extents_file(ctx, ino, inode,
+							       inode_size,
+							       &pctx);
+			if (res < 0) {
+				/* skip FINISH_INODE_LOOP */
+				continue;
+			}
+		}
+
 		/* Test for incorrect inline_data flags settings. */
 		if ((inode->i_flags & EXT4_INLINE_DATA_FL) && !inlinedata_fs &&
 		    (ino >= EXT2_FIRST_INODE(fs->super))) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 26ee51b..4245244 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1056,6 +1056,26 @@ static struct e2fsck_problem problem_table[] = {
 	     "or inline-data flag set.  "),
 	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
 
+	/* Inode has extent header but inline data flag is set */
+	{ PR_1_CLEAR_INLINE_DATA_FOR_EXTENT,
+	  N_("@i %i has @x header but inline data flag is set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode seems to have inline data but extent flag is set */
+	{ PR_1_CLEAR_EXTENT_FOR_INLINE_DATA,
+	  N_("@i %i seems to have inline data but @x flag is set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode seems to have block map but inline data and extent flags set */
+	{ PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS,
+	  N_("@i %i seems to have @b map but inline data and @x flags set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode has inline data and extent flags but i_block contains junk */
+	{ PR_1_CLEAR_EXTENT_INLINE_DATA_INODE,
+	  N_("@i %i has inline data and @x flags set but i_block contains junk.\n"),
+	  PROMPT_CLEAR_INODE, 0 },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 3c5e11a..22c86c5 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -615,6 +615,18 @@ struct problem_context {
 /* extents/inlinedata set on fifo/socket/device */
 #define PR_1_SPECIAL_EXTENTS_IDATA	0x010076
 
+/* idata/extent flag set and extent header found, clear idata flag */
+#define PR_1_CLEAR_INLINE_DATA_FOR_EXTENT	0x010077
+
+/* inlinedata/extent set and no extent header found, clear extent flag */
+#define PR_1_CLEAR_EXTENT_FOR_INLINE_DATA	0x010078
+
+/* inlinedata/extent set, clear both flags */
+#define PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS	0x010079
+
+/* inlinedata/extent set, clear inode */
+#define PR_1_CLEAR_EXTENT_INLINE_DATA_INODE	0x01007A
+
 /*
  * Pass 1b errors
  */
diff --git a/tests/f_idata_and_extents/expect.1 b/tests/f_idata_and_extents/expect.1
new file mode 100644
index 0000000..7f7fbf3
--- /dev/null
+++ b/tests/f_idata_and_extents/expect.1
@@ -0,0 +1,35 @@
+Pass 1: Checking inodes, blocks, and sizes
+Special (device/socket/fifo) file (inode 19) has extents
+or inline-data flag set.  Clear? yes
+
+Inode 20 has extent header but inline data flag is set.
+Fix? yes
+
+Inode 21 has inline data and extent flags set but i_block contains junk.
+Clear inode? yes
+
+Inode 22 seems to have block map but inline data and extent flags set.
+Fix? yes
+
+Inode 23 seems to have inline data but extent flag is set.
+Fix? yes
+
+Pass 2: Checking directory structure
+Entry 'garbage' in /bad (18) has deleted/unused inode 21.  Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Inode bitmap differences:  -21
+Fix? yes
+
+Free inodes count wrong for group #0 (105, counted=106).
+Fix? yes
+
+Free inodes count wrong (105, counted=106).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 22/128 files (0.0% non-contiguous), 21/512 blocks
+Exit status is 1
diff --git a/tests/f_idata_and_extents/expect.2 b/tests/f_idata_and_extents/expect.2
new file mode 100644
index 0000000..307d3f6
--- /dev/null
+++ b/tests/f_idata_and_extents/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: 22/128 files (0.0% non-contiguous), 21/512 blocks
+Exit status is 0
diff --git a/tests/f_idata_and_extents/image.gz b/tests/f_idata_and_extents/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..5187ba14138568a1ccd3540228b092f93186d109
GIT binary patch
literal 3112
zcmeIxT})GV7zXg8MnQ}yL5)$cYIMvfWdxZDVk1r*0)wDisaDj2pi(Rf43x4HC)Fun
zCtre9kJy#LfMTs+3qtD#fz6NdS)fH4C~c)sTPPMzdwTxE>)m*<%f2^H-sF95e#uM7
zb%u_;tU9uAkwJ0dZ1EWn$fOGjZ1hhItkO8eev|1onDFg&H`d}~&zxz`SJRXE0`dO0
zZ2jh9;)@#2&zl>gZjRL6%%+!K?mFlkay7m)&t=<=%10YdH_P@IF9lwBSpUYaN5#No
z<`&%xWh!oLH)ATH`@$5i!kutwQ%yJrDO}ko)TL5Z?HV|8e#s4|<8UbVi@e(n_`RGo
z^ON&upQKMRwo;nDJU&?ZwU>oux}<2q$M829LEY26FPSpyfh3jQ8zxLNd|Xa7P>mkU
zC!I5sB{o-J>TBuW@UDLQQcmyz{)}R7ul67Pj91wh%3Q~Ja0P;1UyH$sq3YW-yXt|w
z0)<abxF8b7iUklP1*-R>*HZ)uYa}Zm2%?%t0azbgkmSlUF5H<z<%`8Lp2KI#_w_3!
z*{2M0+%wyAs(vj>CByI`?5#90-(PHLa3wsR?@IkIbgh~NU1*5SX@2FeU)(ew&=6Sk
zDL#Lsef|N~!-E0yjg;o8rOuz<{Ldw5`=k7&Tp+qL-C|0yMmdj|Os6Kg%A<>7DJ%82
zl23H-*dHZcn@AsK3wEB@J_3E`^6u~Dw2Cq>gxd2Pz*SV3$grj`d$y?If_&KTc_lrl
zjD~GTZg{M&ysZ}CVy_&(zcl?Yv8F?hd=+YUPeL${K2jWRH4LY_*MXtPzDf`qp*(U9
zM-qHX;EE`u*896SN@ZlD?Mjm^AW*SH5iAnN>?4K;WUNTDEYInT8A>?aJ*)&&nWdXB
zFf}(?vRwmD<&u0_cMH=EoTP5-5I$!`1(>;>$2G+?WLNbUT>o`U*<&dg&8m!ORK%WT
zOz878bWvchCf8WbP1W6^k(M1cR@H!OSz+zI^5zIiQNElddR8lu{8VAfOk`n){$&4t
z>yBJ103zl#a8t>a!NgWf?V5`+I%uO9nLOlP*azx+CgaFFEGzOpG2|XRNg|RbtONv%
zk3<*AfNwuf_&zR!g)K7<;h}k@!0rnQRivZ!m{3@?)i4{i&igI`csx$RaC`1*Hpr?D
zvGi~F#m&Y}{+<p0XrGPu^#uYmtX12?il>2ADX0C`PO=d0R$m5$cCZ^fc>S1()xDCJ
ztnn!hQ|q5T6##i!cAMy8=4(MMhaif^QOVspwwq4EZ8HOU^f^r8J&{F!NO{O-?BH;I
zsF2l`(T0#oj1(}Ao+OtVP_Unc<sxvr4zyy`yYS?WX(S%=3HQe%GlH>{05maG%G9U|
zH7dV@IG4-K_cN%u<6}tv0&_8ZKcmHi*cOk<w6Sw)7nF4Il%{0u#bFK`Q(t~p<OwRa
z@xfp(e4u9!PFbFb&XHMGpY$!&c6PYPsg#2n$1`lh{G&i8$x>7E24H%15FotLw#2z>
zrQ*LqnG4!3uA60=wQB`npwaKsKRL!B;1F;KI0PI54uSt&K&v3N2~T{0ppDSKYUGCn

literal 0
HcmV?d00001

diff --git a/tests/f_idata_and_extents/name b/tests/f_idata_and_extents/name
new file mode 100644
index 0000000..362ce0e
--- /dev/null
+++ b/tests/f_idata_and_extents/name
@@ -0,0 +1 @@
+conflicting extents and inline_data inode flags


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (14 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 15/21] e2fsck: fix conflicting extents|inlinedata inode flags Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:44   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 17/21] e2fsck: use the correct block size when salvaging directories Darrick J. Wong
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If we encounter a directory whose i_size != the inline data size, just
set i_size to the size of the inline data.  The pb.last_block
calculation is wrong since pb.last_block == -1, which results in
i_size being set to zero, which corrupts the directory.

Clear the inline_data inode flag if we actually /are/ setting i_size
to zero.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index b214f72..1a9e0d5 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -2832,17 +2832,21 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		if (inode->i_flags & EXT4_INLINE_DATA_FL) {
 			int flags;
 			size_t size;
+			errcode_t err;
 
+			size = 0;
 			flags = ctx->fs->flags;
 			ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
-			if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
-				bad_size = 5;
+			err = ext2fs_inline_data_size(ctx->fs, pctx->ino,
+						      &size);
 			ctx->fs->flags = (flags &
 					  EXT2_FLAG_IGNORE_CSUM_ERRORS) |
 					 (ctx->fs->flags &
 					  ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
-			if (size != inode->i_size)
-				bad_size = 5;
+			if (err || size != inode->i_size) {
+				bad_size = 7;
+				pctx->num = size;
+			}
 		} else if (inode->i_size & (fs->blocksize - 1))
 			bad_size = 5;
 		else if (nblock > (pb.last_block + 1))
@@ -2875,12 +2879,20 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	}
 	/* i_size for symlinks is checked elsewhere */
 	if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
-		pctx->num = (pb.last_block+1) * fs->blocksize;
+		/* Did inline_data set pctx->num earlier? */
+		if (bad_size != 7)
+			pctx->num = (pb.last_block + 1) * fs->blocksize;
 		pctx->group = bad_size;
 		if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
 			if (LINUX_S_ISDIR(inode->i_mode))
 				pctx->num &= 0xFFFFFFFFULL;
 			ext2fs_inode_size_set(fs, inode, pctx->num);
+			if (EXT2_I_SIZE(inode) == 0 &&
+			    (inode->i_flags & EXT4_INLINE_DATA_FL)) {
+				memset(inode->i_block, 0,
+				       sizeof(inode->i_block));
+				inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+			}
 			dirty_inode++;
 		}
 		pctx->num = 0;


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 17/21] e2fsck: use the correct block size when salvaging directories
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (15 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:45   ` Theodore Ts'o
  2014-08-05  1:06 ` [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4 Darrick J. Wong
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Now that the directory salvaging operation is fed the block size,
teach pass 2 that it should use the size of the inline data if the
directory is inline_data.  Without this, it'll "fix" inline
directories by setting the rec_len to something approaching the FS
blocksize, which is clearly wrong.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass2.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)


diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index d56b4c8..abf95bd 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -979,11 +979,17 @@ skip_checksum:
 
 		problem = 0;
 		if (!inline_data_size || dot_state > 1) {
+			size_t max_block_size = fs->blocksize - de_csum_size;
+
+			if (inline_data_size)
+				max_block_size = inline_data_size;
 			dirent = (struct ext2_dir_entry *) (buf + offset);
 			(void) ext2fs_get_rec_len(fs, dirent, &rec_len);
 			cd->pctx.dirent = dirent;
 			cd->pctx.num = offset;
 			if (((offset + rec_len) > fs->blocksize) ||
+			    (inline_data_size > 0 &&
+			     (offset + rec_len) > inline_data_size) ||
 			    (rec_len < 12) ||
 			    ((rec_len % 4) != 0) ||
 			    ((ext2fs_dirent_name_len(dirent) + 8) > rec_len)) {
@@ -991,8 +997,7 @@ skip_checksum:
 						&cd->pctx)) {
 					salvage_directory(fs, dirent, prev,
 							  &offset,
-							  fs->blocksize -
-							  de_csum_size);
+							  max_block_size);
 					dir_modified++;
 					continue;
 				} else


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (16 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 17/21] e2fsck: use the correct block size when salvaging directories Darrick J. Wong
@ 2014-08-05  1:06 ` Darrick J. Wong
  2014-08-10 22:47   ` Theodore Ts'o
  2014-08-05  1:07 ` [PATCH 19/21] e2fsck: be more careful in assuming inline_data inodes are directories Darrick J. Wong
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:06 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Directory entries must have a size that's a multiple of 4; therefore
the inline directory structure must also have a size that is a muliple
of 4.  Since e2fsck doesn't check this, we should check that now.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass2.c   |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 e2fsck/problem.c |   10 ++++++++
 e2fsck/problem.h |    6 +++++
 3 files changed, 80 insertions(+)


diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index abf95bd..ed2c4d7 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -772,6 +772,59 @@ static errcode_t insert_dirent_tail(ext2_filsys fs, void *dirbuf)
 }
 #undef NEXT_DIRENT
 
+static errcode_t fix_inline_dir_size(e2fsck_t ctx, ext2_ino_t ino,
+				     size_t *inline_data_size,
+				     struct problem_context *pctx,
+				     char *buf)
+{
+	ext2_filsys fs = ctx->fs;
+	struct ext2_inode inode;
+	size_t new_size, old_size;
+	errcode_t retval;
+
+	old_size = *inline_data_size;
+	new_size = old_size + (4 - (old_size & 3));
+	memset(buf + old_size, 0, new_size - old_size);
+	retval = ext2fs_inline_data_set(fs, ino, 0, buf, new_size);
+	if (retval == EXT2_ET_INLINE_DATA_NO_SPACE) {
+		new_size -= 4;
+		retval = ext2fs_inline_data_set(fs, ino, 0, buf, new_size);
+		if (retval) {
+			if (fix_problem(ctx, PR_2_FIX_INLINE_DIR_FAILED,
+					pctx)) {
+				new_size = 0;
+				goto write_inode;
+			}
+			goto err;
+		}
+	} else if (retval) {
+		if (fix_problem(ctx, PR_2_FIX_INLINE_DIR_FAILED,
+				pctx)) {
+			new_size = 0;
+			goto write_inode;
+		}
+		goto err;
+	}
+
+write_inode:
+	retval = ext2fs_read_inode(fs, ino, &inode);
+	if (retval)
+		goto err;
+
+	retval = ext2fs_inode_size_set(fs, &inode, new_size);
+	if (retval)
+		goto err;
+	if (new_size == 0)
+		inode.i_flags &= ~EXT4_INLINE_DATA_FL;
+	retval = ext2fs_write_inode(fs, ino, &inode);
+	if (retval)
+		goto err;
+	*inline_data_size = new_size;
+
+err:
+	return retval;
+}
+
 static int check_dir_block(ext2_filsys fs,
 			   struct ext2_db_entry2 *db,
 			   void *priv_data)
@@ -885,6 +938,17 @@ static int check_dir_block(ext2_filsys fs,
 		cd->pctx.errcode = ext2fs_read_dir_block4(fs, block_nr,
 							  buf, 0, ino);
 inline_read_fail:
+	pctx.ino = ino;
+	pctx.num = inline_data_size;
+	if ((inline_data_size & 3) &&
+	    fix_problem(ctx, PR_2_BAD_INLINE_DIR_SIZE, &pctx)) {
+		errcode_t err = fix_inline_dir_size(ctx, ino,
+						    &inline_data_size, &pctx,
+						    buf);
+		if (err)
+			return DIRENT_ABORT;
+
+	}
 	ehandler_operation(0);
 	if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
 		cd->pctx.errcode = 0; /* We'll handle this ourselves */
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 4245244..4f975e5 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1523,6 +1523,16 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@d @i %i, %B, offset %N: @d passes checks but fails checksum.\n"),
 	  PROMPT_FIX, PR_PREEN_OK },
 
+	/* inline directory inode size must be a multiple of 4 */
+	{ PR_2_BAD_INLINE_DIR_SIZE,
+	  N_("Inline @d @i %i size (%N) must be a multiple of 4.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* fixing size of inline directory inode failed */
+	{ PR_2_FIX_INLINE_DIR_FAILED,
+	  N_("Fixing size of inline @d @i %i failed.\n"),
+	  PROMPT_TRUNCATE, 0 },
+
 	/* Pass 3 errors */
 
 	/* Pass 3: Checking directory connectivity */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 22c86c5..e901c8e 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -906,6 +906,12 @@ struct problem_context {
 /* dir leaf node passes checks, but fails checksum */
 #define PR_2_LEAF_NODE_ONLY_CSUM_INVALID	0x02004D
 
+/* bad inline directory size */
+#define PR_2_BAD_INLINE_DIR_SIZE	0x02004E
+
+/* fixing inline dir size failed */
+#define PR_2_FIX_INLINE_DIR_FAILED	0x02004F
+
 /*
  * Pass 3 errors
  */


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 19/21] e2fsck: be more careful in assuming inline_data inodes are directories
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (17 preceding siblings ...)
  2014-08-05  1:06 ` [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4 Darrick J. Wong
@ 2014-08-05  1:07 ` Darrick J. Wong
  2014-08-08 16:22   ` [PATCH v2 " Darrick J. Wong
  2014-08-05  1:07 ` [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir Darrick J. Wong
  2014-08-05  1:07 ` [PATCH 21/21] tests: add regression tests for inlinedata fixes Darrick J. Wong
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:07 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

If a file is marked inline_data but its i_size isn't a multiple of
four, it probably isn't an inline directory, because directory entries
have sizes that are multiples of four.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c |    7 +++++++
 1 file changed, 7 insertions(+)


diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 1a9e0d5..245a755 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -536,10 +536,17 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
 	inlinedata_fs = (ctx->fs->super->s_feature_incompat &
 			 EXT4_FEATURE_INCOMPAT_INLINE_DATA);
 	if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL)) {
+		int flags;
 		size_t size;
 
 		if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
 			return;
+		/*
+		 * If the size isn't a multiple of 4, it's probably not a
+		 * directory??
+		 */
+		if (size & 3)
+			return;
 		/* device files never have a "system.data" entry */
 		goto isdir;
 	} else if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (18 preceding siblings ...)
  2014-08-05  1:07 ` [PATCH 19/21] e2fsck: be more careful in assuming inline_data inodes are directories Darrick J. Wong
@ 2014-08-05  1:07 ` Darrick J. Wong
  2014-08-10 22:50   ` Theodore Ts'o
  2014-08-05  1:07 ` [PATCH 21/21] tests: add regression tests for inlinedata fixes Darrick J. Wong
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:07 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

In an inline directory, the '..' entry is compacted down to just the
inode number; there is no full '..' entry.  Therefore, it makes no
sense to assign 'prev' to the fake dotdot entry we put on the stack,
as this could confuse a salvage_directory call on a corrupted next
entry into modifying stack contents (the fake dotdot entry).

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass2.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)


diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index ed2c4d7..fb98af5 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1330,8 +1330,19 @@ skip_checksum:
 		if (!inline_data_size || dot_state > 1) {
 			offset += rec_len;
 		} else {
-			if (dot_state == 1)
+			if (dot_state == 1) {
 				offset = 4;
+				/*
+				 * If we get here, we're checking an inline
+				 * directory and we've just checked a (fake)
+				 * dotdot entry that we created on the stack.
+				 * Therefore set 'prev' to NULL so that if we
+				 * call salvage_directory on the next entry,
+				 * it won't try to absorb the next entry into
+				 * the on-stack dotdot entry.
+				 */
+				prev = NULL;
+			}
 		}
 		dot_state++;
 	} while (is_last_entry(fs, inline_data_size, offset, de_csum_size));


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH 21/21] tests: add regression tests for inlinedata fixes
  2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
                   ` (19 preceding siblings ...)
  2014-08-05  1:07 ` [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir Darrick J. Wong
@ 2014-08-05  1:07 ` Darrick J. Wong
  2014-08-08 22:47   ` [PATCH v2 " Darrick J. Wong
  20 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-05  1:07 UTC (permalink / raw)
  To: tytso, darrick.wong; +Cc: linux-ext4

Add a regression test to ensure that previous patches' fixes to e2fsck
do not revert.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/f_inlinedata_repair/expect.1 |   78 ++++++++++++++++++++++++++++++++++++
 tests/f_inlinedata_repair/expect.2 |   33 +++++++++++++++
 tests/f_inlinedata_repair/image.gz |  Bin
 tests/f_inlinedata_repair/name     |    1 
 4 files changed, 112 insertions(+)
 create mode 100644 tests/f_inlinedata_repair/expect.1
 create mode 100644 tests/f_inlinedata_repair/expect.2
 create mode 100644 tests/f_inlinedata_repair/image.gz
 create mode 100644 tests/f_inlinedata_repair/name


diff --git a/tests/f_inlinedata_repair/expect.1 b/tests/f_inlinedata_repair/expect.1
new file mode 100644
index 0000000..a91ce76
--- /dev/null
+++ b/tests/f_inlinedata_repair/expect.1
@@ -0,0 +1,78 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has INLINE_DATA_FL flag but extended attribute not found.  Truncate? yes
+
+Inode 16, i_size is 56, should be 60.  Fix? yes
+
+Inode 24, i_size is 59, should be 60.  Fix? yes
+
+Inode 28 is a unknown file type with mode 00 but it looks like it is really a directory.
+Fix? yes
+
+Inode 36 is a unknown file type with mode 00 but it looks like it is really a directory.
+Fix? yes
+
+Inode 36, i_size is 5, should be 60.  Fix? yes
+
+Pass 2: Checking directory structure
+Directory inode 20, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 28, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 32, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 32, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Entry '..' in ??? (36) has invalid inode #: 1633774699.
+Clear? yes
+
+Directory inode 36, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Symlink /1 (inode #12) is invalid.
+Clear? yes
+
+Symlink /3 (inode #14) is invalid.
+Clear? yes
+
+Inode 38 (/B) has invalid mode (00).
+Clear? yes
+
+Entry 'A' in / (2) has an incorrect filetype (was 1, should be 2).
+Fix? yes
+
+Pass 3: Checking directory connectivity
+'..' in /A (36) is ??? (1633774699), should be / (2).
+Fix? yes
+
+Error while adjusting inode count on inode 0
+Pass 4: Checking reference counts
+Unattached zero-length inode 22.  Clear? yes
+
+Unattached zero-length inode 23.  Clear? yes
+
+Unattached zero-length inode 29.  Clear? yes
+
+Unattached zero-length inode 30.  Clear? yes
+
+Unattached zero-length inode 31.  Clear? yes
+
+Unattached zero-length inode 33.  Clear? yes
+
+Unattached zero-length inode 34.  Clear? yes
+
+Unattached zero-length inode 35.  Clear? yes
+
+Inode 36 ref count is 1, should be 2.  Fix? yes
+
+Pass 5: Checking group summary information
+Directories count wrong for group #0 (7, counted=8).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 27/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 1
diff --git a/tests/f_inlinedata_repair/expect.2 b/tests/f_inlinedata_repair/expect.2
new file mode 100644
index 0000000..941241d
--- /dev/null
+++ b/tests/f_inlinedata_repair/expect.2
@@ -0,0 +1,33 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 20, i_size is 60, should be 0.  Fix? yes
+
+Inode 28, i_size is 60, should be 0.  Fix? yes
+
+Inode 32, i_size is 60, should be 0.  Fix? yes
+
+Inode 36, i_size is 60, should be 0.  Fix? yes
+
+Pass 2: Checking directory structure
+Directory inode 20 has an unallocated block #0.  Allocate? yes
+
+Directory inode 28 has an unallocated block #0.  Allocate? yes
+
+Directory inode 32 has an unallocated block #0.  Allocate? yes
+
+Directory inode 36 has an unallocated block #0.  Allocate? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Unattached zero-length inode 21.  Clear? yes
+
+Pass 5: Checking group summary information
+Free blocks count wrong for group #0 (494, counted=490).
+Fix? yes
+
+Free blocks count wrong (494, counted=490).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 26/128 files (0.0% non-contiguous), 22/512 blocks
+Exit status is 1
diff --git a/tests/f_inlinedata_repair/image.gz b/tests/f_inlinedata_repair/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..c33d81dc60f828c89c9b743e64e0b9cf4224da1f
GIT binary patch
literal 3201
zcmeH}TToMX5XOV3SS*O*jEG_=Sfruc3K|e0RjE{iqQyW6AO%r`D1m}NDR8{uSS&JA
z>J5PmD#aMWCEN|+R4qmWns#Cg;6Nymq(IU@0*Qy5oPXm>-<)y!oPF8-cD|jR`OQ8o
z{_+akvzp=PCD!Uu^2x&#C!5&-v0KO5vNL66=O&KsT;dt#>b%s^eUBqOqiFnch84cO
zoYt{?ooAIpqQfrg>J+~<u|DO_cigyHM-#g5hxcE-7@pYTx~H=6MNLSuXX*M8ns87f
zEz;FYMJn}>rut?`7cqUsmv=^f_9^=$Va;o1slzLU%vW)BG?~oex1_b?xW+^~IZvZ(
zhl$b0t3sBC3{+5_8rxB!cF4YW{UgQD^^N@RP5F2Zrd1PTRan;Z3XL5Iy*59u2eP<Z
zV<hO$vq#zXr@S-!Kp$TR`(B{bai|YCUkD0ru7hpei{Ri_HMNB}T=lYaLw-ynn`;6c
z$r+vbH10OlSel&`4)<FR<6eC*`a19;(*}pbdGO~Ap!1-ok9~cP)yS^a?t<*8jbp)e
z9o;NVJ@(ax#UuZy4|E+f)D#x0#JV}VR?$<zKng=7AU+8TfK<1*0zx_CN^xdb-=}wT
zQpxh%rrC2vy>5CsS^mg{yt{ilzWIu&it3_{wjK2~%=ap0?aW(WrjC3T2DZRm@g%c4
zNIXtkX3pcfcPcB>YtvqEhal054qyz*{?e_(q@{0jX;b>zzA*O3K@ZIyzbWL+5_A55
z_%hU~EEAvSVz%D%y>jLQCf;Ys@+cYdABt<*BQy!73;Y8vkn`>G`nU~;>*Hw?u`JQ0
z>zs&{bv+YG+t#Wl$%rn+C9M5qe2m(}FYm<8wxtbhm`efoS04c@kr~<F`#0qAv&y9K
zUz**Wwvj)X(m~qP*G8z{k0=8lxvRk4Vx}T{1OzXjzMBwOw@PhS=dMr6v(IZ9qz|zr
zgMrRY=WSN`7>(^lsLcj?o}o)5{yN!^jp!9D!|~z+C43$mrnkpMERGU%vf5a0M3h>(
z<FGeiD~qcsgUoBpCzEQ@YDDuw*DR#>c7ewdEzD!2#rQ+C66dH?Osh|-k+v9szY^N4
zU=}_=VGbI=zCrRPm2V+Hi)h!5F@1DGW{<ELnpDfGlX$K%@h1qmp$oY;u2%4*j1_J2
zf}I<iWi8piPd0HnP0%oQEQYDU+`LH(awMu3P_-3r&J*{U-k_68h`cQ$bo-*z7(suI
z_Zq+(!}(x;I3{r30pyiIP!;Hs1OeYj<4OdD@1<Z#3CA$fA#ZTn+Sry+IK%!NQY{1m
zX5&_<@m)EOCP~K;o<}wo2pF7fEa{s$3`*}u;YJ|}-KSxFr){_o(!|m@Y-lDOBPG%?
z>br6Zk&TWc(x?e^FGmBe3#w{Gz>A;&C_xA9?m$EEZ#~$RTB!h)QU99&k>{0A-WnyT
z(geKPIu2EVSjr$Mr6@p-L<?~h-}Z3PR;d_;N?sx}as*~Q)EOct&}Y9;1ry(aA5W{+
z3LvKJr9`q_D9~`O!F<>-d)vCXVc$Sh@ogpO=PeHr2m7&@1!%tNHS|M-fZh;_@j51z
zkK;l2HVUm|+OfwZo&(w*l0XF3!*U?Q_}YGPCMea7J)8c6dnz4a;boZ1@QKBsQ@{~i
kvVPxvTly9P76KLm76KLm76Sj9z-C~@tUY1=!Ci6x0)&jPy8r+H

literal 0
HcmV?d00001

diff --git a/tests/f_inlinedata_repair/name b/tests/f_inlinedata_repair/name
new file mode 100644
index 0000000..7e7e898
--- /dev/null
+++ b/tests/f_inlinedata_repair/name
@@ -0,0 +1 @@
+repair corrupt inline data files


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 19/21] e2fsck: be more careful in assuming inline_data inodes are directories
  2014-08-05  1:07 ` [PATCH 19/21] e2fsck: be more careful in assuming inline_data inodes are directories Darrick J. Wong
@ 2014-08-08 16:22   ` Darrick J. Wong
  2014-08-10 22:49     ` Theodore Ts'o
  0 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 16:22 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

If a file is marked inline_data but its i_size isn't a multiple of
four, it probably isn't an inline directory, because directory entries
have sizes that are multiples of four.

v2: Don't add unnecessary variables.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index ce373f3..8cff18d 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -540,6 +540,12 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
 
 		if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
 			return;
+		/*
+		 * If the size isn't a multiple of 4, it's probably not a
+		 * directory??
+		 */
+		if (size & 3)
+			return;
 		/* device files never have a "system.data" entry */
 		goto isdir;
 	} else if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 15/21] e2fsck: fix conflicting extents|inlinedata inode flags
  2014-08-05  1:06 ` [PATCH 15/21] e2fsck: fix conflicting extents|inlinedata inode flags Darrick J. Wong
@ 2014-08-08 16:24   ` Darrick J. Wong
  2014-08-10 22:43     ` Theodore Ts'o
  0 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 16:24 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

If we come across an inode with the inline data and extents inode flag
set, try to figure out the correct flag settings from the contents of
i_block and i_size.  If i_blocks looks like an extent tree head, we'll
make it an extent inode; if it's small enough for inline data, set it
to that.  This leaves the weird gray area where there's no extent
tree but it's too big for the inode -- if /could/ be a block map,
change it to that; otherwise, just clear the inode.

v2: Don't add unnecessary variables.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c                     |  114 ++++++++++++++++++++++++++++++++++++
 e2fsck/problem.c                   |   20 ++++++
 e2fsck/problem.h                   |   12 ++++
 tests/f_idata_and_extents/expect.1 |   35 +++++++++++
 tests/f_idata_and_extents/expect.2 |    7 ++
 tests/f_idata_and_extents/image.gz |  Bin
 tests/f_idata_and_extents/name     |    1 
 7 files changed, 189 insertions(+)
 create mode 100644 tests/f_idata_and_extents/expect.1
 create mode 100644 tests/f_idata_and_extents/expect.2
 create mode 100644 tests/f_idata_and_extents/image.gz
 create mode 100644 tests/f_idata_and_extents/name

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index d41b230..b8ab94a 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -735,6 +735,108 @@ static void finish_processing_inode(e2fsck_t ctx, ext2_ino_t ino,
 			return; \
 	} while (0)
 
+static int could_be_block_map(ext2_filsys fs, struct ext2_inode *inode)
+{
+	__u32 x;
+	int i;
+
+	for (i = 0; i < EXT2_N_BLOCKS; i++) {
+		x = inode->i_block[i];
+#ifdef WORDS_BIGENDIAN
+		x = ext2fs_swab32(x);
+#endif
+		if (x >= ext2fs_blocks_count(fs->super))
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Figure out what to do with an inode that has both extents and inline data
+ * inode flags set.  Returns -1 if we decide to erase the inode, 0 otherwise.
+ */
+static int fix_inline_data_extents_file(e2fsck_t ctx,
+					ext2_ino_t ino,
+					struct ext2_inode *inode,
+					int inode_size,
+					struct problem_context *pctx)
+{
+	size_t max_inline_ea_size;
+	ext2_filsys fs = ctx->fs;
+	int dirty = 0;
+
+	/* Both feature flags not set?  Just run the regular checks */
+	if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				       EXT3_FEATURE_INCOMPAT_EXTENTS) &&
+	    !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_INCOMPAT_INLINE_DATA))
+		return 0;
+
+	/* Clear both flags if it's a special file */
+	if (LINUX_S_ISCHR(inode->i_mode) ||
+	    LINUX_S_ISBLK(inode->i_mode) ||
+	    LINUX_S_ISFIFO(inode->i_mode) ||
+	    LINUX_S_ISSOCK(inode->i_mode)) {
+		check_extents_inlinedata(ctx, pctx);
+		return 0;
+	}
+
+	/* If it looks like an extent tree, try to clear inlinedata */
+	if (ext2fs_extent_header_verify(inode->i_block,
+				 sizeof(inode->i_block)) == 0 &&
+	    fix_problem(ctx, PR_1_CLEAR_INLINE_DATA_FOR_EXTENT, pctx)) {
+		inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+		dirty = 1;
+		goto out;
+	}
+
+	/* If it looks short enough to be inline data, try to clear extents */
+	if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
+		max_inline_ea_size = EXT2_INODE_SIZE(fs->super) -
+				     (EXT2_GOOD_OLD_INODE_SIZE +
+				      ((struct ext2_inode_large *)inode)->i_extra_isize);
+	else
+		max_inline_ea_size = 0;
+	if (EXT2_I_SIZE(inode) <
+	    EXT4_MIN_INLINE_DATA_SIZE + max_inline_ea_size &&
+	    fix_problem(ctx, PR_1_CLEAR_EXTENT_FOR_INLINE_DATA, pctx)) {
+		inode->i_flags &= ~EXT4_EXTENTS_FL;
+		dirty = 1;
+		goto out;
+	}
+
+	/*
+	 * Too big for inline data, but no evidence of extent tree -
+	 * maybe it's a block map file?  If the mappings all look valid?
+	 */
+	if (could_be_block_map(fs, inode) &&
+	    fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS, pctx)) {
+#ifdef WORDS_BIGENDIAN
+		int i;
+
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			inode->i_block[i] = ext2fs_swab32(inode->i_block[i]);
+#endif
+
+		inode->i_flags &= ~(EXT4_EXTENTS_FL | EXT4_INLINE_DATA_FL);
+		dirty = 1;
+		goto out;
+	}
+
+	/* Oh well, just clear the busted inode. */
+	if (fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_INODE, pctx)) {
+		e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+		return -1;
+	}
+
+out:
+	if (dirty)
+		e2fsck_write_inode(ctx, ino, inode, "pass1");
+
+	return 0;
+}
+
 void e2fsck_pass1(e2fsck_t ctx)
 {
 	int	i;
@@ -983,6 +1085,18 @@ void e2fsck_pass1(e2fsck_t ctx)
 			}
 		}
 
+		/* Conflicting inlinedata/extents inode flags? */
+		if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
+		    (inode->i_flags & EXT4_EXTENTS_FL)) {
+			int res = fix_inline_data_extents_file(ctx, ino, inode,
+							       inode_size,
+							       &pctx);
+			if (res < 0) {
+				/* skip FINISH_INODE_LOOP */
+				continue;
+			}
+		}
+
 		/* Test for incorrect inline_data flags settings. */
 		if ((inode->i_flags & EXT4_INLINE_DATA_FL) && !inlinedata_fs &&
 		    (ino >= EXT2_FIRST_INODE(fs->super))) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 26ee51b..4245244 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1056,6 +1056,26 @@ static struct e2fsck_problem problem_table[] = {
 	     "or inline-data flag set.  "),
 	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
 
+	/* Inode has extent header but inline data flag is set */
+	{ PR_1_CLEAR_INLINE_DATA_FOR_EXTENT,
+	  N_("@i %i has @x header but inline data flag is set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode seems to have inline data but extent flag is set */
+	{ PR_1_CLEAR_EXTENT_FOR_INLINE_DATA,
+	  N_("@i %i seems to have inline data but @x flag is set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode seems to have block map but inline data and extent flags set */
+	{ PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS,
+	  N_("@i %i seems to have @b map but inline data and @x flags set.\n"),
+	  PROMPT_FIX, 0 },
+
+	/* Inode has inline data and extent flags but i_block contains junk */
+	{ PR_1_CLEAR_EXTENT_INLINE_DATA_INODE,
+	  N_("@i %i has inline data and @x flags set but i_block contains junk.\n"),
+	  PROMPT_CLEAR_INODE, 0 },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 3c5e11a..22c86c5 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -615,6 +615,18 @@ struct problem_context {
 /* extents/inlinedata set on fifo/socket/device */
 #define PR_1_SPECIAL_EXTENTS_IDATA	0x010076
 
+/* idata/extent flag set and extent header found, clear idata flag */
+#define PR_1_CLEAR_INLINE_DATA_FOR_EXTENT	0x010077
+
+/* inlinedata/extent set and no extent header found, clear extent flag */
+#define PR_1_CLEAR_EXTENT_FOR_INLINE_DATA	0x010078
+
+/* inlinedata/extent set, clear both flags */
+#define PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS	0x010079
+
+/* inlinedata/extent set, clear inode */
+#define PR_1_CLEAR_EXTENT_INLINE_DATA_INODE	0x01007A
+
 /*
  * Pass 1b errors
  */
diff --git a/tests/f_idata_and_extents/expect.1 b/tests/f_idata_and_extents/expect.1
new file mode 100644
index 0000000..7f7fbf3
--- /dev/null
+++ b/tests/f_idata_and_extents/expect.1
@@ -0,0 +1,35 @@
+Pass 1: Checking inodes, blocks, and sizes
+Special (device/socket/fifo) file (inode 19) has extents
+or inline-data flag set.  Clear? yes
+
+Inode 20 has extent header but inline data flag is set.
+Fix? yes
+
+Inode 21 has inline data and extent flags set but i_block contains junk.
+Clear inode? yes
+
+Inode 22 seems to have block map but inline data and extent flags set.
+Fix? yes
+
+Inode 23 seems to have inline data but extent flag is set.
+Fix? yes
+
+Pass 2: Checking directory structure
+Entry 'garbage' in /bad (18) has deleted/unused inode 21.  Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Inode bitmap differences:  -21
+Fix? yes
+
+Free inodes count wrong for group #0 (105, counted=106).
+Fix? yes
+
+Free inodes count wrong (105, counted=106).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 22/128 files (0.0% non-contiguous), 21/512 blocks
+Exit status is 1
diff --git a/tests/f_idata_and_extents/expect.2 b/tests/f_idata_and_extents/expect.2
new file mode 100644
index 0000000..307d3f6
--- /dev/null
+++ b/tests/f_idata_and_extents/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: 22/128 files (0.0% non-contiguous), 21/512 blocks
+Exit status is 0
diff --git a/tests/f_idata_and_extents/image.gz b/tests/f_idata_and_extents/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..5187ba14138568a1ccd3540228b092f93186d109
GIT binary patch
literal 3112
zcmeIxT})GV7zXg8MnQ}yL5)$cYIMvfWdxZDVk1r*0)wDisaDj2pi(Rf43x4HC)Fun
zCtre9kJy#LfMTs+3qtD#fz6NdS)fH4C~c)sTPPMzdwTxE>)m*<%f2^H-sF95e#uM7
zb%u_;tU9uAkwJ0dZ1EWn$fOGjZ1hhItkO8eev|1onDFg&H`d}~&zxz`SJRXE0`dO0
zZ2jh9;)@#2&zl>gZjRL6%%+!K?mFlkay7m)&t=<=%10YdH_P@IF9lwBSpUYaN5#No
z<`&%xWh!oLH)ATH`@$5i!kutwQ%yJrDO}ko)TL5Z?HV|8e#s4|<8UbVi@e(n_`RGo
z^ON&upQKMRwo;nDJU&?ZwU>oux}<2q$M829LEY26FPSpyfh3jQ8zxLNd|Xa7P>mkU
zC!I5sB{o-J>TBuW@UDLQQcmyz{)}R7ul67Pj91wh%3Q~Ja0P;1UyH$sq3YW-yXt|w
z0)<abxF8b7iUklP1*-R>*HZ)uYa}Zm2%?%t0azbgkmSlUF5H<z<%`8Lp2KI#_w_3!
z*{2M0+%wyAs(vj>CByI`?5#90-(PHLa3wsR?@IkIbgh~NU1*5SX@2FeU)(ew&=6Sk
zDL#Lsef|N~!-E0yjg;o8rOuz<{Ldw5`=k7&Tp+qL-C|0yMmdj|Os6Kg%A<>7DJ%82
zl23H-*dHZcn@AsK3wEB@J_3E`^6u~Dw2Cq>gxd2Pz*SV3$grj`d$y?If_&KTc_lrl
zjD~GTZg{M&ysZ}CVy_&(zcl?Yv8F?hd=+YUPeL${K2jWRH4LY_*MXtPzDf`qp*(U9
zM-qHX;EE`u*896SN@ZlD?Mjm^AW*SH5iAnN>?4K;WUNTDEYInT8A>?aJ*)&&nWdXB
zFf}(?vRwmD<&u0_cMH=EoTP5-5I$!`1(>;>$2G+?WLNbUT>o`U*<&dg&8m!ORK%WT
zOz878bWvchCf8WbP1W6^k(M1cR@H!OSz+zI^5zIiQNElddR8lu{8VAfOk`n){$&4t
z>yBJ103zl#a8t>a!NgWf?V5`+I%uO9nLOlP*azx+CgaFFEGzOpG2|XRNg|RbtONv%
zk3<*AfNwuf_&zR!g)K7<;h}k@!0rnQRivZ!m{3@?)i4{i&igI`csx$RaC`1*Hpr?D
zvGi~F#m&Y}{+<p0XrGPu^#uYmtX12?il>2ADX0C`PO=d0R$m5$cCZ^fc>S1()xDCJ
ztnn!hQ|q5T6##i!cAMy8=4(MMhaif^QOVspwwq4EZ8HOU^f^r8J&{F!NO{O-?BH;I
zsF2l`(T0#oj1(}Ao+OtVP_Unc<sxvr4zyy`yYS?WX(S%=3HQe%GlH>{05maG%G9U|
zH7dV@IG4-K_cN%u<6}tv0&_8ZKcmHi*cOk<w6Sw)7nF4Il%{0u#bFK`Q(t~p<OwRa
z@xfp(e4u9!PFbFb&XHMGpY$!&c6PYPsg#2n$1`lh{G&i8$x>7E24H%15FotLw#2z>
zrQ*LqnG4!3uA60=wQB`npwaKsKRL!B;1F;KI0PI54uSt&K&v3N2~T{0ppDSKYUGCn

literal 0
HcmV?d00001

diff --git a/tests/f_idata_and_extents/name b/tests/f_idata_and_extents/name
new file mode 100644
index 0000000..362ce0e
--- /dev/null
+++ b/tests/f_idata_and_extents/name
@@ -0,0 +1 @@
+conflicting extents and inline_data inode flags

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 09/21] e2fsck: check ea-in-inode regions for overlap
  2014-08-05  1:05 ` [PATCH 09/21] e2fsck: check ea-in-inode regions for overlap Darrick J. Wong
@ 2014-08-08 22:43   ` Darrick J. Wong
  2014-08-10 22:35     ` Theodore Ts'o
  0 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 22:43 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

Ensure that the various blobs in the in-inode EA region do not overlap.

v2: Actually clear the magic number when we're clearing a bad inode EA
region, not whatever comes after it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c                      |   43 ++++++++++++++++++++++++++++++++---
 e2fsck/problem.c                    |    5 ++++
 e2fsck/problem.h                    |    3 ++
 tests/f_inode_ea_collision/expect.1 |   15 ++++++++++++
 tests/f_inode_ea_collision/expect.2 |    7 ++++++
 tests/f_inode_ea_collision/image.gz |  Bin
 tests/f_inode_ea_collision/name     |    1 +
 7 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 tests/f_inode_ea_collision/expect.1
 create mode 100644 tests/f_inode_ea_collision/expect.2
 create mode 100644 tests/f_inode_ea_collision/image.gz
 create mode 100644 tests/f_inode_ea_collision/name

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 6c79eed..3fbf00a 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -286,15 +286,17 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 	struct ext2_super_block *sb = ctx->fs->super;
 	struct ext2_inode_large *inode;
 	struct ext2_ext_attr_entry *entry;
-	char *start;
+	char *start, *header;
 	unsigned int storage_size, remain;
 	problem_t problem = 0;
+	region_t region = 0;
 
 	inode = (struct ext2_inode_large *) pctx->inode;
 	storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
 		inode->i_extra_isize;
-	start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
-		inode->i_extra_isize + sizeof(__u32);
+	header = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
+		 inode->i_extra_isize;
+	start = header + sizeof(__u32);
 	entry = (struct ext2_ext_attr_entry *) start;
 
 	/* scan all entry's headers first */
@@ -302,10 +304,28 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 	/* take finish entry 0UL into account */
 	remain = storage_size - sizeof(__u32);
 
+	region = region_create(0, storage_size);
+	if (!region) {
+		fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
+		problem = 0;
+		ctx->flags |= E2F_FLAG_ABORT;
+		return;
+	}
+	if (region_allocate(region, 0, sizeof(__u32))) {
+		problem = PR_1_INODE_EA_ALLOC_COLLISION;
+		goto fix;
+	}
+
 	while (remain >= sizeof(struct ext2_ext_attr_entry) &&
 	       !EXT2_EXT_IS_LAST_ENTRY(entry)) {
 		__u32 hash;
 
+		if (region_allocate(region, (char *)entry - (char *)header,
+				    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
+			problem = PR_1_INODE_EA_ALLOC_COLLISION;
+			goto fix;
+		}
+
 		/* header eats this space */
 		remain -= sizeof(struct ext2_ext_attr_entry);
 
@@ -333,6 +353,13 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 			goto fix;
 		}
 
+		if (entry->e_value_size &&
+		    region_allocate(region, sizeof(__u32) + entry->e_value_offs,
+				    EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
+			problem = PR_1_INODE_EA_ALLOC_COLLISION;
+			goto fix;
+		}
+
 		hash = ext2fs_ext_attr_hash_entry(entry,
 						  start + entry->e_value_offs);
 
@@ -347,7 +374,15 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
 
 		entry = EXT2_EXT_ATTR_NEXT(entry);
 	}
+
+	if (region_allocate(region, (char *)entry - (char *)header,
+			    sizeof(__u32))) {
+		problem = PR_1_INODE_EA_ALLOC_COLLISION;
+		goto fix;
+	}
 fix:
+	if (region)
+		region_free(region);
 	/*
 	 * it seems like a corruption. it's very unlikely we could repair
 	 * EA(s) in automatic fashion -bzzz
@@ -356,7 +391,7 @@ fix:
 		return;
 
 	/* simply remove all possible EA(s) */
-	*((__u32 *)start) = 0UL;
+	*((__u32 *)header) = 0UL;
 	e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
 				EXT2_INODE_SIZE(sb), "pass1");
 }
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 2d29c35..b982a27 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -977,6 +977,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@i %i passes checks, but checksum does not match @i.  "),
 	  PROMPT_FIX, PR_PREEN_OK },
 
+	/* Inode extended attribute is corrupt (allocation collision) */
+	{ PR_1_INODE_EA_ALLOC_COLLISION,
+	  N_("@i %i @a is corrupt (allocation collision).  "),
+	  PROMPT_CLEAR, 0},
+
 	/*
 	 * Inode extent block passes checks, but checksum does not match
 	 * extent
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 89146ec..f051c11 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -577,6 +577,9 @@ struct problem_context {
 /* inode passes checks, but checksum does not match inode */
 #define PR_1_INODE_ONLY_CSUM_INVALID   0x010068
 
+/* Inode EA allocation collision */
+#define PR_1_INODE_EA_ALLOC_COLLISION	0x010069
+
 /* extent block passes checks, but checksum does not match extent block */
 #define PR_1_EXTENT_ONLY_CSUM_INVALID  0x01006A
 
diff --git a/tests/f_inode_ea_collision/expect.1 b/tests/f_inode_ea_collision/expect.1
new file mode 100644
index 0000000..a67a5f1
--- /dev/null
+++ b/tests/f_inode_ea_collision/expect.1
@@ -0,0 +1,15 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 extended attribute is corrupt (allocation collision).  Clear? yes
+
+Inode 13 extended attribute is corrupt (allocation collision).  Clear? yes
+
+Inode 14 extended attribute is corrupt (allocation collision).  Clear? 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: 14/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 1
diff --git a/tests/f_inode_ea_collision/expect.2 b/tests/f_inode_ea_collision/expect.2
new file mode 100644
index 0000000..5a7ca86
--- /dev/null
+++ b/tests/f_inode_ea_collision/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: 14/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 0
diff --git a/tests/f_inode_ea_collision/image.gz b/tests/f_inode_ea_collision/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..5217f6503404864944a88bfc36b7d75a305aafb8
GIT binary patch
literal 2602
zcmb2|=3rRTdo!4c`Ry(1jNn8Oh6n%E1ihnk1;sZu?eJW<NUv+f#j`7&rz`1+%6Chx
z=yzP$zj61~h22d*Bw~&@hIDCYH8poTn;&#Na(uyTr@!x&7j4w~mb&)7_&M9}GoL+C
zGk@+c%=BTul$ZKafv}@r^f(vpkBHY&x}B)u->fWbo2immwCQ=R(4%*W3VPSyYikyH
zZ``1|?Dt2%b4UJs`SxP5`rf<qk6jPBKPPtAKflM1ZxnpF(YbTo*E?sW`@hG%t1C!M
z`g-u=^W<936>Zmo_PxDrmFDffM>TlO`Xe_UFJ)&q5I<qte(j_+r+@wbw<G4~uC?|#
zcOOVHF)%dL-%klvt<gLGpn`#cA>p9+|Nr-;CIy9`sOP>Q<+XI(x<BT7w4IAzdc6J7
zdCqz3<l}rxZf~lc+-s<>{mlI69-Cu#x2fEG^I8O`IbuST)Up5aw?BQf2l6(Y*iy{}
zq!0X%2a*Q=*nuRGpkb%!&drIEK-Cc?HOxRqk_!&ZmynqGV&(DwA>VJu7G9cn-9Ex)
z-%^=bo9>7_cgpxTq2-kMan+l0#@7WOyMF(gCH3|5gR2~8+7~{w*cm?e(XaU;*Z057
z&W!M@EBc%LN2Vw&q3(|N@A<Dn{>E#r(fu{w!1aHyW|G;j`TKwV+ix=G`9b+#`+r?s
zr8ztMpTXa%^)Y*{{yhEf{nO2F^^e8ndMp3^ovC;3;OnAI>tDDPw`Xk)@T=PVQ}yVs
zzqQN%|1gw&XD!<Qdj9lZ>;J9$x8;BAuL5_e$iIgFSN+p<{rgaU<^NmnU)kI5+HJ>n
z;+6g}CVTt;_t($%{7Y`ojOrT=fzc2c4S~@R7!85Z5Fii&8zgEO|2Qt4#K54y004(2
BL%09{

literal 0
HcmV?d00001

diff --git a/tests/f_inode_ea_collision/name b/tests/f_inode_ea_collision/name
new file mode 100644
index 0000000..b64119e
--- /dev/null
+++ b/tests/f_inode_ea_collision/name
@@ -0,0 +1 @@
+collisions in the inode ea area

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 10/21] e2fsck: clear inline_data inode flag if EA missing
  2014-08-05  1:06 ` [PATCH 10/21] e2fsck: clear inline_data inode flag if EA missing Darrick J. Wong
@ 2014-08-08 22:44   ` Darrick J. Wong
  2014-08-10 22:37     ` Theodore Ts'o
  0 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 22:44 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

If i_size indicates that an inode requires a system.data extended
attribute to hold overflow from i_blocks but the EA cannot be found,
offer to truncate the file.

v2: Use the raw xattr editing interface since it'll return error codes
to us directly.  This is a side effect of modifying the library inline
data code not to return "key error" when it can't find the system.data
EA.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 e2fsck/pass1.c   |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 e2fsck/problem.c |    5 +++
 e2fsck/problem.h |    3 ++
 3 files changed, 88 insertions(+)

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 3fbf00a..5115a85 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -669,6 +669,30 @@ static void reserve_block_for_lnf_repair(e2fsck_t ctx)
 	ctx->lnf_repair_block = blk;
 }
 
+static errcode_t get_inline_data_ea_size(ext2_filsys fs, ext2_ino_t ino,
+					 size_t *sz)
+{
+	void *p;
+	struct ext2_xattr_handle *handle;
+	errcode_t retval;
+
+	retval = ext2fs_xattrs_open(fs, ino, &handle);
+	if (retval)
+		return retval;
+
+	retval = ext2fs_xattrs_read(handle);
+	if (retval)
+		goto err;
+
+	retval = ext2fs_xattr_get(handle, "system.data", &p, sz);
+	if (retval)
+		goto err;
+	ext2fs_free_mem(&p);
+err:
+	(void) ext2fs_xattrs_close(&handle);
+	return retval;
+}
+
 static void finish_processing_inode(e2fsck_t ctx, ext2_ino_t ino,
 				    struct problem_context *pctx,
 				    int failed_csum)
@@ -959,6 +983,62 @@ void e2fsck_pass1(e2fsck_t ctx)
 			}
 		}
 
+		/* Test for inline data flag but no attr */
+		if ((inode->i_flags & EXT4_INLINE_DATA_FL) && inlinedata_fs &&
+		    EXT2_I_SIZE(inode) > EXT4_MIN_INLINE_DATA_SIZE &&
+		    (ino >= EXT2_FIRST_INODE(fs->super))) {
+			size_t size = 0;
+			errcode_t err;
+			int flags;
+
+			flags = fs->flags;
+			if (failed_csum)
+				fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+			err = get_inline_data_ea_size(fs, ino, &size);
+			fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
+				    (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
+
+			switch (err) {
+			case 0:
+				/* Everything is awesome... */
+				break;
+			case EXT2_ET_BAD_EA_BLOCK_NUM:
+			case EXT2_ET_BAD_EA_HASH:
+			case EXT2_ET_BAD_EA_HEADER:
+			case EXT2_ET_EA_BAD_NAME_LEN:
+			case EXT2_ET_EA_BAD_VALUE_SIZE:
+			case EXT2_ET_EA_KEY_NOT_FOUND:
+			case EXT2_ET_EA_NO_SPACE:
+			case EXT2_ET_MISSING_EA_FEATURE:
+			case EXT2_ET_INLINE_DATA_CANT_ITERATE:
+			case EXT2_ET_INLINE_DATA_NO_BLOCK:
+			case EXT2_ET_INLINE_DATA_NO_SPACE:
+			case EXT2_ET_NO_INLINE_DATA:
+			case EXT2_ET_EXT_ATTR_CSUM_INVALID:
+			case EXT2_ET_EA_BAD_VALUE_OFFSET:
+				/* broken EA or no system.data EA; truncate */
+				if (fix_problem(ctx, PR_1_INLINE_DATA_NO_ATTR,
+						&pctx)) {
+					err = ext2fs_inode_size_set(fs, inode,
+							sizeof(inode->i_block));
+					if (err) {
+						pctx.errcode = err;
+						ctx->flags |= E2F_FLAG_ABORT;
+						goto endit;
+					}
+					e2fsck_write_inode(ctx, ino, inode,
+							   "pass1");
+					failed_csum = 0;
+				}
+				break;
+			default:
+				/* Some other kind of non-xattr error? */
+				pctx.errcode = err;
+				ctx->flags |= E2F_FLAG_ABORT;
+				goto endit;
+			}
+		}
+
 		/*
 		 * Test for incorrect extent flag settings.
 		 *
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index b982a27..9081277 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1045,6 +1045,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@i %i logical @b %b (physical @b %c) violates cluster allocation rules.\nWill fix in pass 1B.\n"),
 	  PROMPT_NONE, 0 },
 
+	/* Inode has INLINE_DATA_FL flag but extended attribute not found */
+	{ PR_1_INLINE_DATA_NO_ATTR,
+	  N_("@i %i has INLINE_DATA_FL flag but @a not found.  "),
+	  PROMPT_TRUNCATE, 0 },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index f051c11..1f0be2d 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -609,6 +609,9 @@ struct problem_context {
 /* Inode logical block is misaligned */
 #define PR_1_MISALIGNED_CLUSTER		0x010074
 
+/* Inode has INLINE_DATA_FL flag but extended attribute not found */
+#define PR_1_INLINE_DATA_NO_ATTR	0x010075
+
 /*
  * Pass 1b errors
  */

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 07/21] libext2fs: don't fail inline data operations if there's no EA
  2014-08-05  1:05 ` [PATCH 07/21] libext2fs: remove EA when inline data is less than 60 bytes Darrick J. Wong
@ 2014-08-08 22:46   ` Darrick J. Wong
  2014-08-10 22:31     ` Theodore Ts'o
  0 siblings, 1 reply; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 22:46 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

Fix up the rest of the inline data code not to complain if there's no
EA, since it's possible that there's no EA because we're in the
process of creating an inline data file.  Also, don't return an error
code when removing a nonexistent EA, because there's no reason to.

Furthermore, if we write less than 60 bytes of inline data, remove the
EA to avoid wasting space.

v2: Fix a few more places where inline data functions would totally
fail if the EA was missing, even though the EA's presence isn't
required.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/ext_attr.c      |    3 ++-
 lib/ext2fs/inline_data.c   |    9 ++++++++-
 tests/d_xattr_edits/expect |    1 -
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
index 5732ca6..fc191f5 100644
--- a/lib/ext2fs/ext_attr.c
+++ b/lib/ext2fs/ext_attr.c
@@ -1020,7 +1020,8 @@ errcode_t ext2fs_xattr_remove(struct ext2_xattr_handle *handle,
 		}
 	}
 
-	return EXT2_ET_EA_KEY_NOT_FOUND;
+	/* no key found, success! */
+	return 0;
 }
 
 errcode_t ext2fs_xattrs_open(ext2_filsys fs, ext2_ino_t ino,
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index b9bda50..3ba04ae 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -70,7 +70,11 @@ static errcode_t ext2fs_inline_data_ea_get(struct ext2_inline_data *data)
 
 	retval = ext2fs_xattr_get(handle, "system.data",
 				  (void **)&data->ea_data, &data->ea_size);
-	if (retval)
+	if (retval == EXT2_ET_EA_KEY_NOT_FOUND) {
+		data->ea_size = 0;
+		data->ea_data = NULL;
+		retval = 0;
+	} else if (retval)
 		goto err;
 
 err:
@@ -557,6 +561,9 @@ errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
 	}
 
 	if (size <= EXT4_MIN_INLINE_DATA_SIZE) {
+		retval = ext2fs_inline_data_ea_remove(fs, ino);
+		if (retval)
+			return retval;
 		memcpy((void *)inode->i_block, buf, size);
 		return ext2fs_write_inode(fs, ino, inode);
 	}
diff --git a/tests/d_xattr_edits/expect b/tests/d_xattr_edits/expect
index 10e30c1..44ce5e4 100644
--- a/tests/d_xattr_edits/expect
+++ b/tests/d_xattr_edits/expect
@@ -19,7 +19,6 @@ Exit status is 0
 ea_rm / user.moo
 Exit status is 0
 ea_rm / nosuchea
-ea_rm: Extended attribute key not found while removing extended attribute
 Exit status is 0
 ea_list /
 Extended attributes:

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 21/21] tests: add regression tests for inlinedata fixes
  2014-08-05  1:07 ` [PATCH 21/21] tests: add regression tests for inlinedata fixes Darrick J. Wong
@ 2014-08-08 22:47   ` Darrick J. Wong
  0 siblings, 0 replies; 48+ messages in thread
From: Darrick J. Wong @ 2014-08-08 22:47 UTC (permalink / raw)
  To: tytso; +Cc: linux-ext4

Add a regression test to ensure that previous patches' fixes to e2fsck
do not revert.

v2: Amend test case to reflect the inode EA clearing bug fixed earlier.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tests/f_inlinedata_repair/expect.1 |   75 ++++++++++++++++++++++++++++++++++++
 tests/f_inlinedata_repair/expect.2 |    7 +++
 tests/f_inlinedata_repair/image.gz |  Bin
 tests/f_inlinedata_repair/name     |    1 
 4 files changed, 83 insertions(+)
 create mode 100644 tests/f_inlinedata_repair/expect.1
 create mode 100644 tests/f_inlinedata_repair/expect.2
 create mode 100644 tests/f_inlinedata_repair/image.gz
 create mode 100644 tests/f_inlinedata_repair/name

diff --git a/tests/f_inlinedata_repair/expect.1 b/tests/f_inlinedata_repair/expect.1
new file mode 100644
index 0000000..faba192
--- /dev/null
+++ b/tests/f_inlinedata_repair/expect.1
@@ -0,0 +1,75 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 has INLINE_DATA_FL flag but extended attribute not found.  Truncate? yes
+
+Inode 16, i_size is 56, should be 60.  Fix? yes
+
+Inode 24, i_size is 59, should be 60.  Fix? yes
+
+Inode 28 is a unknown file type with mode 00 but it looks like it is really a directory.
+Fix? yes
+
+Inode 36 is a unknown file type with mode 00 but it looks like it is really a directory.
+Fix? yes
+
+Inode 36, i_size is 5, should be 60.  Fix? yes
+
+Pass 2: Checking directory structure
+Directory inode 20, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 28, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 32, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Directory inode 32, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Entry '..' in ??? (36) has invalid inode #: 1633774699.
+Clear? yes
+
+Directory inode 36, block #0, offset 4: directory corrupted
+Salvage? yes
+
+Symlink /3 (inode #14) is invalid.
+Clear? yes
+
+Inode 38 (/B) has invalid mode (00).
+Clear? yes
+
+Entry 'A' in / (2) has an incorrect filetype (was 1, should be 2).
+Fix? yes
+
+Pass 3: Checking directory connectivity
+'..' in /A (36) is ??? (1633774699), should be / (2).
+Fix? yes
+
+Error while adjusting inode count on inode 0
+Pass 4: Checking reference counts
+Unattached zero-length inode 22.  Clear? yes
+
+Unattached zero-length inode 23.  Clear? yes
+
+Unattached zero-length inode 29.  Clear? yes
+
+Unattached zero-length inode 30.  Clear? yes
+
+Unattached zero-length inode 31.  Clear? yes
+
+Unattached zero-length inode 33.  Clear? yes
+
+Unattached zero-length inode 34.  Clear? yes
+
+Unattached zero-length inode 35.  Clear? yes
+
+Inode 36 ref count is 1, should be 2.  Fix? yes
+
+Pass 5: Checking group summary information
+Directories count wrong for group #0 (7, counted=8).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 28/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 1
diff --git a/tests/f_inlinedata_repair/expect.2 b/tests/f_inlinedata_repair/expect.2
new file mode 100644
index 0000000..519f21d
--- /dev/null
+++ b/tests/f_inlinedata_repair/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: 28/128 files (0.0% non-contiguous), 18/512 blocks
+Exit status is 0
diff --git a/tests/f_inlinedata_repair/image.gz b/tests/f_inlinedata_repair/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..c33d81dc60f828c89c9b743e64e0b9cf4224da1f
GIT binary patch
literal 3201
zcmeH}TToMX5XOV3SS*O*jEG_=Sfruc3K|e0RjE{iqQyW6AO%r`D1m}NDR8{uSS&JA
z>J5PmD#aMWCEN|+R4qmWns#Cg;6Nymq(IU@0*Qy5oPXm>-<)y!oPF8-cD|jR`OQ8o
z{_+akvzp=PCD!Uu^2x&#C!5&-v0KO5vNL66=O&KsT;dt#>b%s^eUBqOqiFnch84cO
zoYt{?ooAIpqQfrg>J+~<u|DO_cigyHM-#g5hxcE-7@pYTx~H=6MNLSuXX*M8ns87f
zEz;FYMJn}>rut?`7cqUsmv=^f_9^=$Va;o1slzLU%vW)BG?~oex1_b?xW+^~IZvZ(
zhl$b0t3sBC3{+5_8rxB!cF4YW{UgQD^^N@RP5F2Zrd1PTRan;Z3XL5Iy*59u2eP<Z
zV<hO$vq#zXr@S-!Kp$TR`(B{bai|YCUkD0ru7hpei{Ri_HMNB}T=lYaLw-ynn`;6c
z$r+vbH10OlSel&`4)<FR<6eC*`a19;(*}pbdGO~Ap!1-ok9~cP)yS^a?t<*8jbp)e
z9o;NVJ@(ax#UuZy4|E+f)D#x0#JV}VR?$<zKng=7AU+8TfK<1*0zx_CN^xdb-=}wT
zQpxh%rrC2vy>5CsS^mg{yt{ilzWIu&it3_{wjK2~%=ap0?aW(WrjC3T2DZRm@g%c4
zNIXtkX3pcfcPcB>YtvqEhal054qyz*{?e_(q@{0jX;b>zzA*O3K@ZIyzbWL+5_A55
z_%hU~EEAvSVz%D%y>jLQCf;Ys@+cYdABt<*BQy!73;Y8vkn`>G`nU~;>*Hw?u`JQ0
z>zs&{bv+YG+t#Wl$%rn+C9M5qe2m(}FYm<8wxtbhm`efoS04c@kr~<F`#0qAv&y9K
zUz**Wwvj)X(m~qP*G8z{k0=8lxvRk4Vx}T{1OzXjzMBwOw@PhS=dMr6v(IZ9qz|zr
zgMrRY=WSN`7>(^lsLcj?o}o)5{yN!^jp!9D!|~z+C43$mrnkpMERGU%vf5a0M3h>(
z<FGeiD~qcsgUoBpCzEQ@YDDuw*DR#>c7ewdEzD!2#rQ+C66dH?Osh|-k+v9szY^N4
zU=}_=VGbI=zCrRPm2V+Hi)h!5F@1DGW{<ELnpDfGlX$K%@h1qmp$oY;u2%4*j1_J2
zf}I<iWi8piPd0HnP0%oQEQYDU+`LH(awMu3P_-3r&J*{U-k_68h`cQ$bo-*z7(suI
z_Zq+(!}(x;I3{r30pyiIP!;Hs1OeYj<4OdD@1<Z#3CA$fA#ZTn+Sry+IK%!NQY{1m
zX5&_<@m)EOCP~K;o<}wo2pF7fEa{s$3`*}u;YJ|}-KSxFr){_o(!|m@Y-lDOBPG%?
z>br6Zk&TWc(x?e^FGmBe3#w{Gz>A;&C_xA9?m$EEZ#~$RTB!h)QU99&k>{0A-WnyT
z(geKPIu2EVSjr$Mr6@p-L<?~h-}Z3PR;d_;N?sx}as*~Q)EOct&}Y9;1ry(aA5W{+
z3LvKJr9`q_D9~`O!F<>-d)vCXVc$Sh@ogpO=PeHr2m7&@1!%tNHS|M-fZh;_@j51z
zkK;l2HVUm|+OfwZo&(w*l0XF3!*U?Q_}YGPCMea7J)8c6dnz4a;boZ1@QKBsQ@{~i
kvVPxvTly9P76KLm76KLm76Sj9z-C~@tUY1=!Ci6x0)&jPy8r+H

literal 0
HcmV?d00001

diff --git a/tests/f_inlinedata_repair/name b/tests/f_inlinedata_repair/name
new file mode 100644
index 0000000..7e7e898
--- /dev/null
+++ b/tests/f_inlinedata_repair/name
@@ -0,0 +1 @@
+repair corrupt inline data files

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux
  2014-08-05  1:05 ` [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux Darrick J. Wong
@ 2014-08-10 22:16   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:04PM -0700, Darrick J. Wong wrote:
> Fix clang warnings about forgotten header files, dead code, and pwrite
> support on OS X.  The unistd.h inclusion also fixes a parameter
> truncation bug on i386.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error
  2014-08-05  1:05 ` [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error Darrick J. Wong
@ 2014-08-10 22:16   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:10PM -0700, Darrick J. Wong wrote:
> In pass 3, convert the "delete files and re-run e2fsck" message to a
> proper error code for more consistent error reporting and to make
> translation easier.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 03/21] libext2fs: check EA value offset
  2014-08-05  1:05 ` [PATCH 03/21] libext2fs: check EA value offset Darrick J. Wong
@ 2014-08-10 22:21   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:21 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:17PM -0700, Darrick J. Wong wrote:
> Perform a little more sanity checking of EA value offsets so that we
> don't crash while trying to load things from the filesystem.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thank.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block
  2014-08-05  1:05 ` [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block Darrick J. Wong
@ 2014-08-10 22:22   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:22 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:23PM -0700, Darrick J. Wong wrote:
> When we're (a) reading EAs into a buffer; (b) byte-swapping EA
> entries; or (c) checking EA data, be careful not to run off the end of
> the memory buffer, because this causes invalid memory accesses and
> e2fsck crashes.  This can happen if we encounter a specially crafted
> FS image.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 05/21] misc: fix various endianness problems with inline_data
  2014-08-05  1:05 ` [PATCH 05/21] misc: fix various endianness problems with inline_data Darrick J. Wong
@ 2014-08-10 22:23   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:23 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:30PM -0700, Darrick J. Wong wrote:
> The inline data code fails to perform endianness conversions correctly
> or at all in a number of places, so fix this so that big-endian
> machines function properly.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC
  2014-08-05  1:05 ` [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC Darrick J. Wong
@ 2014-08-10 22:27   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:27 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:36PM -0700, Darrick J. Wong wrote:
> If we're doing a strict overwrite (same data size) of data in an
> inline data file, we should be able to skip the size check.  If the
> in-core EA representation is fine but the on-disk EA is slightly
> corrupt (this happens when fixing minor errors in an inline dir), the
> ext2fs_xattr_inode_max_size() call, which reads the disk EA, can lead
> us to think that there's no space when in reality there is no issue
> with doing a strict overwrite.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 07/21] libext2fs: don't fail inline data operations if there's no EA
  2014-08-08 22:46   ` [PATCH v2 07/21] libext2fs: don't fail inline data operations if there's no EA Darrick J. Wong
@ 2014-08-10 22:31     ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:31 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Fri, Aug 08, 2014 at 03:46:40PM -0700, Darrick J. Wong wrote:
> Fix up the rest of the inline data code not to complain if there's no
> EA, since it's possible that there's no EA because we're in the
> process of creating an inline data file.  Also, don't return an error
> code when removing a nonexistent EA, because there's no reason to.
> 
> Furthermore, if we write less than 60 bytes of inline data, remove the
> EA to avoid wasting space.
> 
> v2: Fix a few more places where inline data functions would totally
> fail if the EA was missing, even though the EA's presence isn't
> required.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory
  2014-08-05  1:05 ` [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory Darrick J. Wong
@ 2014-08-10 22:32   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:32 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:05:49PM -0700, Darrick J. Wong wrote:
> The xattr_get method returns to us a pointer to a buffer containing
> the EA value.  If for some reason we decide to fail out of iterating
> the EA part of an inline-data directory, we must free the buffer that
> xattr_get passed to us (via inline_data_ea_get).
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 09/21] e2fsck: check ea-in-inode regions for overlap
  2014-08-08 22:43   ` [PATCH v2 " Darrick J. Wong
@ 2014-08-10 22:35     ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Fri, Aug 08, 2014 at 03:43:58PM -0700, Darrick J. Wong wrote:
> Ensure that the various blobs in the in-inode EA region do not overlap.
> 
> v2: Actually clear the magic number when we're clearing a bad inode EA
> region, not whatever comes after it.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 10/21] e2fsck: clear inline_data inode flag if EA missing
  2014-08-08 22:44   ` [PATCH v2 " Darrick J. Wong
@ 2014-08-10 22:37     ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:37 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Fri, Aug 08, 2014 at 03:44:48PM -0700, Darrick J. Wong wrote:
> If i_size indicates that an inode requires a system.data extended
> attribute to hold overflow from i_blocks but the EA cannot be found,
> offer to truncate the file.
> 
> v2: Use the raw xattr editing interface since it'll return error codes
> to us directly.  This is a side effect of modifying the library inline
> data code not to return "key error" when it can't find the system.data
> EA.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 11/21] e2fsck: handle inline data symlinks
  2014-08-05  1:06 ` [PATCH 11/21] e2fsck: handle inline data symlinks Darrick J. Wong
@ 2014-08-10 22:38   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:38 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:08PM -0700, Darrick J. Wong wrote:
> Perform some basic checks on inline-data symlinks.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 12/21] e2fsck: check inline directory data "block" first
  2014-08-05  1:06 ` [PATCH 12/21] e2fsck: check inline directory data "block" first Darrick J. Wong
@ 2014-08-10 22:40   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:15PM -0700, Darrick J. Wong wrote:
> Since the inline data flag will cause the extent/block map iteration
> code to abort fsck early, move the test for the inode flag and the
> actual block check call further forward in check_blocks.  This
> eliminates an e2fsck abort on an inline data symlink when the file ACL
> block is set.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it
  2014-08-05  1:06 ` [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it Darrick J. Wong
@ 2014-08-10 22:40   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:22PM -0700, Darrick J. Wong wrote:
> Inodes with inline_data set do not have iterable blocks, so don't try
> to iterate the blocks, because that will just fail, causing e2fsck to
> abort.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes
  2014-08-05  1:06 ` [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes Darrick J. Wong
@ 2014-08-10 22:41   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:29PM -0700, Darrick J. Wong wrote:
> Since fifo, socket, and device inodes cannot have inline data or
> extents, strip off these flags if we find them.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 15/21] e2fsck: fix conflicting extents|inlinedata inode flags
  2014-08-08 16:24   ` [PATCH v2 " Darrick J. Wong
@ 2014-08-10 22:43     ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Fri, Aug 08, 2014 at 09:24:29AM -0700, Darrick J. Wong wrote:
> If we come across an inode with the inline data and extents inode flag
> set, try to figure out the correct flag settings from the contents of
> i_block and i_size.  If i_blocks looks like an extent tree head, we'll
> make it an extent inode; if it's small enough for inline data, set it
> to that.  This leaves the weird gray area where there's no extent
> tree but it's too big for the inode -- if /could/ be a block map,
> change it to that; otherwise, just clear the inode.
> 
> v2: Don't add unnecessary variables.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories
  2014-08-05  1:06 ` [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories Darrick J. Wong
@ 2014-08-10 22:44   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:42PM -0700, Darrick J. Wong wrote:
> If we encounter a directory whose i_size != the inline data size, just
> set i_size to the size of the inline data.  The pb.last_block
> calculation is wrong since pb.last_block == -1, which results in
> i_size being set to zero, which corrupts the directory.
> 
> Clear the inline_data inode flag if we actually /are/ setting i_size
> to zero.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 17/21] e2fsck: use the correct block size when salvaging directories
  2014-08-05  1:06 ` [PATCH 17/21] e2fsck: use the correct block size when salvaging directories Darrick J. Wong
@ 2014-08-10 22:45   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:49PM -0700, Darrick J. Wong wrote:
> Now that the directory salvaging operation is fed the block size,
> teach pass 2 that it should use the size of the inline data if the
> directory is inline_data.  Without this, it'll "fix" inline
> directories by setting the rec_len to something approaching the FS
> blocksize, which is clearly wrong.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4
  2014-08-05  1:06 ` [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4 Darrick J. Wong
@ 2014-08-10 22:47   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:47 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:06:55PM -0700, Darrick J. Wong wrote:
> Directory entries must have a size that's a multiple of 4; therefore
> the inline directory structure must also have a size that is a muliple
> of 4.  Since e2fsck doesn't check this, we should check that now.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

					- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 19/21] e2fsck: be more careful in assuming inline_data inodes are directories
  2014-08-08 16:22   ` [PATCH v2 " Darrick J. Wong
@ 2014-08-10 22:49     ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:49 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Fri, Aug 08, 2014 at 09:22:58AM -0700, Darrick J. Wong wrote:
> If a file is marked inline_data but its i_size isn't a multiple of
> four, it probably isn't an inline directory, because directory entries
> have sizes that are multiples of four.
> 
> v2: Don't add unnecessary variables.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir
  2014-08-05  1:07 ` [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir Darrick J. Wong
@ 2014-08-10 22:50   ` Theodore Ts'o
  0 siblings, 0 replies; 48+ messages in thread
From: Theodore Ts'o @ 2014-08-10 22:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-ext4

On Mon, Aug 04, 2014 at 06:07:09PM -0700, Darrick J. Wong wrote:
> In an inline directory, the '..' entry is compacted down to just the
> inode number; there is no full '..' entry.  Therefore, it makes no
> sense to assign 'prev' to the fake dotdot entry we put on the stack,
> as this could confuse a salvage_directory call on a corrupted next
> entry into modifying stack contents (the fake dotdot entry).
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Applied, thanks.

						- Ted

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2014-08-10 22:51 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-05  1:04 [PATCH 00/21] e2fsprogs Summer 2014 patchbomb, part 3 Darrick J. Wong
2014-08-05  1:05 ` [PATCH 01/21] e2fuzz: fix build problems on macosx and i386 linux Darrick J. Wong
2014-08-10 22:16   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 02/21] e2fsck: convert 'delete files' warning to a proper fix_problem error Darrick J. Wong
2014-08-10 22:16   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 03/21] libext2fs: check EA value offset Darrick J. Wong
2014-08-10 22:21   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 04/21] libext2fs/e2fsck: don't run off the end of the EA block Darrick J. Wong
2014-08-10 22:22   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 05/21] misc: fix various endianness problems with inline_data Darrick J. Wong
2014-08-10 22:23   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 06/21] libext2fs: strict inline data overwrite should not return ENOSPC Darrick J. Wong
2014-08-10 22:27   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 07/21] libext2fs: remove EA when inline data is less than 60 bytes Darrick J. Wong
2014-08-08 22:46   ` [PATCH v2 07/21] libext2fs: don't fail inline data operations if there's no EA Darrick J. Wong
2014-08-10 22:31     ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 08/21] libext2fs: fix memory leak when failing to iterate inline_data directory Darrick J. Wong
2014-08-10 22:32   ` Theodore Ts'o
2014-08-05  1:05 ` [PATCH 09/21] e2fsck: check ea-in-inode regions for overlap Darrick J. Wong
2014-08-08 22:43   ` [PATCH v2 " Darrick J. Wong
2014-08-10 22:35     ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 10/21] e2fsck: clear inline_data inode flag if EA missing Darrick J. Wong
2014-08-08 22:44   ` [PATCH v2 " Darrick J. Wong
2014-08-10 22:37     ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 11/21] e2fsck: handle inline data symlinks Darrick J. Wong
2014-08-10 22:38   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 12/21] e2fsck: check inline directory data "block" first Darrick J. Wong
2014-08-10 22:40   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 13/21] e2fsck: don't try to iterate blocks of an inline_data inode when deallocating it Darrick J. Wong
2014-08-10 22:40   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 14/21] e2fsck: clear extents and inline_data flags from fifo/socket/device inodes Darrick J. Wong
2014-08-10 22:41   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 15/21] e2fsck: fix conflicting extents|inlinedata inode flags Darrick J. Wong
2014-08-08 16:24   ` [PATCH v2 " Darrick J. Wong
2014-08-10 22:43     ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 16/21] e2fsck: do a better job of fixing i_size of inline directories Darrick J. Wong
2014-08-10 22:44   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 17/21] e2fsck: use the correct block size when salvaging directories Darrick J. Wong
2014-08-10 22:45   ` Theodore Ts'o
2014-08-05  1:06 ` [PATCH 18/21] e2fsck: check inline dir size is a multiple of 4 Darrick J. Wong
2014-08-10 22:47   ` Theodore Ts'o
2014-08-05  1:07 ` [PATCH 19/21] e2fsck: be more careful in assuming inline_data inodes are directories Darrick J. Wong
2014-08-08 16:22   ` [PATCH v2 " Darrick J. Wong
2014-08-10 22:49     ` Theodore Ts'o
2014-08-05  1:07 ` [PATCH 20/21] e2fsck: don't set prev after processing '..' on an inline dir Darrick J. Wong
2014-08-10 22:50   ` Theodore Ts'o
2014-08-05  1:07 ` [PATCH 21/21] tests: add regression tests for inlinedata fixes Darrick J. Wong
2014-08-08 22:47   ` [PATCH v2 " Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.