[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200319233433.117144-3-harshadshirwadkar@gmail.com>
Date: Thu, 19 Mar 2020 16:34:28 -0700
From: Harshad Shirwadkar <harshadshirwadkar@...il.com>
To: linux-ext4@...r.kernel.org
Cc: Harshad Shirwadkar <harshadshirwadkar@...il.com>
Subject: [PATCH 2/7] e2fsck: allow rewriting extents of a file
Add a new function e2fsck_rewrite_extent_tree() that replaces extent
tree for an inode. This allows fast_commit code in subsequent patches
to recreate a file as expected.
Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@...il.com>
---
e2fsck/e2fsck.h | 17 +++++
e2fsck/extents.c | 160 +++++++++++++++++++++++++++++------------------
2 files changed, 117 insertions(+), 60 deletions(-)
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 9b2b9ce8..68f7a249 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -526,6 +526,19 @@ void destroy_encryption_policy_map(e2fsck_t ctx);
void destroy_encrypted_file_info(e2fsck_t ctx);
/* extents.c */
+struct extent_list {
+ blk64_t blocks_freed;
+ struct ext2fs_extent *extents;
+ unsigned int count;
+ unsigned int size;
+ unsigned int ext_read;
+ errcode_t retval;
+ ext2_ino_t ino;
+};
+
+#define NUM_EXTENTS 341 /* about one ETB' worth of extents */
+
+
errcode_t e2fsck_rebuild_extents_later(e2fsck_t ctx, ext2_ino_t ino);
int e2fsck_ino_will_be_rebuilt(e2fsck_t ctx, ext2_ino_t ino);
void e2fsck_pass1e(e2fsck_t ctx);
@@ -536,6 +549,10 @@ errcode_t e2fsck_should_rebuild_extents(e2fsck_t ctx,
struct problem_context *pctx,
struct extent_tree_info *eti,
struct ext2_extent_info *info);
+errcode_t e2fsck_read_extents(e2fsck_t ctx, struct extent_list *extents);
+errcode_t e2fsck_rewrite_extent_tree(e2fsck_t ctx,
+ struct extent_list *extents);
+
/* journal.c */
extern errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx);
diff --git a/e2fsck/extents.c b/e2fsck/extents.c
index e9139326..dc10cc8c 100644
--- a/e2fsck/extents.c
+++ b/e2fsck/extents.c
@@ -20,7 +20,6 @@
#undef DEBUG_SUMMARY
#undef DEBUG_FREE
-#define NUM_EXTENTS 341 /* about one ETB' worth of extents */
static errcode_t e2fsck_rebuild_extents(e2fsck_t ctx, ext2_ino_t ino);
@@ -58,16 +57,6 @@ int e2fsck_ino_will_be_rebuilt(e2fsck_t ctx, ext2_ino_t ino)
return ext2fs_test_inode_bitmap2(ctx->inodes_to_rebuild, ino);
}
-struct extent_list {
- blk64_t blocks_freed;
- struct ext2fs_extent *extents;
- unsigned int count;
- unsigned int size;
- unsigned int ext_read;
- errcode_t retval;
- ext2_ino_t ino;
-};
-
static errcode_t load_extents(e2fsck_t ctx, struct extent_list *list)
{
ext2_filsys fs = ctx->fs;
@@ -206,65 +195,35 @@ static int find_blocks(ext2_filsys fs, blk64_t *blocknr, e2_blkcnt_t blockcnt,
return 0;
}
-static errcode_t rebuild_extent_tree(e2fsck_t ctx, struct extent_list *list,
- ext2_ino_t ino)
+errcode_t __e2fsck_rewrite_extent_tree(e2fsck_t ctx, struct extent_list *list,
+ struct ext2_inode_large *inode)
{
- struct ext2_inode_large inode;
errcode_t retval;
ext2_extent_handle_t handle;
unsigned int i, ext_written;
struct ext2fs_extent *ex, extent;
blk64_t start_val, delta;
- list->count = 0;
- list->blocks_freed = 0;
- list->ino = ino;
- list->ext_read = 0;
- e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode), sizeof(inode),
- "rebuild_extents");
-
- /* Skip deleted inodes and inline data files */
- if (inode.i_links_count == 0 ||
- inode.i_flags & EXT4_INLINE_DATA_FL)
- return 0;
-
- /* Collect lblk->pblk mappings */
- if (inode.i_flags & EXT4_EXTENTS_FL) {
- retval = load_extents(ctx, list);
- if (retval)
- goto err;
- goto extents_loaded;
- }
-
- retval = ext2fs_block_iterate3(ctx->fs, ino, BLOCK_FLAG_READ_ONLY, 0,
- find_blocks, list);
- if (retval)
- goto err;
- if (list->retval) {
- retval = list->retval;
- goto err;
- }
-
-extents_loaded:
/* Reset extent tree */
- inode.i_flags &= ~EXT4_EXTENTS_FL;
- memset(inode.i_block, 0, sizeof(inode.i_block));
+ inode->i_flags &= ~EXT4_EXTENTS_FL;
+ memset(inode->i_block, 0, sizeof(inode->i_block));
/* Make a note of freed blocks */
- quota_data_sub(ctx->qctx, &inode, ino,
+ quota_data_sub(ctx->qctx, inode, list->ino,
list->blocks_freed * ctx->fs->blocksize);
- retval = ext2fs_iblk_sub_blocks(ctx->fs, EXT2_INODE(&inode),
+ retval = ext2fs_iblk_sub_blocks(ctx->fs, EXT2_INODE(inode),
list->blocks_freed);
if (retval)
- goto err;
+ return retval;
/* Now stuff extents into the file */
- retval = ext2fs_extent_open2(ctx->fs, ino, EXT2_INODE(&inode), &handle);
+ retval = ext2fs_extent_open2(ctx->fs, list->ino, EXT2_INODE(inode),
+ &handle);
if (retval)
- goto err;
+ return retval;
ext_written = 0;
- start_val = ext2fs_get_stat_i_blocks(ctx->fs, EXT2_INODE(&inode));
+ start_val = ext2fs_get_stat_i_blocks(ctx->fs, EXT2_INODE(inode));
for (i = 0, ex = list->extents; i < list->count; i++, ex++) {
memcpy(&extent, ex, sizeof(struct ext2fs_extent));
extent.e_flags &= EXT2_EXTENT_FLAGS_UNINIT;
@@ -289,36 +248,117 @@ extents_loaded:
}
#ifdef DEBUG
- printf("W: ino=%d pblk=%llu lblk=%llu len=%u\n", ino,
+ printf("W: ino=%d pblk=%llu lblk=%llu len=%u\n", list->ino,
extent.e_pblk, extent.e_lblk, extent.e_len);
#endif
retval = ext2fs_extent_insert(handle, EXT2_EXTENT_INSERT_AFTER,
&extent);
if (retval)
- goto err2;
+ goto err;
retval = ext2fs_extent_fix_parents(handle);
if (retval)
- goto err2;
+ goto err;
ext_written++;
}
- delta = ext2fs_get_stat_i_blocks(ctx->fs, EXT2_INODE(&inode)) -
+ delta = ext2fs_get_stat_i_blocks(ctx->fs, EXT2_INODE(inode)) -
start_val;
if (delta)
- quota_data_add(ctx->qctx, &inode, ino, delta << 9);
+ quota_data_add(ctx->qctx, inode, list->ino, delta << 9);
#if defined(DEBUG) || defined(DEBUG_SUMMARY)
printf("rebuild: ino=%d extents=%d->%d\n", ino, list->ext_read,
ext_written);
#endif
- e2fsck_write_inode(ctx, ino, EXT2_INODE(&inode), "rebuild_extents");
+ e2fsck_write_inode(ctx, list->ino, EXT2_INODE(inode),
+ "rebuild_extents");
-err2:
- ext2fs_extent_free(handle);
err:
+ ext2fs_extent_free(handle);
return retval;
}
+errcode_t e2fsck_rewrite_extent_tree(e2fsck_t ctx, struct extent_list *list)
+{
+ struct ext2_inode_large inode;
+ int i;
+
+ e2fsck_read_inode_full(ctx, list->ino, EXT2_INODE(&inode),
+ sizeof(inode), "e2fsck_rewrite_extent_tree");
+
+ /* Skip deleted inodes and inline data files */
+ if (inode.i_links_count == 0 ||
+ inode.i_flags & EXT4_INLINE_DATA_FL)
+ return 0;
+
+ return __e2fsck_rewrite_extent_tree(ctx, list, &inode);
+}
+
+errcode_t e2fsck_read_extents(e2fsck_t ctx, struct extent_list *extents)
+{
+ struct ext2_inode_large inode;
+ errcode_t retval;
+
+ extents->extents = NULL;
+ extents->count = 0;
+ extents->blocks_freed = 0;
+ extents->ext_read = 0;
+ extents->size = NUM_EXTENTS;
+ retval = ext2fs_get_array(NUM_EXTENTS, sizeof(struct ext2fs_extent),
+ &extents->extents);
+ if (retval)
+ return -ENOMEM;
+
+ e2fsck_read_inode_full(ctx, extents->ino, EXT2_INODE(&inode),
+ sizeof(inode), "read_extents");
+
+ /* Skip deleted inodes and inline data files */
+ if (inode.i_links_count == 0 || inode.i_flags & EXT4_INLINE_DATA_FL)
+ return 0;
+
+ if (!inode.i_flags & EXT4_EXTENTS_FL)
+ return 0;
+ retval = load_extents(ctx, extents);
+ if (retval) {
+ ext2fs_free_mem(&extents->extents);
+ return retval;
+ }
+ return 0;
+}
+
+static errcode_t rebuild_extent_tree(e2fsck_t ctx, struct extent_list *list,
+ ext2_ino_t ino)
+{
+ struct ext2_inode_large inode;
+ errcode_t retval;
+
+ list->count = 0;
+ list->blocks_freed = 0;
+ list->ino = ino;
+ list->ext_read = 0;
+ e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode), sizeof(inode),
+ "rebuild_extents");
+
+ /* Skip deleted inodes and inline data files */
+ if (inode.i_links_count == 0 ||
+ inode.i_flags & EXT4_INLINE_DATA_FL)
+ return 0;
+
+ /* Collect lblk->pblk mappings */
+ if (inode.i_flags & EXT4_EXTENTS_FL) {
+ retval = load_extents(ctx, list);
+ if (retval)
+ return retval;
+ return __e2fsck_rewrite_extent_tree(ctx, list, &inode);
+ }
+
+ retval = ext2fs_block_iterate3(ctx->fs, ino, BLOCK_FLAG_READ_ONLY, 0,
+ find_blocks, list);
+
+ return retval || list->retval ||
+ __e2fsck_rewrite_extent_tree(ctx, list, &inode);
+}
+
/* Rebuild the extents immediately */
static errcode_t e2fsck_rebuild_extents(e2fsck_t ctx, ext2_ino_t ino)
{
--
2.25.1.696.g5e7596f4ac-goog
Powered by blists - more mailing lists