2022-08-03 08:13:23

by Alexey Lyahkov

[permalink] [raw]
Subject: [PATCH] e2fsprogs: avoid code duplication

debugfs and e2fsck have a so much code duplication in journal handing.
debugfs have lack a many journal features handing also.
Let's start code merging to avoid code duplication and lack features.

userspace buffer head emulation moved into library.

Signed-off-by: Alexey Lyashkov <[email protected]>
---
debugfs/Makefile.in | 14 +-
debugfs/debugfs.c | 2 +-
debugfs/journal.c | 251 ---------------------------
debugfs/journal.h | 2 +-
debugfs/logdump.c | 2 +-
e2fsck/Makefile.in | 8 +-
e2fsck/e2fsck.c | 5 -
e2fsck/e2fsck.h | 1 -
e2fsck/journal.c | 278 ++----------------------------
e2fsck/logfile.c | 2 +-
e2fsck/recovery.c | 2 +-
e2fsck/revoke.c | 2 +-
e2fsck/unix.c | 4 +-
e2fsck/util.c | 2 +-
lib/ext2fs/Android.bp | 1 +
lib/ext2fs/Makefile.in | 23 +--
lib/ext2fs/jfs_user.c | 255 +++++++++++++++++++++++++++
{e2fsck => lib/ext2fs}/jfs_user.h | 55 +++---
misc/Makefile.in | 10 +-
19 files changed, 341 insertions(+), 578 deletions(-)
create mode 100644 lib/ext2fs/jfs_user.c
rename {e2fsck => lib/ext2fs}/jfs_user.h (89%)

diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index ed4ea8d8..cc846cb1 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -49,7 +49,7 @@ STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) \

# This nastiness is needed because of jfs_user.h hackery; when we finally
# clean up this mess, we should be able to drop it
-LOCAL_CFLAGS = -I$(srcdir)/../e2fsck -DDEBUGFS
+LOCAL_CFLAGS = -DDEBUGFS
DEPEND_CFLAGS = -I$(srcdir)

.c.o:
@@ -186,7 +186,7 @@ debugfs.o: $(srcdir)/debugfs.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/quotaio.h \
$(top_srcdir)/lib/support/dqblk_v2.h \
$(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/version.h \
- $(srcdir)/../e2fsck/jfs_user.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
+ $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
$(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
$(top_srcdir)/lib/ext2fs/compiler.h $(top_srcdir)/lib/support/plausible.h
util.o: $(srcdir)/util.c $(top_builddir)/lib/config.h \
@@ -277,7 +277,7 @@ logdump.o: $(srcdir)/logdump.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../misc/create_inode.h \
$(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/quotaio.h \
$(top_srcdir)/lib/support/dqblk_v2.h \
- $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/../e2fsck/jfs_user.h \
+ $(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h
@@ -382,7 +382,7 @@ quota.o: $(srcdir)/quota.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/support/quotaio_tree.h
journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/journal.h \
- $(srcdir)/../e2fsck/jfs_user.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
@@ -390,7 +390,7 @@ journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
$(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
$(top_srcdir)/lib/ext2fs/compiler.h
-revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
+revoke.o: $(srcdir)/../e2fsck/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
@@ -399,7 +399,7 @@ revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
$(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
$(top_srcdir)/lib/ext2fs/compiler.h
-recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \
+recovery.o: $(srcdir)/../e2fsck/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
@@ -421,4 +421,4 @@ do_journal.o: $(srcdir)/do_journal.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/support/quotaio_tree.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
- $(srcdir)/journal.h $(srcdir)/../e2fsck/jfs_user.h
+ $(srcdir)/journal.h $(top_srcdir)/lib/ext2fs/jfs_user.h
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index b67a88bc..28f1ddf0 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -37,7 +37,7 @@ extern char *optarg;
#include <ext2fs/ext2_ext_attr.h>

#include "../version.h"
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
#include "support/plausible.h"

#ifndef BUFSIZ
diff --git a/debugfs/journal.c b/debugfs/journal.c
index 095fff00..ee25419a 100644
--- a/debugfs/journal.c
+++ b/debugfs/journal.c
@@ -26,8 +26,6 @@
#include "uuid/uuid.h"
#include "journal.h"

-static int bh_count = 0;
-
#if EXT2_FLAT_INCLUDES
#include "blkid.h"
#else
@@ -43,221 +41,6 @@ static int bh_count = 0;
*/
#undef USE_INODE_IO

-/* Checksumming functions */
-static int ext2fs_journal_verify_csum_type(journal_t *j,
- journal_superblock_t *jsb)
-{
- if (!jbd2_journal_has_csum_v2or3(j))
- return 1;
-
- return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
-}
-
-static __u32 ext2fs_journal_sb_csum(journal_superblock_t *jsb)
-{
- __u32 crc, old_crc;
-
- old_crc = jsb->s_checksum;
- jsb->s_checksum = 0;
- crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
- sizeof(journal_superblock_t));
- jsb->s_checksum = old_crc;
-
- return crc;
-}
-
-static int ext2fs_journal_sb_csum_verify(journal_t *j,
- journal_superblock_t *jsb)
-{
- __u32 provided, calculated;
-
- if (!jbd2_journal_has_csum_v2or3(j))
- return 1;
-
- provided = ext2fs_be32_to_cpu(jsb->s_checksum);
- calculated = ext2fs_journal_sb_csum(jsb);
-
- return provided == calculated;
-}
-
-static errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
- journal_superblock_t *jsb)
-{
- __u32 crc;
-
- if (!jbd2_journal_has_csum_v2or3(j))
- return 0;
-
- crc = ext2fs_journal_sb_csum(jsb);
- jsb->s_checksum = ext2fs_cpu_to_be32(crc);
- return 0;
-}
-
-/* Kernel compatibility functions for handling the journal. These allow us
- * to use the recovery.c file virtually unchanged from the kernel, so we
- * don't have to do much to keep kernel and user recovery in sync.
- */
-int jbd2_journal_bmap(journal_t *journal, unsigned long block,
- unsigned long long *phys)
-{
-#ifdef USE_INODE_IO
- *phys = block;
- return 0;
-#else
- struct inode *inode = journal->j_inode;
- errcode_t retval;
- blk64_t pblk;
-
- if (!inode) {
- *phys = block;
- return 0;
- }
-
- retval = ext2fs_bmap2(inode->i_fs, inode->i_ino,
- &inode->i_ext2, NULL, 0, (blk64_t) block,
- 0, &pblk);
- *phys = pblk;
- return (int) retval;
-#endif
-}
-
-struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
- int blocksize)
-{
- struct buffer_head *bh;
- int bufsize = sizeof(*bh) + kdev->k_fs->blocksize -
- sizeof(bh->b_data);
- errcode_t retval;
-
- retval = ext2fs_get_memzero(bufsize, &bh);
- if (retval)
- return NULL;
-
- if (journal_enable_debug >= 3)
- bh_count++;
- jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
- blocknr, blocksize, bh_count);
-
- bh->b_fs = kdev->k_fs;
- if (kdev->k_dev == K_DEV_FS)
- bh->b_io = kdev->k_fs->io;
- else
- bh->b_io = kdev->k_fs->journal_io;
- bh->b_size = blocksize;
- bh->b_blocknr = blocknr;
-
- return bh;
-}
-
-int sync_blockdev(kdev_t kdev)
-{
- io_channel io;
-
- if (kdev->k_dev == K_DEV_FS)
- io = kdev->k_fs->io;
- else
- io = kdev->k_fs->journal_io;
-
- return io_channel_flush(io) ? EIO : 0;
-}
-
-void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
- struct buffer_head *bhp[])
-{
- errcode_t retval;
- struct buffer_head *bh;
-
- for (; nr > 0; --nr) {
- bh = *bhp++;
- if (rw == REQ_OP_READ && !bh->b_uptodate) {
- jfs_debug(3, "reading block %llu/%p\n",
- bh->b_blocknr, (void *) bh);
- retval = io_channel_read_blk64(bh->b_io,
- bh->b_blocknr,
- 1, bh->b_data);
- if (retval) {
- com_err(bh->b_fs->device_name, retval,
- "while reading block %llu\n",
- bh->b_blocknr);
- bh->b_err = (int) retval;
- continue;
- }
- bh->b_uptodate = 1;
- } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
- jfs_debug(3, "writing block %llu/%p\n",
- bh->b_blocknr,
- (void *) bh);
- retval = io_channel_write_blk64(bh->b_io,
- bh->b_blocknr,
- 1, bh->b_data);
- if (retval) {
- com_err(bh->b_fs->device_name, retval,
- "while writing block %llu\n",
- bh->b_blocknr);
- bh->b_err = (int) retval;
- continue;
- }
- bh->b_dirty = 0;
- bh->b_uptodate = 1;
- } else {
- jfs_debug(3, "no-op %s for block %llu\n",
- rw == REQ_OP_READ ? "read" : "write",
- bh->b_blocknr);
- }
- }
-}
-
-void mark_buffer_dirty(struct buffer_head *bh)
-{
- bh->b_dirty = 1;
-}
-
-static void mark_buffer_clean(struct buffer_head *bh)
-{
- bh->b_dirty = 0;
-}
-
-void brelse(struct buffer_head *bh)
-{
- if (bh->b_dirty)
- ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
- jfs_debug(3, "freeing block %llu/%p (total %d)\n",
- bh->b_blocknr, (void *) bh, --bh_count);
- ext2fs_free_mem(&bh);
-}
-
-int buffer_uptodate(struct buffer_head *bh)
-{
- return bh->b_uptodate;
-}
-
-void mark_buffer_uptodate(struct buffer_head *bh, int val)
-{
- bh->b_uptodate = val;
-}
-
-void wait_on_buffer(struct buffer_head *bh)
-{
- if (!bh->b_uptodate)
- ll_rw_block(REQ_OP_READ, 0, 1, &bh);
-}
-
-
-static void ext2fs_clear_recover(ext2_filsys fs, int error)
-{
- ext2fs_clear_feature_journal_needs_recovery(fs->super);
-
- /* if we had an error doing journal recovery, we need a full fsck */
- if (error)
- fs->super->s_state &= ~EXT2_VALID_FS;
- /*
- * If we replayed the journal by definition the file system
- * was mounted since the last time it was checked
- */
- if (fs->super->s_lastcheck >= fs->super->s_mtime)
- fs->super->s_lastcheck = fs->super->s_mtime - 1;
- ext2fs_mark_super_dirty(fs);
-}

/*
* This is a helper function to check the validity of the journal.
@@ -640,40 +423,6 @@ static errcode_t ext2fs_journal_load(journal_t *journal)
return 0;
}

-static void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
- int reset, int drop)
-{
- journal_superblock_t *jsb;
-
- if (drop)
- mark_buffer_clean(journal->j_sb_buffer);
- else if (fs->flags & EXT2_FLAG_RW) {
- jsb = journal->j_superblock;
- jsb->s_sequence = htonl(journal->j_tail_sequence);
- if (reset)
- jsb->s_start = 0; /* this marks the journal as empty */
- ext2fs_journal_sb_csum_set(journal, jsb);
- mark_buffer_dirty(journal->j_sb_buffer);
- }
- brelse(journal->j_sb_buffer);
-
- if (fs && fs->journal_io) {
- if (fs->io != fs->journal_io)
- io_channel_close(fs->journal_io);
- fs->journal_io = NULL;
- free(fs->journal_name);
- fs->journal_name = NULL;
- }
-
-#ifndef USE_INODE_IO
- if (journal->j_inode)
- ext2fs_free_mem(&journal->j_inode);
-#endif
- if (journal->j_fs_dev)
- ext2fs_free_mem(&journal->j_fs_dev);
- ext2fs_free_mem(&journal);
-}
-
/*
* This function makes sure that the superblock fields regarding the
* journal are consistent.
diff --git a/debugfs/journal.h b/debugfs/journal.h
index 10b638eb..44d4fa72 100644
--- a/debugfs/journal.h
+++ b/debugfs/journal.h
@@ -12,7 +12,7 @@
* any later version.
*/

-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"

/* journal.c */
errcode_t ext2fs_open_journal(ext2_filsys fs, journal_t **j);
diff --git a/debugfs/logdump.c b/debugfs/logdump.c
index 4154ef2a..99934077 100644
--- a/debugfs/logdump.c
+++ b/debugfs/logdump.c
@@ -32,7 +32,7 @@ extern char *optarg;

#include "debugfs.h"
#include "blkid/blkid.h"
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
#if __GNUC_PREREQ (4, 6)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
index 71ac3cf5..fb8b2b71 100644
--- a/e2fsck/Makefile.in
+++ b/e2fsck/Makefile.in
@@ -383,7 +383,7 @@ pass5.o: $(srcdir)/pass5.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(srcdir)/problem.h
journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/jfs_user.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
@@ -396,7 +396,7 @@ journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h $(srcdir)/problem.h
-recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_user.h \
+recovery.o: $(srcdir)/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
@@ -410,7 +410,7 @@ recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_user.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h
-revoke.o: $(srcdir)/revoke.c $(srcdir)/jfs_user.h \
+revoke.o: $(srcdir)/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
@@ -464,7 +464,7 @@ unix.o: $(srcdir)/unix.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/support/quotaio_tree.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
- $(srcdir)/problem.h $(srcdir)/jfs_user.h \
+ $(srcdir)/problem.h $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/version.h
dirinfo.o: $(srcdir)/dirinfo.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 1e295e3e..0ea1e0df 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -83,11 +83,6 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
ext2fs_free_icount(ctx->inode_link_info);
ctx->inode_link_info = 0;
}
- if (ctx->journal_io) {
- if (ctx->fs && ctx->fs->io != ctx->journal_io)
- io_channel_close(ctx->journal_io);
- ctx->journal_io = 0;
- }
if (ctx->fs && ctx->fs->dblist) {
ext2fs_free_dblist(ctx->fs->dblist);
ctx->fs->dblist = 0;
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 2db216f5..33334781 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -380,7 +380,6 @@ struct e2fsck_struct {
/*
* ext3 journal support
*/
- io_channel journal_io;
char *journal_name;

/*
diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index 2e867234..39d545a3 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -23,12 +23,11 @@
#endif

#define E2FSCK_INCLUDE_INLINE_FUNCS
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
+#include "e2fsck.h"
#include "problem.h"
#include "uuid/uuid.h"

-static int bh_count = 0;
-
/*
* Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
* This creates a larger static binary, and a smaller binary using
@@ -38,215 +37,6 @@ static int bh_count = 0;
*/
#undef USE_INODE_IO

-/* Checksumming functions */
-static int e2fsck_journal_verify_csum_type(journal_t *j,
- journal_superblock_t *jsb)
-{
- if (!jbd2_journal_has_csum_v2or3(j))
- return 1;
-
- return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
-}
-
-static __u32 e2fsck_journal_sb_csum(journal_superblock_t *jsb)
-{
- __u32 crc, old_crc;
-
- old_crc = jsb->s_checksum;
- jsb->s_checksum = 0;
- crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
- sizeof(journal_superblock_t));
- jsb->s_checksum = old_crc;
-
- return crc;
-}
-
-static int e2fsck_journal_sb_csum_verify(journal_t *j,
- journal_superblock_t *jsb)
-{
- __u32 provided, calculated;
-
- if (!jbd2_journal_has_csum_v2or3(j))
- return 1;
-
- provided = ext2fs_be32_to_cpu(jsb->s_checksum);
- calculated = e2fsck_journal_sb_csum(jsb);
-
- return provided == calculated;
-}
-
-static errcode_t e2fsck_journal_sb_csum_set(journal_t *j,
- journal_superblock_t *jsb)
-{
- __u32 crc;
-
- if (!jbd2_journal_has_csum_v2or3(j))
- return 0;
-
- crc = e2fsck_journal_sb_csum(jsb);
- jsb->s_checksum = ext2fs_cpu_to_be32(crc);
- return 0;
-}
-
-/* Kernel compatibility functions for handling the journal. These allow us
- * to use the recovery.c file virtually unchanged from the kernel, so we
- * don't have to do much to keep kernel and user recovery in sync.
- */
-int jbd2_journal_bmap(journal_t *journal, unsigned long block,
- unsigned long long *phys)
-{
-#ifdef USE_INODE_IO
- *phys = block;
- return 0;
-#else
- struct inode *inode = journal->j_inode;
- errcode_t retval;
- blk64_t pblk;
-
- if (!inode) {
- *phys = block;
- return 0;
- }
-
- retval= ext2fs_bmap2(inode->i_ctx->fs, inode->i_ino,
- &inode->i_ext2, NULL, 0, (blk64_t) block,
- 0, &pblk);
- *phys = pblk;
- return -1 * ((int) retval);
-#endif
-}
-
-struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
- int blocksize)
-{
- struct buffer_head *bh;
- int bufsize = sizeof(*bh) + kdev->k_ctx->fs->blocksize -
- sizeof(bh->b_data);
-
- bh = e2fsck_allocate_memory(kdev->k_ctx, bufsize, "block buffer");
- if (!bh)
- return NULL;
-
- if (journal_enable_debug >= 3)
- bh_count++;
- jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
- blocknr, blocksize, bh_count);
-
- bh->b_ctx = kdev->k_ctx;
- if (kdev->k_dev == K_DEV_FS)
- bh->b_io = kdev->k_ctx->fs->io;
- else
- bh->b_io = kdev->k_ctx->journal_io;
- bh->b_size = blocksize;
- bh->b_blocknr = blocknr;
-
- return bh;
-}
-
-int sync_blockdev(kdev_t kdev)
-{
- io_channel io;
-
- if (kdev->k_dev == K_DEV_FS)
- io = kdev->k_ctx->fs->io;
- else
- io = kdev->k_ctx->journal_io;
-
- return io_channel_flush(io) ? -EIO : 0;
-}
-
-void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
- struct buffer_head *bhp[])
-{
- errcode_t retval;
- struct buffer_head *bh;
-
- for (; nr > 0; --nr) {
- bh = *bhp++;
- if (rw == REQ_OP_READ && !bh->b_uptodate) {
- jfs_debug(3, "reading block %llu/%p\n",
- bh->b_blocknr, (void *) bh);
- retval = io_channel_read_blk64(bh->b_io,
- bh->b_blocknr,
- 1, bh->b_data);
- if (retval) {
- com_err(bh->b_ctx->device_name, retval,
- "while reading block %llu\n",
- bh->b_blocknr);
- bh->b_err = (int) retval;
- continue;
- }
- bh->b_uptodate = 1;
- } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
- jfs_debug(3, "writing block %llu/%p\n",
- bh->b_blocknr,
- (void *) bh);
- retval = io_channel_write_blk64(bh->b_io,
- bh->b_blocknr,
- 1, bh->b_data);
- if (retval) {
- com_err(bh->b_ctx->device_name, retval,
- "while writing block %llu\n",
- bh->b_blocknr);
- bh->b_err = (int) retval;
- continue;
- }
- bh->b_dirty = 0;
- bh->b_uptodate = 1;
- } else {
- jfs_debug(3, "no-op %s for block %llu\n",
- rw == REQ_OP_READ ? "read" : "write",
- bh->b_blocknr);
- }
- }
-}
-
-void mark_buffer_dirty(struct buffer_head *bh)
-{
- bh->b_dirty = 1;
-}
-
-static void mark_buffer_clean(struct buffer_head * bh)
-{
- bh->b_dirty = 0;
-}
-
-void brelse(struct buffer_head *bh)
-{
- if (bh->b_dirty)
- ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
- jfs_debug(3, "freeing block %llu/%p (total %d)\n",
- bh->b_blocknr, (void *) bh, --bh_count);
- ext2fs_free_mem(&bh);
-}
-
-int buffer_uptodate(struct buffer_head *bh)
-{
- return bh->b_uptodate;
-}
-
-void mark_buffer_uptodate(struct buffer_head *bh, int val)
-{
- bh->b_uptodate = val;
-}
-
-void wait_on_buffer(struct buffer_head *bh)
-{
- if (!bh->b_uptodate)
- ll_rw_block(REQ_OP_READ, 0, 1, &bh);
-}
-
-
-static void e2fsck_clear_recover(e2fsck_t ctx, int error)
-{
- ext2fs_clear_feature_journal_needs_recovery(ctx->fs->super);
-
- /* if we had an error doing journal recovery, we need a full fsck */
- if (error)
- ctx->fs->super->s_state &= ~EXT2_VALID_FS;
- ext2fs_mark_super_dirty(ctx->fs);
-}
-
/*
* This is a helper function to check the validity of the journal.
*/
@@ -980,6 +770,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
dev_journal = dev_fs+1;

dev_fs->k_ctx = dev_journal->k_ctx = ctx;
+ dev_fs->k_fs = dev_journal->k_fs = ctx->fs;
dev_fs->k_dev = K_DEV_FS;
dev_journal->k_dev = K_DEV_JOURNAL;

@@ -1001,6 +792,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
}

j_inode->i_ctx = ctx;
+ j_inode->i_fs = ctx->fs;
j_inode->i_ino = sb->s_journal_inum;

if ((retval = ext2fs_read_inode(ctx->fs,
@@ -1061,7 +853,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
io_ptr = inode_io_manager;
#else
journal->j_inode = j_inode;
- ctx->journal_io = ctx->fs->io;
+ ctx->fs->journal_io = ctx->fs->io;
if ((ret = jbd2_journal_bmap(journal, 0, &start)) != 0) {
retval = (errcode_t) (-1 * ret);
goto errout;
@@ -1108,12 +900,12 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)


retval = io_ptr->open(journal_name, flags,
- &ctx->journal_io);
+ &ctx->fs->journal_io);
}
if (retval)
goto errout;

- io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
+ io_channel_set_blksize(ctx->fs->journal_io, ctx->fs->blocksize);

if (ext_journal) {
blk64_t maxlen;
@@ -1226,13 +1018,13 @@ static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
memset(sb->s_jnl_blocks, 0, sizeof(sb->s_jnl_blocks));
ctx->flags |= E2F_FLAG_JOURNAL_INODE;
ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- e2fsck_clear_recover(ctx, 1);
+ ext2fs_clear_recover(ctx->fs, 1);
return 0;
}
return EXT2_ET_CORRUPT_JOURNAL_SB;
} else if (recover) {
if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
- e2fsck_clear_recover(ctx, 1);
+ ext2fs_clear_recover(ctx->fs, 1);
return 0;
}
return EXT2_ET_UNSUPP_FEATURE;
@@ -1330,8 +1122,8 @@ static errcode_t e2fsck_journal_load(journal_t *journal)
jbd2_has_feature_checksum(journal))
return EXT2_ET_CORRUPT_JOURNAL_SB;

- if (!e2fsck_journal_verify_csum_type(journal, jsb) ||
- !e2fsck_journal_sb_csum_verify(journal, jsb))
+ if (!ext2fs_journal_verify_csum_type(journal, jsb) ||
+ !ext2fs_journal_sb_csum_verify(journal, jsb))
return EXT2_ET_CORRUPT_JOURNAL_SB;

if (jbd2_journal_has_csum_v2or3(journal))
@@ -1419,7 +1211,7 @@ static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
for (i = 0; i < 4; i ++)
new_seq ^= u.val[i];
jsb->s_sequence = htonl(new_seq);
- e2fsck_journal_sb_csum_set(journal, jsb);
+ ext2fs_journal_sb_csum_set(journal, jsb);

mark_buffer_dirty(journal->j_sb_buffer);
ll_rw_block(REQ_OP_WRITE, 0, 1, &journal->j_sb_buffer);
@@ -1437,7 +1229,7 @@ static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
e2fsck_journal_reset_super(ctx, journal->j_superblock,
journal);
journal->j_transaction_sequence = 1;
- e2fsck_clear_recover(ctx, recover);
+ ext2fs_clear_recover(ctx->fs, recover);
return 0;
}
return EXT2_ET_CORRUPT_JOURNAL_SB;
@@ -1447,38 +1239,6 @@ static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
return 0;
}

-static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
- int reset, int drop)
-{
- journal_superblock_t *jsb;
-
- if (drop)
- mark_buffer_clean(journal->j_sb_buffer);
- else if (!(ctx->options & E2F_OPT_READONLY)) {
- jsb = journal->j_superblock;
- jsb->s_sequence = htonl(journal->j_tail_sequence);
- if (reset)
- jsb->s_start = 0; /* this marks the journal as empty */
- e2fsck_journal_sb_csum_set(journal, jsb);
- mark_buffer_dirty(journal->j_sb_buffer);
- }
- brelse(journal->j_sb_buffer);
-
- if (ctx->journal_io) {
- if (ctx->fs && ctx->fs->io != ctx->journal_io)
- io_channel_close(ctx->journal_io);
- ctx->journal_io = 0;
- }
-
-#ifndef USE_INODE_IO
- if (journal->j_inode)
- ext2fs_free_mem(&journal->j_inode);
-#endif
- if (journal->j_fs_dev)
- ext2fs_free_mem(&journal->j_fs_dev);
- ext2fs_free_mem(&journal);
-}
-
/*
* This function makes sure that the superblock fields regarding the
* journal are consistent.
@@ -1525,7 +1285,7 @@ errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx)
(!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
&pctx);
- e2fsck_journal_release(ctx, journal, 0, 1);
+ ext2fs_journal_release(ctx->fs, journal, 0, 1);
return retval;
}

@@ -1552,7 +1312,7 @@ no_has_journal:
sb->s_journal_dev = 0;
memset(sb->s_journal_uuid, 0,
sizeof(sb->s_journal_uuid));
- e2fsck_clear_recover(ctx, force_fsck);
+ ext2fs_clear_recover(ctx->fs, force_fsck);
} else if (!(ctx->options & E2F_OPT_READONLY)) {
ext2fs_set_feature_journal(sb);
ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
@@ -1602,11 +1362,11 @@ no_has_journal:
ctx->fs->super->s_state |= EXT2_ERROR_FS;
ext2fs_mark_super_dirty(ctx->fs);
journal->j_superblock->s_errno = 0;
- e2fsck_journal_sb_csum_set(journal, journal->j_superblock);
+ ext2fs_journal_sb_csum_set(journal, journal->j_superblock);
mark_buffer_dirty(journal->j_sb_buffer);
}

- e2fsck_journal_release(ctx, journal, reset, 0);
+ ext2fs_journal_release(ctx->fs, journal, reset, 0);
return retval;
}

@@ -1655,7 +1415,7 @@ errout:
jbd2_journal_destroy_revoke(journal);
jbd2_journal_destroy_revoke_record_cache();
jbd2_journal_destroy_revoke_table_cache();
- e2fsck_journal_release(ctx, journal, 1, 0);
+ ext2fs_journal_release(ctx->fs, journal, 1, 0);
return retval;
}

@@ -1706,7 +1466,7 @@ errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
ctx->fs->super->s_kbytes_written += kbytes_written;

/* Set the superblock flags */
- e2fsck_clear_recover(ctx, recover_retval != 0);
+ ext2fs_clear_recover(ctx->fs, recover_retval != 0);

/*
* Do one last sanity check, and propagate journal->s_errno to
diff --git a/e2fsck/logfile.c b/e2fsck/logfile.c
index 63e9a12f..2b92ecd7 100644
--- a/e2fsck/logfile.c
+++ b/e2fsck/logfile.c
@@ -20,7 +20,7 @@
#include "e2fsck.h"
#include <pwd.h>

-extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
+extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */

struct string {
char *s;
diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c
index 8ca35271..92d35426 100644
--- a/e2fsck/recovery.c
+++ b/e2fsck/recovery.c
@@ -11,7 +11,7 @@
*/

#ifndef __KERNEL__
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
#else
#include <linux/time.h>
#include <linux/fs.h>
diff --git a/e2fsck/revoke.c b/e2fsck/revoke.c
index fa608788..8bb97c2f 100644
--- a/e2fsck/revoke.c
+++ b/e2fsck/revoke.c
@@ -78,7 +78,7 @@
*/

#ifndef __KERNEL__
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
#else
#include <linux/time.h>
#include <linux/fs.h>
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index ae231f93..92fadda9 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -54,7 +54,7 @@ extern int optind;
#include "support/plausible.h"
#include "e2fsck.h"
#include "problem.h"
-#include "jfs_user.h"
+#include "ext2fs/jfs_user.h"
#include "../version.h"

/* Command line options */
@@ -66,7 +66,7 @@ static int replace_bad_blocks;
static int keep_bad_blocks;
static char *bad_blocks_file;

-e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
+struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */

#ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jbd-debug */
int journal_enable_debug = -1;
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 3fe3c988..7b8e2267 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -39,7 +39,7 @@

#include "e2fsck.h"

-extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
+extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */

#include <stdarg.h>
#include <time.h>
diff --git a/lib/ext2fs/Android.bp b/lib/ext2fs/Android.bp
index 919adb13..37d9174d 100644
--- a/lib/ext2fs/Android.bp
+++ b/lib/ext2fs/Android.bp
@@ -81,6 +81,7 @@ cc_library {
"mmp.c",
"mkdir.c",
"mkjournal.c",
+ "jfs_user.c",
"namei.c",
"native.c",
"newdir.c",
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index f6a050a2..b3fc1ba9 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -5,10 +5,8 @@ top_builddir = ../..
my_dir = lib/ext2fs
INSTALL = @INSTALL@
MKDIR_P = @MKDIR_P@
-DEPEND_CFLAGS = -I$(top_srcdir)/debugfs -I$(srcdir)/../../e2fsck -DDEBUGFS
-# This nastiness is needed because of jfs_user.h hackery; when we finally
-# clean up this mess, we should be able to drop it
-DEBUGFS_CFLAGS = -I$(srcdir)/../../e2fsck $(ALL_CFLAGS) -DDEBUGFS
+DEPEND_CFLAGS = -I$(top_srcdir)/debugfs -DDEBUGFS
+DEBUGFS_CFLAGS = $(ALL_CFLAGS) -DDEBUGFS

@MCONFIG@

@@ -109,6 +107,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
lookup.o \
mkdir.o \
mkjournal.o \
+ jfs_user.o \
mmp.o \
namei.o \
native.o \
@@ -193,6 +192,7 @@ SRCS= ext2_err.c \
$(srcdir)/lookup.c \
$(srcdir)/mkdir.c \
$(srcdir)/mkjournal.c \
+ $(srcdir)/jfs_user.c \
$(srcdir)/mmp.c \
$(srcdir)/namei.c \
$(srcdir)/native.c \
@@ -1010,6 +1010,9 @@ mkjournal.o: $(srcdir)/mkjournal.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
$(srcdir)/hashmap.h $(srcdir)/bitops.h $(srcdir)/kernel-jbd.h \
$(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
+jfs_user.o: $(srcdir)/jfs_user.c $(top_builddir)/lib/config.h \
+ $(srcdir)/jfs_user.h \
+ $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
mmp.o: $(srcdir)/mmp.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
@@ -1231,7 +1234,7 @@ debugfs.o: $(top_srcdir)/debugfs/debugfs.c $(top_builddir)/lib/config.h \
$(top_srcdir)/debugfs/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
$(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
$(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/debugfs/../version.h \
- $(srcdir)/../../e2fsck/jfs_user.h $(srcdir)/kernel-jbd.h \
+ $(srcdir)/jfs_user.h $(srcdir)/kernel-jbd.h \
$(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h \
$(top_srcdir)/lib/support/plausible.h
util.o: $(top_srcdir)/debugfs/util.c $(top_builddir)/lib/config.h \
@@ -1321,7 +1324,7 @@ logdump.o: $(top_srcdir)/debugfs/logdump.c $(top_builddir)/lib/config.h \
$(srcdir)/hashmap.h $(srcdir)/bitops.h \
$(top_srcdir)/debugfs/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
$(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
- $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/../../e2fsck/jfs_user.h \
+ $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/jfs_user.h \
$(srcdir)/kernel-jbd.h $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h \
$(srcdir)/compiler.h $(srcdir)/fast_commit.h
htree.o: $(top_srcdir)/debugfs/htree.c $(top_builddir)/lib/config.h \
@@ -1422,20 +1425,20 @@ create_inode.o: $(top_srcdir)/misc/create_inode.c \
$(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/nls-enable.h
journal.o: $(top_srcdir)/debugfs/journal.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(top_srcdir)/debugfs/journal.h \
- $(srcdir)/../../e2fsck/jfs_user.h $(srcdir)/ext2_fs.h \
+ $(srcdir)/jfs_user.h $(srcdir)/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
$(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
$(srcdir)/hashmap.h $(srcdir)/bitops.h $(srcdir)/kernel-jbd.h \
$(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
-revoke.o: $(top_srcdir)/e2fsck/revoke.c $(top_srcdir)/e2fsck/jfs_user.h \
+revoke.o: $(top_srcdir)/e2fsck/revoke.c $(srcdir)/jfs_user.h \
$(srcdir)/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(srcdir)/ext2_ext_attr.h $(srcdir)/hashmap.h $(srcdir)/bitops.h \
$(srcdir)/kernel-jbd.h $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h \
$(srcdir)/compiler.h
-recovery.o: $(top_srcdir)/e2fsck/recovery.c $(top_srcdir)/e2fsck/jfs_user.h \
+recovery.o: $(top_srcdir)/e2fsck/recovery.c $(srcdir)/jfs_user.h \
$(srcdir)/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
@@ -1454,4 +1457,4 @@ do_journal.o: $(top_srcdir)/debugfs/do_journal.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
$(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/kernel-jbd.h \
$(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h \
- $(top_srcdir)/debugfs/journal.h $(srcdir)/../../e2fsck/jfs_user.h
+ $(top_srcdir)/debugfs/journal.h $(srcdir)/jfs_user.h
diff --git a/lib/ext2fs/jfs_user.c b/lib/ext2fs/jfs_user.c
new file mode 100644
index 00000000..b6ae0229
--- /dev/null
+++ b/lib/ext2fs/jfs_user.c
@@ -0,0 +1,255 @@
+#include <jfs_user.h>
+
+static int bh_count = 0;
+
+void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
+ struct buffer_head *bhp[])
+{
+ errcode_t retval;
+ struct buffer_head *bh;
+
+ for (; nr > 0; --nr) {
+ bh = *bhp++;
+ if (rw == REQ_OP_READ && !bh->b_uptodate) {
+ jfs_debug(3, "reading block %llu/%p\n",
+ bh->b_blocknr, (void *) bh);
+ retval = io_channel_read_blk64(bh->b_io,
+ bh->b_blocknr,
+ 1, bh->b_data);
+ if (retval) {
+ com_err(bh->b_fs->device_name, retval,
+ "while reading block %llu\n",
+ bh->b_blocknr);
+ bh->b_err = (int) retval;
+ continue;
+ }
+ bh->b_uptodate = 1;
+ } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
+ jfs_debug(3, "writing block %llu/%p\n",
+ bh->b_blocknr,
+ (void *) bh);
+ retval = io_channel_write_blk64(bh->b_io,
+ bh->b_blocknr,
+ 1, bh->b_data);
+ if (retval) {
+ com_err(bh->b_fs->device_name, retval,
+ "while writing block %llu\n",
+ bh->b_blocknr);
+ bh->b_err = (int) retval;
+ continue;
+ }
+ bh->b_dirty = 0;
+ bh->b_uptodate = 1;
+ } else {
+ jfs_debug(3, "no-op %s for block %llu\n",
+ rw == REQ_OP_READ ? "read" : "write",
+ bh->b_blocknr);
+ }
+ }
+}
+
+void mark_buffer_dirty(struct buffer_head *bh)
+{
+ bh->b_dirty = 1;
+}
+
+void mark_buffer_clean(struct buffer_head * bh)
+{
+ bh->b_dirty = 0;
+}
+
+int sync_blockdev(kdev_t kdev)
+{
+ io_channel io;
+
+ if (kdev->k_dev == K_DEV_FS)
+ io = kdev->k_fs->io;
+ else
+ io = kdev->k_fs->journal_io;
+
+ return io_channel_flush(io) ? EIO : 0;
+}
+
+int buffer_uptodate(struct buffer_head *bh)
+{
+ return bh->b_uptodate;
+}
+
+void mark_buffer_uptodate(struct buffer_head *bh, int val)
+{
+ bh->b_uptodate = val;
+}
+
+void wait_on_buffer(struct buffer_head *bh)
+{
+ if (!bh->b_uptodate)
+ ll_rw_block(REQ_OP_READ, 0, 1, &bh);
+}
+
+
+struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
+ int blocksize)
+{
+ struct buffer_head *bh;
+ int bufsize = sizeof(*bh) + kdev->k_fs->blocksize -
+ sizeof(bh->b_data);
+ errcode_t retval;
+
+ retval = ext2fs_get_memzero(bufsize, &bh);
+ if (retval)
+ return NULL;
+
+ if (journal_enable_debug >= 3)
+ bh_count++;
+ jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
+ blocknr, blocksize, bh_count);
+
+ bh->b_fs = kdev->k_fs;
+ bh->b_ctx = kdev->k_ctx;
+ if (kdev->k_dev == K_DEV_FS)
+ bh->b_io = kdev->k_fs->io;
+ else
+ bh->b_io = kdev->k_fs->journal_io;
+ bh->b_size = blocksize;
+ bh->b_blocknr = blocknr;
+
+ return bh;
+}
+
+
+void brelse(struct buffer_head *bh)
+{
+ if (bh->b_dirty)
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
+ jfs_debug(3, "freeing block %llu/%p (total %d)\n",
+ bh->b_blocknr, (void *) bh, --bh_count);
+ ext2fs_free_mem(&bh);
+}
+
+/* Kernel compatibility functions for handling the journal. These allow us
+ * to use the recovery.c file virtually unchanged from the kernel, so we
+ * don't have to do much to keep kernel and user recovery in sync.
+ */
+int jbd2_journal_bmap(journal_t *journal, unsigned long block,
+ unsigned long long *phys)
+{
+#ifdef USE_INODE_IO
+ *phys = block;
+ return 0;
+#else
+ struct inode *inode = journal->j_inode;
+ errcode_t retval;
+ blk64_t pblk;
+
+ if (!inode) {
+ *phys = block;
+ return 0;
+ }
+
+ retval = ext2fs_bmap2(inode->i_fs, inode->i_ino,
+ &inode->i_ext2, NULL, 0, (blk64_t) block,
+ 0, &pblk);
+ *phys = pblk;
+ return (int) retval;
+#endif
+}
+
+static __u32 ext2fs_journal_sb_csum(journal_superblock_t *jsb)
+{
+ __u32 crc, old_crc;
+
+ old_crc = jsb->s_checksum;
+ jsb->s_checksum = 0;
+ crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
+ sizeof(journal_superblock_t));
+ jsb->s_checksum = old_crc;
+
+ return crc;
+}
+
+int ext2fs_journal_sb_csum_verify(journal_t *j,
+ journal_superblock_t *jsb)
+{
+ __u32 provided, calculated;
+
+ if (!jbd2_journal_has_csum_v2or3(j))
+ return 1;
+
+ provided = ext2fs_be32_to_cpu(jsb->s_checksum);
+ calculated = ext2fs_journal_sb_csum(jsb);
+
+ return provided == calculated;
+}
+
+errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
+ journal_superblock_t *jsb)
+{
+ __u32 crc;
+
+ if (!jbd2_journal_has_csum_v2or3(j))
+ return 0;
+
+ crc = ext2fs_journal_sb_csum(jsb);
+ jsb->s_checksum = ext2fs_cpu_to_be32(crc);
+ return 0;
+}
+
+/* Checksumming functions */
+int ext2fs_journal_verify_csum_type(journal_t *j,
+ journal_superblock_t *jsb)
+{
+ if (!jbd2_journal_has_csum_v2or3(j))
+ return 1;
+
+ return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
+}
+
+void ext2fs_clear_recover(ext2_filsys fs, int error)
+{
+ ext2fs_clear_feature_journal_needs_recovery(fs->super);
+
+ /* if we had an error doing journal recovery, we need a full fsck */
+ if (error)
+ fs->super->s_state &= ~EXT2_VALID_FS;
+ /*
+ * If we replayed the journal by definition the file system
+ * was mounted since the last time it was checked
+ */
+ if (fs->super->s_lastcheck >= fs->super->s_mtime)
+ fs->super->s_lastcheck = fs->super->s_mtime - 1;
+ ext2fs_mark_super_dirty(fs);
+}
+
+void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
+ int reset, int drop)
+{
+ journal_superblock_t *jsb;
+
+ if (drop)
+ mark_buffer_clean(journal->j_sb_buffer);
+ else if (fs->flags & EXT2_FLAG_RW) {
+ jsb = journal->j_superblock;
+ jsb->s_sequence = htonl(journal->j_tail_sequence);
+ if (reset)
+ jsb->s_start = 0; /* this marks the journal as empty */
+ ext2fs_journal_sb_csum_set(journal, jsb);
+ mark_buffer_dirty(journal->j_sb_buffer);
+ }
+ brelse(journal->j_sb_buffer);
+
+ if (fs && fs->journal_io) {
+ if (fs->io != fs->journal_io)
+ io_channel_close(fs->journal_io);
+ fs->journal_io = NULL;
+ free(fs->journal_name);
+ fs->journal_name = NULL;
+ }
+
+#ifndef USE_INODE_IO
+ if (journal->j_inode)
+ ext2fs_free_mem(&journal->j_inode);
+#endif
+ if (journal->j_fs_dev)
+ ext2fs_free_mem(&journal->j_fs_dev);
+ ext2fs_free_mem(&journal);
+}
diff --git a/e2fsck/jfs_user.h b/lib/ext2fs/jfs_user.h
similarity index 89%
rename from e2fsck/jfs_user.h
rename to lib/ext2fs/jfs_user.h
index 4ad2005a..ed75c4a5 100644
--- a/e2fsck/jfs_user.h
+++ b/lib/ext2fs/jfs_user.h
@@ -11,7 +11,6 @@
#ifndef _JFS_USER_H
#define _JFS_USER_H

-#ifdef DEBUGFS
#include <stdio.h>
#include <stdlib.h>
#if EXT2_FLAT_INCLUDES
@@ -23,13 +22,8 @@
#include "ext2fs/ext2fs.h"
#include "blkid/blkid.h"
#endif
-#else
-/*
- * Pull in the definition of the e2fsck context structure
- */
-#include "config.h"
-#include "e2fsck.h"
-#endif
+
+struct e2fsck_struct;

#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2 || _MSC_VER >= 1300
@@ -40,11 +34,8 @@
#endif

struct buffer_head {
-#ifdef DEBUGFS
ext2_filsys b_fs;
-#else
- e2fsck_t b_ctx;
-#endif
+ struct e2fsck_struct *b_ctx;
io_channel b_io;
int b_size;
int b_err;
@@ -55,21 +46,15 @@ struct buffer_head {
};

struct inode {
-#ifdef DEBUGFS
ext2_filsys i_fs;
-#else
- e2fsck_t i_ctx;
-#endif
+ struct e2fsck_struct *i_ctx;
ext2_ino_t i_ino;
struct ext2_inode i_ext2;
};

struct kdev_s {
-#ifdef DEBUGFS
ext2_filsys k_fs;
-#else
- e2fsck_t k_ctx;
-#endif
+ struct e2fsck_struct *k_ctx;
int k_dev;
};

@@ -223,27 +208,41 @@ int sync_blockdev(kdev_t kdev);
void ll_rw_block(int rw, int op_flags, int nr, struct buffer_head *bh[]);
void mark_buffer_dirty(struct buffer_head *bh);
void mark_buffer_uptodate(struct buffer_head *bh, int val);
+void mark_buffer_clean(struct buffer_head * bh);
void brelse(struct buffer_head *bh);
int buffer_uptodate(struct buffer_head *bh);
void wait_on_buffer(struct buffer_head *bh);

+int ext2fs_journal_verify_csum_type(journal_t *j,
+ journal_superblock_t *jsb);
+int ext2fs_journal_sb_csum_verify(journal_t *j,
+ journal_superblock_t *jsb);
+errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
+ journal_superblock_t *jsb);
+
+void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
+ int reset, int drop);
+void ext2fs_clear_recover(ext2_filsys fs, int error);
+
+
/*
* Define newer 2.5 interfaces
*/
#define __getblk(dev, blocknr, blocksize) getblk(dev, blocknr, blocksize)
#define set_buffer_uptodate(bh) mark_buffer_uptodate(bh, 1)

-#ifdef DEBUGFS
-#include <assert.h>
-#undef J_ASSERT
-#define J_ASSERT(x) assert(x)
-
#define JSB_HAS_INCOMPAT_FEATURE(jsb, mask) \
((jsb)->s_header.h_blocktype == ext2fs_cpu_to_be32(JBD2_SUPERBLOCK_V2) && \
((jsb)->s_feature_incompat & ext2fs_cpu_to_be32((mask))))
-#else /* !DEBUGFS */

-extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
+#ifdef DEBUGFS
+#include <assert.h>
+#undef J_ASSERT
+#define J_ASSERT(x) assert(x)
+#else
+
+extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */
+extern void fatal_error(struct e2fsck_struct * ctx, const char * fmt_string);

#define J_ASSERT(assert) \
do { if (!(assert)) { \
@@ -279,4 +278,6 @@ extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t);
extern int jbd2_journal_test_revoke(journal_t *, unsigned long long, tid_t);
extern void jbd2_journal_clear_revoke(journal_t *);

+
+
#endif /* _JFS_USER_H */
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 4db59cdf..6f863773 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -126,8 +126,8 @@ COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../lib/et/et ../lib/et/compile_et

# This nastiness is needed because of jfs_user.h hackery; when we finally
# clean up this mess, we should be able to drop it
-JOURNAL_CFLAGS = -I$(srcdir)/../e2fsck $(ALL_CFLAGS) -DDEBUGFS
-DEPEND_CFLAGS = -I$(top_srcdir)/e2fsck
+JOURNAL_CFLAGS = $(ALL_CFLAGS) -DDEBUGFS
+DEPEND_CFLAGS =

.c.o:
$(E) " CC $<"
@@ -878,7 +878,7 @@ check_fuzzer.o: $(srcdir)/check_fuzzer.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_srcdir)/lib/ext2fs/bitops.h
journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/../debugfs/journal.h \
- $(top_srcdir)/e2fsck/jfs_user.h $(top_srcdir)/e2fsck/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/e2fsck/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
@@ -891,7 +891,7 @@ journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h
-revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
+revoke.o: $(srcdir)/../e2fsck/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
$(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
@@ -905,7 +905,7 @@ revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
$(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
$(top_srcdir)/lib/ext2fs/kernel-jbd.h
-recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \
+recovery.o: $(srcdir)/../e2fsck/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
$(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
$(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
--
2.31.1



2022-08-03 16:41:26

by Lukas Czerner

[permalink] [raw]
Subject: Re: [PATCH] e2fsprogs: avoid code duplication

Hi Alexey,

I assume this change is based on the maint branch?

On Wed, Aug 03, 2022 at 10:54:07AM +0300, Alexey Lyashkov wrote:
> debugfs and e2fsck have a so much code duplication in journal handing.
> debugfs have lack a many journal features handing also.
> Let's start code merging to avoid code duplication and lack features.
>
> userspace buffer head emulation moved into library.

I can see that this is a little bit more involved than just moving the
code, can you describe a little bit more what has to be done in order to
move and deduplicate the code? I have not done a proper review but I can
already see that the function prototypes are changing as well as some
structures. I think it would be nice to get some idea from the commit
description what to expect from this change.

I've done some limited testing on this and I see no regression.

>
> Signed-off-by: Alexey Lyashkov <[email protected]>
> ---
> debugfs/Makefile.in | 14 +-
> debugfs/debugfs.c | 2 +-
> debugfs/journal.c | 251 ---------------------------
> debugfs/journal.h | 2 +-
> debugfs/logdump.c | 2 +-
> e2fsck/Makefile.in | 8 +-
> e2fsck/e2fsck.c | 5 -
> e2fsck/e2fsck.h | 1 -
> e2fsck/journal.c | 278 ++----------------------------
> e2fsck/logfile.c | 2 +-
> e2fsck/recovery.c | 2 +-
> e2fsck/revoke.c | 2 +-
> e2fsck/unix.c | 4 +-
> e2fsck/util.c | 2 +-
> lib/ext2fs/Android.bp | 1 +
> lib/ext2fs/Makefile.in | 23 +--
> lib/ext2fs/jfs_user.c | 255 +++++++++++++++++++++++++++
> {e2fsck => lib/ext2fs}/jfs_user.h | 55 +++---

Can we perhaps take the opportunity to rename jfs_user to journal? I
know it was historically this way, but it can we a bit confusing these
days, especially when we actually have jfs file system.

More below...

> misc/Makefile.in | 10 +-
> 19 files changed, 341 insertions(+), 578 deletions(-)
> create mode 100644 lib/ext2fs/jfs_user.c
> rename {e2fsck => lib/ext2fs}/jfs_user.h (89%)
>
> diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
> index ed4ea8d8..cc846cb1 100644
> --- a/debugfs/Makefile.in
> +++ b/debugfs/Makefile.in
> @@ -49,7 +49,7 @@ STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) \
>
> # This nastiness is needed because of jfs_user.h hackery; when we finally
> # clean up this mess, we should be able to drop it
> -LOCAL_CFLAGS = -I$(srcdir)/../e2fsck -DDEBUGFS
> +LOCAL_CFLAGS = -DDEBUGFS
> DEPEND_CFLAGS = -I$(srcdir)
>
> .c.o:
> @@ -186,7 +186,7 @@ debugfs.o: $(srcdir)/debugfs.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/quotaio.h \
> $(top_srcdir)/lib/support/dqblk_v2.h \
> $(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/version.h \
> - $(srcdir)/../e2fsck/jfs_user.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
> + $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
> $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
> $(top_srcdir)/lib/ext2fs/compiler.h $(top_srcdir)/lib/support/plausible.h
> util.o: $(srcdir)/util.c $(top_builddir)/lib/config.h \
> @@ -277,7 +277,7 @@ logdump.o: $(srcdir)/logdump.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../misc/create_inode.h \
> $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/quotaio.h \
> $(top_srcdir)/lib/support/dqblk_v2.h \
> - $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/../e2fsck/jfs_user.h \
> + $(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h
> @@ -382,7 +382,7 @@ quota.o: $(srcdir)/quota.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/support/quotaio_tree.h
> journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/dirpaths.h $(srcdir)/journal.h \
> - $(srcdir)/../e2fsck/jfs_user.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> + $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
> $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
> @@ -390,7 +390,7 @@ journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
> $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
> $(top_srcdir)/lib/ext2fs/compiler.h
> -revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
> +revoke.o: $(srcdir)/../e2fsck/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
> $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
> @@ -399,7 +399,7 @@ revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/ext2fs/kernel-jbd.h \
> $(top_srcdir)/lib/ext2fs/jfs_compat.h $(top_srcdir)/lib/ext2fs/kernel-list.h \
> $(top_srcdir)/lib/ext2fs/compiler.h
> -recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \
> +recovery.o: $(srcdir)/../e2fsck/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
> $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
> @@ -421,4 +421,4 @@ do_journal.o: $(srcdir)/do_journal.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/support/quotaio_tree.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> - $(srcdir)/journal.h $(srcdir)/../e2fsck/jfs_user.h
> + $(srcdir)/journal.h $(top_srcdir)/lib/ext2fs/jfs_user.h
> diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
> index b67a88bc..28f1ddf0 100644
> --- a/debugfs/debugfs.c
> +++ b/debugfs/debugfs.c
> @@ -37,7 +37,7 @@ extern char *optarg;
> #include <ext2fs/ext2_ext_attr.h>
>
> #include "../version.h"
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> #include "support/plausible.h"
>
> #ifndef BUFSIZ
> diff --git a/debugfs/journal.c b/debugfs/journal.c
> index 095fff00..ee25419a 100644
> --- a/debugfs/journal.c
> +++ b/debugfs/journal.c
> @@ -26,8 +26,6 @@
> #include "uuid/uuid.h"
> #include "journal.h"
>
> -static int bh_count = 0;
> -
> #if EXT2_FLAT_INCLUDES
> #include "blkid.h"
> #else
> @@ -43,221 +41,6 @@ static int bh_count = 0;
> */
> #undef USE_INODE_IO
>
> -/* Checksumming functions */
> -static int ext2fs_journal_verify_csum_type(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 1;
> -
> - return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
> -}
> -
> -static __u32 ext2fs_journal_sb_csum(journal_superblock_t *jsb)
> -{
> - __u32 crc, old_crc;
> -
> - old_crc = jsb->s_checksum;
> - jsb->s_checksum = 0;
> - crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
> - sizeof(journal_superblock_t));
> - jsb->s_checksum = old_crc;
> -
> - return crc;
> -}
> -
> -static int ext2fs_journal_sb_csum_verify(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - __u32 provided, calculated;
> -
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 1;
> -
> - provided = ext2fs_be32_to_cpu(jsb->s_checksum);
> - calculated = ext2fs_journal_sb_csum(jsb);
> -
> - return provided == calculated;
> -}
> -
> -static errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - __u32 crc;
> -
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 0;
> -
> - crc = ext2fs_journal_sb_csum(jsb);
> - jsb->s_checksum = ext2fs_cpu_to_be32(crc);
> - return 0;
> -}
> -
> -/* Kernel compatibility functions for handling the journal. These allow us
> - * to use the recovery.c file virtually unchanged from the kernel, so we
> - * don't have to do much to keep kernel and user recovery in sync.
> - */
> -int jbd2_journal_bmap(journal_t *journal, unsigned long block,
> - unsigned long long *phys)
> -{
> -#ifdef USE_INODE_IO
> - *phys = block;
> - return 0;
> -#else
> - struct inode *inode = journal->j_inode;
> - errcode_t retval;
> - blk64_t pblk;
> -
> - if (!inode) {
> - *phys = block;
> - return 0;
> - }
> -
> - retval = ext2fs_bmap2(inode->i_fs, inode->i_ino,
> - &inode->i_ext2, NULL, 0, (blk64_t) block,
> - 0, &pblk);
> - *phys = pblk;
> - return (int) retval;
> -#endif
> -}
> -
> -struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
> - int blocksize)
> -{
> - struct buffer_head *bh;
> - int bufsize = sizeof(*bh) + kdev->k_fs->blocksize -
> - sizeof(bh->b_data);
> - errcode_t retval;
> -
> - retval = ext2fs_get_memzero(bufsize, &bh);
> - if (retval)
> - return NULL;
> -
> - if (journal_enable_debug >= 3)
> - bh_count++;
> - jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
> - blocknr, blocksize, bh_count);
> -
> - bh->b_fs = kdev->k_fs;
> - if (kdev->k_dev == K_DEV_FS)
> - bh->b_io = kdev->k_fs->io;
> - else
> - bh->b_io = kdev->k_fs->journal_io;
> - bh->b_size = blocksize;
> - bh->b_blocknr = blocknr;
> -
> - return bh;
> -}
> -
> -int sync_blockdev(kdev_t kdev)
> -{
> - io_channel io;
> -
> - if (kdev->k_dev == K_DEV_FS)
> - io = kdev->k_fs->io;
> - else
> - io = kdev->k_fs->journal_io;
> -
> - return io_channel_flush(io) ? EIO : 0;
> -}
> -
> -void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
> - struct buffer_head *bhp[])
> -{
> - errcode_t retval;
> - struct buffer_head *bh;
> -
> - for (; nr > 0; --nr) {
> - bh = *bhp++;
> - if (rw == REQ_OP_READ && !bh->b_uptodate) {
> - jfs_debug(3, "reading block %llu/%p\n",
> - bh->b_blocknr, (void *) bh);
> - retval = io_channel_read_blk64(bh->b_io,
> - bh->b_blocknr,
> - 1, bh->b_data);
> - if (retval) {
> - com_err(bh->b_fs->device_name, retval,
> - "while reading block %llu\n",
> - bh->b_blocknr);
> - bh->b_err = (int) retval;
> - continue;
> - }
> - bh->b_uptodate = 1;
> - } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
> - jfs_debug(3, "writing block %llu/%p\n",
> - bh->b_blocknr,
> - (void *) bh);
> - retval = io_channel_write_blk64(bh->b_io,
> - bh->b_blocknr,
> - 1, bh->b_data);
> - if (retval) {
> - com_err(bh->b_fs->device_name, retval,
> - "while writing block %llu\n",
> - bh->b_blocknr);
> - bh->b_err = (int) retval;
> - continue;
> - }
> - bh->b_dirty = 0;
> - bh->b_uptodate = 1;
> - } else {
> - jfs_debug(3, "no-op %s for block %llu\n",
> - rw == REQ_OP_READ ? "read" : "write",
> - bh->b_blocknr);
> - }
> - }
> -}
> -
> -void mark_buffer_dirty(struct buffer_head *bh)
> -{
> - bh->b_dirty = 1;
> -}
> -
> -static void mark_buffer_clean(struct buffer_head *bh)
> -{
> - bh->b_dirty = 0;
> -}
> -
> -void brelse(struct buffer_head *bh)
> -{
> - if (bh->b_dirty)
> - ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
> - jfs_debug(3, "freeing block %llu/%p (total %d)\n",
> - bh->b_blocknr, (void *) bh, --bh_count);
> - ext2fs_free_mem(&bh);
> -}
> -
> -int buffer_uptodate(struct buffer_head *bh)
> -{
> - return bh->b_uptodate;
> -}
> -
> -void mark_buffer_uptodate(struct buffer_head *bh, int val)
> -{
> - bh->b_uptodate = val;
> -}
> -
> -void wait_on_buffer(struct buffer_head *bh)
> -{
> - if (!bh->b_uptodate)
> - ll_rw_block(REQ_OP_READ, 0, 1, &bh);
> -}
> -
> -
> -static void ext2fs_clear_recover(ext2_filsys fs, int error)
> -{
> - ext2fs_clear_feature_journal_needs_recovery(fs->super);
> -
> - /* if we had an error doing journal recovery, we need a full fsck */
> - if (error)
> - fs->super->s_state &= ~EXT2_VALID_FS;
> - /*
> - * If we replayed the journal by definition the file system
> - * was mounted since the last time it was checked
> - */
> - if (fs->super->s_lastcheck >= fs->super->s_mtime)
> - fs->super->s_lastcheck = fs->super->s_mtime - 1;
> - ext2fs_mark_super_dirty(fs);
> -}
>
> /*
> * This is a helper function to check the validity of the journal.
> @@ -640,40 +423,6 @@ static errcode_t ext2fs_journal_load(journal_t *journal)
> return 0;
> }
>
> -static void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
> - int reset, int drop)
> -{
> - journal_superblock_t *jsb;
> -
> - if (drop)
> - mark_buffer_clean(journal->j_sb_buffer);
> - else if (fs->flags & EXT2_FLAG_RW) {
> - jsb = journal->j_superblock;
> - jsb->s_sequence = htonl(journal->j_tail_sequence);
> - if (reset)
> - jsb->s_start = 0; /* this marks the journal as empty */
> - ext2fs_journal_sb_csum_set(journal, jsb);
> - mark_buffer_dirty(journal->j_sb_buffer);
> - }
> - brelse(journal->j_sb_buffer);
> -
> - if (fs && fs->journal_io) {
> - if (fs->io != fs->journal_io)
> - io_channel_close(fs->journal_io);
> - fs->journal_io = NULL;
> - free(fs->journal_name);
> - fs->journal_name = NULL;
> - }
> -
> -#ifndef USE_INODE_IO
> - if (journal->j_inode)
> - ext2fs_free_mem(&journal->j_inode);
> -#endif
> - if (journal->j_fs_dev)
> - ext2fs_free_mem(&journal->j_fs_dev);
> - ext2fs_free_mem(&journal);
> -}
> -
> /*
> * This function makes sure that the superblock fields regarding the
> * journal are consistent.
> diff --git a/debugfs/journal.h b/debugfs/journal.h
> index 10b638eb..44d4fa72 100644
> --- a/debugfs/journal.h
> +++ b/debugfs/journal.h
> @@ -12,7 +12,7 @@
> * any later version.
> */
>
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
>
> /* journal.c */
> errcode_t ext2fs_open_journal(ext2_filsys fs, journal_t **j);
> diff --git a/debugfs/logdump.c b/debugfs/logdump.c
> index 4154ef2a..99934077 100644
> --- a/debugfs/logdump.c
> +++ b/debugfs/logdump.c
> @@ -32,7 +32,7 @@ extern char *optarg;
>
> #include "debugfs.h"
> #include "blkid/blkid.h"
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> #if __GNUC_PREREQ (4, 6)
> #pragma GCC diagnostic push
> #pragma GCC diagnostic ignored "-Wunused-function"
> diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
> index 71ac3cf5..fb8b2b71 100644
> --- a/e2fsck/Makefile.in
> +++ b/e2fsck/Makefile.in
> @@ -383,7 +383,7 @@ pass5.o: $(srcdir)/pass5.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(srcdir)/problem.h
> journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
> - $(top_builddir)/lib/dirpaths.h $(srcdir)/jfs_user.h $(srcdir)/e2fsck.h \
> + $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/jfs_user.h $(srcdir)/e2fsck.h \
> $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
> $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
> @@ -396,7 +396,7 @@ journal.o: $(srcdir)/journal.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(srcdir)/problem.h
> -recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_user.h \
> +recovery.o: $(srcdir)/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
> $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> @@ -410,7 +410,7 @@ recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h
> -revoke.o: $(srcdir)/revoke.c $(srcdir)/jfs_user.h \
> +revoke.o: $(srcdir)/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
> $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> @@ -464,7 +464,7 @@ unix.o: $(srcdir)/unix.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/support/quotaio_tree.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> - $(srcdir)/problem.h $(srcdir)/jfs_user.h \
> + $(srcdir)/problem.h $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/version.h
> dirinfo.o: $(srcdir)/dirinfo.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/dirpaths.h $(srcdir)/e2fsck.h \
> diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
> index 1e295e3e..0ea1e0df 100644
> --- a/e2fsck/e2fsck.c
> +++ b/e2fsck/e2fsck.c
> @@ -83,11 +83,6 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
> ext2fs_free_icount(ctx->inode_link_info);
> ctx->inode_link_info = 0;
> }
> - if (ctx->journal_io) {
> - if (ctx->fs && ctx->fs->io != ctx->journal_io)
> - io_channel_close(ctx->journal_io);
> - ctx->journal_io = 0;
> - }
> if (ctx->fs && ctx->fs->dblist) {
> ext2fs_free_dblist(ctx->fs->dblist);
> ctx->fs->dblist = 0;
> diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
> index 2db216f5..33334781 100644
> --- a/e2fsck/e2fsck.h
> +++ b/e2fsck/e2fsck.h
> @@ -380,7 +380,6 @@ struct e2fsck_struct {
> /*
> * ext3 journal support
> */
> - io_channel journal_io;
> char *journal_name;
>
> /*
> diff --git a/e2fsck/journal.c b/e2fsck/journal.c
> index 2e867234..39d545a3 100644
> --- a/e2fsck/journal.c
> +++ b/e2fsck/journal.c
> @@ -23,12 +23,11 @@
> #endif
>
> #define E2FSCK_INCLUDE_INLINE_FUNCS
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> +#include "e2fsck.h"
> #include "problem.h"
> #include "uuid/uuid.h"
>
> -static int bh_count = 0;
> -
> /*
> * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
> * This creates a larger static binary, and a smaller binary using
> @@ -38,215 +37,6 @@ static int bh_count = 0;
> */
> #undef USE_INODE_IO
>
> -/* Checksumming functions */
> -static int e2fsck_journal_verify_csum_type(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 1;
> -
> - return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
> -}
> -
> -static __u32 e2fsck_journal_sb_csum(journal_superblock_t *jsb)
> -{
> - __u32 crc, old_crc;
> -
> - old_crc = jsb->s_checksum;
> - jsb->s_checksum = 0;
> - crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
> - sizeof(journal_superblock_t));
> - jsb->s_checksum = old_crc;
> -
> - return crc;
> -}
> -
> -static int e2fsck_journal_sb_csum_verify(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - __u32 provided, calculated;
> -
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 1;
> -
> - provided = ext2fs_be32_to_cpu(jsb->s_checksum);
> - calculated = e2fsck_journal_sb_csum(jsb);
> -
> - return provided == calculated;
> -}
> -
> -static errcode_t e2fsck_journal_sb_csum_set(journal_t *j,
> - journal_superblock_t *jsb)
> -{
> - __u32 crc;
> -
> - if (!jbd2_journal_has_csum_v2or3(j))
> - return 0;
> -
> - crc = e2fsck_journal_sb_csum(jsb);
> - jsb->s_checksum = ext2fs_cpu_to_be32(crc);
> - return 0;
> -}
> -
> -/* Kernel compatibility functions for handling the journal. These allow us
> - * to use the recovery.c file virtually unchanged from the kernel, so we
> - * don't have to do much to keep kernel and user recovery in sync.
> - */
> -int jbd2_journal_bmap(journal_t *journal, unsigned long block,
> - unsigned long long *phys)
> -{
> -#ifdef USE_INODE_IO
> - *phys = block;
> - return 0;
> -#else
> - struct inode *inode = journal->j_inode;
> - errcode_t retval;
> - blk64_t pblk;
> -
> - if (!inode) {
> - *phys = block;
> - return 0;
> - }
> -
> - retval= ext2fs_bmap2(inode->i_ctx->fs, inode->i_ino,
> - &inode->i_ext2, NULL, 0, (blk64_t) block,
> - 0, &pblk);
> - *phys = pblk;
> - return -1 * ((int) retval);
> -#endif
> -}
> -
> -struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
> - int blocksize)
> -{
> - struct buffer_head *bh;
> - int bufsize = sizeof(*bh) + kdev->k_ctx->fs->blocksize -
> - sizeof(bh->b_data);
> -
> - bh = e2fsck_allocate_memory(kdev->k_ctx, bufsize, "block buffer");
> - if (!bh)
> - return NULL;
> -
> - if (journal_enable_debug >= 3)
> - bh_count++;
> - jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
> - blocknr, blocksize, bh_count);
> -
> - bh->b_ctx = kdev->k_ctx;
> - if (kdev->k_dev == K_DEV_FS)
> - bh->b_io = kdev->k_ctx->fs->io;
> - else
> - bh->b_io = kdev->k_ctx->journal_io;
> - bh->b_size = blocksize;
> - bh->b_blocknr = blocknr;
> -
> - return bh;
> -}
> -
> -int sync_blockdev(kdev_t kdev)
> -{
> - io_channel io;
> -
> - if (kdev->k_dev == K_DEV_FS)
> - io = kdev->k_ctx->fs->io;
> - else
> - io = kdev->k_ctx->journal_io;
> -
> - return io_channel_flush(io) ? -EIO : 0;
> -}
> -
> -void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
> - struct buffer_head *bhp[])
> -{
> - errcode_t retval;
> - struct buffer_head *bh;
> -
> - for (; nr > 0; --nr) {
> - bh = *bhp++;
> - if (rw == REQ_OP_READ && !bh->b_uptodate) {
> - jfs_debug(3, "reading block %llu/%p\n",
> - bh->b_blocknr, (void *) bh);
> - retval = io_channel_read_blk64(bh->b_io,
> - bh->b_blocknr,
> - 1, bh->b_data);
> - if (retval) {
> - com_err(bh->b_ctx->device_name, retval,
> - "while reading block %llu\n",
> - bh->b_blocknr);
> - bh->b_err = (int) retval;
> - continue;
> - }
> - bh->b_uptodate = 1;
> - } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
> - jfs_debug(3, "writing block %llu/%p\n",
> - bh->b_blocknr,
> - (void *) bh);
> - retval = io_channel_write_blk64(bh->b_io,
> - bh->b_blocknr,
> - 1, bh->b_data);
> - if (retval) {
> - com_err(bh->b_ctx->device_name, retval,
> - "while writing block %llu\n",
> - bh->b_blocknr);
> - bh->b_err = (int) retval;
> - continue;
> - }
> - bh->b_dirty = 0;
> - bh->b_uptodate = 1;
> - } else {
> - jfs_debug(3, "no-op %s for block %llu\n",
> - rw == REQ_OP_READ ? "read" : "write",
> - bh->b_blocknr);
> - }
> - }
> -}
> -
> -void mark_buffer_dirty(struct buffer_head *bh)
> -{
> - bh->b_dirty = 1;
> -}
> -
> -static void mark_buffer_clean(struct buffer_head * bh)
> -{
> - bh->b_dirty = 0;
> -}
> -
> -void brelse(struct buffer_head *bh)
> -{
> - if (bh->b_dirty)
> - ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
> - jfs_debug(3, "freeing block %llu/%p (total %d)\n",
> - bh->b_blocknr, (void *) bh, --bh_count);
> - ext2fs_free_mem(&bh);
> -}
> -
> -int buffer_uptodate(struct buffer_head *bh)
> -{
> - return bh->b_uptodate;
> -}
> -
> -void mark_buffer_uptodate(struct buffer_head *bh, int val)
> -{
> - bh->b_uptodate = val;
> -}
> -
> -void wait_on_buffer(struct buffer_head *bh)
> -{
> - if (!bh->b_uptodate)
> - ll_rw_block(REQ_OP_READ, 0, 1, &bh);
> -}
> -
> -
> -static void e2fsck_clear_recover(e2fsck_t ctx, int error)
> -{
> - ext2fs_clear_feature_journal_needs_recovery(ctx->fs->super);
> -
> - /* if we had an error doing journal recovery, we need a full fsck */
> - if (error)
> - ctx->fs->super->s_state &= ~EXT2_VALID_FS;
> - ext2fs_mark_super_dirty(ctx->fs);
> -}
> -
> /*
> * This is a helper function to check the validity of the journal.
> */
> @@ -980,6 +770,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
> dev_journal = dev_fs+1;
>
> dev_fs->k_ctx = dev_journal->k_ctx = ctx;
> + dev_fs->k_fs = dev_journal->k_fs = ctx->fs;
> dev_fs->k_dev = K_DEV_FS;
> dev_journal->k_dev = K_DEV_JOURNAL;
>
> @@ -1001,6 +792,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
> }
>
> j_inode->i_ctx = ctx;
> + j_inode->i_fs = ctx->fs;
> j_inode->i_ino = sb->s_journal_inum;
>
> if ((retval = ext2fs_read_inode(ctx->fs,
> @@ -1061,7 +853,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
> io_ptr = inode_io_manager;
> #else
> journal->j_inode = j_inode;
> - ctx->journal_io = ctx->fs->io;
> + ctx->fs->journal_io = ctx->fs->io;
> if ((ret = jbd2_journal_bmap(journal, 0, &start)) != 0) {
> retval = (errcode_t) (-1 * ret);
> goto errout;
> @@ -1108,12 +900,12 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
>
>
> retval = io_ptr->open(journal_name, flags,
> - &ctx->journal_io);
> + &ctx->fs->journal_io);
> }
> if (retval)
> goto errout;
>
> - io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
> + io_channel_set_blksize(ctx->fs->journal_io, ctx->fs->blocksize);
>
> if (ext_journal) {
> blk64_t maxlen;
> @@ -1226,13 +1018,13 @@ static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
> memset(sb->s_jnl_blocks, 0, sizeof(sb->s_jnl_blocks));
> ctx->flags |= E2F_FLAG_JOURNAL_INODE;
> ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
> - e2fsck_clear_recover(ctx, 1);
> + ext2fs_clear_recover(ctx->fs, 1);
> return 0;
> }
> return EXT2_ET_CORRUPT_JOURNAL_SB;
> } else if (recover) {
> if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
> - e2fsck_clear_recover(ctx, 1);
> + ext2fs_clear_recover(ctx->fs, 1);
> return 0;
> }
> return EXT2_ET_UNSUPP_FEATURE;
> @@ -1330,8 +1122,8 @@ static errcode_t e2fsck_journal_load(journal_t *journal)
> jbd2_has_feature_checksum(journal))
> return EXT2_ET_CORRUPT_JOURNAL_SB;
>
> - if (!e2fsck_journal_verify_csum_type(journal, jsb) ||
> - !e2fsck_journal_sb_csum_verify(journal, jsb))
> + if (!ext2fs_journal_verify_csum_type(journal, jsb) ||
> + !ext2fs_journal_sb_csum_verify(journal, jsb))
> return EXT2_ET_CORRUPT_JOURNAL_SB;
>
> if (jbd2_journal_has_csum_v2or3(journal))
> @@ -1419,7 +1211,7 @@ static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
> for (i = 0; i < 4; i ++)
> new_seq ^= u.val[i];
> jsb->s_sequence = htonl(new_seq);
> - e2fsck_journal_sb_csum_set(journal, jsb);
> + ext2fs_journal_sb_csum_set(journal, jsb);
>
> mark_buffer_dirty(journal->j_sb_buffer);
> ll_rw_block(REQ_OP_WRITE, 0, 1, &journal->j_sb_buffer);
> @@ -1437,7 +1229,7 @@ static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
> e2fsck_journal_reset_super(ctx, journal->j_superblock,
> journal);
> journal->j_transaction_sequence = 1;
> - e2fsck_clear_recover(ctx, recover);
> + ext2fs_clear_recover(ctx->fs, recover);
> return 0;
> }
> return EXT2_ET_CORRUPT_JOURNAL_SB;
> @@ -1447,38 +1239,6 @@ static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
> return 0;
> }
>
> -static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
> - int reset, int drop)
> -{
> - journal_superblock_t *jsb;
> -
> - if (drop)
> - mark_buffer_clean(journal->j_sb_buffer);
> - else if (!(ctx->options & E2F_OPT_READONLY)) {
> - jsb = journal->j_superblock;
> - jsb->s_sequence = htonl(journal->j_tail_sequence);
> - if (reset)
> - jsb->s_start = 0; /* this marks the journal as empty */
> - e2fsck_journal_sb_csum_set(journal, jsb);
> - mark_buffer_dirty(journal->j_sb_buffer);
> - }
> - brelse(journal->j_sb_buffer);
> -
> - if (ctx->journal_io) {
> - if (ctx->fs && ctx->fs->io != ctx->journal_io)
> - io_channel_close(ctx->journal_io);
> - ctx->journal_io = 0;
> - }
> -
> -#ifndef USE_INODE_IO
> - if (journal->j_inode)
> - ext2fs_free_mem(&journal->j_inode);
> -#endif
> - if (journal->j_fs_dev)
> - ext2fs_free_mem(&journal->j_fs_dev);
> - ext2fs_free_mem(&journal);
> -}
> -
> /*
> * This function makes sure that the superblock fields regarding the
> * journal are consistent.
> @@ -1525,7 +1285,7 @@ errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx)
> (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
> retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
> &pctx);
> - e2fsck_journal_release(ctx, journal, 0, 1);
> + ext2fs_journal_release(ctx->fs, journal, 0, 1);
> return retval;
> }
>
> @@ -1552,7 +1312,7 @@ no_has_journal:
> sb->s_journal_dev = 0;
> memset(sb->s_journal_uuid, 0,
> sizeof(sb->s_journal_uuid));
> - e2fsck_clear_recover(ctx, force_fsck);
> + ext2fs_clear_recover(ctx->fs, force_fsck);

This is the kind of function prototype change I'd like to be mentioned
in the description. Just to make it easier for reviewer today and for
the future.

> } else if (!(ctx->options & E2F_OPT_READONLY)) {
> ext2fs_set_feature_journal(sb);
> ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
> @@ -1602,11 +1362,11 @@ no_has_journal:
> ctx->fs->super->s_state |= EXT2_ERROR_FS;
> ext2fs_mark_super_dirty(ctx->fs);
> journal->j_superblock->s_errno = 0;
> - e2fsck_journal_sb_csum_set(journal, journal->j_superblock);
> + ext2fs_journal_sb_csum_set(journal, journal->j_superblock);
> mark_buffer_dirty(journal->j_sb_buffer);
> }
>
> - e2fsck_journal_release(ctx, journal, reset, 0);
> + ext2fs_journal_release(ctx->fs, journal, reset, 0);
> return retval;
> }
>
> @@ -1655,7 +1415,7 @@ errout:
> jbd2_journal_destroy_revoke(journal);
> jbd2_journal_destroy_revoke_record_cache();
> jbd2_journal_destroy_revoke_table_cache();
> - e2fsck_journal_release(ctx, journal, 1, 0);
> + ext2fs_journal_release(ctx->fs, journal, 1, 0);
> return retval;
> }
>
> @@ -1706,7 +1466,7 @@ errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
> ctx->fs->super->s_kbytes_written += kbytes_written;
>
> /* Set the superblock flags */
> - e2fsck_clear_recover(ctx, recover_retval != 0);
> + ext2fs_clear_recover(ctx->fs, recover_retval != 0);
>
> /*
> * Do one last sanity check, and propagate journal->s_errno to
> diff --git a/e2fsck/logfile.c b/e2fsck/logfile.c
> index 63e9a12f..2b92ecd7 100644
> --- a/e2fsck/logfile.c
> +++ b/e2fsck/logfile.c
> @@ -20,7 +20,7 @@
> #include "e2fsck.h"
> #include <pwd.h>
>
> -extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
> +extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */
>
> struct string {
> char *s;
> diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c
> index 8ca35271..92d35426 100644
> --- a/e2fsck/recovery.c
> +++ b/e2fsck/recovery.c
> @@ -11,7 +11,7 @@
> */
>
> #ifndef __KERNEL__
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> #else
> #include <linux/time.h>
> #include <linux/fs.h>
> diff --git a/e2fsck/revoke.c b/e2fsck/revoke.c
> index fa608788..8bb97c2f 100644
> --- a/e2fsck/revoke.c
> +++ b/e2fsck/revoke.c
> @@ -78,7 +78,7 @@
> */
>
> #ifndef __KERNEL__
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> #else
> #include <linux/time.h>
> #include <linux/fs.h>
> diff --git a/e2fsck/unix.c b/e2fsck/unix.c
> index ae231f93..92fadda9 100644
> --- a/e2fsck/unix.c
> +++ b/e2fsck/unix.c
> @@ -54,7 +54,7 @@ extern int optind;
> #include "support/plausible.h"
> #include "e2fsck.h"
> #include "problem.h"
> -#include "jfs_user.h"
> +#include "ext2fs/jfs_user.h"
> #include "../version.h"
>
> /* Command line options */
> @@ -66,7 +66,7 @@ static int replace_bad_blocks;
> static int keep_bad_blocks;
> static char *bad_blocks_file;
>
> -e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
> +struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */

Why is this necessary? I am just curious.

>
> #ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jbd-debug */
> int journal_enable_debug = -1;
> diff --git a/e2fsck/util.c b/e2fsck/util.c
> index 3fe3c988..7b8e2267 100644
> --- a/e2fsck/util.c
> +++ b/e2fsck/util.c
> @@ -39,7 +39,7 @@
>
> #include "e2fsck.h"
>
> -extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
> +extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */

same question here.

>
> #include <stdarg.h>
> #include <time.h>
> diff --git a/lib/ext2fs/Android.bp b/lib/ext2fs/Android.bp
> index 919adb13..37d9174d 100644
> --- a/lib/ext2fs/Android.bp
> +++ b/lib/ext2fs/Android.bp
> @@ -81,6 +81,7 @@ cc_library {
> "mmp.c",
> "mkdir.c",
> "mkjournal.c",
> + "jfs_user.c",
> "namei.c",
> "native.c",
> "newdir.c",
> diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
> index f6a050a2..b3fc1ba9 100644
> --- a/lib/ext2fs/Makefile.in
> +++ b/lib/ext2fs/Makefile.in
> @@ -5,10 +5,8 @@ top_builddir = ../..
> my_dir = lib/ext2fs
> INSTALL = @INSTALL@
> MKDIR_P = @MKDIR_P@
> -DEPEND_CFLAGS = -I$(top_srcdir)/debugfs -I$(srcdir)/../../e2fsck -DDEBUGFS
> -# This nastiness is needed because of jfs_user.h hackery; when we finally
> -# clean up this mess, we should be able to drop it
> -DEBUGFS_CFLAGS = -I$(srcdir)/../../e2fsck $(ALL_CFLAGS) -DDEBUGFS
> +DEPEND_CFLAGS = -I$(top_srcdir)/debugfs -DDEBUGFS
> +DEBUGFS_CFLAGS = $(ALL_CFLAGS) -DDEBUGFS
>
> @MCONFIG@
>
> @@ -109,6 +107,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
> lookup.o \
> mkdir.o \
> mkjournal.o \
> + jfs_user.o \
> mmp.o \
> namei.o \
> native.o \
> @@ -193,6 +192,7 @@ SRCS= ext2_err.c \
> $(srcdir)/lookup.c \
> $(srcdir)/mkdir.c \
> $(srcdir)/mkjournal.c \
> + $(srcdir)/jfs_user.c \
> $(srcdir)/mmp.c \
> $(srcdir)/namei.c \
> $(srcdir)/native.c \
> @@ -1010,6 +1010,9 @@ mkjournal.o: $(srcdir)/mkjournal.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
> $(srcdir)/hashmap.h $(srcdir)/bitops.h $(srcdir)/kernel-jbd.h \
> $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
> +jfs_user.o: $(srcdir)/jfs_user.c $(top_builddir)/lib/config.h \
> + $(srcdir)/jfs_user.h \
> + $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
> mmp.o: $(srcdir)/mmp.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
> @@ -1231,7 +1234,7 @@ debugfs.o: $(top_srcdir)/debugfs/debugfs.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/debugfs/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
> $(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
> $(top_srcdir)/lib/support/quotaio_tree.h $(top_srcdir)/debugfs/../version.h \
> - $(srcdir)/../../e2fsck/jfs_user.h $(srcdir)/kernel-jbd.h \
> + $(srcdir)/jfs_user.h $(srcdir)/kernel-jbd.h \
> $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h \
> $(top_srcdir)/lib/support/plausible.h
> util.o: $(top_srcdir)/debugfs/util.c $(top_builddir)/lib/config.h \
> @@ -1321,7 +1324,7 @@ logdump.o: $(top_srcdir)/debugfs/logdump.c $(top_builddir)/lib/config.h \
> $(srcdir)/hashmap.h $(srcdir)/bitops.h \
> $(top_srcdir)/debugfs/../misc/create_inode.h $(top_srcdir)/lib/e2p/e2p.h \
> $(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
> - $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/../../e2fsck/jfs_user.h \
> + $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/jfs_user.h \
> $(srcdir)/kernel-jbd.h $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h \
> $(srcdir)/compiler.h $(srcdir)/fast_commit.h
> htree.o: $(top_srcdir)/debugfs/htree.c $(top_builddir)/lib/config.h \
> @@ -1422,20 +1425,20 @@ create_inode.o: $(top_srcdir)/misc/create_inode.c \
> $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/support/nls-enable.h
> journal.o: $(top_srcdir)/debugfs/journal.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/dirpaths.h $(top_srcdir)/debugfs/journal.h \
> - $(srcdir)/../../e2fsck/jfs_user.h $(srcdir)/ext2_fs.h \
> + $(srcdir)/jfs_user.h $(srcdir)/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
> $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
> $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
> $(srcdir)/hashmap.h $(srcdir)/bitops.h $(srcdir)/kernel-jbd.h \
> $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h
> -revoke.o: $(top_srcdir)/e2fsck/revoke.c $(top_srcdir)/e2fsck/jfs_user.h \
> +revoke.o: $(top_srcdir)/e2fsck/revoke.c $(srcdir)/jfs_user.h \
> $(srcdir)/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
> $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
> $(srcdir)/ext2_ext_attr.h $(srcdir)/hashmap.h $(srcdir)/bitops.h \
> $(srcdir)/kernel-jbd.h $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h \
> $(srcdir)/compiler.h
> -recovery.o: $(top_srcdir)/e2fsck/recovery.c $(top_srcdir)/e2fsck/jfs_user.h \
> +recovery.o: $(top_srcdir)/e2fsck/recovery.c $(srcdir)/jfs_user.h \
> $(srcdir)/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
> $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
> @@ -1454,4 +1457,4 @@ do_journal.o: $(top_srcdir)/debugfs/do_journal.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/support/quotaio.h $(top_srcdir)/lib/support/dqblk_v2.h \
> $(top_srcdir)/lib/support/quotaio_tree.h $(srcdir)/kernel-jbd.h \
> $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h $(srcdir)/compiler.h \
> - $(top_srcdir)/debugfs/journal.h $(srcdir)/../../e2fsck/jfs_user.h
> + $(top_srcdir)/debugfs/journal.h $(srcdir)/jfs_user.h
> diff --git a/lib/ext2fs/jfs_user.c b/lib/ext2fs/jfs_user.c
> new file mode 100644
> index 00000000..b6ae0229
> --- /dev/null
> +++ b/lib/ext2fs/jfs_user.c
> @@ -0,0 +1,255 @@
> +#include <jfs_user.h>
> +
> +static int bh_count = 0;
> +
> +void ll_rw_block(int rw, int op_flags EXT2FS_ATTR((unused)), int nr,
> + struct buffer_head *bhp[])
> +{
> + errcode_t retval;
> + struct buffer_head *bh;
> +
> + for (; nr > 0; --nr) {
> + bh = *bhp++;
> + if (rw == REQ_OP_READ && !bh->b_uptodate) {
> + jfs_debug(3, "reading block %llu/%p\n",
> + bh->b_blocknr, (void *) bh);
> + retval = io_channel_read_blk64(bh->b_io,
> + bh->b_blocknr,
> + 1, bh->b_data);
> + if (retval) {
> + com_err(bh->b_fs->device_name, retval,
> + "while reading block %llu\n",
> + bh->b_blocknr);
> + bh->b_err = (int) retval;
> + continue;
> + }
> + bh->b_uptodate = 1;
> + } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
> + jfs_debug(3, "writing block %llu/%p\n",
> + bh->b_blocknr,
> + (void *) bh);
> + retval = io_channel_write_blk64(bh->b_io,
> + bh->b_blocknr,
> + 1, bh->b_data);
> + if (retval) {
> + com_err(bh->b_fs->device_name, retval,
> + "while writing block %llu\n",
> + bh->b_blocknr);
> + bh->b_err = (int) retval;
> + continue;
> + }
> + bh->b_dirty = 0;
> + bh->b_uptodate = 1;
> + } else {
> + jfs_debug(3, "no-op %s for block %llu\n",
> + rw == REQ_OP_READ ? "read" : "write",
> + bh->b_blocknr);
> + }
> + }
> +}
> +
> +void mark_buffer_dirty(struct buffer_head *bh)
> +{
> + bh->b_dirty = 1;
> +}
> +
> +void mark_buffer_clean(struct buffer_head * bh)
> +{
> + bh->b_dirty = 0;
> +}
> +
> +int sync_blockdev(kdev_t kdev)
> +{
> + io_channel io;
> +
> + if (kdev->k_dev == K_DEV_FS)
> + io = kdev->k_fs->io;
> + else
> + io = kdev->k_fs->journal_io;
> +
> + return io_channel_flush(io) ? EIO : 0;
> +}
> +
> +int buffer_uptodate(struct buffer_head *bh)
> +{
> + return bh->b_uptodate;
> +}
> +
> +void mark_buffer_uptodate(struct buffer_head *bh, int val)
> +{
> + bh->b_uptodate = val;
> +}
> +
> +void wait_on_buffer(struct buffer_head *bh)
> +{
> + if (!bh->b_uptodate)
> + ll_rw_block(REQ_OP_READ, 0, 1, &bh);
> +}
> +
> +
> +struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
> + int blocksize)
> +{
> + struct buffer_head *bh;
> + int bufsize = sizeof(*bh) + kdev->k_fs->blocksize -
> + sizeof(bh->b_data);
> + errcode_t retval;
> +
> + retval = ext2fs_get_memzero(bufsize, &bh);
> + if (retval)
> + return NULL;
> +
> + if (journal_enable_debug >= 3)
> + bh_count++;
> + jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
> + blocknr, blocksize, bh_count);
> +
> + bh->b_fs = kdev->k_fs;
> + bh->b_ctx = kdev->k_ctx;
> + if (kdev->k_dev == K_DEV_FS)
> + bh->b_io = kdev->k_fs->io;
> + else
> + bh->b_io = kdev->k_fs->journal_io;
> + bh->b_size = blocksize;
> + bh->b_blocknr = blocknr;
> +
> + return bh;
> +}
> +
> +
> +void brelse(struct buffer_head *bh)
> +{
> + if (bh->b_dirty)
> + ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
> + jfs_debug(3, "freeing block %llu/%p (total %d)\n",
> + bh->b_blocknr, (void *) bh, --bh_count);
> + ext2fs_free_mem(&bh);
> +}
> +
> +/* Kernel compatibility functions for handling the journal. These allow us
> + * to use the recovery.c file virtually unchanged from the kernel, so we
> + * don't have to do much to keep kernel and user recovery in sync.
> + */
> +int jbd2_journal_bmap(journal_t *journal, unsigned long block,
> + unsigned long long *phys)
> +{
> +#ifdef USE_INODE_IO
> + *phys = block;
> + return 0;
> +#else
> + struct inode *inode = journal->j_inode;
> + errcode_t retval;
> + blk64_t pblk;
> +
> + if (!inode) {
> + *phys = block;
> + return 0;
> + }
> +
> + retval = ext2fs_bmap2(inode->i_fs, inode->i_ino,
> + &inode->i_ext2, NULL, 0, (blk64_t) block,
> + 0, &pblk);
> + *phys = pblk;
> + return (int) retval;
> +#endif
> +}
> +
> +static __u32 ext2fs_journal_sb_csum(journal_superblock_t *jsb)
> +{
> + __u32 crc, old_crc;
> +
> + old_crc = jsb->s_checksum;
> + jsb->s_checksum = 0;
> + crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
> + sizeof(journal_superblock_t));
> + jsb->s_checksum = old_crc;
> +
> + return crc;
> +}
> +
> +int ext2fs_journal_sb_csum_verify(journal_t *j,
> + journal_superblock_t *jsb)
> +{
> + __u32 provided, calculated;
> +
> + if (!jbd2_journal_has_csum_v2or3(j))
> + return 1;
> +
> + provided = ext2fs_be32_to_cpu(jsb->s_checksum);
> + calculated = ext2fs_journal_sb_csum(jsb);
> +
> + return provided == calculated;
> +}
> +
> +errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
> + journal_superblock_t *jsb)
> +{
> + __u32 crc;
> +
> + if (!jbd2_journal_has_csum_v2or3(j))
> + return 0;
> +
> + crc = ext2fs_journal_sb_csum(jsb);
> + jsb->s_checksum = ext2fs_cpu_to_be32(crc);
> + return 0;
> +}
> +
> +/* Checksumming functions */
> +int ext2fs_journal_verify_csum_type(journal_t *j,
> + journal_superblock_t *jsb)
> +{
> + if (!jbd2_journal_has_csum_v2or3(j))
> + return 1;
> +
> + return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
> +}
> +
> +void ext2fs_clear_recover(ext2_filsys fs, int error)
> +{
> + ext2fs_clear_feature_journal_needs_recovery(fs->super);
> +
> + /* if we had an error doing journal recovery, we need a full fsck */
> + if (error)
> + fs->super->s_state &= ~EXT2_VALID_FS;
> + /*
> + * If we replayed the journal by definition the file system
> + * was mounted since the last time it was checked
> + */
> + if (fs->super->s_lastcheck >= fs->super->s_mtime)
> + fs->super->s_lastcheck = fs->super->s_mtime - 1;
> + ext2fs_mark_super_dirty(fs);
> +}
> +
> +void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
> + int reset, int drop)
> +{
> + journal_superblock_t *jsb;
> +
> + if (drop)
> + mark_buffer_clean(journal->j_sb_buffer);
> + else if (fs->flags & EXT2_FLAG_RW) {
> + jsb = journal->j_superblock;
> + jsb->s_sequence = htonl(journal->j_tail_sequence);
> + if (reset)
> + jsb->s_start = 0; /* this marks the journal as empty */
> + ext2fs_journal_sb_csum_set(journal, jsb);
> + mark_buffer_dirty(journal->j_sb_buffer);
> + }
> + brelse(journal->j_sb_buffer);
> +
> + if (fs && fs->journal_io) {
> + if (fs->io != fs->journal_io)
> + io_channel_close(fs->journal_io);
> + fs->journal_io = NULL;
> + free(fs->journal_name);
> + fs->journal_name = NULL;
> + }
> +
> +#ifndef USE_INODE_IO
> + if (journal->j_inode)
> + ext2fs_free_mem(&journal->j_inode);
> +#endif
> + if (journal->j_fs_dev)
> + ext2fs_free_mem(&journal->j_fs_dev);
> + ext2fs_free_mem(&journal);
> +}
> diff --git a/e2fsck/jfs_user.h b/lib/ext2fs/jfs_user.h
> similarity index 89%
> rename from e2fsck/jfs_user.h
> rename to lib/ext2fs/jfs_user.h
> index 4ad2005a..ed75c4a5 100644
> --- a/e2fsck/jfs_user.h
> +++ b/lib/ext2fs/jfs_user.h
> @@ -11,7 +11,6 @@
> #ifndef _JFS_USER_H
> #define _JFS_USER_H
>
> -#ifdef DEBUGFS
> #include <stdio.h>
> #include <stdlib.h>
> #if EXT2_FLAT_INCLUDES
> @@ -23,13 +22,8 @@
> #include "ext2fs/ext2fs.h"
> #include "blkid/blkid.h"
> #endif
> -#else
> -/*
> - * Pull in the definition of the e2fsck context structure
> - */
> -#include "config.h"
> -#include "e2fsck.h"
> -#endif
> +
> +struct e2fsck_struct;
>
> #if __STDC_VERSION__ < 199901L
> # if __GNUC__ >= 2 || _MSC_VER >= 1300
> @@ -40,11 +34,8 @@
> #endif
>
> struct buffer_head {
> -#ifdef DEBUGFS
> ext2_filsys b_fs;
> -#else
> - e2fsck_t b_ctx;
> -#endif
> + struct e2fsck_struct *b_ctx;

Do we need to have both k_ctx and k_fs? Can we use union instead, or is
not worth it?

> io_channel b_io;
> int b_size;
> int b_err;
> @@ -55,21 +46,15 @@ struct buffer_head {
> };
>
> struct inode {
> -#ifdef DEBUGFS
> ext2_filsys i_fs;
> -#else
> - e2fsck_t i_ctx;
> -#endif
> + struct e2fsck_struct *i_ctx;

same here

> ext2_ino_t i_ino;
> struct ext2_inode i_ext2;
> };
>
> struct kdev_s {
> -#ifdef DEBUGFS
> ext2_filsys k_fs;
> -#else
> - e2fsck_t k_ctx;
> -#endif
> + struct e2fsck_struct *k_ctx;

and here

> int k_dev;
> };
>
> @@ -223,27 +208,41 @@ int sync_blockdev(kdev_t kdev);
> void ll_rw_block(int rw, int op_flags, int nr, struct buffer_head *bh[]);
> void mark_buffer_dirty(struct buffer_head *bh);
> void mark_buffer_uptodate(struct buffer_head *bh, int val);
> +void mark_buffer_clean(struct buffer_head * bh);
> void brelse(struct buffer_head *bh);
> int buffer_uptodate(struct buffer_head *bh);
> void wait_on_buffer(struct buffer_head *bh);
>
> +int ext2fs_journal_verify_csum_type(journal_t *j,
> + journal_superblock_t *jsb);
> +int ext2fs_journal_sb_csum_verify(journal_t *j,
> + journal_superblock_t *jsb);
> +errcode_t ext2fs_journal_sb_csum_set(journal_t *j,
> + journal_superblock_t *jsb);
> +
> +void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
> + int reset, int drop);
> +void ext2fs_clear_recover(ext2_filsys fs, int error);
> +
> +
> /*
> * Define newer 2.5 interfaces
> */
> #define __getblk(dev, blocknr, blocksize) getblk(dev, blocknr, blocksize)
> #define set_buffer_uptodate(bh) mark_buffer_uptodate(bh, 1)
>
> -#ifdef DEBUGFS
> -#include <assert.h>
> -#undef J_ASSERT
> -#define J_ASSERT(x) assert(x)
> -
> #define JSB_HAS_INCOMPAT_FEATURE(jsb, mask) \
> ((jsb)->s_header.h_blocktype == ext2fs_cpu_to_be32(JBD2_SUPERBLOCK_V2) && \
> ((jsb)->s_feature_incompat & ext2fs_cpu_to_be32((mask))))
> -#else /* !DEBUGFS */
>
> -extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
> +#ifdef DEBUGFS
> +#include <assert.h>
> +#undef J_ASSERT
> +#define J_ASSERT(x) assert(x)
> +#else
> +
> +extern struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */
> +extern void fatal_error(struct e2fsck_struct * ctx, const char * fmt_string);
>
> #define J_ASSERT(assert) \
> do { if (!(assert)) { \
> @@ -279,4 +278,6 @@ extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t);
> extern int jbd2_journal_test_revoke(journal_t *, unsigned long long, tid_t);
> extern void jbd2_journal_clear_revoke(journal_t *);
>
> +
> +
> #endif /* _JFS_USER_H */
> diff --git a/misc/Makefile.in b/misc/Makefile.in
> index 4db59cdf..6f863773 100644
> --- a/misc/Makefile.in
> +++ b/misc/Makefile.in
> @@ -126,8 +126,8 @@ COMPILE_ET= _ET_DIR_OVERRIDE=$(srcdir)/../lib/et/et ../lib/et/compile_et
>
> # This nastiness is needed because of jfs_user.h hackery; when we finally
> # clean up this mess, we should be able to drop it
> -JOURNAL_CFLAGS = -I$(srcdir)/../e2fsck $(ALL_CFLAGS) -DDEBUGFS
> -DEPEND_CFLAGS = -I$(top_srcdir)/e2fsck
> +JOURNAL_CFLAGS = $(ALL_CFLAGS) -DDEBUGFS
> +DEPEND_CFLAGS =
^
You have a trailing whitespace here.

Thanks!
-Lukas

>
> .c.o:
> $(E) " CC $<"
> @@ -878,7 +878,7 @@ check_fuzzer.o: $(srcdir)/check_fuzzer.c $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_srcdir)/lib/ext2fs/bitops.h
> journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \
> $(top_builddir)/lib/dirpaths.h $(srcdir)/../debugfs/journal.h \
> - $(top_srcdir)/e2fsck/jfs_user.h $(top_srcdir)/e2fsck/e2fsck.h \
> + $(top_srcdir)/lib/ext2fs/jfs_user.h $(top_srcdir)/e2fsck/e2fsck.h \
> $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
> $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
> $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
> @@ -891,7 +891,7 @@ journal.o: $(srcdir)/../debugfs/journal.c $(top_builddir)/lib/config.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h
> -revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
> +revoke.o: $(srcdir)/../e2fsck/revoke.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
> $(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> @@ -905,7 +905,7 @@ revoke.o: $(srcdir)/../e2fsck/revoke.c $(srcdir)/../e2fsck/jfs_user.h \
> $(top_srcdir)/lib/ext2fs/fast_commit.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
> $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/lib/ext2fs/compiler.h \
> $(top_srcdir)/lib/ext2fs/kernel-jbd.h
> -recovery.o: $(srcdir)/../e2fsck/recovery.c $(srcdir)/../e2fsck/jfs_user.h \
> +recovery.o: $(srcdir)/../e2fsck/recovery.c $(top_srcdir)/lib/ext2fs/jfs_user.h \
> $(top_builddir)/lib/config.h $(top_builddir)/lib/dirpaths.h \
> $(srcdir)/../e2fsck/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
> $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> --
> 2.31.1
>


2022-08-03 17:05:11

by Alexey Lyahkov

[permalink] [raw]
Subject: Re: [PATCH] e2fsprogs: avoid code duplication

Hi Lukas,

It don’t have any improvement. It have changes a prototype in the e2fsck to use a generic types,
instead of home coded as similar as debugfs does. Removing ctx->journal needs for same reason.
(as generic code have work with ext2fs

I started this work to make debugfs work fine with journal dump and modifications.
Originally, I found tag v3 isn’t work well with journal dump (large block numbers truncated),
checksums isn’t checked well with dump, … etc.
Loading journal have a lack init for structures related to the fast commit.


> On 3 Aug 2022, at 19:39, Lukas Czerner <[email protected]> wrote:
>
> Hi Alexey,
>
> I assume this change is based on the maint branch?
>
> On Wed, Aug 03, 2022 at 10:54:07AM +0300, Alexey Lyashkov wrote:
>> debugfs and e2fsck have a so much code duplication in journal handing.
>> debugfs have lack a many journal features handing also.
>> Let's start code merging to avoid code duplication and lack features.
>>
>> userspace buffer head emulation moved into library.
>
> I can see that this is a little bit more involved than just moving the
> code, can you describe a little bit more what has to be done in order to
> move and deduplicate the code? I have not done a proper review but I can
> already see that the function prototypes are changing as well as some
> structures. I think it would be nice to get some idea from the commit
> description what to expect from this change.
>
> I've done some limited testing on this and I see no regression.
>
>>
>> Signed-off-by: Alexey Lyashkov <[email protected]>
>> ---
>> debugfs/Makefile.in | 14 +-
>> debugfs/debugfs.c | 2 +-
>> debugfs/journal.c | 251 ---------------------------
>> debugfs/journal.h | 2 +-
>> debugfs/logdump.c | 2 +-
>> e2fsck/Makefile.in | 8 +-
>> e2fsck/e2fsck.c | 5 -
>> e2fsck/e2fsck.h | 1 -
>> e2fsck/journal.c | 278 ++----------------------------
>> e2fsck/logfile.c | 2 +-
>> e2fsck/recovery.c | 2 +-
>> e2fsck/revoke.c | 2 +-
>> e2fsck/unix.c | 4 +-
>> e2fsck/util.c | 2 +-
>> lib/ext2fs/Android.bp | 1 +
>> lib/ext2fs/Makefile.in | 23 +--
>> lib/ext2fs/jfs_user.c | 255 +++++++++++++++++++++++++++
>> {e2fsck => lib/ext2fs}/jfs_user.h | 55 +++---
>
> Can we perhaps take the opportunity to rename jfs_user to journal? I
> know it was historically this way, but it can we a bit confusing these
> days, especially when we actually have jfs file system.

I do it originally but… it conflicts with journal.c from e2fsck.
And this code handle just kernel API emulation now.


>
> More below...
>>
>> -
>> -}
>> -
>> /*
>> * This function makes sure that the superblock fields regarding the
>> * journal are consistent.
>> @@ -1525,7 +1285,7 @@ errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx)
>> (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
>> retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
>> &pctx);
>> - e2fsck_journal_release(ctx, journal, 0, 1);
>> + ext2fs_journal_release(ctx->fs, journal, 0, 1);
>> return retval;
>> }
>>
>> @@ -1552,7 +1312,7 @@ no_has_journal:
>> sb->s_journal_dev = 0;
>> memset(sb->s_journal_uuid, 0,
>> sizeof(sb->s_journal_uuid));
>> - e2fsck_clear_recover(ctx, force_fsck);
>> + ext2fs_clear_recover(ctx->fs, force_fsck);
>
> This is the kind of function prototype change I'd like to be mentioned
> in the description. Just to make it easier for reviewer today and for
> the future.
>
I may put a wrappers who just call ext2fs_* functions if it will be help with review.
It will have just ctx->fs call inside.
>>
>>
>> /* Command line options */
>> @@ -66,7 +66,7 @@ static int replace_bad_blocks;
>> static int keep_bad_blocks;
>> static char *bad_blocks_file;
>>
>> -e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
>> +struct e2fsck_struct *e2fsck_global_ctx; /* Try your very best not to use this! */
>
> Why is this necessary? I am just curious.
>
Using a pointer to structure make a full structure definition unnecessary.
So I can do

extern struct data *ptr;
some_call(ptr);

Without teach source about struct data itself.
It’s a specially for the jfs_user.h and J_ASSERT() implementation.

>> diff --git a/e2fsck/jfs_user.h b/lib/ext2fs/jfs_user.h
>> similarity index 89%
>> rename from e2fsck/jfs_user.h
>> rename to lib/ext2fs/jfs_user.h
>> index 4ad2005a..ed75c4a5 100644
>> --- a/e2fsck/jfs_user.h
>> +++ b/lib/ext2fs/jfs_user.h
>> @@ -11,7 +11,6 @@
>> #ifndef _JFS_USER_H
>> #define _JFS_USER_H
>>
>> -#ifdef DEBUGFS
>> #include <stdio.h>
>> #include <stdlib.h>
>> #if EXT2_FLAT_INCLUDES
>> @@ -23,13 +22,8 @@
>> #include "ext2fs/ext2fs.h"
>> #include "blkid/blkid.h"
>> #endif
>> -#else
>> -/*
>> - * Pull in the definition of the e2fsck context structure
>> - */
>> -#include "config.h"
>> -#include "e2fsck.h"
>> -#endif
>> +
>> +struct e2fsck_struct;
>>
>> #if __STDC_VERSION__ < 199901L
>> # if __GNUC__ >= 2 || _MSC_VER >= 1300
>> @@ -40,11 +34,8 @@
>> #endif
>>
>> struct buffer_head {
>> -#ifdef DEBUGFS
>> ext2_filsys b_fs;
>> -#else
>> - e2fsck_t b_ctx;
>> -#endif
>> + struct e2fsck_struct *b_ctx;
>
> Do we need to have both k_ctx and k_fs? Can we use union instead, or is
> not worth it?
>
I think better to have both, in some cases e2fsck looks to the own context attached to these structures.
I’m not a very understand this part - and probably it will be removed in future.

>
>>
>> # This nastiness is needed because of jfs_user.h hackery; when we finally
>> # clean up this mess, we should be able to drop it
>> -JOURNAL_CFLAGS = -I$(srcdir)/../e2fsck $(ALL_CFLAGS) -DDEBUGFS
>> -DEPEND_CFLAGS = -I$(top_srcdir)/e2fsck
>> +JOURNAL_CFLAGS = $(ALL_CFLAGS) -DDEBUGFS
>> +DEPEND_CFLAGS =
> ^
> You have a trailing whitespace here.

Thanks! Will fix it. It looks comment can removed also.

Alex

>
> Thanks!
> -Lukas
>
>>
>> .
>> --
>> 2.31.1
>>
>


2022-08-03 20:14:45

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] e2fsprogs: avoid code duplication

On Wed, Aug 03, 2022 at 10:54:07AM +0300, Alexey Lyashkov wrote:
> debugfs and e2fsck have a so much code duplication in journal handing.
> debugfs have lack a many journal features handing also.
> Let's start code merging to avoid code duplication and lack features.

This is definitely worth doing, and as you've pointed out, there are a
number of features which are in e2fsck/journal.c, which are not in
debugfs/journal.c. The most notable one which I picked up on is the
fast_commit code --- which is in the master/next branch, but not in
the maint branch.

I suggest that we move the functionality into the libsupport library
first. I want to make sure we get the abstractions right before we
"cast them into stone" by moving the functions to libext2fs.
Libsupport is not exported outside of e2fsprogs, so if we decide we
want to change function signatures, or make some functions private, we
can do that more easily if we experiment with moving things into
libsupport first.

- Ted

2022-08-03 21:55:27

by Alexey Lyahkov

[permalink] [raw]
Subject: Re: [PATCH] e2fsprogs: avoid code duplication

Thanks for pointing to the libsupport. I looking into kernel-jbd.h as example (it also don’t export outside of e2fsprogs),
but libsupport is lost from my radar.

Lack of tag v3 is big lost also. It mean debugfs don’t able to print log records correctly if block number over 2^32.

Alex

> On 3 Aug 2022, at 22:58, Theodore Ts'o <[email protected]> wrote:
>
> On Wed, Aug 03, 2022 at 10:54:07AM +0300, Alexey Lyashkov wrote:
>> debugfs and e2fsck have a so much code duplication in journal handing.
>> debugfs have lack a many journal features handing also.
>> Let's start code merging to avoid code duplication and lack features.
>
> This is definitely worth doing, and as you've pointed out, there are a
> number of features which are in e2fsck/journal.c, which are not in
> debugfs/journal.c. The most notable one which I picked up on is the
> fast_commit code --- which is in the master/next branch, but not in
> the maint branch.
>
> I suggest that we move the functionality into the libsupport library
> first. I want to make sure we get the abstractions right before we
> "cast them into stone" by moving the functions to libext2fs.
> Libsupport is not exported outside of e2fsprogs, so if we decide we
> want to change function signatures, or make some functions private, we
> can do that more easily if we experiment with moving things into
> libsupport first.
>
> - Ted