| 2989 | } |
| 2990 | |
| 2991 | void Client::handle_client_reply(const MConstRef<MClientReply>& reply) |
| 2992 | { |
| 2993 | mds_rank_t mds_num = mds_rank_t(reply->get_source().num()); |
| 2994 | |
| 2995 | std::scoped_lock cl(client_lock); |
| 2996 | auto session = _get_mds_session(mds_num, reply->get_connection().get()); |
| 2997 | if (!session) { |
| 2998 | return; |
| 2999 | } |
| 3000 | |
| 3001 | ceph_tid_t tid = reply->get_tid(); |
| 3002 | bool is_safe = reply->is_safe(); |
| 3003 | |
| 3004 | auto it = mds_requests.find(tid); |
| 3005 | if (it == mds_requests.end()) { |
| 3006 | lderr(cct) << __func__ << " no pending request on tid " << tid |
| 3007 | << " safe is:" << is_safe << dendl; |
| 3008 | return; |
| 3009 | } |
| 3010 | MetaRequest *request = it->second; |
| 3011 | |
| 3012 | ldout(cct, 20) << __func__ << " got a reply. Safe:" << is_safe |
| 3013 | << " tid " << tid << dendl; |
| 3014 | |
| 3015 | // correct sessions ? |
| 3016 | if (request->mds != mds_num) { |
| 3017 | ldout(cct, 0) << "got a stale reply from mds." << mds_num |
| 3018 | << " instead of mds." << request->mds << dendl; |
| 3019 | return; |
| 3020 | } |
| 3021 | |
| 3022 | if (request->got_unsafe && !is_safe) { |
| 3023 | //duplicate response |
| 3024 | ldout(cct, 0) << "got a duplicate reply on tid " << tid << " from mds " |
| 3025 | << mds_num << " safe:" << is_safe << dendl; |
| 3026 | return; |
| 3027 | } |
| 3028 | |
| 3029 | ceph_assert(!request->reply); |
| 3030 | request->reply = reply; |
| 3031 | insert_trace(request, session.get()); |
| 3032 | |
| 3033 | // Handle unsafe reply |
| 3034 | if (!is_safe) { |
| 3035 | request->got_unsafe = true; |
| 3036 | session->unsafe_requests.push_back(&request->unsafe_item); |
| 3037 | if (is_dir_operation(request)) { |
| 3038 | Inode *dir = request->inode(); |
| 3039 | ceph_assert(dir); |
| 3040 | dir->unsafe_ops.push_back(&request->unsafe_dir_item); |
| 3041 | } |
| 3042 | if (request->target) { |
| 3043 | InodeRef &in = request->target; |
| 3044 | in->unsafe_ops.push_back(&request->unsafe_target_item); |
| 3045 | } |
| 3046 | } |
| 3047 | |
| 3048 | // Only signal the caller once (on the first reply): |
nothing calls this directly
no test coverage detected