From: Xiubo Li Date: Wed, 17 Apr 2024 07:24:10 +0000 (+0800) Subject: mds: find a new head for the batch ops when the head is dead X-Git-Tag: v20.0.0~1927^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=793ea12a2c7b03140331d40f028677f63cfc9de6;p=ceph.git mds: find a new head for the batch ops when the head is dead If the batch head request is already dead and then we need to choose a new batch head anyways and release the reference for the current batch head request. Else it will be reported as slow request. Fixes: https://tracker.ceph.com/issues/65536 Signed-off-by: Xiubo Li --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index f65f81d217e1..9cc2eb8d9d68 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -9811,7 +9811,25 @@ void MDCache::request_forward(const MDRequestRef& mdr, mds_rank_t who, int port) void MDCache::dispatch_request(const MDRequestRef& mdr) { if (mdr->dead) { - dout(20) << __func__ << ": dead " << *mdr << dendl; + dout(10) << __func__ << ": dead " << *mdr << dendl; + //if the mdr is a "batch_op" and it has followers, pick a follower as + //the new "head of the batch ops" and go on processing the new one. + if (mdr->client_request && mdr->is_batch_head()) { + int mask = mdr->client_request->head.args.getattr.mask; + auto it = mdr->batch_op_map->find(mask); + auto new_batch_head = it->second->find_new_head(); + if (!new_batch_head) { + mdr->batch_op_map->erase(it); + dout(10) << __func__ << ": mask '" << mask + << "' batch head is dead and there is no follower" << dendl; + return; + } + dout(10) << __func__ << ": mask '" << mask + << "' batch head is dead and queue a new one " + << *new_batch_head << dendl; + mds->finisher->queue(new C_MDS_RetryRequest(this, new_batch_head)); + return; + } return; } if (mdr->client_request) { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 0bb30664ac5f..14faeb3ecc95 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2647,9 +2647,14 @@ void Server::dispatch_client_request(const MDRequestRef& mdr) auto it = mdr->batch_op_map->find(mask); auto new_batch_head = it->second->find_new_head(); if (!new_batch_head) { - mdr->batch_op_map->erase(it); - return; + mdr->batch_op_map->erase(it); + dout(10) << __func__ << ": mask '" << mask + << "' batch head is killed and there is no follower" << dendl; + return; } + dout(10) << __func__ << ": mask '" << mask + << "' batch head is killed and queue a new one " + << *new_batch_head << dendl; mds->finisher->queue(new C_MDS_RetryRequest(mdcache, new_batch_head)); return; } else {