From: Dhairya Parmar Date: Wed, 24 Sep 2025 11:33:29 +0000 (+0530) Subject: client: do not allow zero‑length reads X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8f1c1e45266746fbde8ac2cfb643202cceb3a4c2;p=ceph.git client: do not allow zero‑length reads fixing this in Client::_read which is called by both async and sync code paths. Fixes: https://tracker.ceph.com/issues/73037 Signed-off-by: Dhairya Parmar --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 2c4a0a129927..7631a2c8885f 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4680,6 +4680,11 @@ void Client::_flush_range(Inode *in, int64_t offset, uint64_t size) return; } + if (size == 0) { + ldout(cct, 10) << "zero size flush is not supported by OSD" << dendl; + return; + } + C_SaferCond onflush("Client::_flush_range flock"); bool ret = objectcacher->file_flush(&in->oset, &in->layout, in->snaprealm->get_snap_context(), offset, size, &onflush); @@ -11554,6 +11559,20 @@ int64_t Client::_read(Fh *f, int64_t offset, uint64_t size, bufferlist *bl, { ceph_assert(ceph_mutex_is_locked_by_me(client_lock)); + ldout(cct, 10) << __func__ << " " << f->inode.get() << " " << offset << "~" + << size << dendl; + + if ((f->mode & CEPH_FILE_MODE_RD) == 0 && !read_for_write) + return -EBADF; + + // zero bytes read is not supported by osd + if (size == 0) { + if (onfinish) { + onfinish->complete(0); + } + return 0; + } + int want, have = 0; bool movepos = false; std::unique_ptr iofinish = nullptr; @@ -11565,10 +11584,6 @@ int64_t Client::_read(Fh *f, int64_t offset, uint64_t size, bufferlist *bl, utime_t start = mono_clock_now(); CRF_iofinish *crf_iofinish = nullptr; - ldout(cct, 10) << __func__ << " " << *in << " " << offset << "~" << size << dendl; - - if ((f->mode & CEPH_FILE_MODE_RD) == 0 && !read_for_write) - return -EBADF; //bool lazy = f->mode == CEPH_FILE_MODE_LAZY; if (offset < 0) { @@ -11687,18 +11702,6 @@ retry: // is duplicated and modified and exists in // C_Read_Sync_NonBlocking::finish(). - // trim read based on file size? - if (size == 0) { - // zero byte read requested -- therefore just release managed - // pointers and complete the C_Read_Finisher immediately with 0 bytes - Context *iof = iofinish.release(); - crf.release(); - iof->complete(0); - - // Signal async completion - return 0; - } - C_Read_Sync_NonBlocking *crsa = new C_Read_Sync_NonBlocking(this, iofinish.release(), f, in, f->pos, offset, size, bl, filer.get(), have); @@ -11966,6 +11969,10 @@ int Client::_read_sync(Fh *f, uint64_t off, uint64_t len, bufferlist *bl, bool *checkeof) { ceph_assert(ceph_mutex_is_locked_by_me(client_lock)); + if (len == 0) { + // zero byte read is not supported by OSD + return 0; + } Inode *in = f->inode.get();