| 2857 | } |
| 2858 | |
| 2859 | ref_t<MClientRequest> Client::build_client_request(MetaRequest *request, mds_rank_t mds) |
| 2860 | { |
| 2861 | auto session = mds_sessions.at(mds); |
| 2862 | bool old_version = !session->mds_features.test(CEPHFS_FEATURE_32BITS_RETRY_FWD); |
| 2863 | |
| 2864 | /* |
| 2865 | * Avoid inifinite retrying after overflow. |
| 2866 | * |
| 2867 | * The client will increase the retry count and if the MDS is |
| 2868 | * old version, so we limit to retry at most 256 times. |
| 2869 | */ |
| 2870 | if (request->retry_attempt) { |
| 2871 | int old_max_retry = sizeof(((struct ceph_mds_request_head*)0)->num_retry); |
| 2872 | old_max_retry = 1 << (old_max_retry * CHAR_BIT); |
| 2873 | if ((old_version && request->retry_attempt >= old_max_retry) || |
| 2874 | (uint32_t)request->retry_attempt >= UINT32_MAX) { |
| 2875 | request->abort(-EMULTIHOP); |
| 2876 | request->caller_cond->notify_all(); |
| 2877 | ldout(cct, 1) << __func__ << " request tid " << request->tid |
| 2878 | << " retry seq overflow" << ", abort it" << dendl; |
| 2879 | return nullptr; |
| 2880 | } |
| 2881 | } |
| 2882 | |
| 2883 | auto req = make_message<MClientRequest>(request->get_op(), session->mds_features); |
| 2884 | req->set_tid(request->tid); |
| 2885 | req->set_stamp(request->op_stamp); |
| 2886 | memcpy(&req->head, &request->head, sizeof(ceph_mds_request_head)); |
| 2887 | |
| 2888 | // if the filepath's haven't been set, set them! |
| 2889 | if (request->path.empty()) { |
| 2890 | Inode *in = request->inode(); |
| 2891 | Dentry *de = request->dentry(); |
| 2892 | if (in) |
| 2893 | in->make_nosnap_relative_path(request->path); |
| 2894 | else if (de) { |
| 2895 | if (de->inode) |
| 2896 | de->inode->make_nosnap_relative_path(request->path); |
| 2897 | else if (de->dir) { |
| 2898 | de->dir->parent_inode->make_nosnap_relative_path(request->path); |
| 2899 | request->path.push_dentry(de->name); |
| 2900 | } |
| 2901 | else ldout(cct, 1) << "Warning -- unable to construct a filepath!" |
| 2902 | << " No path, inode, or appropriately-endowed dentry given!" |
| 2903 | << dendl; |
| 2904 | } else ldout(cct, 1) << "Warning -- unable to construct a filepath!" |
| 2905 | << " No path, inode, or dentry given!" |
| 2906 | << dendl; |
| 2907 | } |
| 2908 | req->set_filepath(request->get_filepath()); |
| 2909 | req->set_filepath2(request->get_filepath2()); |
| 2910 | req->set_alternate_name(request->alternate_name); |
| 2911 | req->set_data(request->data); |
| 2912 | req->fscrypt_auth = request->fscrypt_auth; |
| 2913 | req->fscrypt_file = request->fscrypt_file; |
| 2914 | req->set_retry_attempt(request->retry_attempt++); |
| 2915 | req->head.ext_num_fwd = request->num_fwd; |
| 2916 | const gid_t *_gids; |
nothing calls this directly
no test coverage detected