* make a request * * Blocking helper to make an MDS request. * * If the ptarget flag is set, behavior changes slightly: the caller * expects to get a pointer to the inode we are creating or operating * on. As a result, we will follow up any traceless mutation reply * with a getattr or lookup to transparently handle a traceless reply * from the MDS (as when the MDS restarts and the client
| 2218 | * @param pdirbl [optional; disallowed if ptarget] where to pass extra reply payload to the caller |
| 2219 | */ |
| 2220 | int Client::make_request(MetaRequest *request, |
| 2221 | const UserPerm& perms, |
| 2222 | InodeRef *ptarget, bool *pcreated, |
| 2223 | mds_rank_t use_mds, |
| 2224 | bufferlist *pdirbl, |
| 2225 | size_t feature_needed) |
| 2226 | { |
| 2227 | int r = 0; |
| 2228 | |
| 2229 | // assign a unique tid |
| 2230 | ceph_tid_t tid = ++last_tid; |
| 2231 | request->set_tid(tid); |
| 2232 | |
| 2233 | // and timestamp |
| 2234 | request->op_stamp = ceph_clock_now(); |
| 2235 | request->created = ceph::coarse_mono_clock::now(); |
| 2236 | |
| 2237 | // make note |
| 2238 | mds_requests[tid] = request->get(); |
| 2239 | if (oldest_tid == 0 && request->get_op() != CEPH_MDS_OP_SETFILELOCK) |
| 2240 | oldest_tid = tid; |
| 2241 | |
| 2242 | request->set_caller_perms(perms); |
| 2243 | |
| 2244 | if (cct->_conf->client_inject_fixed_oldest_tid) { |
| 2245 | ldout(cct, 20) << __func__ << " injecting fixed oldest_client_tid(1)" << dendl; |
| 2246 | request->set_oldest_client_tid(1); |
| 2247 | } else { |
| 2248 | request->set_oldest_client_tid(oldest_tid); |
| 2249 | } |
| 2250 | |
| 2251 | // hack target mds? |
| 2252 | if (use_mds >= 0) |
| 2253 | request->resend_mds = use_mds; |
| 2254 | |
| 2255 | MetaSessionRef session = NULL; |
| 2256 | while (1) { |
| 2257 | if (request->aborted()) |
| 2258 | break; |
| 2259 | |
| 2260 | if (blocklisted) { |
| 2261 | request->abort(-EBLOCKLISTED); |
| 2262 | break; |
| 2263 | } |
| 2264 | |
| 2265 | // set up wait cond |
| 2266 | ceph::condition_variable caller_cond; |
| 2267 | request->caller_cond = &caller_cond; |
| 2268 | |
| 2269 | // choose mds |
| 2270 | Inode *hash_diri = NULL; |
| 2271 | mds_rank_t mds = choose_target_mds(request, &hash_diri); |
| 2272 | int mds_state = (mds == MDS_RANK_NONE) ? MDSMap::STATE_NULL : mdsmap->get_state(mds); |
| 2273 | if (mds_state != MDSMap::STATE_ACTIVE && mds_state != MDSMap::STATE_STOPPING) { |
| 2274 | if (mds_state == MDSMap::STATE_NULL && mds >= mdsmap->get_max_mds()) { |
| 2275 | if (hash_diri) { |
| 2276 | ldout(cct, 10) << " target mds." << mds << " has stopped, remove it from fragmap" << dendl; |
| 2277 | _fragmap_remove_stopped_mds(hash_diri, mds); |
no test coverage detected