int jbd2_journal_force_commit(journal_t *journal)
{
	handle_t *handle;
	int ret;

	handle = jbd2_journal_start(journal, 1);
	if (IS_ERR(handle)) {
		ret = PTR_ERR(handle);
	} else {
		handle->h_sync = 1;
		ret = jbd2_journal_stop(handle);
	}
	return ret;
}
handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
{
	journal_t *journal = osb->journal->j_journal;
	handle_t *handle;

	BUG_ON(!osb || !osb->journal->j_journal);

	if (ocfs2_is_hard_readonly(osb))
		return ERR_PTR(-EROFS);

	BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE);
	BUG_ON(max_buffs <= 0);

	
	if (journal_current_handle())
		return jbd2_journal_start(journal, max_buffs);

	down_read(&osb->journal->j_trans_barrier);

	handle = jbd2_journal_start(journal, max_buffs);
	if (IS_ERR(handle)) {
		up_read(&osb->journal->j_trans_barrier);

		mlog_errno(PTR_ERR(handle));

		if (is_journal_aborted(journal)) {
			ocfs2_abort(osb->sb, "Detected aborted journal");
			handle = ERR_PTR(-EROFS);
		}
	} else {
		if (!ocfs2_mount_local(osb))
			atomic_inc(&(osb->journal->j_num_trans));
	}

	return handle;
}
Exemple #3
0
/* FIXME: The write support is rudimentary. I have not figured out a way to do writes
 * from particular offsets (even though I have written some untested code for this below) efficiently. */
ssize_t simplefs_write(struct file * filp, const char __user * buf, size_t len,
                       loff_t * ppos)
{
    /* After the commit dd37978c5 in the upstream linux kernel,
     * we can use just filp->f_inode instead of the
     * f->f_path.dentry->d_inode redirection */
    struct inode *inode;
    struct simplefs_inode *sfs_inode;
    struct buffer_head *bh;
    struct super_block *sb;
    struct simplefs_super_block *sfs_sb;
    handle_t *handle;

    char *buffer;

    int retval;

    sb = filp->f_path.dentry->d_inode->i_sb;
    sfs_sb = SIMPLEFS_SB(sb);

    handle = jbd2_journal_start(sfs_sb->journal, 1);
    if (IS_ERR(handle))
        return PTR_ERR(handle);
    retval = generic_write_checks(filp, ppos, &len, 0);
    if (retval)
        return retval;

    inode = filp->f_path.dentry->d_inode;
    sfs_inode = SIMPLEFS_INODE(inode);

    bh = sb_bread(filp->f_path.dentry->d_inode->i_sb,
                  sfs_inode->data_block_number);

    if (!bh) {
        printk(KERN_ERR "Reading the block number [%llu] failed.",
               sfs_inode->data_block_number);
        return 0;
    }
    buffer = (char *)bh->b_data;

    /* Move the pointer until the required byte offset */
    buffer += *ppos;

    retval = jbd2_journal_get_write_access(handle, bh);
    if (WARN_ON(retval)) {
        brelse(bh);
        sfs_trace("Can't get write access for bh\n");
        return retval;
    }

    if (copy_from_user(buffer, buf, len)) {
        brelse(bh);
        printk(KERN_ERR
               "Error copying file contents from the userspace buffer to the kernel space\n");
        return -EFAULT;
    }
    *ppos += len;

    retval = jbd2_journal_dirty_metadata(handle, bh);
    if (WARN_ON(retval)) {
        brelse(bh);
        return retval;
    }
    handle->h_sync = 1;
    retval = jbd2_journal_stop(handle);
    if (WARN_ON(retval)) {
        brelse(bh);
        return retval;
    }

    mark_buffer_dirty(bh);
    sync_dirty_buffer(bh);
    brelse(bh);

    /* Set new size
     * sfs_inode->file_size = max(sfs_inode->file_size, *ppos);
     *
     * FIXME: What to do if someone writes only some parts in between ?
     * The above code will also fail in case a file is overwritten with
     * a shorter buffer */
    if (mutex_lock_interruptible(&simplefs_inodes_mgmt_lock)) {
        sfs_trace("Failed to acquire mutex lock\n");
        return -EINTR;
    }
    sfs_inode->file_size = *ppos;
    retval = simplefs_inode_save(sb, sfs_inode);
    if (retval) {
        len = retval;
    }
    mutex_unlock(&simplefs_inodes_mgmt_lock);

    return len;
}