/*
* synchronous read direct to user buffer.
*
- * FIXME: if read spans object boundary, just do two two separate
- * reads. for a correct atomic read, we should take read locks on
- * all objects.
+ * FIXME: if read spans object boundary, just do two separate reads.
+ * for a correct atomic read, we should take read locks on all
+ * objects.
*/
int ceph_osdc_sync_read(struct ceph_osd_client *osdc, struct ceph_vino vino,
struct ceph_file_layout *layout,
/*
* synchronous write. from userspace.
+ *
+ * FIXME: if write spans object boundary, just do two separate write.
+ * for a correct atomic write, we should take write locks on all
+ * objects, rollback on failure, etc.
*/
int ceph_osdc_sync_write(struct ceph_osd_client *osdc, struct ceph_vino vino,
struct ceph_file_layout *layout,
struct ceph_osd_request *req;
int num_pages, i, po, l, left;
__s32 rc;
+ u64 rlen;
+ int finalrc = 0;
dout(10, "sync_write on ino %llx.%llx at %llu~%llu\n", vino.ino,
vino.snap, off, len);
+more:
/* request msg */
reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE, snapc);
if (IS_ERR(reqm))
return PTR_ERR(req);
}
- len = calc_layout(osdc, vino, layout, off, len, req);
- num_pages = calc_pages_for(off, len); /* recalc */
- dout(10, "sync_write %llu~%llu -> %d pages\n", off, len, num_pages);
+ rlen = calc_layout(osdc, vino, layout, off, len, req);
+ num_pages = calc_pages_for(off, rlen); /* recalc */
+ dout(10, "sync_write %llu~%llu -> %d pages\n", off, rlen, num_pages);
/* copy data into a set of pages */
- left = len;
+ left = rlen;
po = off & ~PAGE_MASK;
for (i = 0; i < num_pages; i++) {
int bad;
}
reqm->pages = req->r_pages;
reqm->nr_pages = num_pages;
- reqm->hdr.data_len = cpu_to_le32(len);
+ reqm->hdr.data_len = cpu_to_le32(rlen);
reqm->hdr.data_off = cpu_to_le32(off);
rc = do_request(osdc, req);
for (i = 0; i < req->r_num_pages; i++)
__free_pages(req->r_pages[i], 0);
put_request(req);
- if (rc == 0)
- rc = len;
- dout(10, "sync_write result %d\n", rc);
- return rc;
+ if (rc == 0) {
+ finalrc += rlen;
+ off += rlen;
+ len -= rlen;
+ if (len > 0)
+ goto more;
+ } else
+ finalrc = rc;
+ dout(10, "sync_write result %d\n", finalrc);
+ return finalrc;
}
/*