loff_t endoff = pos + iov->iov_len;
int got = 0;
int ret;
+ int do_sync = (file->f_flags & O_SYNC) || IS_SYNC(inode);
if (ceph_snap(inode) != CEPH_NOSNAP)
return -EROFS;
ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
&iocb->ki_pos);
} else {
+ if (do_sync)
+ atomic_inc(&ci->i_want_sync_writeout);
ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
if (ret >= 0 &&
ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL)) {
ret = sync_page_range(inode, mapping, pos, ret);
}
+ if (do_sync)
+ atomic_dec(&ci->i_want_sync_writeout);
}
if (ret >= 0)
ci->i_dirty_caps |= CEPH_CAP_FILE_WR;
ci->i_caps = RB_ROOT;
ci->i_dirty_caps = 0;
- for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
- ci->i_nr_by_mode[i] = 0;
init_waitqueue_head(&ci->i_cap_wq);
+ ci->i_hold_caps_until = 0;
+ INIT_LIST_HEAD(&ci->i_cap_delay_list);
+ ci->i_cap_exporting_mds = 0;
+ ci->i_cap_exporting_mseq = 0;
+ ci->i_cap_exporting_issued = 0;
INIT_LIST_HEAD(&ci->i_cap_snaps);
- ci->i_snap_caps = 0;
ci->i_head_snapc = NULL;
+ ci->i_snap_caps = 0;
+ for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
+ ci->i_nr_by_mode[i] = 0;
+
+ ci->i_max_size = 0;
+ ci->i_reported_size = 0;
ci->i_wanted_max_size = 0;
ci->i_requested_max_size = 0;
- ci->i_cap_exporting_mds = 0;
- ci->i_cap_exporting_mseq = 0;
- ci->i_cap_exporting_issued = 0;
-
ci->i_rd_ref = 0;
ci->i_rdcache_ref = 0;
ci->i_wr_ref = 0;
ci->i_wrbuffer_ref_head = 0;
ci->i_rdcache_gen = 0;
ci->i_rdcache_revoking = 0;
- ci->i_hold_caps_until = 0;
- INIT_LIST_HEAD(&ci->i_cap_delay_list);
+ atomic_set(&ci->i_want_sync_writeout, 0);
ci->i_snap_realm = NULL;
INIT_LIST_HEAD(&ci->i_snap_realm_item);
* build osd request message only.
*/
static struct ceph_msg *new_request_msg(struct ceph_osd_client *osdc, short opc,
- struct ceph_snap_context *snapc)
+ struct ceph_snap_context *snapc,
+ int do_sync)
{
struct ceph_msg *req;
struct ceph_osd_request_head *head;
struct ceph_osd_op *op;
__le64 *snaps;
- size_t size = sizeof(*head) + sizeof(*op);
+ size_t size = sizeof(*head) + (1 + do_sync)*sizeof(*op);
int i;
if (snapc)
/* encode head */
head->client_inc = cpu_to_le32(1); /* always, for now. */
head->flags = 0;
- head->num_ops = cpu_to_le16(1);
+ head->num_ops = cpu_to_le16(1 + do_sync);
op->op = cpu_to_le16(opc);
+ if (do_sync) {
+ op++;
+ op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC);
+ }
+
if (snapc) {
head->snap_seq = cpu_to_le64(snapc->seq);
head->num_snaps = cpu_to_le32(snapc->num_snaps);
struct ceph_file_layout *layout,
struct ceph_vino vino,
u64 off, u64 *plen, int op,
- struct ceph_snap_context *snapc)
+ struct ceph_snap_context *snapc,
+ int do_sync)
{
struct ceph_osd_request *req;
struct ceph_msg *msg;
if (req == NULL)
return ERR_PTR(-ENOMEM);
- msg = new_request_msg(osdc, op, snapc);
+ msg = new_request_msg(osdc, op, snapc, do_sync);
if (IS_ERR(msg)) {
kfree(req);
return ERR_PTR(PTR_ERR(msg));
more:
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
- CEPH_OSD_OP_READ, NULL);
+ CEPH_OSD_OP_READ, NULL, 0);
if (IS_ERR(req))
return PTR_ERR(req);
dout(10, "readpage on ino %llx.%llx at %lld~%lld\n", vino.ino,
vino.snap, off, len);
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
- CEPH_OSD_OP_READ, NULL);
+ CEPH_OSD_OP_READ, NULL, 0);
if (IS_ERR(req))
return PTR_ERR(req);
BUG_ON(len != PAGE_CACHE_SIZE);
/* alloc request, w/ optimistically-sized page vector */
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
- CEPH_OSD_OP_READ, NULL);
+ CEPH_OSD_OP_READ, NULL, 0);
if (IS_ERR(req))
return PTR_ERR(req);
more:
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
- CEPH_OSD_OP_WRITE, snapc);
+ CEPH_OSD_OP_WRITE, snapc, 0);
if (IS_ERR(req))
return PTR_ERR(req);
reqm = req->r_request;
BUG_ON(vino.snap != CEPH_NOSNAP);
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
- CEPH_OSD_OP_WRITE, snapc);
+ CEPH_OSD_OP_WRITE, snapc, 0);
if (IS_ERR(req))
return PTR_ERR(req);
reqm = req->r_request;