ocfs2: serialize unaligned aio
Fix a corruption that can happen when we have (two or more) outstanding
aio's to an overlapping unaligned region. Ext4
(e9e3bcecf4
) and xfs recently had to fix
similar issues.
In our case what happens is that we can have an outstanding aio on a region
and if a write comes in with some bytes overlapping the original aio we may
decide to read that region into a page before continuing (typically because
of buffered-io fallback). Since we have no ordering guarantees with the
aio, we can read stale or bad data into the page and then write it back out.
If the i/o is page and block aligned, then we avoid this issue as there
won't be any need to read data from disk.
I took the same approach as Eric in the ext4 patch and introduced some
serialization of unaligned async direct i/o. I don't expect this to have an
effect on the most common cases of AIO. Unaligned aio will be slower
though, but that's far more acceptable than data corruption.
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Joel Becker <jlbec@evilplan.org>
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
#include "ocfs1_fs_compat.h"
|
||||
|
||||
#include "alloc.h"
|
||||
#include "aops.h"
|
||||
#include "blockcheck.h"
|
||||
#include "dlmglue.h"
|
||||
#include "export.h"
|
||||
@@ -1616,12 +1617,17 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
|
||||
|
||||
static int __init ocfs2_init(void)
|
||||
{
|
||||
int status;
|
||||
int status, i;
|
||||
|
||||
ocfs2_print_version();
|
||||
|
||||
for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++)
|
||||
init_waitqueue_head(&ocfs2__ioend_wq[i]);
|
||||
|
||||
status = init_ocfs2_uptodate_cache();
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
@@ -1760,7 +1766,7 @@ static void ocfs2_inode_init_once(void *data)
|
||||
ocfs2_extent_map_init(&oi->vfs_inode);
|
||||
INIT_LIST_HEAD(&oi->ip_io_markers);
|
||||
oi->ip_dir_start_lookup = 0;
|
||||
|
||||
atomic_set(&oi->ip_unaligned_aio, 0);
|
||||
init_rwsem(&oi->ip_alloc_sem);
|
||||
init_rwsem(&oi->ip_xattr_sem);
|
||||
mutex_init(&oi->ip_io_mutex);
|
||||
|
Reference in New Issue
Block a user