From 18069b2bc221820b552e108a95d91b396d07fb07 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 22 Aug 2008 16:55:58 -0700 Subject: [PATCH] kclient: retry sync_write on EOLDSNAP --- src/include/ceph_fs.h | 4 +++- src/kernel/file.c | 9 +++++++++ src/kernel/osd_client.c | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 28c59a4d466c9..1a19b79e68e81 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -1013,9 +1013,11 @@ enum { CEPH_OSD_OP_INCLOCK_FAIL = 8, /* fail on inclock collision */ CEPH_OSD_OP_BALANCE_READS = 16, CEPH_OSD_OP_ACKNVRAM = 32, /* ACK when stable in NVRAM, not RAM */ - CEPH_OSD_OP_ORDERSNAP = 64, /* fail (EBADF) if snap ordering is incorrect */ + CEPH_OSD_OP_ORDERSNAP = 64, /* EOLDSNAP if snapc is out of order */ }; +#define EOLDSNAPC 44 /* ORDERSNAP specified and writer has old snap context*/ + struct ceph_osd_peer_stat { struct ceph_timespec stamp; float oprate; diff --git a/src/kernel/file.c b/src/kernel/file.c index ef36e6d96b264..a993ff1e149d4 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -251,6 +251,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, if (pos > i_size_read(inode)) ceph_inode_set_size(inode, pos); } + return ret; } @@ -335,6 +336,7 @@ ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, if (ceph_snap(inode) != CEPH_NOSNAP) return -EROFS; +retry_snap: __ceph_do_pending_vmtruncate(inode); check_max_size(inode, endoff); dout(10, "aio_write %p %llu~%u getting caps. i_size %llu\n", @@ -361,6 +363,13 @@ out: dout(10, "aio_write %p %llu~%u dropping cap refs on %d\n", inode, pos, (unsigned)iov->iov_len, got); ceph_put_cap_refs(ci, got); + + if (ret == -EOLDSNAPC) { + dout(10, "aio_write %p %llu~%u got EOLDSNAPC, retrying\n", + inode, pos, (unsigned)iov->iov_len); + goto retry_snap; + } + return ret; } diff --git a/src/kernel/osd_client.c b/src/kernel/osd_client.c index 06a139c6e1fbe..355402f020434 100644 --- a/src/kernel/osd_client.c +++ b/src/kernel/osd_client.c @@ -798,7 +798,8 @@ int ceph_osdc_sync_write(struct ceph_osd_client *osdc, struct ceph_vino vino, if (IS_ERR(reqm)) return PTR_ERR(reqm); reqhead = reqm->front.iov_base; - reqhead->flags = CEPH_OSD_OP_ACK; /* just ack.. FIXME */ + reqhead->flags = CEPH_OSD_OP_ACK | /* just ack for now... FIXME */ + CEPH_OSD_OP_ORDERSNAP; /* get EOLDSNAPC if out of order */ /* how many pages? */ num_pages = calc_pages_for(off, len); -- 2.39.5