func: static void quorum_vote(QuorumAIOCB *acb)
  
  {
  
      bool quorum = true;
  
      int i, j, ret;
  
      QuorumVoteValue hash;
  
      BDRVQuorumState *s = acb->common.bs->opaque;
  
      QuorumVoteVersion *winner;
  
  
  
      if (quorum_has_too_much_io_failed(acb)) {
  
          return;
  
      }
  
  
  
      /* get the index of the first successful read */
  
      for (i = 0; i < s->num_children; i++) {
  
          if (!acb->qcrs[i].ret) {
  
              break;
  
          }
  
      }
  
  
  
      assert(i < s->num_children);
  
  
  
      /* compare this read with all other successful reads stopping at quorum
  
       * failure
  
       */
  
      for (j = i + 1; j < s->num_children; j++) {
  
          if (acb->qcrs[j].ret) {
  
              continue;
  
          }
  
          quorum = quorum_compare(acb, &acb->qcrs[i].qiov, &acb->qcrs[j].qiov);
  
          if (!quorum) {
  
              break;
  
         }
  
      }
  
  
  
      /* Every successful read agrees */
  
      if (quorum) {
  
          quorum_copy_qiov(acb->qiov, &acb->qcrs[i].qiov);
  
          return;
  
      }
  
  
  
      /* compute hashes for each successful read, also store indexes */
  
      for (i = 0; i < s->num_children; i++) {
  
          if (acb->qcrs[i].ret) {
  
              continue;
  
          }
  
          ret = quorum_compute_hash(acb, i, &hash);
  
          /* if ever the hash computation failed */
  
          if (ret < 0) {
  
              acb->vote_ret = ret;
  
              goto free_exit;
  
          }
  
          quorum_count_vote(&acb->votes, &hash, i);
  
      }
  
  
  
      /* vote to select the most represented version */
  
      winner = quorum_get_vote_winner(&acb->votes);
  
  
  
      /* if the winner count is smaller than threshold the read fails */
  
      if (winner->vote_count < s->threshold) {
  
          quorum_report_failure(acb);
  
          acb->vote_ret = -EIO;
  
          goto free_exit;
  
      }
  
  
  
      /* we have a winner: copy it */
  
      quorum_copy_qiov(acb->qiov, &acb->qcrs[winner->index].qiov);
  
  
  
      /* some versions are bad print them */
  
      quorum_report_bad_versions(s, acb, &winner->value);
  
  
  
  free_exit:
  
      /* free lists */
  
      quorum_free_vote_list(&acb->votes);
  
  }
  