]> Git Repo - linux.git/blobdiff - net/tipc/group.c
Merge tag 'ceph-for-4.15-rc8' of git://github.com/ceph/ceph-client
[linux.git] / net / tipc / group.c
index 7ebbdeb2a90e1d8429113b81370ad67f05ee633e..5f4ffae807eee899a51ab79c258d3b26a8c863d9 100644 (file)
@@ -109,7 +109,8 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
 static void tipc_group_decr_active(struct tipc_group *grp,
                                   struct tipc_member *m)
 {
-       if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING)
+       if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING ||
+           m->state == MBR_REMITTED)
                grp->active_cnt--;
 }
 
@@ -368,18 +369,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack)
        u16 prev = grp->bc_snd_nxt - 1;
        struct tipc_member *m;
        struct rb_node *n;
+       u16 ackers = 0;
 
        for (n = rb_first(&grp->members); n; n = rb_next(n)) {
                m = container_of(n, struct tipc_member, tree_node);
                if (tipc_group_is_enabled(m)) {
                        tipc_group_update_member(m, len);
                        m->bc_acked = prev;
+                       ackers++;
                }
        }
 
        /* Mark number of acknowledges to expect, if any */
        if (ack)
-               grp->bc_ackers = grp->member_cnt;
+               grp->bc_ackers = ackers;
        grp->bc_snd_nxt++;
 }
 
@@ -560,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
        int max_active = grp->max_active;
        int reclaim_limit = max_active * 3 / 4;
        int active_cnt = grp->active_cnt;
-       struct tipc_member *m, *rm;
+       struct tipc_member *m, *rm, *pm;
 
        m = tipc_group_find_member(grp, node, port);
        if (!m)
@@ -603,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
                        pr_warn_ratelimited("Rcv unexpected msg after REMIT\n");
                        tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
                }
+               grp->active_cnt--;
+               list_del_init(&m->list);
+               if (list_empty(&grp->pending))
+                       return;
+
+               /* Set oldest pending member to active and advertise */
+               pm = list_first_entry(&grp->pending, struct tipc_member, list);
+               pm->state = MBR_ACTIVE;
+               list_move_tail(&pm->list, &grp->active);
+               grp->active_cnt++;
+               tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
                break;
        case MBR_RECLAIMING:
        case MBR_DISCOVERED:
@@ -740,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
                if (!m || m->state != MBR_RECLAIMING)
                        return;
 
-               list_del_init(&m->list);
-               grp->active_cnt--;
                remitted = msg_grp_remitted(hdr);
 
                /* Messages preceding the REMIT still in receive queue */
                if (m->advertised > remitted) {
                        m->state = MBR_REMITTED;
                        in_flight = m->advertised - remitted;
+                       m->advertised = ADV_IDLE + in_flight;
+                       return;
                }
                /* All messages preceding the REMIT have been read */
                if (m->advertised <= remitted) {
@@ -759,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
                        tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
 
                m->advertised = ADV_IDLE + in_flight;
+               grp->active_cnt--;
+               list_del_init(&m->list);
 
                /* Set oldest pending member to active and advertise */
                if (list_empty(&grp->pending))
@@ -848,17 +864,26 @@ void tipc_group_member_evt(struct tipc_group *grp,
                *usr_wakeup = true;
                m->usr_pending = false;
                node_up = tipc_node_is_up(net, node);
-
-               /* Hold back event if more messages might be expected */
-               if (m->state != MBR_LEAVING && node_up) {
-                       m->event_msg = skb;
-                       tipc_group_decr_active(grp, m);
-                       m->state = MBR_LEAVING;
-               } else {
-                       if (node_up)
+               m->event_msg = NULL;
+
+               if (node_up) {
+                       /* Hold back event if a LEAVE msg should be expected */
+                       if (m->state != MBR_LEAVING) {
+                               m->event_msg = skb;
+                               tipc_group_decr_active(grp, m);
+                               m->state = MBR_LEAVING;
+                       } else {
                                msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
-                       else
+                               __skb_queue_tail(inputq, skb);
+                       }
+               } else {
+                       if (m->state != MBR_LEAVING) {
+                               tipc_group_decr_active(grp, m);
+                               m->state = MBR_LEAVING;
                                msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt);
+                       } else {
+                               msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
+                       }
                        __skb_queue_tail(inputq, skb);
                }
                list_del_init(&m->list);
This page took 0.035235 seconds and 4 git commands to generate.