mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 10:19:47 +00:00
![Frank Mayhar](/assets/img/avatar_default.png)
A few weeks ago I posted a patch for discussion that allowed ext4 to run without a journal. Since that time I've integrated the excellent comments from Andreas and fixed several serious bugs. We're currently running with this patch and generating some performance numbers against both ext2 (with backported reservations code) and ext4 with and without a journal. It just so happens that running without a journal is slightly faster for most everything. We did iozone -T -t 4 s 2g -r 256k -T -I -i0 -i1 -i2 which creates 4 threads, each of which create and do reads and writes on a 2G file, with a buffer size of 256K, using O_DIRECT for all file opens to bypass the page cache. Results: ext2 ext4, default ext4, no journal initial writes 13.0 MB/s 15.4 MB/s 15.7 MB/s rewrites 13.1 MB/s 15.6 MB/s 15.9 MB/s reads 15.2 MB/s 16.9 MB/s 17.2 MB/s re-reads 15.3 MB/s 16.9 MB/s 17.2 MB/s random readers 5.6 MB/s 5.6 MB/s 5.7 MB/s random writers 5.1 MB/s 5.3 MB/s 5.4 MB/s So it seems that, so far, this was a useful exercise. Signed-off-by: Frank Mayhar <fmayhar@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
102 lines
2.2 KiB
C
102 lines
2.2 KiB
C
/*
|
|
* Interface between ext4 and JBD
|
|
*/
|
|
|
|
#include "ext4_jbd2.h"
|
|
|
|
int __ext4_journal_get_undo_access(const char *where, handle_t *handle,
|
|
struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_get_undo_access(handle, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __ext4_journal_get_write_access(const char *where, handle_t *handle,
|
|
struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_get_write_access(handle, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __ext4_journal_forget(const char *where, handle_t *handle,
|
|
struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_forget(handle, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __ext4_journal_revoke(const char *where, handle_t *handle,
|
|
ext4_fsblk_t blocknr, struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_revoke(handle, blocknr, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __ext4_journal_get_create_access(const char *where,
|
|
handle_t *handle, struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_get_create_access(handle, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
|
|
struct inode *inode, struct buffer_head *bh)
|
|
{
|
|
int err = 0;
|
|
|
|
if (ext4_handle_valid(handle)) {
|
|
err = jbd2_journal_dirty_metadata(handle, bh);
|
|
if (err)
|
|
ext4_journal_abort_handle(where, __func__, bh,
|
|
handle, err);
|
|
} else {
|
|
mark_buffer_dirty(bh);
|
|
if (inode && inode_needs_sync(inode)) {
|
|
sync_dirty_buffer(bh);
|
|
if (buffer_req(bh) && !buffer_uptodate(bh)) {
|
|
ext4_error(inode->i_sb, __func__,
|
|
"IO error syncing inode, "
|
|
"inode=%lu, block=%llu",
|
|
inode->i_ino,
|
|
(unsigned long long) bh->b_blocknr);
|
|
err = -EIO;
|
|
}
|
|
}
|
|
}
|
|
return err;
|
|
}
|