#endif
#define E2FSCK_INCLUDE_INLINE_FUNCS
-#include "jfs_user.h"
#include "uuid/uuid.h"
+#include "journal.h"
#ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jfs-debug */
static int bh_count = 0;
static int ext2fs_journal_verify_csum_type(journal_t *j,
journal_superblock_t *jsb)
{
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return 1;
return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
{
__u32 provided, calculated;
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return 1;
provided = ext2fs_be32_to_cpu(jsb->s_checksum);
{
__u32 crc;
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return 0;
crc = ext2fs_journal_sb_csum(jsb);
* 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 journal_bmap(journal_t *journal, blk64_t block, unsigned long long *phys)
+int jbd2_journal_bmap(journal_t *journal, blk64_t block,
+ unsigned long long *phys)
{
#ifdef USE_INODE_IO
*phys = block;
return io_channel_flush(io) ? EIO : 0;
}
-void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
+void ll_rw_block(int rw, int op_flags, int nr, struct buffer_head *bhp[])
{
errcode_t retval;
struct buffer_head *bh;
for (; nr > 0; --nr) {
bh = *bhp++;
- if (rw == READ && !bh->b_uptodate) {
+ 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,
continue;
}
bh->b_uptodate = 1;
- } else if (rw == WRITE && bh->b_dirty) {
+ } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
jfs_debug(3, "writing block %llu/%p\n",
bh->b_blocknr,
(void *) bh);
bh->b_uptodate = 1;
} else {
jfs_debug(3, "no-op %s for block %llu\n",
- rw == READ ? "read" : "write",
+ rw == REQ_OP_READ ? "read" : "write",
bh->b_blocknr);
}
}
void brelse(struct buffer_head *bh)
{
if (bh->b_dirty)
- ll_rw_block(WRITE, 1, &bh);
+ 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 wait_on_buffer(struct buffer_head *bh)
{
if (!bh->b_uptodate)
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(REQ_OP_READ, 0, 1, &bh);
}
static void ext2fs_clear_recover(ext2_filsys fs, int error)
{
- fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
+ 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);
}
goto try_backup_journal;
}
if (EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize <
- JFS_MIN_JOURNAL_BLOCKS) {
+ JBD2_MIN_JOURNAL_BLOCKS) {
retval = EXT2_ET_JOURNAL_TOO_SMALL;
goto try_backup_journal;
}
#else
journal->j_inode = j_inode;
fs->journal_io = fs->io;
- retval = (errcode_t)journal_bmap(journal, 0, &start);
+ retval = (errcode_t) jbd2_journal_bmap(journal, 0, &start);
if (retval)
goto errout;
#endif
retval = EXT2_ET_NO_MEMORY;
goto errout;
}
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(REQ_OP_READ, 0, 1, &bh);
retval = bh->b_err;
if (retval) {
brelse(bh);
ext2fs_swap_super(&jsuper);
#endif
if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
- !(jsuper.s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
+ !ext2fs_has_feature_journal_dev(&jsuper)) {
retval = EXT2_ET_LOAD_EXT_JOURNAL;
brelse(bh);
goto errout;
}
/* Check the superblock checksum */
- if (jsuper.s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
+ if (ext2fs_has_feature_metadata_csum(&jsuper)) {
struct struct_ext2_filsys fsx;
struct ext2_super_block superx;
void *p;
memcpy(&fsx, fs, sizeof(fsx));
memcpy(&superx, fs->super, sizeof(superx));
fsx.super = &superx;
- fsx.super->s_feature_ro_compat |=
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
+ ext2fs_set_feature_metadata_csum(fsx.super);
if (!ext2fs_superblock_csum_verify(&fsx, p)) {
retval = EXT2_ET_LOAD_EXT_JOURNAL;
brelse(bh);
static errcode_t ext2fs_journal_fix_bad_inode(ext2_filsys fs)
{
struct ext2_super_block *sb = fs->super;
- int recover = fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_RECOVER;
- int has_journal = fs->super->s_feature_compat &
- EXT3_FEATURE_COMPAT_HAS_JOURNAL;
+ int recover = ext2fs_has_feature_journal_needs_recovery(fs->super);
+ int has_journal = ext2fs_has_feature_journal(fs->super);
if (has_journal || sb->s_journal_inum) {
/* The journal inode is bogus, remove and force full fsck */
journal_superblock_t *jsb;
struct buffer_head *jbh = journal->j_sb_buffer;
- ll_rw_block(READ, 1, &jbh);
+ ll_rw_block(REQ_OP_READ, 0, 1, &jbh);
if (jbh->b_err)
return jbh->b_err;
jsb = journal->j_superblock;
- /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
- if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
+ /* If we don't even have JBD2_MAGIC, we probably have a wrong inode */
+ if (jsb->s_header.h_magic != htonl(JBD2_MAGIC_NUMBER))
return ext2fs_journal_fix_bad_inode(fs);
switch (ntohl(jsb->s_header.h_blocktype)) {
- case JFS_SUPERBLOCK_V1:
+ case JBD2_SUPERBLOCK_V1:
journal->j_format_version = 1;
if (jsb->s_feature_compat ||
jsb->s_feature_incompat ||
clear_v2_journal_fields(journal);
break;
- case JFS_SUPERBLOCK_V2:
+ case JBD2_SUPERBLOCK_V2:
journal->j_format_version = 2;
if (ntohl(jsb->s_nr_users) > 1 &&
uuid_is_null(fs->super->s_journal_uuid))
* These should never appear in a journal super block, so if
* they do, the journal is badly corrupted.
*/
- case JFS_DESCRIPTOR_BLOCK:
- case JFS_COMMIT_BLOCK:
- case JFS_REVOKE_BLOCK:
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ case JBD2_DESCRIPTOR_BLOCK:
+ case JBD2_COMMIT_BLOCK:
+ case JBD2_REVOKE_BLOCK:
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
/* If we don't understand the superblock major type, but there
* is a magic number, then it is likely to be a new format we
return EXT2_ET_JOURNAL_UNSUPP_VERSION;
}
- if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
+ if (JBD2_HAS_INCOMPAT_FEATURE(journal, ~JBD2_KNOWN_INCOMPAT_FEATURES))
return EXT2_ET_UNSUPP_FEATURE;
- if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
+ if (JBD2_HAS_RO_COMPAT_FEATURE(journal, ~JBD2_KNOWN_ROCOMPAT_FEATURES))
return EXT2_ET_RO_UNSUPP_FEATURE;
/* Checksum v1-3 are mutually exclusive features. */
- if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_CSUM_V2) &&
- JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_CSUM_V3))
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ if (jbd2_has_feature_csum2(journal) && jbd2_has_feature_csum3(journal))
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
- if (journal_has_csum_v2or3(journal) &&
- JFS_HAS_COMPAT_FEATURE(journal, JFS_FEATURE_COMPAT_CHECKSUM))
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ if (jbd2_journal_has_csum_v2or3(journal) &&
+ jbd2_has_feature_checksum(journal))
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
if (!ext2fs_journal_verify_csum_type(journal, jsb) ||
!ext2fs_journal_sb_csum_verify(journal, jsb))
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
- if (journal_has_csum_v2or3(journal))
+ if (jbd2_journal_has_csum_v2or3(journal))
journal->j_csum_seed = jbd2_chksum(journal, ~0, jsb->s_uuid,
sizeof(jsb->s_uuid));
* format to be able to proceed safely, so any other checks that
* fail we should attempt to recover from. */
if (jsb->s_blocksize != htonl(journal->j_blocksize))
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
journal->j_maxlen = ntohl(jsb->s_maxlen);
else if (ntohl(jsb->s_maxlen) > journal->j_maxlen)
- return EXT2_ET_CORRUPT_SUPERBLOCK;
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
journal->j_tail_sequence = ntohl(jsb->s_sequence);
journal->j_transaction_sequence = journal->j_tail_sequence;
return 0;
}
-void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
+static void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
int reset, int drop)
{
journal_superblock_t *jsb;
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
* This function makes sure that the superblock fields regarding the
* journal are consistent.
*/
-errcode_t ext2fs_check_ext3_journal(ext2_filsys fs)
+static errcode_t ext2fs_check_ext3_journal(ext2_filsys fs)
{
struct ext2_super_block *sb = fs->super;
journal_t *journal;
- int recover = fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_RECOVER;
+ int recover = ext2fs_has_feature_journal_needs_recovery(fs->super);
errcode_t retval;
/* If we don't have any journal features, don't do anything more */
- if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+ if (!ext2fs_has_feature_journal(sb) &&
!recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
uuid_is_null(sb->s_journal_uuid))
return 0;
* needs_recovery set but has_journal clear. We can't get in a loop
* with -y, -n, or -p, only if a user isn't making up their mind.
*/
- if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
+ if (!ext2fs_has_feature_journal(sb)) {
retval = EXT2_ET_JOURNAL_FLAGS_WRONG;
goto err;
}
- if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
- !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
+ if (ext2fs_has_feature_journal(sb) &&
+ !ext2fs_has_feature_journal_needs_recovery(sb) &&
journal->j_superblock->s_start != 0) {
retval = EXT2_ET_JOURNAL_FLAGS_WRONG;
goto err;
* the journal's errno is set; if so, we need to mark the file
* system as being corrupt and clear the journal's s_errno.
*/
- if (!(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
+ if (!ext2fs_has_feature_journal_needs_recovery(sb) &&
journal->j_superblock->s_errno) {
fs->super->s_state |= EXT2_ERROR_FS;
ext2fs_mark_super_dirty(fs);
journal_t *journal;
errcode_t retval;
- journal_init_revoke_caches();
+ jbd2_journal_init_revoke_caches();
retval = ext2fs_get_journal(fs, &journal);
if (retval)
return retval;
if (retval)
goto errout;
- retval = journal_init_revoke(journal, 1024);
+ retval = jbd2_journal_init_revoke(journal, 1024);
if (retval)
goto errout;
- retval = -journal_recover(journal);
+ retval = -jbd2_journal_recover(journal);
if (retval)
goto errout;
}
errout:
- journal_destroy_revoke(journal);
- journal_destroy_revoke_caches();
+ jbd2_journal_destroy_revoke(journal);
+ jbd2_journal_destroy_revoke_caches();
ext2fs_journal_release(fs, journal, 1, 0);
return retval;
}
kbytes_written = stats->bytes_written >> 10;
ext2fs_mmp_stop(fs);
- fsname = strdup(fs->device_name);
+ fsname = fs->device_name;
+ fs->device_name = NULL;
fsflags = fs->flags;
fsblocksize = fs->blocksize;
ext2fs_free(fs);
- retval = ext2fs_open(fsname, fsflags,
- 0, fsblocksize, io_ptr,
- fsp);
- free(fsname);
+ *fsp = NULL;
+ retval = ext2fs_open(fsname, fsflags, 0, fsblocksize, io_ptr, fsp);
+ ext2fs_free_mem(&fsname);
if (retval)
return retval;
journal_t *journal;
errcode_t retval;
- journal_init_revoke_caches();
+ jbd2_journal_init_revoke_caches();
retval = ext2fs_get_journal(fs, &journal);
if (retval)
return retval;
if (retval)
goto errout;
- retval = journal_init_revoke(journal, 1024);
+ retval = jbd2_journal_init_revoke(journal, 1024);
if (retval)
goto errout;
return 0;
errout:
- journal_destroy_revoke(journal);
- journal_destroy_revoke_caches();
+ jbd2_journal_destroy_revoke(journal);
+ jbd2_journal_destroy_revoke_caches();
ext2fs_journal_release(fs, journal, 1, 0);
return retval;
}
{
journal_t *journal = *j;
- journal_destroy_revoke(journal);
- journal_destroy_revoke_caches();
+ jbd2_journal_destroy_revoke(journal);
+ jbd2_journal_destroy_revoke_caches();
ext2fs_journal_release(fs, journal, 0, 0);
*j = NULL;
struct commit_header *h;
__u32 csum;
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return;
h = (struct commit_header *)(bh->b_data);
void jbd2_revoke_csum_set(journal_t *j, struct buffer_head *bh)
{
- struct journal_revoke_tail *tail;
- __u32 csum;
-
- if (!journal_has_csum_v2or3(j))
- return;
-
- tail = (struct journal_revoke_tail *)(bh->b_data + j->j_blocksize -
- sizeof(struct journal_revoke_tail));
- tail->r_checksum = 0;
- csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize);
- tail->r_checksum = ext2fs_cpu_to_be32(csum);
+ jbd2_descr_block_csum_set(j, bh);
}
void jbd2_descr_block_csum_set(journal_t *j, struct buffer_head *bh)
{
- struct journal_block_tail *tail;
+ struct jbd2_journal_block_tail *tail;
__u32 csum;
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return;
- tail = (struct journal_block_tail *)(bh->b_data + j->j_blocksize -
- sizeof(struct journal_block_tail));
+ tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize -
+ sizeof(struct jbd2_journal_block_tail));
tail->t_checksum = 0;
csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize);
tail->t_checksum = ext2fs_cpu_to_be32(csum);
__u32 csum32;
__be32 seq;
- if (!journal_has_csum_v2or3(j))
+ if (!jbd2_journal_has_csum_v2or3(j))
return;
seq = ext2fs_cpu_to_be32(sequence);
csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq));
csum32 = jbd2_chksum(j, csum32, bh->b_data, bh->b_size);
- if (JFS_HAS_INCOMPAT_FEATURE(j, JFS_FEATURE_INCOMPAT_CSUM_V3))
+ if (jbd2_has_feature_csum3(j))
tag3->t_checksum = ext2fs_cpu_to_be32(csum32);
else
tag->t_checksum = ext2fs_cpu_to_be16(csum32);