diff options
author | Jeff Layton <jlayton@kernel.org> | 2020-01-14 15:06:40 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2020-03-30 12:42:41 +0200 |
commit | 891f3f5a6a0615a2ed93cc495b54d1a8121d0968 (patch) | |
tree | e6b1a73c5b85b4603f5c328e97397265f84d3c6a /fs/ceph/caps.c | |
parent | f5e17aed3accb406f51ae528d657c275efc1edfc (diff) | |
download | linux-891f3f5a6a0615a2ed93cc495b54d1a8121d0968.tar.bz2 |
ceph: add infrastructure for waiting for async create to complete
When we issue an async create, we must ensure that any later on-the-wire
requests involving it wait for the create reply.
Expand i_ceph_flags to be an unsigned long, and add a new bit that
MDS requests can wait on. If the bit is set in the inode when sending
caps, then don't send it and just return that it has been delayed.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 739c06611522..fcad5d8ebcfa 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -511,7 +511,7 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci, bool set_timeout) { - dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, + dout("__cap_delay_requeue %p flags 0x%lx at %lu\n", &ci->vfs_inode, ci->i_ceph_flags, ci->i_hold_caps_max); if (!mdsc->stopping) { spin_lock(&mdsc->cap_delay_lock); @@ -1294,6 +1294,13 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, int delayed = 0; int ret; + /* Don't send anything if it's still being created. Return delayed */ + if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) { + spin_unlock(&ci->i_ceph_lock); + dout("%s async create in flight for %p\n", __func__, inode); + return 1; + } + held = cap->issued | cap->implemented; revoking = cap->implemented & ~cap->issued; retain &= ~revoking; @@ -2253,6 +2260,10 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) if (datasync) goto out; + ret = ceph_wait_on_async_create(inode); + if (ret) + goto out; + dirty = try_flush_caps(inode, &flush_tid); dout("fsync dirty caps are %s\n", ceph_cap_string(dirty)); |