Re: [PATCH 5/9] libceph: resubmit linger ops when pg mapping changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jul 20, 2012 at 5:41 PM, Sage Weil <sage@xxxxxxxxxxx> wrote:
> The linger op registration (i.e., watch) modifies the object state.  As
> such, the OSD will reply with success if it has already applied without
> doing the associated side-effects (setting up the watch session state).
> If we lose the ACK and resubmit, we will see success but the watch will not
> be correctly registered and we won't get notifies.
>
> To fix this, always resubmit the linger op with a new tid.  We accomplish
> this by re-registering as a linger (i.e., 'registered') if we are not yet
> registered.  Then the second loop will treat this just like a normal
> case of re-registering.
>
> This mirrors a similar fix on the userland ceph.git, commit 5dd68b95, and
> ceph bug #2796.
>
> Signed-off-by: Sage Weil <sage@xxxxxxxxxxx>
> ---
>  net/ceph/osd_client.c |   26 +++++++++++++++++++++-----
>  1 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
> index 07920ca..c605705 100644
> --- a/net/ceph/osd_client.c
> +++ b/net/ceph/osd_client.c
> @@ -891,7 +891,9 @@ static void __register_linger_request(struct ceph_osd_client *osdc,
>  {
>         dout("__register_linger_request %p\n", req);
>         list_add_tail(&req->r_linger_item, &osdc->req_linger);
> -       list_add_tail(&req->r_linger_osd, &req->r_osd->o_linger_requests);
> +       if (req->r_osd)
> +               list_add_tail(&req->r_linger_osd,
> +                             &req->r_osd->o_linger_requests);
>  }
>
>  static void __unregister_linger_request(struct ceph_osd_client *osdc,
> @@ -1305,8 +1307,9 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
>
>         dout("kick_requests %s\n", force_resend ? " (force resend)" : "");
>         mutex_lock(&osdc->request_mutex);
> -       for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
> +       for (p = rb_first(&osdc->requests); p; ) {
>                 req = rb_entry(p, struct ceph_osd_request, r_node);
> +               p = rb_next(p);

It is not clear why you moved p = rb_next(p) from up there to here.

>                 err = __map_request(osdc, req, force_resend);
>                 if (err < 0)
>                         continue;  /* error */
> @@ -1314,10 +1317,23 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
>                         dout("%p tid %llu maps to no osd\n", req, req->r_tid);
>                         needmap++;  /* request a newer map */
>                 } else if (err > 0) {
> -                       dout("%p tid %llu requeued on osd%d\n", req, req->r_tid,
> -                            req->r_osd ? req->r_osd->o_osd : -1);
> -                       if (!req->r_linger)
> +                       if (!req->r_linger) {
> +                               dout("%p tid %llu requeued on osd%d\n", req,
> +                                    req->r_tid,
> +                                    req->r_osd ? req->r_osd->o_osd : -1);

I think we should create a helper for this, the code is cluttered with
all these tests:

static inline int osd_num(struct ceph_osd *osd)
{
  return (osd ? osd->o_osd : -1);
}

We can do it later.

>                                 req->r_flags |= CEPH_OSD_FLAG_RETRY;
> +                       }
> +               }
> +               if (req->r_linger && list_empty(&req->r_linger_item)) {
> +                       /*
> +                        * register as a linger so that we will
> +                        * re-submit below and get a new tid
> +                        */
> +                       dout("%p tid %llu restart on osd%d\n",
> +                            req, req->r_tid,
> +                            req->r_osd ? req->r_osd->o_osd : -1);
> +                       __register_linger_request(osdc, req);
> +                       __unregister_request(osdc, req);
>                 }
>         }
>
> --
> 1.7.9
>
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux