ceph: fix sync and dio writes across stripe boundaries
authorSage Weil <sage@newdream.net>
Mon, 13 Jun 2011 23:22:18 +0000 (16:22 -0700)
committerSage Weil <sage@newdream.net>
Mon, 13 Jun 2011 23:26:22 +0000 (16:26 -0700)
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>
fs/ceph/file.c

index 2be0f35afdfb42fff83d2bba2797bd08e34c22d9..4698a5c553dc010fa0aedabe3f3f4e0fb68b65c8 100644 (file)
@@ -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;