Esempio n. 1
0
/**
 *  journal_t * journal_init_inode () - creates a journal which maps to a inode.
 *  @inode: An inode to create the journal in
 *
 * journal_init_inode creates a journal which maps an on-disk inode as
 * the journal.  The inode must exist already, must support bmap() and
 * must have all data blocks preallocated.
 */
journal_t * journal_init_inode (struct inode *inode)
{
    struct buffer_head *bh;
    journal_t *journal = journal_init_common();
    int err;
    int n;
    unsigned long blocknr;

    if (!journal)
        return NULL;

    journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev;
    journal->j_inode = inode;
    jbd_debug(1,
              "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n",
              journal, inode->i_sb->s_id, inode->i_ino,
              (s64) inode->i_size,
              inode->i_sb->s_blocksize_bits, inode->i_sb->s_blocksize);

    journal->j_maxlen = (unsigned int)(inode->i_size >> inode->i_sb->s_blocksize_bits);
    journal->j_blocksize = inode->i_sb->s_blocksize;

    /* journal descriptor can store up to n blocks -bzzz */
    n = journal->j_blocksize / sizeof(journal_block_tag_t);
    journal->j_wbufsize = n;
    journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
    if (!journal->j_wbuf) {
        printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n",
               __FUNCTION__);

        J_ASSERT(journal->j_revoke != NULL);
        if (journal->j_revoke)
            journal_destroy_revoke(journal);

        kfree(journal);
        return NULL;
    }

    err = journal_bmap(journal, 0, &blocknr);
    /* If that failed, give up */
    if (err) {
        printk(KERN_ERR "%s: Cannnot locate journal superblock\n",
               __FUNCTION__);

        J_ASSERT(journal->j_revoke != NULL);
        if (journal->j_revoke)
            journal_destroy_revoke(journal);
        J_ASSERT(journal->j_wbuf != NULL);
        kfree(journal->j_wbuf);
        kfree(journal);
        return NULL;
    }

    bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
    J_ASSERT(bh != NULL);
    journal->j_sb_buffer = bh;
    journal->j_superblock = (journal_superblock_t *)bh->b_data;

    return journal;
}
Esempio n. 2
0
static errcode_t recover_ext3_journal(e2fsck_t ctx)
{
	journal_t *journal;
	int retval;

	journal_init_revoke_caches();
	retval = e2fsck_get_journal(ctx, &journal);
	if (retval)
		return retval;

	retval = e2fsck_journal_load(journal);
	if (retval)
		goto errout;

	retval = journal_init_revoke(journal, 1024);
	if (retval)
		goto errout;
	
	retval = -journal_recover(journal);
	if (retval)
		goto errout;
	
	if (journal->j_superblock->s_errno) {
		ctx->fs->super->s_state |= EXT2_ERROR_FS;
		ext2fs_mark_super_dirty(ctx->fs);
		journal->j_superblock->s_errno = 0;
		mark_buffer_dirty(journal->j_sb_buffer);
	}
		
errout:
	journal_destroy_revoke(journal);
	journal_destroy_revoke_caches();
	e2fsck_journal_release(ctx, journal, 1, 0);
	return retval;
}
Esempio n. 3
0
errcode_t ext2fs_open_journal(ext2_filsys fs, journal_t **j)
{
	journal_t *journal;
	errcode_t retval;

	journal_init_revoke_caches();
	retval = ext2fs_get_journal(fs, &journal);
	if (retval)
		return retval;

	retval = ext2fs_journal_load(journal);
	if (retval)
		goto errout;

	retval = journal_init_revoke(journal, 1024);
	if (retval)
		goto errout;

	if (journal->j_failed_commit) {
		journal->j_superblock->s_errno = -EINVAL;
		mark_buffer_dirty(journal->j_sb_buffer);
	}

	*j = journal;
	return 0;

errout:
	journal_destroy_revoke(journal);
	journal_destroy_revoke_caches();
	ext2fs_journal_release(fs, journal, 1, 0);
	return retval;
}
Esempio n. 4
0
errcode_t ext2fs_close_journal(ext2_filsys fs, journal_t **j)
{
	journal_t *journal = *j;

	journal_destroy_revoke(journal);
	journal_destroy_revoke_caches();
	ext2fs_journal_release(fs, journal, 0, 0);
	*j = NULL;

	return 0;
}
Esempio n. 5
0
/**
 * void journal_destroy() - Release a journal_t structure.
 * @journal: Journal to act on.
 *
 * Release a journal_t structure once it is no longer in use by the
 * journaled object.
 */
void journal_destroy(journal_t *journal)
{
#if 0
    /* Wait for the commit thread to wake up and die. */
    journal_kill_thread(journal);

    /* Force a final log commit */
    if (journal->j_running_transaction)
        journal_commit_transaction(journal);

    /* Force any old transactions to disk */

    /* Totally anal locking here... */
    jbd_lock(&journal->j_list_lock);
    while (journal->j_checkpoint_transactions != NULL) {
        jbd_unlock(&journal->j_list_lock);
        log_do_checkpoint(journal);
        jbd_lock(&journal->j_list_lock);
    }

    J_ASSERT(journal->j_running_transaction == NULL);
    J_ASSERT(journal->j_committing_transaction == NULL);
    J_ASSERT(journal->j_checkpoint_transactions == NULL);
    jbd_unlock(&journal->j_list_lock);

    /* We can now mark the journal as empty. */
    journal->j_tail = 0;
    journal->j_tail_sequence = ++journal->j_transaction_sequence;
    if (journal->j_sb_buffer) {
        journal_update_superblock(journal, 1);
        brelse(journal->j_sb_buffer);
    }
#endif

    if (journal->j_sb_buffer) {
        brelse(journal->j_sb_buffer);
    }
    if (journal->j_inode)
        iput(journal->j_inode);
    if (journal->j_revoke)
        journal_destroy_revoke(journal);
    kfree(journal->j_wbuf);
    kfree(journal);
}
Esempio n. 6
0
static errcode_t recover_ext3_journal(e2fsck_t ctx)
{
	struct problem_context	pctx;
	journal_t *journal;
	int retval;

	clear_problem_context(&pctx);

	journal_init_revoke_caches();
	retval = e2fsck_get_journal(ctx, &journal);
	if (retval)
		return retval;

	retval = e2fsck_journal_load(journal);
	if (retval)
		goto errout;

	retval = journal_init_revoke(journal, 1024);
	if (retval)
		goto errout;

	retval = -journal_recover(journal);
	if (retval)
		goto errout;

	if (journal->j_failed_commit) {
		pctx.ino = journal->j_failed_commit;
		fix_problem(ctx, PR_0_JNL_TXN_CORRUPT, &pctx);
		journal->j_superblock->s_errno = -EINVAL;
		mark_buffer_dirty(journal->j_sb_buffer);
	}

errout:
	journal_destroy_revoke(journal);
	journal_destroy_revoke_caches();
	e2fsck_journal_release(ctx, journal, 1, 0);
	return retval;
}