Message ID | 20220804095618.887684-5-alexey.lyashkov@gmail.com |
---|---|
State | New |
Headers | show |
Series | [1/5] move a jfs_user.h to better place. | expand |
On Aug 4, 2022, at 3:56 AM, Alexey Lyashkov <alexey.lyashkov@gmail.com> wrote: > > move a buffer_head and device code into libsupport. Missing Signed-off-by: line, but looks fine otherwise. Reviewed-by: Andreas Dilger <adilger@dilger.ca> -- This patch was pushed before 1.47.0 was released, so debugfs/journal.c is still missing the ext4_fc_replay*() code only in e2fsck/journal.c, but at least it removes much of the duplication between these files. We _might_ be able to merge the rest of this code into a single file with something tricky, like having the fix_problem() calls handled via function pointers in the journal context for e2fsck_journal_load() and similar, and do nothing in the debugfs case. I haven't looked into that yet. Cheers, Andreas > --- > debugfs/journal.c | 147 ----------------------------------------- > e2fsck/journal.c | 143 --------------------------------------- > lib/support/jfs_user.c | 142 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 142 insertions(+), 290 deletions(-) > > diff --git a/debugfs/journal.c b/debugfs/journal.c > index 202312fe..510a0acb 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 > @@ -47,151 +45,6 @@ static int bh_count = 0; > * 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) > { > diff --git a/e2fsck/journal.c b/e2fsck/journal.c > index 728f5a24..9ff1dc94 100644 > --- a/e2fsck/journal.c > +++ b/e2fsck/journal.c > @@ -27,8 +27,6 @@ > #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 > @@ -42,147 +40,6 @@ static int bh_count = 0; > * 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 -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_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; > -} > - > -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); > diff --git a/lib/support/jfs_user.c b/lib/support/jfs_user.c > index d8a2f842..26f0090b 100644 > --- a/lib/support/jfs_user.c > +++ b/lib/support/jfs_user.c > @@ -1,6 +1,8 @@ > #define DEBUGFS > #include "jfs_user.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 > @@ -60,12 +62,116 @@ errcode_t ext2fs_journal_sb_csum_set(journal_t *j, > return 0; > } > > +void mark_buffer_dirty(struct buffer_head *bh) > +{ > + bh->b_dirty = 1; > +} > + > +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 mark_buffer_clean(struct buffer_head * bh) > { > bh->b_dirty = 0; > } > > +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; > +} > + > +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); > +} > + > +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 ext2fs_journal_release(ext2_filsys fs, journal_t *journal, > int reset, int drop) > { > @@ -99,3 +205,39 @@ void ext2fs_journal_release(ext2_filsys fs, journal_t *journal, > ext2fs_free_mem(&journal->j_fs_dev); > ext2fs_free_mem(&journal); > } > + > +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 > +} > + > +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; > +} > -- > 2.31.1 > Cheers, Andreas
diff --git a/debugfs/journal.c b/debugfs/journal.c index 202312fe..510a0acb 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 @@ -47,151 +45,6 @@ static int bh_count = 0; * 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) { diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 728f5a24..9ff1dc94 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -27,8 +27,6 @@ #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 @@ -42,147 +40,6 @@ static int bh_count = 0; * 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 -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_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; -} - -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); diff --git a/lib/support/jfs_user.c b/lib/support/jfs_user.c index d8a2f842..26f0090b 100644 --- a/lib/support/jfs_user.c +++ b/lib/support/jfs_user.c @@ -1,6 +1,8 @@ #define DEBUGFS #include "jfs_user.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 @@ -60,12 +62,116 @@ errcode_t ext2fs_journal_sb_csum_set(journal_t *j, return 0; } +void mark_buffer_dirty(struct buffer_head *bh) +{ + bh->b_dirty = 1; +} + +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 mark_buffer_clean(struct buffer_head * bh) { bh->b_dirty = 0; } +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; +} + +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); +} + +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 ext2fs_journal_release(ext2_filsys fs, journal_t *journal, int reset, int drop) { @@ -99,3 +205,39 @@ void ext2fs_journal_release(ext2_filsys fs, journal_t *journal, ext2fs_free_mem(&journal->j_fs_dev); ext2fs_free_mem(&journal); } + +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 +} + +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; +}