lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1205385147-12855-3-git-send-email-tytso@mit.edu>
Date:	Thu, 13 Mar 2008 01:12:26 -0400
From:	Theodore Ts'o <tytso@....edu>
To:	bas@....tetra.nl
Cc:	linux-ext4@...r.kernel.org, Theodore Ts'o <tytso@....edu>
Subject: [E2FSPROGS PATCH 3/4] e2fsck: Fix directory i_size handling

If a directory's i_size is bigger than the number of blocks, don't try
to allocate extra empty blocks to the end of the directory; there's no
real point to do that.  Also, if a directory's i_size is not a
multiple of the blocksize, flag that as a mistake so it can be fixed.

This more elegantly addresses the problem which was found on Bas van
Schaik's filesystem.

Signed-off-by: "Theodore Ts'o" <tytso@....edu>
---
 e2fsck/pass1.c           |   25 ++++++++++++++++++++++++-
 tests/f_holedir/expect.1 |   13 ++++++++++---
 tests/f_holedir/expect.2 |    2 +-
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index b4db8ef..839f099 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1546,6 +1546,26 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		goto out;
 	}
 	
+	if (pb.is_dir) {
+		while (1) {
+			struct ext2_db_entry *entry;
+
+			if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
+			    (entry->ino != ino) ||
+			    (entry->blk != 0) ||
+			    (entry->blockcnt == 0))
+				break;
+			/* printf("Dropping ino %lu blk %lu blockcnt %d\n", 
+				  entry->ino, entry->blk, entry->blockcnt); */
+			ext2fs_dblist_drop_last(fs->dblist);
+			if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
+			    (entry->ino != ino))
+				pb.last_block--;
+			else
+				pb.last_block = entry->blockcnt;
+		}
+	}
+
 	if (inode->i_flags & EXT2_INDEX_FL) {
 		if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
 			inode->i_flags &= ~EXT2_INDEX_FL;
@@ -1583,7 +1603,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 #endif
 	if (pb.is_dir) {
 		int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
-		if (nblock > (pb.last_block + 1))
+		if (inode->i_size & (fs->blocksize - 1)) 
+			bad_size = 5;
+		else if (nblock > (pb.last_block + 1))
 			bad_size = 1;
 		else if (nblock < (pb.last_block + 1)) {
 			if (((pb.last_block + 1) - nblock) >
@@ -1745,6 +1767,7 @@ static int process_block(ext2_filsys fs,
 			printf("Missing block (#%d) in directory inode %lu!\n",
 			       blockcnt, p->ino);
 #endif
+			p->last_block = blockcnt;
 			goto mark_dir;
 		}
 		return 0;
diff --git a/tests/f_holedir/expect.1 b/tests/f_holedir/expect.1
index 05e0cbb..ad74fa6 100644
--- a/tests/f_holedir/expect.1
+++ b/tests/f_holedir/expect.1
@@ -15,12 +15,19 @@ Directory inode 11 has an unallocated block #3.  Allocate? yes
 
 Directory inode 11 has an unallocated block #6.  Allocate? yes
 
-Directory inode 11 has an unallocated block #11.  Allocate? yes
-
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
+Block bitmap differences:  -21
+Fix? yes
+
+Free blocks count wrong for group #0 (78, counted=79).
+Fix? yes
+
+Free blocks count wrong (78, counted=79).
+Fix? yes
+
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/32 files (9.1% non-contiguous), 22/100 blocks
+test_filesys: 11/32 files (9.1% non-contiguous), 21/100 blocks
 Exit status is 1
diff --git a/tests/f_holedir/expect.2 b/tests/f_holedir/expect.2
index a821f87..4c0b4f2 100644
--- a/tests/f_holedir/expect.2
+++ b/tests/f_holedir/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: 11/32 files (0.0% non-contiguous), 22/100 blocks
+test_filesys: 11/32 files (0.0% non-contiguous), 21/100 blocks
 Exit status is 0
-- 
1.5.4.1.144.gdfee-dirty

--
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ