From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: tytso@mit.edu, darrick.wong@oracle.com
Cc: linux-ext4@vger.kernel.org
Subject: [PATCH 12/24] e2fsck: force all block allocations to use block_found_map
Date: Fri, 18 Jul 2014 15:53:41 -0700 [thread overview]
Message-ID: <20140718225341.31374.29415.stgit@birch.djwong.org> (raw)
In-Reply-To: <20140718225200.31374.85411.stgit@birch.djwong.org>
During the later passes of efsck, we sometimes need to allocate and
map blocks into a file. This can happen either by fsck directly
calling new_block() or indirectly by the library calling new_block
because it needs to allocate a block for lower level metadata (bmap2()
with BMAP_SET; block_iterate3() with BLOCK_CHANGED).
We need to force new_block to allocate blocks from the found block
map, because the FS block map could be inaccurate for various reasons:
the map is wrong, there are missing blocks, the checksum failed, etc.
Therefore, any time fsck does something that could to allocate blocks,
we need to intercept allocation requests so that they're sourced from
the found block map. Remove the previous code that swapped bitmap
pointers as this is now unneeded.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
e2fsck/e2fsck.h | 1 +
e2fsck/pass1.c | 18 ++++++++----------
e2fsck/pass1b.c | 1 -
e2fsck/pass2.c | 3 ---
e2fsck/pass3.c | 37 -------------------------------------
e2fsck/rehash.c | 2 --
6 files changed, 9 insertions(+), 53 deletions(-)
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 53f10b1..d6d0ba9 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -473,6 +473,7 @@ extern int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
extern void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
struct ext2_inode *inode, int restart_flag,
const char *source);
+extern void e2fsck_intercept_block_allocations(e2fsck_t ctx);
/* pass2.c */
extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 37b05ff..5ad7fe5 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -764,6 +764,7 @@ void e2fsck_pass1(e2fsck_t ctx)
"block interate buffer");
if (EXT2_INODE_SIZE(fs->super) == EXT2_GOOD_OLD_INODE_SIZE)
e2fsck_use_inode_shortcuts(ctx, 1);
+ e2fsck_intercept_block_allocations(ctx);
old_op = ehandler_operation(_("opening inode scan"));
pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
&scan);
@@ -1306,10 +1307,6 @@ void e2fsck_pass1(e2fsck_t ctx)
}
if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
- ext2fs_block_bitmap save_bmap;
-
- save_bmap = fs->block_map;
- fs->block_map = ctx->block_found_map;
clear_problem_context(&pctx);
pctx.errcode = ext2fs_create_resize_inode(fs);
if (pctx.errcode) {
@@ -1327,7 +1324,6 @@ void e2fsck_pass1(e2fsck_t ctx)
e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
"recreate inode");
}
- fs->block_map = save_bmap;
ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
}
@@ -3206,11 +3202,6 @@ void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts)
fs->read_inode = pass1_read_inode;
fs->write_inode = pass1_write_inode;
ctx->stashed_ino = 0;
- ext2fs_set_alloc_block_callback(fs, e2fsck_get_alloc_block,
- 0);
- ext2fs_set_block_alloc_stats_callback(fs,
- e2fsck_block_alloc_stats,
- 0);
} else {
fs->get_blocks = 0;
fs->check_directory = 0;
@@ -3218,3 +3209,10 @@ void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts)
fs->write_inode = 0;
}
}
+
+void e2fsck_intercept_block_allocations(e2fsck_t ctx)
+{
+ ext2fs_set_alloc_block_callback(ctx->fs, e2fsck_get_alloc_block, 0);
+ ext2fs_set_block_alloc_stats_callback(ctx->fs,
+ e2fsck_block_alloc_stats, 0);
+}
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index c2a3cf3..8d42d10 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -630,7 +630,6 @@ static int delete_file_block(ext2_filsys fs,
_("internal error: can't find dup_blk for %llu\n"),
*block_nr);
} else {
- ext2fs_unmark_block_bitmap2(ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
pb->dup_blocks++;
}
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 5488c73..0ef9637 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1336,7 +1336,6 @@ static int deallocate_inode_block(ext2_filsys fs,
if ((*block_nr < fs->super->s_first_data_block) ||
(*block_nr >= ext2fs_blocks_count(fs->super)))
return 0;
- ext2fs_unmark_block_bitmap2(p->ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
p->num++;
return 0;
@@ -1379,8 +1378,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
return;
}
if (count == 0) {
- ext2fs_unmark_block_bitmap2(ctx->block_found_map,
- ext2fs_file_acl_block(fs, &inode));
ext2fs_block_alloc_stats2(fs,
ext2fs_file_acl_block(fs, &inode), -1);
}
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 6f7f855..4fc390a 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -779,27 +779,6 @@ static int expand_dir_proc(ext2_filsys fs,
return BLOCK_CHANGED;
}
-/*
- * Ensure that all blocks are marked in the block_found_map, since it's
- * possible that the library allocated an extent node block or a block map
- * block during the directory rebuilding; these new allocations are not
- * captured in block_found_map. This is bad since we could later use
- * block_found_map to allocate more blocks.
- */
-static int find_new_blocks_proc(ext2_filsys fs,
- blk64_t *blocknr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *priv_data)
-{
- struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
- e2fsck_t ctx = es->ctx;
-
- ext2fs_mark_block_bitmap2(ctx->block_found_map, *blocknr);
- return 0;
-}
-
errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
int num, int guaranteed_size)
{
@@ -830,27 +809,11 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
es.ctx = ctx;
es.dir = dir;
- before = ext2fs_free_blocks_count(fs->super);
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
0, expand_dir_proc, &es);
if (es.err)
return es.err;
- after = ext2fs_free_blocks_count(fs->super);
-
- /*
- * If the free block count has dropped by more than the blocks we
- * allocated ourselves, then we must've allocated some extent/map
- * blocks. Therefore, we must iterate this dir's blocks again to
- * ensure that all newly allocated blocks are captured in
- * block_found_map.
- */
- if ((before - after) > es.newblocks) {
- retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY,
- 0, find_new_blocks_proc, &es);
- if (es.err)
- return es.err;
- }
/*
* Update the size and block count fields in the inode.
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index 3b05715..f75479a 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -725,8 +725,6 @@ static int write_dir_block(ext2_filsys fs,
* once.
*/
if (blk % EXT2FS_CLUSTER_RATIO(fs) == 0) {
- ext2fs_unmark_block_bitmap2(wd->ctx->block_found_map,
- blk);
ext2fs_block_alloc_stats2(fs, blk, -1);
wd->cleared++;
}
next prev parent reply other threads:[~2014-07-18 22:53 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-18 22:52 [PATCH 00/24] e2fsprogs patchbomb 7/14, part 1 Darrick J. Wong
2014-07-18 22:52 ` [PATCH 01/24] e4defrag: backwards-allocated files should be defragmented too Darrick J. Wong
2014-07-21 23:44 ` Akira Fujita
2014-07-22 16:32 ` Theodore Ts'o
2014-07-18 22:52 ` [PATCH 02/24] debugfs: Only print the first 60 bytes from i_block on a fast symlink Darrick J. Wong
2014-07-19 16:49 ` Andreas Dilger
2014-07-22 16:43 ` Theodore Ts'o
2014-07-22 20:39 ` Darrick J. Wong
2014-07-22 20:34 ` Darrick J. Wong
2014-07-18 22:52 ` [PATCH 03/24] debugfs: create idump command to dump an inode in hex Darrick J. Wong
2014-07-22 17:47 ` Theodore Ts'o
2014-07-18 22:52 ` [PATCH 04/24] debugfs: allow bmap to allocate blocks Darrick J. Wong
2014-07-22 17:52 ` Theodore Ts'o
2014-07-18 22:52 ` [PATCH 05/24] e2fsck: report correct inode number in pass1b Darrick J. Wong
2014-07-22 17:47 ` Theodore Ts'o
2014-07-18 22:52 ` [PATCH 06/24] e2fsck: don't offer to recreate the journal if fsck is aborting due to bad block bitmaps Darrick J. Wong
2014-07-22 17:58 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 07/24] e2fsck: skip clearing bad extents if bitmaps are unreadable Darrick J. Wong
2014-07-22 17:58 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 08/24] e2fsck: fix inode coherency issue when iterating an inode's blocks Darrick J. Wong
2014-07-22 18:58 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 09/24] e2fsck: clear i_block if there are too many bad block mappings Darrick J. Wong
2014-07-22 18:59 ` Theodore Ts'o
2014-07-22 22:14 ` Darrick J. Wong
2014-07-22 22:48 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 10/24] e2fsck: don't clobber critical metadata during check_blocks Darrick J. Wong
2014-07-25 1:03 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 11/24] e2fsck: free ctx->fs, not fs, at the end of fsck Darrick J. Wong
2014-07-25 1:14 ` Theodore Ts'o
2014-07-18 22:53 ` Darrick J. Wong [this message]
2014-07-25 2:18 ` [PATCH 12/24] e2fsck: force all block allocations to use block_found_map Theodore Ts'o
2014-07-18 22:53 ` [PATCH 13/24] e2fsck: fix off-by-one bounds check on group number Darrick J. Wong
2014-07-25 2:20 ` Theodore Ts'o
2014-07-18 22:53 ` [PATCH 14/24] libext2fs: fix bounds check of the bitmap test range in get_free_blocks2 Darrick J. Wong
2014-07-25 11:13 ` Theodore Ts'o
2014-07-18 22:54 ` [PATCH 15/24] misc: fix problems with strncat Darrick J. Wong
2014-07-25 11:22 ` Theodore Ts'o
2014-07-18 22:54 ` [PATCH 16/24] e2fsck: don't crash during rehash Darrick J. Wong
2014-07-25 11:22 ` Theodore Ts'o
2014-07-18 22:54 ` [PATCH 17/24] e2fsck: reserve blocks for root/lost+found directory repair Darrick J. Wong
2014-07-25 12:12 ` Theodore Ts'o
2014-07-25 20:19 ` Darrick J. Wong
2014-07-18 22:54 ` [PATCH 18/24] e2fsck: collapse holes in extent-based directories Darrick J. Wong
2014-07-25 12:33 ` Theodore Ts'o
2014-07-18 22:54 ` [PATCH 19/24] e2fsck: always submit logical block 0 of a directory for pass 2 Darrick J. Wong
2014-07-25 12:40 ` Theodore Ts'o
2014-07-18 22:54 ` [PATCH 20/24] e2fsck: pass2 should not process directory blocks that are impossibly large Darrick J. Wong
2014-07-25 12:42 ` Theodore Ts'o
2014-07-18 22:55 ` [PATCH 21/24] e2fsck: clear uninit flag on directory extents Darrick J. Wong
2014-07-25 13:00 ` Theodore Ts'o
2014-07-18 22:55 ` [PATCH 22/24] e2fsck: check return value of ext2fs_extent_fix_parents() Darrick J. Wong
2014-07-25 12:51 ` Theodore Ts'o
2014-07-18 22:55 ` [PATCH 23/24] mke2fs: set error behavior at initialization time Darrick J. Wong
2014-07-25 13:00 ` Theodore Ts'o
2014-07-18 22:55 ` [PATCH 24/24] e2fuzz: Create a tool to fuzz ext* filesystems Darrick J. Wong
2014-07-25 13:16 ` Theodore Ts'o
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140718225341.31374.29415.stgit@birch.djwong.org \
--to=darrick.wong@oracle.com \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).