client: increment file position on _read_sync near eof

Fixes: https://tracker.ceph.com/issues/48076
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
Patrick Donnelly 2020-11-02 12:01:29 -08:00
parent 161b7e118b
commit 83f84f601a
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB

View File

@ -9464,7 +9464,7 @@ int64_t Client::_read(Fh *f, int64_t offset, uint64_t size, bufferlist *bl)
int want, have = 0; int want, have = 0;
bool movepos = false; bool movepos = false;
std::unique_ptr<C_SaferCond> onuninline; std::unique_ptr<C_SaferCond> onuninline;
int64_t r = 0; int64_t rc = 0;
const auto& conf = cct->_conf; const auto& conf = cct->_conf;
Inode *in = f->inode.get(); Inode *in = f->inode.get();
utime_t lat; utime_t lat;
@ -9482,8 +9482,9 @@ int64_t Client::_read(Fh *f, int64_t offset, uint64_t size, bufferlist *bl)
loff_t start_pos = offset; loff_t start_pos = offset;
if (in->inline_version == 0) { if (in->inline_version == 0) {
r = _getattr(in, CEPH_STAT_CAP_INLINE_DATA, f->actor_perms, true); auto r = _getattr(in, CEPH_STAT_CAP_INLINE_DATA, f->actor_perms, true);
if (r < 0) { if (r < 0) {
rc = r;
goto done; goto done;
} }
ceph_assert(in->inline_version > 0); ceph_assert(in->inline_version > 0);
@ -9494,9 +9495,12 @@ retry:
want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO; want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
else else
want = CEPH_CAP_FILE_CACHE; want = CEPH_CAP_FILE_CACHE;
r = get_caps(f, CEPH_CAP_FILE_RD, want, &have, -1); {
if (r < 0) { auto r = get_caps(f, CEPH_CAP_FILE_RD, want, &have, -1);
goto done; if (r < 0) {
rc = r;
goto done;
}
} }
if (f->flags & O_DIRECT) if (f->flags & O_DIRECT)
have &= ~(CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO); have &= ~(CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO);
@ -9518,12 +9522,12 @@ retry:
bl->substr_of(in->inline_data, offset, len - offset); bl->substr_of(in->inline_data, offset, len - offset);
bl->append_zero(endoff - len); bl->append_zero(endoff - len);
} }
r = endoff - offset; rc = endoff - offset;
} else if ((uint64_t)offset < endoff) { } else if ((uint64_t)offset < endoff) {
bl->append_zero(endoff - offset); bl->append_zero(endoff - offset);
r = endoff - offset; rc = endoff - offset;
} else { } else {
r = 0; rc = 0;
} }
goto success; goto success;
} }
@ -9536,27 +9540,31 @@ retry:
if (f->flags & O_RSYNC) { if (f->flags & O_RSYNC) {
_flush_range(in, offset, size); _flush_range(in, offset, size);
} }
r = _read_async(f, offset, size, bl); rc = _read_async(f, offset, size, bl);
if (r < 0) if (rc < 0)
goto done; goto done;
} else { } else {
if (f->flags & O_DIRECT) if (f->flags & O_DIRECT)
_flush_range(in, offset, size); _flush_range(in, offset, size);
bool checkeof = false; bool checkeof = false;
r = _read_sync(f, offset, size, bl, &checkeof); rc = _read_sync(f, offset, size, bl, &checkeof);
if (r < 0) if (rc < 0)
goto done; goto done;
if (checkeof) { if (checkeof) {
offset += r; offset += rc;
size -= r; size -= rc;
put_cap_ref(in, CEPH_CAP_FILE_RD); put_cap_ref(in, CEPH_CAP_FILE_RD);
have = 0; have = 0;
// reverify size // reverify size
r = _getattr(in, CEPH_STAT_CAP_SIZE, f->actor_perms); {
if (r < 0) auto r = _getattr(in, CEPH_STAT_CAP_SIZE, f->actor_perms);
goto done; if (r < 0) {
rc = r;
goto done;
}
}
// eof? short read. // eof? short read.
if ((uint64_t)offset < in->size) if ((uint64_t)offset < in->size)
@ -9565,10 +9573,10 @@ retry:
} }
success: success:
ceph_assert(r >= 0); ceph_assert(rc >= 0);
if (movepos) { if (movepos) {
// adjust fd pos // adjust fd pos
f->pos = start_pos + r; f->pos = start_pos + rc;
} }
lat = ceph_clock_now(); lat = ceph_clock_now();
@ -9588,7 +9596,7 @@ done:
in->mark_caps_dirty(CEPH_CAP_FILE_WR); in->mark_caps_dirty(CEPH_CAP_FILE_WR);
check_caps(in, 0); check_caps(in, 0);
} else } else
r = ret; rc = ret;
} }
if (have) { if (have) {
put_cap_ref(in, CEPH_CAP_FILE_RD); put_cap_ref(in, CEPH_CAP_FILE_RD);
@ -9596,7 +9604,7 @@ done:
if (movepos) { if (movepos) {
unlock_fh_pos(f); unlock_fh_pos(f);
} }
return r; return rc;
} }
Client::C_Readahead::C_Readahead(Client *c, Fh *f) : Client::C_Readahead::C_Readahead(Client *c, Fh *f) :