Commit a5cd74ad authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov

ceph: fix -EOLDSNAPC handling

Need to drop cap reference before retry. Besides, it's better to
redo file write checks for each retry because we re-lock inode.
Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 5d37ca14
...@@ -1309,6 +1309,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -1309,6 +1309,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (!prealloc_cf) if (!prealloc_cf)
return -ENOMEM; return -ENOMEM;
retry_snap:
inode_lock(inode); inode_lock(inode);
/* We can write back this queue in page reclaim */ /* We can write back this queue in page reclaim */
...@@ -1340,7 +1341,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -1340,7 +1341,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
goto out; goto out;
} }
retry_snap:
/* FIXME: not complete since it doesn't account for being at quota */ /* FIXME: not complete since it doesn't account for being at quota */
if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) { if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) {
err = -ENOSPC; err = -ENOSPC;
...@@ -1389,14 +1389,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -1389,14 +1389,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
&prealloc_cf); &prealloc_cf);
else else
written = ceph_sync_write(iocb, &data, pos, snapc); written = ceph_sync_write(iocb, &data, pos, snapc);
if (written == -EOLDSNAPC) {
dout("aio_write %p %llx.%llx %llu~%u"
"got EOLDSNAPC, retrying\n",
inode, ceph_vinop(inode),
pos, (unsigned)count);
inode_lock(inode);
goto retry_snap;
}
if (written > 0) if (written > 0)
iov_iter_advance(from, written); iov_iter_advance(from, written);
ceph_put_snap_context(snapc); ceph_put_snap_context(snapc);
...@@ -1430,10 +1422,15 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -1430,10 +1422,15 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
ceph_cap_string(got)); ceph_cap_string(got));
ceph_put_cap_refs(ci, got); ceph_put_cap_refs(ci, got);
if (written == -EOLDSNAPC) {
dout("aio_write %p %llx.%llx %llu~%u" "got EOLDSNAPC, retrying\n",
inode, ceph_vinop(inode), pos, (unsigned)count);
goto retry_snap;
}
if (written >= 0) { if (written >= 0) {
if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL)) if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL))
iocb->ki_flags |= IOCB_DSYNC; iocb->ki_flags |= IOCB_DSYNC;
written = generic_write_sync(iocb, written); written = generic_write_sync(iocb, written);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment