drbd: Pass struct packet_info down to the receive functions
authorAndreas Gruenbacher <agruen@linbit.com>
Thu, 24 Mar 2011 23:57:38 +0000 (00:57 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 8 Nov 2012 15:44:56 +0000 (16:44 +0100)
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_receiver.c

index edad6ac..cc729c4 100644 (file)
@@ -50,8 +50,8 @@
 
 struct packet_info {
        enum drbd_packet cmd;
-       int size;
-       int vnr;
+       unsigned int size;
+       unsigned int vnr;
 };
 
 enum finish_epoch {
@@ -1540,8 +1540,7 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id,
        return NULL;
 }
 
-static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
-                            unsigned int data_size)
+static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct drbd_request *req;
        sector_t sector;
@@ -1559,7 +1558,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
        /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
         * special casing it there for the various failure cases.
         * still no race with drbd_fail_pending_reads */
-       err = recv_dless_read(mdev, req, sector, data_size);
+       err = recv_dless_read(mdev, req, sector, pi->size);
        if (!err)
                req_mod(req, DATA_RECEIVED);
        /* else: nothing. handled from drbd_disconnect...
@@ -1569,8 +1568,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
        return err;
 }
 
-static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
-                              unsigned int data_size)
+static int receive_RSDataReply(struct drbd_conf *mdev, struct packet_info *pi)
 {
        sector_t sector;
        int err;
@@ -1583,17 +1581,17 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
                /* data is submitted to disk within recv_resync_read.
                 * corresponding put_ldev done below on error,
                 * or in drbd_peer_request_endio. */
-               err = recv_resync_read(mdev, sector, data_size);
+               err = recv_resync_read(mdev, sector, pi->size);
        } else {
                if (__ratelimit(&drbd_ratelimit_state))
                        dev_err(DEV, "Can not write resync data to local disk.\n");
 
-               err = drbd_drain_block(mdev, data_size);
+               err = drbd_drain_block(mdev, pi->size);
 
-               drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size);
+               drbd_send_ack_dp(mdev, P_NEG_ACK, p, pi->size);
        }
 
-       atomic_add(data_size >> 9, &mdev->rs_sect_in);
+       atomic_add(pi->size >> 9, &mdev->rs_sect_in);
 
        return err;
 }
@@ -1958,8 +1956,7 @@ static int handle_write_conflicts(struct drbd_conf *mdev,
 }
 
 /* mirrored write */
-static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
-                       unsigned int data_size)
+static int receive_Data(struct drbd_conf *mdev, struct packet_info *pi)
 {
        sector_t sector;
        struct drbd_peer_request *peer_req;
@@ -1973,9 +1970,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
                int err2;
 
                err = wait_for_and_update_peer_seq(mdev, peer_seq);
-               drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size);
+               drbd_send_ack_dp(mdev, P_NEG_ACK, p, pi->size);
                atomic_inc(&mdev->current_epoch->epoch_size);
-               err2 = drbd_drain_block(mdev, data_size);
+               err2 = drbd_drain_block(mdev, pi->size);
                if (!err)
                        err = err2;
                return err;
@@ -1988,7 +1985,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
         */
 
        sector = be64_to_cpu(p->sector);
-       peer_req = read_in_block(mdev, p->block_id, sector, data_size);
+       peer_req = read_in_block(mdev, p->block_id, sector, pi->size);
        if (!peer_req) {
                put_ldev(mdev);
                return -EIO;
@@ -2138,8 +2135,7 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector)
 }
 
 
-static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
-                              unsigned int digest_size)
+static int receive_DataRequest(struct drbd_conf *mdev, struct packet_info *pi)
 {
        sector_t sector;
        const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
@@ -2165,7 +2161,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
 
        if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) {
                verb = 1;
-               switch (cmd) {
+               switch (pi->cmd) {
                case P_DATA_REQUEST:
                        drbd_send_ack_rp(mdev, P_NEG_DREPLY, p);
                        break;
@@ -2187,7 +2183,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
                            "no local data.\n");
 
                /* drain possibly payload */
-               return drbd_drain_block(mdev, digest_size);
+               return drbd_drain_block(mdev, pi->size);
        }
 
        /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
@@ -2199,7 +2195,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
                return -ENOMEM;
        }
 
-       switch (cmd) {
+       switch (pi->cmd) {
        case P_DATA_REQUEST:
                peer_req->w.cb = w_e_end_data_req;
                fault_type = DRBD_FAULT_DT_RD;
@@ -2216,25 +2212,25 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
        case P_OV_REPLY:
        case P_CSUM_RS_REQUEST:
                fault_type = DRBD_FAULT_RS_RD;
-               di = kmalloc(sizeof(*di) + digest_size, GFP_NOIO);
+               di = kmalloc(sizeof(*di) + pi->size, GFP_NOIO);
                if (!di)
                        goto out_free_e;
 
-               di->digest_size = digest_size;
+               di->digest_size = pi->size;
                di->digest = (((char *)di)+sizeof(struct digest_info));
 
                peer_req->digest = di;
                peer_req->flags |= EE_HAS_DIGEST;
 
-               if (drbd_recv(mdev->tconn, di->digest, digest_size) != digest_size)
+               if (drbd_recv_all(mdev->tconn, di->digest, pi->size))
                        goto out_free_e;
 
-               if (cmd == P_CSUM_RS_REQUEST) {
+               if (pi->cmd == P_CSUM_RS_REQUEST) {
                        D_ASSERT(mdev->tconn->agreed_pro_version >= 89);
                        peer_req->w.cb = w_e_end_csum_rs_req;
                        /* used in the sector offset progress display */
                        mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
-               } else if (cmd == P_OV_REPLY) {
+               } else if (pi->cmd == P_OV_REPLY) {
                        /* track progress, we may need to throttle */
                        atomic_add(size >> 9, &mdev->rs_sect_in);
                        peer_req->w.cb = w_e_end_ov_reply;
@@ -2860,8 +2856,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
        return 1;
 }
 
-static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
-                           unsigned int data_size)
+static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct p_protocol *p = tconn->data.rbuf;
        int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
@@ -2915,7 +2910,7 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
                unsigned char *my_alg = tconn->net_conf->integrity_alg;
                int err;
 
-               err = drbd_recv_all(tconn, p_integrity_alg, data_size);
+               err = drbd_recv_all(tconn, p_integrity_alg, pi->size);
                if (err)
                        return err;
 
@@ -2962,8 +2957,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
        return tfm;
 }
 
-static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
-                            unsigned int packet_size)
+static int receive_SyncParam(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_rs_param_95 *p = mdev->tconn->data.rbuf;
        unsigned int header_size, data_size, exp_max_sz;
@@ -2980,22 +2974,22 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
                    : apv <= 94 ? sizeof(struct p_rs_param_89)
                    : /* apv >= 95 */ sizeof(struct p_rs_param_95);
 
-       if (packet_size > exp_max_sz) {
+       if (pi->size > exp_max_sz) {
                dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n",
-                   packet_size, exp_max_sz);
+                   pi->size, exp_max_sz);
                return -EIO;
        }
 
        if (apv <= 88) {
                header_size = sizeof(struct p_rs_param) - sizeof(struct p_header);
-               data_size   = packet_size  - header_size;
+               data_size = pi->size - header_size;
        } else if (apv <= 94) {
                header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header);
-               data_size   = packet_size  - header_size;
+               data_size = pi->size - header_size;
                D_ASSERT(data_size == 0);
        } else {
                header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header);
-               data_size   = packet_size  - header_size;
+               data_size = pi->size - header_size;
                D_ASSERT(data_size == 0);
        }
 
@@ -3134,8 +3128,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev,
                     (unsigned long long)a, (unsigned long long)b);
 }
 
-static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
-                        unsigned int data_size)
+static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_sizes *p = mdev->tconn->data.rbuf;
        enum determine_dev_size dd = unchanged;
@@ -3232,8 +3225,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
        return 0;
 }
 
-static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
-                        unsigned int data_size)
+static int receive_uuids(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_uuids *p = mdev->tconn->data.rbuf;
        u64 *p_uuid;
@@ -3328,8 +3320,7 @@ static union drbd_state convert_state(union drbd_state ps)
        return ms;
 }
 
-static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
-                            unsigned int data_size)
+static int receive_req_state(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_req_state *p = mdev->tconn->data.rbuf;
        union drbd_state mask, val;
@@ -3355,8 +3346,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
        return 0;
 }
 
-static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd,
-                                 unsigned int data_size)
+static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        struct p_req_state *p = tconn->data.rbuf;
        union drbd_state mask, val;
@@ -3380,8 +3370,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd
        return 0;
 }
 
-static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
-                        unsigned int data_size)
+static int receive_state(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_state *p = mdev->tconn->data.rbuf;
        union drbd_state os, ns, peer_state;
@@ -3533,8 +3522,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
        return 0;
 }
 
-static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
-                            unsigned int data_size)
+static int receive_sync_uuid(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_rs_uuid *p = mdev->tconn->data.rbuf;
 
@@ -3743,13 +3731,11 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev,
    in order to be agnostic to the 32 vs 64 bits issue.
 
    returns 0 on failure, 1 if we successfully received it. */
-static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
-                         unsigned int data_size)
+static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct bm_xfer_ctx c;
        int err;
        struct p_header *h = mdev->tconn->data.rbuf;
-       struct packet_info pi;
 
        drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
        /* you are supposed to send additional out-of-sync information
@@ -3761,48 +3747,46 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
        };
 
        for(;;) {
-               if (cmd == P_BITMAP) {
-                       err = receive_bitmap_plain(mdev, data_size, h, &c);
-               } else if (cmd == P_COMPRESSED_BITMAP) {
+               if (pi->cmd == P_BITMAP) {
+                       err = receive_bitmap_plain(mdev, pi->size, h, &c);
+               } else if (pi->cmd == P_COMPRESSED_BITMAP) {
                        /* MAYBE: sanity check that we speak proto >= 90,
                         * and the feature is enabled! */
                        struct p_compressed_bm *p;
 
-                       if (data_size > BM_PACKET_PAYLOAD_BYTES) {
+                       if (pi->size > BM_PACKET_PAYLOAD_BYTES) {
                                dev_err(DEV, "ReportCBitmap packet too large\n");
                                err = -EIO;
                                goto out;
                        }
 
                        p = mdev->tconn->data.rbuf;
-                       err = drbd_recv_all(mdev->tconn, p->head.payload, data_size);
+                       err = drbd_recv_all(mdev->tconn, p->head.payload, pi->size);
                        if (err)
                               goto out;
-                       if (data_size <= (sizeof(*p) - sizeof(p->head))) {
-                               dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size);
+                       if (pi->size <= (sizeof(*p) - sizeof(p->head))) {
+                               dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size);
                                err = -EIO;
                                goto out;
                        }
-                       err = decode_bitmap_c(mdev, p, &c, data_size);
+                       err = decode_bitmap_c(mdev, p, &c, pi->size);
                } else {
-                       dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", cmd);
+                       dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd);
                        err = -EIO;
                        goto out;
                }
 
-               c.packets[cmd == P_BITMAP]++;
-               c.bytes[cmd == P_BITMAP] += sizeof(struct p_header) + data_size;
+               c.packets[pi->cmd == P_BITMAP]++;
+               c.bytes[pi->cmd == P_BITMAP] += sizeof(struct p_header) + pi->size;
 
                if (err <= 0) {
                        if (err < 0)
                                goto out;
                        break;
                }
-               err = drbd_recv_header(mdev->tconn, &pi);
+               err = drbd_recv_header(mdev->tconn, pi);
                if (err)
                        goto out;
-               cmd = pi.cmd;
-               data_size = pi.size;
        }
 
        INFO_bm_xfer_stats(mdev, "receive", &c);
@@ -3848,25 +3832,23 @@ static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size)
        return size ? -EIO : 0;
 }
 
-static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd,
-                       unsigned int data_size)
+static int receive_skip(struct drbd_conf *mdev, struct packet_info *pi)
 {
        dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n",
-                cmd, data_size);
+                pi->cmd, pi->size);
 
-       return _tconn_receive_skip(mdev->tconn, data_size);
+       return _tconn_receive_skip(mdev->tconn, pi->size);
 }
 
-static int tconn_receive_skip(struct drbd_tconn *tconn, enum drbd_packet cmd, unsigned int data_size)
+static int tconn_receive_skip(struct drbd_tconn *tconn, struct packet_info *pi)
 {
        conn_warn(tconn, "skipping packet for non existing volume type %d, l: %d!\n",
-                 cmd, data_size);
+                 pi->cmd, pi->size);
 
-       return _tconn_receive_skip(tconn, data_size);
+       return _tconn_receive_skip(tconn, pi->size);
 }
 
-static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
-                               unsigned int data_size)
+static int receive_UnplugRemote(struct drbd_conf *mdev, struct packet_info *pi)
 {
        /* Make sure we've acked all the TCP data associated
         * with the data requests being unplugged */
@@ -3875,8 +3857,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
        return 0;
 }
 
-static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
-                              unsigned int data_size)
+static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi)
 {
        struct p_block_desc *p = mdev->tconn->data.rbuf;
 
@@ -3900,10 +3881,8 @@ struct data_cmd {
        size_t pkt_size;
        enum mdev_or_conn fa_type; /* first argument's type */
        union {
-               int (*mdev_fn)(struct drbd_conf *, enum drbd_packet cmd,
-                                 unsigned int to_receive);
-               int (*conn_fn)(struct drbd_tconn *, enum drbd_packet cmd,
-                                 unsigned int to_receive);
+               int (*mdev_fn)(struct drbd_conf *, struct packet_info *);
+               int (*conn_fn)(struct drbd_tconn *, struct packet_info *);
        };
 };
 
@@ -3963,15 +3942,16 @@ static void drbdd(struct drbd_tconn *tconn)
                        err = drbd_recv_all_warn(tconn, &header->payload, shs);
                        if (err)
                                goto err_out;
+                       pi.size -= shs;
                }
 
-               if (cmd->fa_type == CONN) {
-                       err = cmd->conn_fn(tconn, pi.cmd, pi.size - shs);
-               else {
+               if (cmd->fa_type == CONN)
+                       err = cmd->conn_fn(tconn, &pi);
+               else {
                        struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr);
                        err = mdev ?
-                               cmd->mdev_fn(mdev, pi.cmd, pi.size - shs) :
-                               tconn_receive_skip(tconn, pi.cmd, pi.size - shs);
+                               cmd->mdev_fn(mdev, &pi) :
+                               tconn_receive_skip(tconn, &pi);
                }
 
                if (unlikely(err)) {