Exemplo n.º 1
0
int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
{
	struct super_block *sb;
	int err;
	int rc;

	if (!ext4_handle_valid(handle)) {
		ext4_put_nojournal(handle);
		return 0;
	}

	if (!handle->h_transaction) {
		err = jbd2_journal_stop(handle);
		return handle->h_err ? handle->h_err : err;
	}

	sb = handle->h_transaction->t_journal->j_private;
	err = handle->h_err;
	rc = jbd2_journal_stop(handle);

	if (!err)
		err = rc;
	if (err)
		__ext4_std_error(sb, where, line, err);
	return err;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
int ocfs2_commit_trans(struct ocfs2_super *osb,
		       handle_t *handle)
{
	int ret, nested;
	struct ocfs2_journal *journal = osb->journal;

	BUG_ON(!handle);

	nested = handle->h_ref > 1;
	ret = jbd2_journal_stop(handle);
	if (ret < 0)
		mlog_errno(ret);

	if (!nested)
		up_read(&journal->j_trans_barrier);

	return ret;
}
Exemplo n.º 4
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;
}