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; }
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; }
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; }
/* 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; }