From d6c7a5fcd08873c45a2dcd645a0690fd1443af50 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 3 Sep 2026 18:48:36 -0700 Subject: [PATCH] libceph: only set read_from_replica on read requests ceph_osdc_alloc_request() ORs the mount option's read_from_replica flag into r_flags for every request, writes included. The flag is meant for reads: calc_target() skips the replica choice for any request that has CEPH_OSD_FLAG_WRITE, and the OSDs only know BALANCE_READS on read ops. Sending it on writes is at best ignored; with read_from_replica=balance a buffered write that fell back to ceph_sync_write() after losing BUFFER to a revoke failed with -EIO, while the same run without the option works fine. Gate the flag on CEPH_OSD_FLAG_READ. Cc: stable@vger.kernel.org Fixes: 22d2cfdffa5b ("libceph: move away from global osd_req_flags") Assisted-by: Cursor Signed-off-by: Xiubo Li Reviewed-by: Alex Markuze Signed-off-by: Ilya Dryomov --- net/ceph/osd_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index f36ce5ae7568..8c2b89e2004b 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1108,7 +1108,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, req->r_base_oloc.pool = layout->pool_id; req->r_base_oloc.pool_ns = ceph_try_get_string(layout->pool_ns); ceph_oid_printf(&req->r_base_oid, "%llx.%08llx", vino.ino, objnum); - req->r_flags = flags | osdc->client->options->read_from_replica; + req->r_flags = flags; + if (flags & CEPH_OSD_FLAG_READ) + req->r_flags |= osdc->client->options->read_from_replica; req->r_snapid = vino.snap; if (flags & CEPH_OSD_FLAG_WRITE)