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: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
5d37ca1480
commit
a5cd74ad38
|
@ -1309,6 +1309,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
|||
if (!prealloc_cf)
|
||||
return -ENOMEM;
|
||||
|
||||
retry_snap:
|
||||
inode_lock(inode);
|
||||
|
||||
/* 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)
|
|||
goto out;
|
||||
}
|
||||
|
||||
retry_snap:
|
||||
/* FIXME: not complete since it doesn't account for being at quota */
|
||||
if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) {
|
||||
err = -ENOSPC;
|
||||
|
@ -1389,14 +1389,6 @@ retry_snap:
|
|||
&prealloc_cf);
|
||||
else
|
||||
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)
|
||||
iov_iter_advance(from, written);
|
||||
ceph_put_snap_context(snapc);
|
||||
|
@ -1430,10 +1422,15 @@ retry_snap:
|
|||
ceph_cap_string(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 (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL))
|
||||
iocb->ki_flags |= IOCB_DSYNC;
|
||||
|
||||
written = generic_write_sync(iocb, written);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue