[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150127073730.13308.10353.stgit@birch.djwong.org>
Date: Mon, 26 Jan 2015 23:37:31 -0800
From: "Darrick J. Wong" <darrick.wong@...cle.com>
To: tytso@....edu, darrick.wong@...cle.com
Cc: linux-ext4@...r.kernel.org
Subject: [PATCH 18/54] e2fsck: improve the inline directory detector
Strengthen the checks that guess if the inode we're looking at is an
inline directory. The current check sweeps up any inline inode if
its length is a multiple of four; now we'll at least try to see if
there's the beginning of a valid directory entry.
Signed-off-by: Darrick J. Wong <darrick.wong@...cle.com>
---
e2fsck/pass1.c | 23 +++++++++++++++++++++++
tests/f_inlinedata_repair/expect.1 | 26 +++-----------------------
tests/f_inlinedata_repair/expect.2 | 2 +-
tests/f_inlinedir_detector/expect.1 | 20 ++++++++++++++++++++
tests/f_inlinedir_detector/expect.2 | 7 +++++++
tests/f_inlinedir_detector/image.gz | Bin
tests/f_inlinedir_detector/name | 1 +
7 files changed, 55 insertions(+), 24 deletions(-)
create mode 100644 tests/f_inlinedir_detector/expect.1
create mode 100644 tests/f_inlinedir_detector/expect.2
create mode 100644 tests/f_inlinedir_detector/image.gz
create mode 100644 tests/f_inlinedir_detector/name
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 69a9ac1..9f22826 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -537,6 +537,9 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
EXT4_FEATURE_INCOMPAT_INLINE_DATA);
if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL)) {
size_t size;
+ __u32 dotdot;
+ unsigned int rec_len;
+ struct ext2_dir_entry de;
if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
return;
@@ -546,6 +549,26 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
*/
if (size & 3)
return;
+ /*
+ * If the first 10 bytes don't look like a directory entry,
+ * it's probably not a directory.
+ */
+ memcpy(&dotdot, inode->i_block, sizeof(dotdot));
+ memcpy(&de, ((char *)inode->i_block) + EXT4_INLINE_DATA_DOTDOT_SIZE,
+ EXT2_DIR_REC_LEN(0));
+ dotdot = ext2fs_le32_to_cpu(dotdot);
+ de.inode = ext2fs_le32_to_cpu(de.inode);
+ de.rec_len = ext2fs_le16_to_cpu(de.rec_len);
+ ext2fs_get_rec_len(ctx->fs, &de, &rec_len);
+ if (dotdot >= ctx->fs->super->s_inodes_count ||
+ (dotdot < EXT2_FIRST_INO(ctx->fs->super) &&
+ dotdot != EXT2_ROOT_INO) ||
+ de.inode >= ctx->fs->super->s_inodes_count ||
+ (de.inode < EXT2_FIRST_INO(ctx->fs->super) &&
+ de.inode != 0) ||
+ rec_len > EXT4_MIN_INLINE_DATA_SIZE -
+ EXT4_INLINE_DATA_DOTDOT_SIZE)
+ return;
/* device files never have a "system.data" entry */
goto isdir;
} else if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {
diff --git a/tests/f_inlinedata_repair/expect.1 b/tests/f_inlinedata_repair/expect.1
index faba192..cc220ba 100644
--- a/tests/f_inlinedata_repair/expect.1
+++ b/tests/f_inlinedata_repair/expect.1
@@ -8,11 +8,6 @@ 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
@@ -26,26 +21,16 @@ 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
+Inode 36 (/A) has invalid mode (00).
+Clear? 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
@@ -63,13 +48,8 @@ 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
+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
index 519f21d..2c400a5 100644
--- a/tests/f_inlinedata_repair/expect.2
+++ b/tests/f_inlinedata_repair/expect.2
@@ -3,5 +3,5 @@ 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
+test_filesys: 27/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 0
diff --git a/tests/f_inlinedir_detector/expect.1 b/tests/f_inlinedir_detector/expect.1
new file mode 100644
index 0000000..72b7519
--- /dev/null
+++ b/tests/f_inlinedir_detector/expect.1
@@ -0,0 +1,20 @@
+Pass 1: Checking inodes, blocks, and sizes
+Special (device/socket/fifo) file (inode 12) has extents
+or inline-data flag set. Clear? yes
+
+Special (device/socket/fifo) inode 12 has non-zero size. Fix? yes
+
+Inode 13 is a named pipe but it looks like it is really a directory.
+Fix? yes
+
+Pass 2: Checking directory structure
+Entry 'moo' in / (2) has an incorrect filetype (was 1, should be 5).
+Fix? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 13/128 files (0.0% non-contiguous), 17/512 blocks
+Exit status is 1
diff --git a/tests/f_inlinedir_detector/expect.2 b/tests/f_inlinedir_detector/expect.2
new file mode 100644
index 0000000..06886a4
--- /dev/null
+++ b/tests/f_inlinedir_detector/expect.2
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 13/128 files (0.0% non-contiguous), 17/512 blocks
+Exit status is 0
diff --git a/tests/f_inlinedir_detector/image.gz b/tests/f_inlinedir_detector/image.gz
new file mode 100644
index 0000000000000000000000000000000000000000..34b4518849cd60d83890b5c69ff6a0aefaa54d57
GIT binary patch
literal 2640
zcmb2|=3qD$xIcu6`R%Rq*)pLr3?IxlYj2y~vTS8L7pwfo71CL^ompDhH082Xu2x-J
zdNY?<+C0T9M8L30!*$}L`UeZYT#5dA=fTO<wpEvAbG&lg(;;yG4S)2t+=Z$eGk^co
zx&Qsy**!NOS{vKkJCnz8U~<-GolgSue6PNb<T#p8Yu6Fie%5jSlDcQlZVGJMe&26y
z@...-ufIFZ_VvgD!}+W7?Rg&_4#}VU>*J*>XC9f)zaRDc)u-$7v6T`#>;B)qdb&Q;
ze}8fA%k%nvcYY<>ajPFrxp%)TUC#Qc$FG#+YvI8*Pp>gEJW$kFzTa3gt@...rI4!4
zm-i{%skkZ0#K6$te*gIIRS(~vYJR_;mw|!dP36<~|0gS+e(v;tKf`3j^Ut6C`v0(2
z?aHUJ<uCSKc$Kqfe@veC;z?`EtP-_!>&q8Rn*TcHix4YN=eHf5yKVkYud{pb2go~+
zoP0|YNHd)O4<bnb8+LD-FP+H@)X^`S??8e^bfr7wf1kf&W8I^!`95Ae$k0~rf7Xrb
ztAD4y?blhmQ`bB2X5(Xd$zs_%y$Aj$ex4kXGgrp=UuyHj_XmA@...K_f1?@...0Ab
zJAV4h@...U7yR<<gtF>?lmBnJ{WIQH;!xD8^h<^9hDK4o(~o}MSe>}EW9`&3W3jV&
zg41WOJ?3VuyT$7D#*Jlm>$dy~6+CZx>+Q3mJv%P#y>Rozv8}&P)~Bibe|1^^+cdu=
zGqU3U7wx>5d*|(Lsn@+%)3)!7yOPE2y?+1hEg!BuTD|$}(I3yU^N&<1%k_R$x)%Pp
zW=*|7yp`DNyEmiOp7}p@...~TcM^Hl|DXGlKl-zE%|G|g_Fv}zx&M3n*URb05AXfN
mjvg+f{Lv5?4S~@...85Z5Eu;sDusZ?U*<Usuk0BZ6c_*iEnI&9
literal 0
HcmV?d00001
diff --git a/tests/f_inlinedir_detector/name b/tests/f_inlinedir_detector/name
new file mode 100644
index 0000000..3368af5
--- /dev/null
+++ b/tests/f_inlinedir_detector/name
@@ -0,0 +1 @@
+detect inline dirs correctly
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists