Lines Matching refs:lreq
52 struct ceph_osd_linger_request *lreq);
54 struct ceph_osd_linger_request *lreq);
85 static inline void verify_lreq_locked(struct ceph_osd_linger_request *lreq)
87 WARN_ON(!mutex_is_locked(&lreq->lock));
93 static inline void verify_lreq_locked(struct ceph_osd_linger_request *lreq) { }
1383 struct ceph_osd_linger_request *lreq =
1388 dout(" reassigning lreq %p linger_id %llu\n", lreq,
1389 lreq->linger_id);
1390 unlink_linger(osd, lreq);
1391 link_linger(&osdc->homeless_osd, lreq);
2784 struct ceph_osd_linger_request *lreq =
2787 dout("%s lreq %p reg_req %p ping_req %p\n", __func__, lreq,
2788 lreq->reg_req, lreq->ping_req);
2789 WARN_ON(!RB_EMPTY_NODE(&lreq->node));
2790 WARN_ON(!RB_EMPTY_NODE(&lreq->osdc_node));
2791 WARN_ON(!RB_EMPTY_NODE(&lreq->mc_node));
2792 WARN_ON(!list_empty(&lreq->scan_item));
2793 WARN_ON(!list_empty(&lreq->pending_lworks));
2794 WARN_ON(lreq->osd);
2796 if (lreq->request_pl)
2797 ceph_pagelist_release(lreq->request_pl);
2798 if (lreq->notify_id_pages)
2799 ceph_release_page_vector(lreq->notify_id_pages, 1);
2801 ceph_osdc_put_request(lreq->reg_req);
2802 ceph_osdc_put_request(lreq->ping_req);
2803 target_destroy(&lreq->t);
2804 kfree(lreq);
2807 static void linger_put(struct ceph_osd_linger_request *lreq)
2809 if (lreq)
2810 kref_put(&lreq->kref, linger_release);
2814 linger_get(struct ceph_osd_linger_request *lreq)
2816 kref_get(&lreq->kref);
2817 return lreq;
2823 struct ceph_osd_linger_request *lreq;
2825 lreq = kzalloc(sizeof(*lreq), GFP_NOIO);
2826 if (!lreq)
2829 kref_init(&lreq->kref);
2830 mutex_init(&lreq->lock);
2831 RB_CLEAR_NODE(&lreq->node);
2832 RB_CLEAR_NODE(&lreq->osdc_node);
2833 RB_CLEAR_NODE(&lreq->mc_node);
2834 INIT_LIST_HEAD(&lreq->scan_item);
2835 INIT_LIST_HEAD(&lreq->pending_lworks);
2836 init_completion(&lreq->reg_commit_wait);
2837 init_completion(&lreq->notify_finish_wait);
2839 lreq->osdc = osdc;
2840 target_init(&lreq->t);
2842 dout("%s lreq %p\n", __func__, lreq);
2843 return lreq;
2853 * @lreq has to be registered, @osd may be homeless.
2856 struct ceph_osd_linger_request *lreq)
2859 WARN_ON(!lreq->linger_id || lreq->osd);
2860 dout("%s osd %p osd%d lreq %p linger_id %llu\n", __func__, osd,
2861 osd->o_osd, lreq, lreq->linger_id);
2869 insert_linger(&osd->o_linger_requests, lreq);
2870 lreq->osd = osd;
2874 struct ceph_osd_linger_request *lreq)
2877 WARN_ON(lreq->osd != osd);
2878 dout("%s osd %p osd%d lreq %p linger_id %llu\n", __func__, osd,
2879 osd->o_osd, lreq, lreq->linger_id);
2881 lreq->osd = NULL;
2882 erase_linger(&osd->o_linger_requests, lreq);
2891 static bool __linger_registered(struct ceph_osd_linger_request *lreq)
2893 verify_osdc_locked(lreq->osdc);
2895 return !RB_EMPTY_NODE(&lreq->osdc_node);
2898 static bool linger_registered(struct ceph_osd_linger_request *lreq)
2900 struct ceph_osd_client *osdc = lreq->osdc;
2904 registered = __linger_registered(lreq);
2910 static void linger_register(struct ceph_osd_linger_request *lreq)
2912 struct ceph_osd_client *osdc = lreq->osdc;
2915 WARN_ON(lreq->linger_id);
2917 linger_get(lreq);
2918 lreq->linger_id = ++osdc->last_linger_id;
2919 insert_linger_osdc(&osdc->linger_requests, lreq);
2922 static void linger_unregister(struct ceph_osd_linger_request *lreq)
2924 struct ceph_osd_client *osdc = lreq->osdc;
2928 erase_linger_osdc(&osdc->linger_requests, lreq);
2929 linger_put(lreq);
2934 struct ceph_osd_linger_request *lreq = req->r_priv;
2938 linger_put(lreq);
2943 struct ceph_osd_linger_request *lreq;
2962 static struct linger_work *lwork_alloc(struct ceph_osd_linger_request *lreq,
2973 lwork->lreq = linger_get(lreq);
2980 struct ceph_osd_linger_request *lreq = lwork->lreq;
2982 mutex_lock(&lreq->lock);
2984 mutex_unlock(&lreq->lock);
2986 linger_put(lreq);
2992 struct ceph_osd_linger_request *lreq = lwork->lreq;
2993 struct ceph_osd_client *osdc = lreq->osdc;
2995 verify_lreq_locked(lreq);
2999 list_add_tail(&lwork->pending_item, &lreq->pending_lworks);
3006 struct ceph_osd_linger_request *lreq = lwork->lreq;
3008 if (!linger_registered(lreq)) {
3009 dout("%s lreq %p not registered\n", __func__, lreq);
3013 WARN_ON(!lreq->is_watch);
3014 dout("%s lreq %p notify_id %llu notifier_id %llu payload_len %zu\n",
3015 __func__, lreq, lwork->notify.notify_id, lwork->notify.notifier_id,
3017 lreq->wcb(lreq->data, lwork->notify.notify_id, lreq->linger_id,
3029 struct ceph_osd_linger_request *lreq = lwork->lreq;
3031 if (!linger_registered(lreq)) {
3032 dout("%s lreq %p not registered\n", __func__, lreq);
3036 dout("%s lreq %p err %d\n", __func__, lreq, lwork->error.err);
3037 lreq->errcb(lreq->data, lreq->linger_id, lwork->error.err);
3043 static void queue_watch_error(struct ceph_osd_linger_request *lreq)
3047 lwork = lwork_alloc(lreq, do_watch_error);
3053 lwork->error.err = lreq->last_error;
3057 static void linger_reg_commit_complete(struct ceph_osd_linger_request *lreq,
3060 if (!completion_done(&lreq->reg_commit_wait)) {
3061 lreq->reg_commit_error = (result <= 0 ? result : 0);
3062 complete_all(&lreq->reg_commit_wait);
3068 struct ceph_osd_linger_request *lreq = req->r_priv;
3070 mutex_lock(&lreq->lock);
3071 if (req != lreq->reg_req) {
3072 dout("%s lreq %p linger_id %llu unknown req (%p != %p)\n",
3073 __func__, lreq, lreq->linger_id, req, lreq->reg_req);
3077 dout("%s lreq %p linger_id %llu result %d\n", __func__, lreq,
3078 lreq->linger_id, req->r_result);
3079 linger_reg_commit_complete(lreq, req->r_result);
3080 lreq->committed = true;
3082 if (!lreq->is_watch) {
3092 lreq->notify_id = ceph_decode_64(&p);
3093 dout("lreq %p notify_id %llu\n", lreq,
3094 lreq->notify_id);
3096 dout("lreq %p no notify_id\n", lreq);
3101 mutex_unlock(&lreq->lock);
3102 linger_put(lreq);
3120 struct ceph_osd_linger_request *lreq = req->r_priv;
3122 mutex_lock(&lreq->lock);
3123 if (req != lreq->reg_req) {
3124 dout("%s lreq %p linger_id %llu unknown req (%p != %p)\n",
3125 __func__, lreq, lreq->linger_id, req, lreq->reg_req);
3129 dout("%s lreq %p linger_id %llu result %d last_error %d\n", __func__,
3130 lreq, lreq->linger_id, req->r_result, lreq->last_error);
3132 if (!lreq->last_error) {
3133 lreq->last_error = normalize_watch_error(req->r_result);
3134 queue_watch_error(lreq);
3139 mutex_unlock(&lreq->lock);
3140 linger_put(lreq);
3143 static void send_linger(struct ceph_osd_linger_request *lreq)
3145 struct ceph_osd_client *osdc = lreq->osdc;
3150 mutex_lock(&lreq->lock);
3151 dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
3153 if (lreq->reg_req) {
3154 if (lreq->reg_req->r_osd)
3155 cancel_linger_request(lreq->reg_req);
3156 ceph_osdc_put_request(lreq->reg_req);
3162 target_copy(&req->r_t, &lreq->t);
3163 req->r_mtime = lreq->mtime;
3165 if (lreq->is_watch && lreq->committed) {
3167 lreq->linger_id, ++lreq->register_gen);
3168 dout("lreq %p reconnect register_gen %u\n", lreq,
3172 if (lreq->is_watch) {
3174 lreq->linger_id, 0);
3176 lreq->notify_id = 0;
3178 refcount_inc(&lreq->request_pl->refcnt);
3179 osd_req_op_notify_init(req, 0, lreq->linger_id,
3180 lreq->request_pl);
3183 lreq->notify_id_pages, PAGE_SIZE, 0, false, false);
3185 dout("lreq %p register\n", lreq);
3192 req->r_priv = linger_get(lreq);
3194 lreq->reg_req = req;
3195 mutex_unlock(&lreq->lock);
3202 struct ceph_osd_linger_request *lreq = req->r_priv;
3204 mutex_lock(&lreq->lock);
3205 if (req != lreq->ping_req) {
3206 dout("%s lreq %p linger_id %llu unknown req (%p != %p)\n",
3207 __func__, lreq, lreq->linger_id, req, lreq->ping_req);
3211 dout("%s lreq %p linger_id %llu result %d ping_sent %lu last_error %d\n",
3212 __func__, lreq, lreq->linger_id, req->r_result, lreq->ping_sent,
3213 lreq->last_error);
3214 if (lreq->register_gen == req->r_ops[0].watch.gen) {
3216 lreq->watch_valid_thru = lreq->ping_sent;
3217 } else if (!lreq->last_error) {
3218 lreq->last_error = normalize_watch_error(req->r_result);
3219 queue_watch_error(lreq);
3222 dout("lreq %p register_gen %u ignoring old pong %u\n", lreq,
3223 lreq->register_gen, req->r_ops[0].watch.gen);
3227 mutex_unlock(&lreq->lock);
3228 linger_put(lreq);
3231 static void send_linger_ping(struct ceph_osd_linger_request *lreq)
3233 struct ceph_osd_client *osdc = lreq->osdc;
3242 lreq->ping_sent = jiffies;
3243 dout("%s lreq %p linger_id %llu ping_sent %lu register_gen %u\n",
3244 __func__, lreq, lreq->linger_id, lreq->ping_sent,
3245 lreq->register_gen);
3247 if (lreq->ping_req) {
3248 if (lreq->ping_req->r_osd)
3249 cancel_linger_request(lreq->ping_req);
3250 ceph_osdc_put_request(lreq->ping_req);
3256 target_copy(&req->r_t, &lreq->t);
3257 osd_req_op_watch_init(req, 0, CEPH_OSD_WATCH_OP_PING, lreq->linger_id,
3258 lreq->register_gen);
3264 req->r_priv = linger_get(lreq);
3266 lreq->ping_req = req;
3271 link_request(lreq->osd, req);
3275 static void linger_submit(struct ceph_osd_linger_request *lreq)
3277 struct ceph_osd_client *osdc = lreq->osdc;
3281 linger_register(lreq);
3283 calc_target(osdc, &lreq->t, false);
3284 osd = lookup_create_osd(osdc, lreq->t.osd, true);
3285 link_linger(osd, lreq);
3287 send_linger(lreq);
3291 static void cancel_linger_map_check(struct ceph_osd_linger_request *lreq)
3293 struct ceph_osd_client *osdc = lreq->osdc;
3299 lreq->linger_id);
3303 WARN_ON(lookup_lreq != lreq);
3304 erase_linger_mc(&osdc->linger_map_checks, lreq);
3305 linger_put(lreq);
3309 * @lreq has to be both registered and linked.
3311 static void __linger_cancel(struct ceph_osd_linger_request *lreq)
3313 if (lreq->ping_req && lreq->ping_req->r_osd)
3314 cancel_linger_request(lreq->ping_req);
3315 if (lreq->reg_req && lreq->reg_req->r_osd)
3316 cancel_linger_request(lreq->reg_req);
3317 cancel_linger_map_check(lreq);
3318 unlink_linger(lreq->osd, lreq);
3319 linger_unregister(lreq);
3322 static void linger_cancel(struct ceph_osd_linger_request *lreq)
3324 struct ceph_osd_client *osdc = lreq->osdc;
3327 if (__linger_registered(lreq))
3328 __linger_cancel(lreq);
3332 static void send_linger_map_check(struct ceph_osd_linger_request *lreq);
3334 static void check_linger_pool_dne(struct ceph_osd_linger_request *lreq)
3336 struct ceph_osd_client *osdc = lreq->osdc;
3342 if (lreq->register_gen) {
3343 lreq->map_dne_bound = map->epoch;
3344 dout("%s lreq %p linger_id %llu pool disappeared\n", __func__,
3345 lreq, lreq->linger_id);
3347 dout("%s lreq %p linger_id %llu map_dne_bound %u have %u\n",
3348 __func__, lreq, lreq->linger_id, lreq->map_dne_bound,
3352 if (lreq->map_dne_bound) {
3353 if (map->epoch >= lreq->map_dne_bound) {
3356 lreq->linger_id);
3357 linger_reg_commit_complete(lreq, -ENOENT);
3358 __linger_cancel(lreq);
3361 send_linger_map_check(lreq);
3368 struct ceph_osd_linger_request *lreq;
3374 lreq = lookup_linger_mc(&osdc->linger_map_checks, linger_id);
3375 if (!lreq) {
3380 dout("%s lreq %p linger_id %llu map_dne_bound %u newest %llu\n",
3381 __func__, lreq, lreq->linger_id, lreq->map_dne_bound,
3383 if (!lreq->map_dne_bound)
3384 lreq->map_dne_bound = greq->u.newest;
3385 erase_linger_mc(&osdc->linger_map_checks, lreq);
3386 check_linger_pool_dne(lreq);
3388 linger_put(lreq);
3393 static void send_linger_map_check(struct ceph_osd_linger_request *lreq)
3395 struct ceph_osd_client *osdc = lreq->osdc;
3402 lreq->linger_id);
3404 WARN_ON(lookup_lreq != lreq);
3408 linger_get(lreq);
3409 insert_linger_mc(&osdc->linger_map_checks, lreq);
3411 linger_map_check_cb, lreq->linger_id);
3415 static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq)
3419 dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
3420 ret = wait_for_completion_killable(&lreq->reg_commit_wait);
3421 return ret ?: lreq->reg_commit_error;
3424 static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq,
3429 dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
3430 left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait,
3435 left = lreq->notify_finish_error; /* completed */
3487 struct ceph_osd_linger_request *lreq =
3490 dout(" lreq %p linger_id %llu is served by osd%d\n",
3491 lreq, lreq->linger_id, osd->o_osd);
3494 mutex_lock(&lreq->lock);
3495 if (lreq->is_watch && lreq->committed && !lreq->last_error)
3496 send_linger_ping(lreq);
3497 mutex_unlock(&lreq->lock);
3922 recalc_linger_target(struct ceph_osd_linger_request *lreq)
3924 struct ceph_osd_client *osdc = lreq->osdc;
3927 ct_res = calc_target(osdc, &lreq->t, true);
3931 osd = lookup_create_osd(osdc, lreq->t.osd, true);
3932 if (osd != lreq->osd) {
3933 unlink_linger(lreq->osd, lreq);
3934 link_linger(osd, lreq);
3956 struct ceph_osd_linger_request *lreq =
3962 dout("%s lreq %p linger_id %llu\n", __func__, lreq,
3963 lreq->linger_id);
3964 ct_res = recalc_linger_target(lreq);
3969 pool_cleared_full(osdc, lreq->t.base_oloc.pool));
3975 cancel_linger_map_check(lreq);
3981 if (list_empty(&lreq->scan_item))
3982 list_add_tail(&lreq->scan_item, need_resend_linger);
3985 list_del_init(&lreq->scan_item);
3986 check_linger_pool_dne(lreq);
4098 struct ceph_osd_linger_request *lreq, *nlreq;
4136 list_for_each_entry_safe(lreq, nlreq, need_resend_linger, scan_item) {
4137 if (!osd_homeless(lreq->osd))
4138 send_linger(lreq);
4140 list_del_init(&lreq->scan_item);
4284 struct ceph_osd_linger_request *lreq =
4287 send_linger(lreq);
4578 struct ceph_osd_linger_request *lreq;
4607 lreq = lookup_linger_osdc(&osdc->linger_requests, cookie);
4608 if (!lreq) {
4614 mutex_lock(&lreq->lock);
4615 dout("%s opcode %d cookie %llu lreq %p is_watch %d\n", __func__,
4616 opcode, cookie, lreq, lreq->is_watch);
4618 if (!lreq->last_error) {
4619 lreq->last_error = -ENOTCONN;
4620 queue_watch_error(lreq);
4622 } else if (!lreq->is_watch) {
4624 if (lreq->notify_id && lreq->notify_id != notify_id) {
4625 dout("lreq %p notify_id %llu != %llu, ignoring\n", lreq,
4626 lreq->notify_id, notify_id);
4627 } else if (!completion_done(&lreq->notify_finish_wait)) {
4632 if (lreq->preply_pages) {
4635 *lreq->preply_pages = data->pages;
4636 *lreq->preply_len = data->length;
4640 lreq->notify_finish_error = return_code;
4641 complete_all(&lreq->notify_finish_wait);
4645 lwork = lwork_alloc(lreq, do_watch_notify);
4660 mutex_unlock(&lreq->lock);
4785 struct ceph_osd_linger_request *lreq;
4788 lreq = linger_alloc(osdc);
4789 if (!lreq)
4792 lreq->is_watch = true;
4793 lreq->wcb = wcb;
4794 lreq->errcb = errcb;
4795 lreq->data = data;
4796 lreq->watch_valid_thru = jiffies;
4798 ceph_oid_copy(&lreq->t.base_oid, oid);
4799 ceph_oloc_copy(&lreq->t.base_oloc, oloc);
4800 lreq->t.flags = CEPH_OSD_FLAG_WRITE;
4801 ktime_get_real_ts64(&lreq->mtime);
4803 linger_submit(lreq);
4804 ret = linger_reg_commit_wait(lreq);
4806 linger_cancel(lreq);
4810 return lreq;
4813 linger_put(lreq);
4826 struct ceph_osd_linger_request *lreq)
4836 ceph_oid_copy(&req->r_base_oid, &lreq->t.base_oid);
4837 ceph_oloc_copy(&req->r_base_oloc, &lreq->t.base_oloc);
4841 lreq->linger_id, 0);
4848 linger_cancel(lreq);
4849 linger_put(lreq);
4944 struct ceph_osd_linger_request *lreq;
4953 lreq = linger_alloc(osdc);
4954 if (!lreq)
4957 lreq->request_pl = ceph_pagelist_alloc(GFP_NOIO);
4958 if (!lreq->request_pl) {
4963 ret = ceph_pagelist_encode_32(lreq->request_pl, 1); /* prot_ver */
4964 ret |= ceph_pagelist_encode_32(lreq->request_pl, timeout);
4965 ret |= ceph_pagelist_encode_32(lreq->request_pl, payload_len);
4966 ret |= ceph_pagelist_append(lreq->request_pl, payload, payload_len);
4973 lreq->notify_id_pages = ceph_alloc_page_vector(1, GFP_NOIO);
4974 if (IS_ERR(lreq->notify_id_pages)) {
4975 ret = PTR_ERR(lreq->notify_id_pages);
4976 lreq->notify_id_pages = NULL;
4980 lreq->preply_pages = preply_pages;
4981 lreq->preply_len = preply_len;
4983 ceph_oid_copy(&lreq->t.base_oid, oid);
4984 ceph_oloc_copy(&lreq->t.base_oloc, oloc);
4985 lreq->t.flags = CEPH_OSD_FLAG_READ;
4987 linger_submit(lreq);
4988 ret = linger_reg_commit_wait(lreq);
4990 ret = linger_notify_finish_wait(lreq,
4993 dout("lreq %p failed to initiate notify %d\n", lreq, ret);
4995 linger_cancel(lreq);
4997 linger_put(lreq);
5008 struct ceph_osd_linger_request *lreq)
5014 mutex_lock(&lreq->lock);
5015 stamp = lreq->watch_valid_thru;
5016 if (!list_empty(&lreq->pending_lworks)) {
5018 list_first_entry(&lreq->pending_lworks,
5026 dout("%s lreq %p linger_id %llu age %lu last_error %d\n", __func__,
5027 lreq, lreq->linger_id, age, lreq->last_error);
5029 ret = lreq->last_error ?: 1 + jiffies_to_msecs(age);
5031 mutex_unlock(&lreq->lock);