#endif
#include "debugfs.h"
-#include "jfs_user.h"
#include "ext2fs/kernel-jbd.h"
-
-/* journal.c */
-errcode_t ext2fs_open_journal(ext2_filsys fs, journal_t **j);
-errcode_t ext2fs_close_journal(ext2_filsys fs, journal_t **j);
-errcode_t ext2fs_run_ext3_journal(ext2_filsys *fs);
-void jbd2_commit_block_csum_set(journal_t *j, struct buffer_head *bh);
-void jbd2_revoke_csum_set(journal_t *j, struct buffer_head *bh);
-void jbd2_descr_block_csum_set(journal_t *j, struct buffer_head *bh);
-void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
- struct buffer_head *bh, __u32 sequence);
+#include "journal.h"
#undef DEBUG
static journal_t *current_journal = NULL;
-static void journal_dump_trans(journal_transaction_t *trans, const char *tag)
+static void journal_dump_trans(journal_transaction_t *trans EXT2FS_ATTR((unused)),
+ const char *tag EXT2FS_ATTR((unused)))
{
dbg_printf("TRANS %p(%s): tid=%d start=%llu block=%llu end=%llu "
"flags=0x%x\n", trans, tag, trans->tid, trans->start,
/* write the descriptor block header */
commit = (struct commit_header *)bh->b_data;
- commit->h_magic = ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER);
- commit->h_blocktype = ext2fs_cpu_to_be32(JFS_COMMIT_BLOCK);
+ commit->h_magic = ext2fs_cpu_to_be32(JBD2_MAGIC_NUMBER);
+ commit->h_blocktype = ext2fs_cpu_to_be32(JBD2_COMMIT_BLOCK);
commit->h_sequence = ext2fs_cpu_to_be32(trans->tid);
- if (JFS_HAS_COMPAT_FEATURE(trans->journal,
- JFS_FEATURE_COMPAT_CHECKSUM)) {
+ if (jbd2_has_feature_checksum(trans->journal)) {
__u32 csum_v1 = ~0;
blk64_t cblk;
}
for (cblk = trans->start; cblk < trans->block; cblk++) {
- err = journal_bmap(trans->journal, cblk,
- &cbh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, cblk,
+ &cbh->b_blocknr);
if (err)
goto error;
mark_buffer_uptodate(cbh, 0);
- ll_rw_block(READ, 1, &cbh);
+ ll_rw_block(REQ_OP_READ, 0, 1, &cbh);
err = cbh->b_err;
if (err)
goto error;
cbh->b_size);
}
- commit->h_chksum_type = JFS_CRC32_CHKSUM;
- commit->h_chksum_size = JFS_CRC32_CHKSUM_SIZE;
+ commit->h_chksum_type = JBD2_CRC32_CHKSUM;
+ commit->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE;
commit->h_chksum[0] = ext2fs_cpu_to_be32(csum_v1);
} else {
commit->h_chksum_type = 0;
/* Write block */
jbd2_commit_block_csum_set(trans->journal, bh);
- err = journal_bmap(trans->journal, trans->block, &bh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, trans->block, &bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing commit block at %llu:%llu\n", trans->block,
bh->b_blocknr);
mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
err = bh->b_err;
if (err)
goto error;
trans->flags &= ~J_TRANS_OPEN;
trans->block++;
- trans->fs->super->s_feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;
+ ext2fs_set_feature_journal_needs_recovery(trans->fs->super);
ext2fs_mark_super_dirty(trans->fs);
error:
if (cbh)
blk64_t *revoke_list,
size_t revoke_len)
{
- journal_revoke_header_t *jrb;
+ jbd2_journal_revoke_header_t *jrb;
void *buf;
size_t i, offset;
blk64_t curr_blk;
- int csum_size = 0;
+ unsigned int sz;
+ unsigned csum_size = 0;
struct buffer_head *bh;
errcode_t err;
return 0;
/* Do we need to leave space at the end for a checksum? */
- if (journal_has_csum_v2or3(trans->journal))
- csum_size = sizeof(struct journal_revoke_tail);
+ if (jbd2_journal_has_csum_v2or3(trans->journal))
+ csum_size = sizeof(struct jbd2_journal_block_tail);
curr_blk = trans->block;
if (bh == NULL)
return ENOMEM;
jrb = buf = bh->b_data;
- jrb->r_header.h_magic = ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER);
- jrb->r_header.h_blocktype = ext2fs_cpu_to_be32(JFS_REVOKE_BLOCK);
+ jrb->r_header.h_magic = ext2fs_cpu_to_be32(JBD2_MAGIC_NUMBER);
+ jrb->r_header.h_blocktype = ext2fs_cpu_to_be32(JBD2_REVOKE_BLOCK);
jrb->r_header.h_sequence = ext2fs_cpu_to_be32(trans->tid);
offset = sizeof(*jrb);
+ if (jbd2_has_feature_64bit(trans->journal))
+ sz = 8;
+ else
+ sz = 4;
+
for (i = 0; i < revoke_len; i++) {
/* Block full, write to journal */
- if (offset > trans->journal->j_blocksize - csum_size) {
+ if (offset + sz > trans->journal->j_blocksize - csum_size) {
jrb->r_count = ext2fs_cpu_to_be32(offset);
jbd2_revoke_csum_set(trans->journal, bh);
- err = journal_bmap(trans->journal, curr_blk,
- &bh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, curr_blk,
+ &bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing revoke block at %llu:%llu\n",
curr_blk, bh->b_blocknr);
mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
err = bh->b_err;
if (err)
goto error;
goto error;
}
- if (JFS_HAS_INCOMPAT_FEATURE(trans->journal,
- JFS_FEATURE_INCOMPAT_64BIT)) {
+ if (jbd2_has_feature_64bit(trans->journal))
*((__u64 *)(&((char *)buf)[offset])) =
ext2fs_cpu_to_be64(revoke_list[i]);
- offset += 8;
-
- } else {
+ else
*((__u32 *)(&((char *)buf)[offset])) =
ext2fs_cpu_to_be32(revoke_list[i]);
- offset += 4;
- }
+ offset += sz;
}
if (offset > 0) {
jrb->r_count = ext2fs_cpu_to_be32(offset);
jbd2_revoke_csum_set(trans->journal, bh);
- err = journal_bmap(trans->journal, curr_blk, &bh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, curr_blk,
+ &bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing revoke block at %llu:%llu\n",
curr_blk, bh->b_blocknr);
mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
err = bh->b_err;
if (err)
goto error;
return 0;
/* Do we need to leave space at the end for a checksum? */
- if (journal_has_csum_v2or3(trans->journal))
- csum_size = sizeof(struct journal_block_tail);
+ if (jbd2_journal_has_csum_v2or3(trans->journal))
+ csum_size = sizeof(struct jbd2_journal_block_tail);
curr_blk = jdb_blk = trans->block;
goto error;
}
jdb = jdb_buf = bh->b_data;
- jdb->h_magic = ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER);
- jdb->h_blocktype = ext2fs_cpu_to_be32(JFS_DESCRIPTOR_BLOCK);
+ jdb->h_magic = ext2fs_cpu_to_be32(JBD2_MAGIC_NUMBER);
+ jdb->h_blocktype = ext2fs_cpu_to_be32(JBD2_DESCRIPTOR_BLOCK);
jdb->h_sequence = ext2fs_cpu_to_be32(trans->tid);
jdbt = (journal_block_tag_t *)(jdb + 1);
if ((char *)jdbt + tag_bytes >
(char *)jdb_buf + trans->journal->j_blocksize - csum_size) {
jbd2_descr_block_csum_set(trans->journal, bh);
- err = journal_bmap(trans->journal, jdb_blk,
+ err = jbd2_journal_bmap(trans->journal, jdb_blk,
&bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing descriptor block at %llu:%llu\n",
jdb_blk, bh->b_blocknr);
mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
err = bh->b_err;
if (err)
goto error;
jdbt->t_blocknr = ext2fs_cpu_to_be32(block_list[i] & 0xFFFFFFFF);
jdbt->t_flags = 0;
if (jdbt != (journal_block_tag_t *)(jdb + 1))
- jdbt->t_flags |= ext2fs_cpu_to_be16(JFS_FLAG_SAME_UUID);
+ jdbt->t_flags |= ext2fs_cpu_to_be16(JBD2_FLAG_SAME_UUID);
else {
memcpy(jdbt + tag_bytes,
trans->journal->j_superblock->s_uuid,
tag_bytes += 16;
}
if (i == block_len - 1)
- jdbt->t_flags |= ext2fs_cpu_to_be16(JFS_FLAG_LAST_TAG);
- if (*((__u32 *)buf) == ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER)) {
+ jdbt->t_flags |= ext2fs_cpu_to_be16(JBD2_FLAG_LAST_TAG);
+ if (*((__u32 *)buf) == ext2fs_cpu_to_be32(JBD2_MAGIC_NUMBER)) {
*((__u32 *)buf) = 0;
- jdbt->t_flags |= ext2fs_cpu_to_be16(JFS_FLAG_ESCAPE);
+ jdbt->t_flags |= ext2fs_cpu_to_be16(JBD2_FLAG_ESCAPE);
}
- if (JFS_HAS_INCOMPAT_FEATURE(trans->journal,
- JFS_FEATURE_INCOMPAT_64BIT))
+ if (jbd2_has_feature_64bit(trans->journal))
jdbt->t_blocknr_high = ext2fs_cpu_to_be32(block_list[i] >> 32);
jbd2_block_tag_csum_set(trans->journal, jdbt, data_bh,
trans->tid);
/* Write the data block */
- err = journal_bmap(trans->journal, curr_blk,
- &data_bh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, curr_blk,
+ &data_bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing data block %llu at %llu:%llu tag %d\n",
block_list[i], curr_blk, data_bh->b_blocknr,
tag_bytes);
mark_buffer_dirty(data_bh);
- ll_rw_block(WRITE, 1, &data_bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &data_bh);
err = data_bh->b_err;
if (err)
goto error;
/* Write out the last descriptor block */
if (jdbt != (journal_block_tag_t *)(jdb + 1)) {
jbd2_descr_block_csum_set(trans->journal, bh);
- err = journal_bmap(trans->journal, jdb_blk, &bh->b_blocknr);
+ err = jbd2_journal_bmap(trans->journal, jdb_blk,
+ &bh->b_blocknr);
if (err)
goto error;
dbg_printf("Writing descriptor block at %llu:%llu\n",
jdb_blk, bh->b_blocknr);
mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
+ ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
err = bh->b_err;
if (err)
goto error;
/* Estimate # of revoke blocks */
bs = journal->j_blocksize;
- if (journal_has_csum_v2or3(journal))
- bs -= sizeof(struct journal_revoke_tail);
- sz = JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT) ?
- sizeof(__u64) : sizeof(__u32);
+ if (jbd2_journal_has_csum_v2or3(journal))
+ bs -= sizeof(struct jbd2_journal_block_tail);
+ sz = jbd2_has_feature_64bit(journal) ? sizeof(__u64) : sizeof(__u32);
ret += revoke_blocks * sz / bs;
/* Estimate # of data blocks */
bs = journal->j_blocksize - 16;
- if (journal_has_csum_v2or3(journal))
- bs -= sizeof(struct journal_block_tail);
+ if (jbd2_journal_has_csum_v2or3(journal))
+ bs -= sizeof(struct jbd2_journal_block_tail);
sz = journal_tag_bytes(journal);
ret += data_blocks * sz / bs;
trans->magic = 0;
/* Mark ourselves as needing recovery */
- if (!(EXT2_HAS_INCOMPAT_FEATURE(trans->fs->super,
- EXT3_FEATURE_INCOMPAT_RECOVER))) {
- trans->fs->super->s_feature_incompat |=
- EXT3_FEATURE_INCOMPAT_RECOVER;
+ if (!ext2fs_has_feature_journal_needs_recovery(trans->fs->super)) {
+ ext2fs_set_feature_journal_needs_recovery(trans->fs->super);
ext2fs_mark_super_dirty(trans->fs);
}
errcode_t err;
if (revoke_len > 0) {
- journal->j_superblock->s_feature_incompat |=
- ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_REVOKE);
+ jbd2_set_feature_revoke(journal);
mark_buffer_dirty(journal->j_sb_buffer);
}
return err;
}
-void do_journal_write(int argc, char *argv[])
+void do_journal_write(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
{
blk64_t *blist = NULL, *rlist = NULL;
size_t bn = 0, rn = 0;
int nr = 0, size = journal->j_blocksize;
int tag_bytes = journal_tag_bytes(journal);
- if (journal_has_csum_v2or3(journal))
- size -= sizeof(struct journal_block_tail);
+ if (jbd2_journal_has_csum_v2or3(journal))
+ size -= sizeof(struct jbd2_journal_block_tail);
tagp = buf + sizeof(journal_header_t);
nr++;
tagp += tag_bytes;
- if (!(tag->t_flags & ext2fs_cpu_to_be16(JFS_FLAG_SAME_UUID)))
+ if (!(tag->t_flags & ext2fs_cpu_to_be16(JBD2_FLAG_SAME_UUID)))
tagp += 16;
- if (tag->t_flags & ext2fs_cpu_to_be16(JFS_FLAG_LAST_TAG))
+ if (tag->t_flags & ext2fs_cpu_to_be16(JBD2_FLAG_LAST_TAG))
break;
}
return nr;
}
-errcode_t journal_find_head(journal_t *journal)
+static errcode_t journal_find_head(journal_t *journal)
{
unsigned int next_commit_ID;
blk64_t next_log_block, head_block;
/* Skip over each chunk of the transaction looking
* either the next descriptor block or the final commit
* record. */
- err = journal_bmap(journal, next_log_block, &bh->b_blocknr);
+ err = jbd2_journal_bmap(journal, next_log_block,
+ &bh->b_blocknr);
if (err)
goto err;
mark_buffer_uptodate(bh, 0);
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(REQ_OP_READ, 0, 1, &bh);
err = bh->b_err;
if (err)
goto err;
tmp = (journal_header_t *)bh->b_data;
- if (tmp->h_magic != ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER)) {
+ if (tmp->h_magic != ext2fs_cpu_to_be32(JBD2_MAGIC_NUMBER)) {
dbg_printf("JBD2: wrong magic 0x%x\n", tmp->h_magic);
goto err;
}
* to do with it? That depends on the pass... */
switch (blocktype) {
- case JFS_DESCRIPTOR_BLOCK:
+ case JBD2_DESCRIPTOR_BLOCK:
next_log_block += count_tags(journal, bh->b_data);
wrap(journal, next_log_block);
continue;
- case JFS_COMMIT_BLOCK:
+ case JBD2_COMMIT_BLOCK:
head_block = next_log_block;
next_commit_ID++;
continue;
- case JFS_REVOKE_BLOCK:
+ case JBD2_REVOKE_BLOCK:
continue;
default:
return;
if (journal->j_tail != 0 ||
- EXT2_HAS_INCOMPAT_FEATURE(journal->j_fs_dev->k_fs->super,
- EXT3_FEATURE_INCOMPAT_RECOVER)) {
+ ext2fs_has_feature_journal_needs_recovery(
+ journal->j_fs_dev->k_fs->super)) {
printf("Journal needs recovery, will not add csums.\n");
return;
}
/* metadata_csum implies journal csum v3 */
jsb = journal->j_superblock;
- if (EXT2_HAS_RO_COMPAT_FEATURE(journal->j_fs_dev->k_fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ if (ext2fs_has_feature_metadata_csum(journal->j_fs_dev->k_fs->super)) {
printf("Setting csum v%d\n", ver);
switch (ver) {
case 2:
- journal->j_superblock->s_feature_incompat &=
- ext2fs_cpu_to_be32(~JFS_FEATURE_INCOMPAT_CSUM_V3);
- journal->j_superblock->s_feature_incompat |=
- ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2);
- journal->j_superblock->s_feature_compat &=
- ext2fs_cpu_to_be32(~JFS_FEATURE_COMPAT_CHECKSUM);
+ jbd2_clear_feature_csum3(journal);
+ jbd2_set_feature_csum2(journal);
+ jbd2_clear_feature_checksum(journal);
break;
case 3:
- journal->j_superblock->s_feature_incompat &=
- ext2fs_cpu_to_be32(~JFS_FEATURE_INCOMPAT_CSUM_V2);
- journal->j_superblock->s_feature_incompat |=
- ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V3);
- journal->j_superblock->s_feature_compat &=
- ext2fs_cpu_to_be32(~JFS_FEATURE_COMPAT_CHECKSUM);
+ jbd2_set_feature_csum3(journal);
+ jbd2_clear_feature_csum2(journal);
+ jbd2_clear_feature_checksum(journal);
break;
default:
printf("Unknown checksum v%d\n", ver);
journal->j_csum_seed = jbd2_chksum(journal, ~0, jsb->s_uuid,
sizeof(jsb->s_uuid));
} else {
- journal->j_superblock->s_feature_compat |=
- ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_CHECKSUM);
- journal->j_superblock->s_feature_incompat &=
- ext2fs_cpu_to_be32(~(JFS_FEATURE_INCOMPAT_CSUM_V2 |
- JFS_FEATURE_INCOMPAT_CSUM_V3));
+ jbd2_clear_feature_csum3(journal);
+ jbd2_clear_feature_csum2(journal);
+ jbd2_set_feature_checksum(journal);
}
}
return;
fs = journal->j_fs_dev->k_fs;
- if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_64BIT))
+ if (!ext2fs_has_feature_64bit(fs->super))
return;
- if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT) &&
- EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_64BIT))
+ if (jbd2_has_feature_64bit(journal) &&
+ ext2fs_has_feature_64bit(fs->super))
return;
if (journal->j_tail != 0 ||
- EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT3_FEATURE_INCOMPAT_RECOVER)) {
+ ext2fs_has_feature_journal_needs_recovery(fs->super)) {
printf("Journal needs recovery, will not set 64bit.\n");
return;
}
if (journal->j_format_version < 2)
return;
- if (!EXT2_HAS_INCOMPAT_FEATURE(journal->j_fs_dev->k_fs->super,
- EXT4_FEATURE_INCOMPAT_64BIT))
+ if (!ext2fs_has_feature_64bit(journal->j_fs_dev->k_fs->super))
return;
- if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT) &&
- EXT2_HAS_INCOMPAT_FEATURE(journal->j_fs_dev->k_fs->super,
- EXT4_FEATURE_INCOMPAT_64BIT))
+ if (jbd2_has_feature_64bit(journal) &&
+ ext2fs_has_feature_64bit(journal->j_fs_dev->k_fs->super))
return;
if (journal->j_tail != 0 ||
- EXT2_HAS_INCOMPAT_FEATURE(journal->j_fs_dev->k_fs->super,
- EXT3_FEATURE_INCOMPAT_RECOVER)) {
+ ext2fs_has_feature_journal_needs_recovery(
+ journal->j_fs_dev->k_fs->super)) {
printf("Journal needs recovery, will not set 64bit.\n");
return;
}
- journal->j_superblock->s_feature_incompat |=
- ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_64BIT);
+ jbd2_set_feature_64bit(journal);
}
-void do_journal_open(int argc, char *argv[])
+void do_journal_open(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
{
int opt, enable_csum = 0, csum_ver = 3;
journal_t *journal;
printf("Journal is already open.\n");
return;
}
- if (!EXT2_HAS_COMPAT_FEATURE(current_fs->super,
- EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
+ if (!ext2fs_has_feature_journal(current_fs->super)) {
printf("Journalling is not enabled on this filesystem.\n");
return;
}
}
break;
default:
- printf("%s: [-c] [-v ver]\n", argv[0]);
+ printf("%s: [-c] [-v ver] [-f ext_jnl]\n", argv[0]);
printf("-c: Enable journal checksumming.\n");
printf("-v: Use this version checksum format.\n");
+ printf("-f: Load this external journal.\n");
}
}
com_err(argv[0], err, "while examining journal");
}
-void do_journal_close(int argc, char *argv[])
+void do_journal_close(int argc EXT2FS_ATTR((unused)),
+ char *argv[] EXT2FS_ATTR((unused)),
+ int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
{
if (current_journal == NULL) {
printf("Journal not open.\n");
ext2fs_close_journal(current_fs, ¤t_journal);
}
-void do_journal_run(int argc, char *argv[])
+void do_journal_run(int argc EXT2FS_ATTR((unused)), char *argv[],
+ int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
{
errcode_t err;
if (err)
com_err("journal_run", err, "while recovering journal");
else {
- current_fs->super->s_feature_incompat &=
- ~EXT3_FEATURE_INCOMPAT_RECOVER;
+ ext2fs_clear_feature_journal_needs_recovery(current_fs->super);
ext2fs_mark_super_dirty(current_fs);
}
}