diff options
author | Mark Fasheh <mfasheh@suse.com> | 2011-06-23 01:23:38 +0400 |
---|---|---|
committer | Joel Becker <jlbec@evilplan.org> | 2011-07-28 13:07:16 +0400 |
commit | a11f7e63c59810a81494d4c4b028af707d4c7ca4 (patch) | |
tree | 6d28cfc9519f96db5c20780bf765de9e0fc03bef /fs/ocfs2/inode.h | |
parent | 730e663bd82c1a10a85ff00728d34152a5a67ec8 (diff) | |
download | linux-a11f7e63c59810a81494d4c4b028af707d4c7ca4.tar.xz |
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
(e9e3bcecf44c04b9e6b505fd8e2eb9cea58fb94d) 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>
Diffstat (limited to 'fs/ocfs2/inode.h')
-rw-r--r-- | fs/ocfs2/inode.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 1c508b149b3a..88924a3133fa 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h @@ -43,6 +43,9 @@ struct ocfs2_inode_info /* protects extended attribute changes on this inode */ struct rw_semaphore ip_xattr_sem; + /* Number of outstanding AIO's which are not page aligned */ + atomic_t ip_unaligned_aio; + /* These fields are protected by ip_lock */ spinlock_t ip_lock; u32 ip_open_count; |