summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-06-14 01:22:18 +0200
committerSage Weil <sage@newdream.net>2011-06-14 01:26:22 +0200
commitd7f124f129a6aea99938e0d4172c741b56fefeda (patch)
tree25ee1b2b91de6e490ddd05b00d6a3f844a224987
parentlibceph: fix page calculation for non-page-aligned io (diff)
downloadlinux-d7f124f129a6aea99938e0d4172c741b56fefeda.tar.xz
linux-d7f124f129a6aea99938e0d4172c741b56fefeda.zip
ceph: fix sync and dio writes across stripe boundaries
We were iterating across stripe boundaries properly, but not moving the write buffer pointer forward. This caused us to rewrite the same data after the break. Fix by adjusting the data pointer forward, and recalculating the io and buffer alignment after the break. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to '')
-rw-r--r--fs/ceph/file.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 2be0f35afdfb..4698a5c553dc 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -476,9 +476,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
else
pos = *offset;
- io_align = pos & ~PAGE_MASK;
- buf_align = (unsigned long)data & ~PAGE_MASK;
-
ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
if (ret < 0)
return ret;
@@ -502,6 +499,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
* boundary. this isn't atomic, unfortunately. :(
*/
more:
+ io_align = pos & ~PAGE_MASK;
+ buf_align = (unsigned long)data & ~PAGE_MASK;
len = left;
if (file->f_flags & O_DIRECT) {
/* write from beginning of first page, regardless of
@@ -591,6 +590,7 @@ out:
pos += len;
written += len;
left -= len;
+ data += written;
if (left)
goto more;