diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-03-24 21:43:51 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:44:56 -0500 |
commit | 4a76b1612f35d8c3e5c3e77e10c7d72eed79dfe0 (patch) | |
tree | c63d11e8b77351d22d1f79ed0c103d129c3ecb06 | |
parent | e28572167cfd882b16c12992bbcbbca3c4fa59fb (diff) |
drbd: Map from (connection, volume number) to device in the receive handlers
The receive handlers do not all handle unknown volume numbers the same
way.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 262 |
1 files changed, 164 insertions, 98 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index cc729c4982cb..3243c7849914 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1232,13 +1232,17 @@ static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev, | |||
1232 | wake_up(&mdev->misc_wait); | 1232 | wake_up(&mdev->misc_wait); |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, | 1235 | static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) |
1236 | unsigned int data_size) | ||
1237 | { | 1236 | { |
1237 | struct drbd_conf *mdev; | ||
1238 | int rv; | 1238 | int rv; |
1239 | struct p_barrier *p = mdev->tconn->data.rbuf; | 1239 | struct p_barrier *p = tconn->data.rbuf; |
1240 | struct drbd_epoch *epoch; | 1240 | struct drbd_epoch *epoch; |
1241 | 1241 | ||
1242 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
1243 | if (!mdev) | ||
1244 | return -EIO; | ||
1245 | |||
1242 | inc_unacked(mdev); | 1246 | inc_unacked(mdev); |
1243 | 1247 | ||
1244 | mdev->current_epoch->barrier_nr = p->barrier; | 1248 | mdev->current_epoch->barrier_nr = p->barrier; |
@@ -1540,12 +1544,17 @@ find_request(struct drbd_conf *mdev, struct rb_root *root, u64 id, | |||
1540 | return NULL; | 1544 | return NULL; |
1541 | } | 1545 | } |
1542 | 1546 | ||
1543 | static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi) | 1547 | static int receive_DataReply(struct drbd_tconn *tconn, struct packet_info *pi) |
1544 | { | 1548 | { |
1549 | struct drbd_conf *mdev; | ||
1545 | struct drbd_request *req; | 1550 | struct drbd_request *req; |
1546 | sector_t sector; | 1551 | sector_t sector; |
1547 | int err; | 1552 | int err; |
1548 | struct p_data *p = mdev->tconn->data.rbuf; | 1553 | struct p_data *p = tconn->data.rbuf; |
1554 | |||
1555 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
1556 | if (!mdev) | ||
1557 | return -EIO; | ||
1549 | 1558 | ||
1550 | sector = be64_to_cpu(p->sector); | 1559 | sector = be64_to_cpu(p->sector); |
1551 | 1560 | ||
@@ -1568,11 +1577,16 @@ static int receive_DataReply(struct drbd_conf *mdev, struct packet_info *pi) | |||
1568 | return err; | 1577 | return err; |
1569 | } | 1578 | } |
1570 | 1579 | ||
1571 | static int receive_RSDataReply(struct drbd_conf *mdev, struct packet_info *pi) | 1580 | static int receive_RSDataReply(struct drbd_tconn *tconn, struct packet_info *pi) |
1572 | { | 1581 | { |
1582 | struct drbd_conf *mdev; | ||
1573 | sector_t sector; | 1583 | sector_t sector; |
1574 | int err; | 1584 | int err; |
1575 | struct p_data *p = mdev->tconn->data.rbuf; | 1585 | struct p_data *p = tconn->data.rbuf; |
1586 | |||
1587 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
1588 | if (!mdev) | ||
1589 | return -EIO; | ||
1576 | 1590 | ||
1577 | sector = be64_to_cpu(p->sector); | 1591 | sector = be64_to_cpu(p->sector); |
1578 | D_ASSERT(p->block_id == ID_SYNCER); | 1592 | D_ASSERT(p->block_id == ID_SYNCER); |
@@ -1956,16 +1970,21 @@ static int handle_write_conflicts(struct drbd_conf *mdev, | |||
1956 | } | 1970 | } |
1957 | 1971 | ||
1958 | /* mirrored write */ | 1972 | /* mirrored write */ |
1959 | static int receive_Data(struct drbd_conf *mdev, struct packet_info *pi) | 1973 | static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi) |
1960 | { | 1974 | { |
1975 | struct drbd_conf *mdev; | ||
1961 | sector_t sector; | 1976 | sector_t sector; |
1962 | struct drbd_peer_request *peer_req; | 1977 | struct drbd_peer_request *peer_req; |
1963 | struct p_data *p = mdev->tconn->data.rbuf; | 1978 | struct p_data *p = tconn->data.rbuf; |
1964 | u32 peer_seq = be32_to_cpu(p->seq_num); | 1979 | u32 peer_seq = be32_to_cpu(p->seq_num); |
1965 | int rw = WRITE; | 1980 | int rw = WRITE; |
1966 | u32 dp_flags; | 1981 | u32 dp_flags; |
1967 | int err; | 1982 | int err; |
1968 | 1983 | ||
1984 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
1985 | if (!mdev) | ||
1986 | return -EIO; | ||
1987 | |||
1969 | if (!get_ldev(mdev)) { | 1988 | if (!get_ldev(mdev)) { |
1970 | int err2; | 1989 | int err2; |
1971 | 1990 | ||
@@ -2135,15 +2154,21 @@ int drbd_rs_should_slow_down(struct drbd_conf *mdev, sector_t sector) | |||
2135 | } | 2154 | } |
2136 | 2155 | ||
2137 | 2156 | ||
2138 | static int receive_DataRequest(struct drbd_conf *mdev, struct packet_info *pi) | 2157 | static int receive_DataRequest(struct drbd_tconn *tconn, struct packet_info *pi) |
2139 | { | 2158 | { |
2159 | struct drbd_conf *mdev; | ||
2140 | sector_t sector; | 2160 | sector_t sector; |
2141 | const sector_t capacity = drbd_get_capacity(mdev->this_bdev); | 2161 | sector_t capacity; |
2142 | struct drbd_peer_request *peer_req; | 2162 | struct drbd_peer_request *peer_req; |
2143 | struct digest_info *di = NULL; | 2163 | struct digest_info *di = NULL; |
2144 | int size, verb; | 2164 | int size, verb; |
2145 | unsigned int fault_type; | 2165 | unsigned int fault_type; |
2146 | struct p_block_req *p = mdev->tconn->data.rbuf; | 2166 | struct p_block_req *p = tconn->data.rbuf; |
2167 | |||
2168 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
2169 | if (!mdev) | ||
2170 | return -EIO; | ||
2171 | capacity = drbd_get_capacity(mdev->this_bdev); | ||
2147 | 2172 | ||
2148 | sector = be64_to_cpu(p->sector); | 2173 | sector = be64_to_cpu(p->sector); |
2149 | size = be32_to_cpu(p->blksize); | 2174 | size = be32_to_cpu(p->blksize); |
@@ -2957,17 +2982,60 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev, | |||
2957 | return tfm; | 2982 | return tfm; |
2958 | } | 2983 | } |
2959 | 2984 | ||
2960 | static int receive_SyncParam(struct drbd_conf *mdev, struct packet_info *pi) | 2985 | static int ignore_remaining_packet(struct drbd_tconn *tconn, struct packet_info *pi) |
2986 | { | ||
2987 | void *buffer = tconn->data.rbuf; | ||
2988 | int size = pi->size; | ||
2989 | |||
2990 | while (size) { | ||
2991 | int s = min_t(int, size, DRBD_SOCKET_BUFFER_SIZE); | ||
2992 | s = drbd_recv(tconn, buffer, s); | ||
2993 | if (s <= 0) { | ||
2994 | if (s < 0) | ||
2995 | return s; | ||
2996 | break; | ||
2997 | } | ||
2998 | size -= s; | ||
2999 | } | ||
3000 | if (size) | ||
3001 | return -EIO; | ||
3002 | return 0; | ||
3003 | } | ||
3004 | |||
3005 | /* | ||
3006 | * config_unknown_volume - device configuration command for unknown volume | ||
3007 | * | ||
3008 | * When a device is added to an existing connection, the node on which the | ||
3009 | * device is added first will send configuration commands to its peer but the | ||
3010 | * peer will not know about the device yet. It will warn and ignore these | ||
3011 | * commands. Once the device is added on the second node, the second node will | ||
3012 | * send the same device configuration commands, but in the other direction. | ||
3013 | * | ||
3014 | * (We can also end up here if drbd is misconfigured.) | ||
3015 | */ | ||
3016 | static int config_unknown_volume(struct drbd_tconn *tconn, struct packet_info *pi) | ||
3017 | { | ||
3018 | conn_warn(tconn, "Volume %u unknown; ignoring %s packet\n", | ||
3019 | pi->vnr, cmdname(pi->cmd)); | ||
3020 | return ignore_remaining_packet(tconn, pi); | ||
3021 | } | ||
3022 | |||
3023 | static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi) | ||
2961 | { | 3024 | { |
2962 | struct p_rs_param_95 *p = mdev->tconn->data.rbuf; | 3025 | struct drbd_conf *mdev; |
3026 | struct p_rs_param_95 *p = tconn->data.rbuf; | ||
2963 | unsigned int header_size, data_size, exp_max_sz; | 3027 | unsigned int header_size, data_size, exp_max_sz; |
2964 | struct crypto_hash *verify_tfm = NULL; | 3028 | struct crypto_hash *verify_tfm = NULL; |
2965 | struct crypto_hash *csums_tfm = NULL; | 3029 | struct crypto_hash *csums_tfm = NULL; |
2966 | const int apv = mdev->tconn->agreed_pro_version; | 3030 | const int apv = tconn->agreed_pro_version; |
2967 | int *rs_plan_s = NULL; | 3031 | int *rs_plan_s = NULL; |
2968 | int fifo_size = 0; | 3032 | int fifo_size = 0; |
2969 | int err; | 3033 | int err; |
2970 | 3034 | ||
3035 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3036 | if (!mdev) | ||
3037 | return config_unknown_volume(tconn, pi); | ||
3038 | |||
2971 | exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param) | 3039 | exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param) |
2972 | : apv == 88 ? sizeof(struct p_rs_param) | 3040 | : apv == 88 ? sizeof(struct p_rs_param) |
2973 | + SHARED_SECRET_MAX | 3041 | + SHARED_SECRET_MAX |
@@ -3128,14 +3196,19 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev, | |||
3128 | (unsigned long long)a, (unsigned long long)b); | 3196 | (unsigned long long)a, (unsigned long long)b); |
3129 | } | 3197 | } |
3130 | 3198 | ||
3131 | static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi) | 3199 | static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi) |
3132 | { | 3200 | { |
3133 | struct p_sizes *p = mdev->tconn->data.rbuf; | 3201 | struct drbd_conf *mdev; |
3202 | struct p_sizes *p = tconn->data.rbuf; | ||
3134 | enum determine_dev_size dd = unchanged; | 3203 | enum determine_dev_size dd = unchanged; |
3135 | sector_t p_size, p_usize, my_usize; | 3204 | sector_t p_size, p_usize, my_usize; |
3136 | int ldsc = 0; /* local disk size changed */ | 3205 | int ldsc = 0; /* local disk size changed */ |
3137 | enum dds_flags ddsf; | 3206 | enum dds_flags ddsf; |
3138 | 3207 | ||
3208 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3209 | if (!mdev) | ||
3210 | return config_unknown_volume(tconn, pi); | ||
3211 | |||
3139 | p_size = be64_to_cpu(p->d_size); | 3212 | p_size = be64_to_cpu(p->d_size); |
3140 | p_usize = be64_to_cpu(p->u_size); | 3213 | p_usize = be64_to_cpu(p->u_size); |
3141 | 3214 | ||
@@ -3225,12 +3298,17 @@ static int receive_sizes(struct drbd_conf *mdev, struct packet_info *pi) | |||
3225 | return 0; | 3298 | return 0; |
3226 | } | 3299 | } |
3227 | 3300 | ||
3228 | static int receive_uuids(struct drbd_conf *mdev, struct packet_info *pi) | 3301 | static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi) |
3229 | { | 3302 | { |
3230 | struct p_uuids *p = mdev->tconn->data.rbuf; | 3303 | struct drbd_conf *mdev; |
3304 | struct p_uuids *p = tconn->data.rbuf; | ||
3231 | u64 *p_uuid; | 3305 | u64 *p_uuid; |
3232 | int i, updated_uuids = 0; | 3306 | int i, updated_uuids = 0; |
3233 | 3307 | ||
3308 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3309 | if (!mdev) | ||
3310 | return config_unknown_volume(tconn, pi); | ||
3311 | |||
3234 | p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); | 3312 | p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); |
3235 | 3313 | ||
3236 | for (i = UI_CURRENT; i < UI_EXTENDED_SIZE; i++) | 3314 | for (i = UI_CURRENT; i < UI_EXTENDED_SIZE; i++) |
@@ -3320,12 +3398,17 @@ static union drbd_state convert_state(union drbd_state ps) | |||
3320 | return ms; | 3398 | return ms; |
3321 | } | 3399 | } |
3322 | 3400 | ||
3323 | static int receive_req_state(struct drbd_conf *mdev, struct packet_info *pi) | 3401 | static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi) |
3324 | { | 3402 | { |
3325 | struct p_req_state *p = mdev->tconn->data.rbuf; | 3403 | struct drbd_conf *mdev; |
3404 | struct p_req_state *p = tconn->data.rbuf; | ||
3326 | union drbd_state mask, val; | 3405 | union drbd_state mask, val; |
3327 | enum drbd_state_rv rv; | 3406 | enum drbd_state_rv rv; |
3328 | 3407 | ||
3408 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3409 | if (!mdev) | ||
3410 | return -EIO; | ||
3411 | |||
3329 | mask.i = be32_to_cpu(p->mask); | 3412 | mask.i = be32_to_cpu(p->mask); |
3330 | val.i = be32_to_cpu(p->val); | 3413 | val.i = be32_to_cpu(p->val); |
3331 | 3414 | ||
@@ -3370,14 +3453,19 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info * | |||
3370 | return 0; | 3453 | return 0; |
3371 | } | 3454 | } |
3372 | 3455 | ||
3373 | static int receive_state(struct drbd_conf *mdev, struct packet_info *pi) | 3456 | static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi) |
3374 | { | 3457 | { |
3375 | struct p_state *p = mdev->tconn->data.rbuf; | 3458 | struct drbd_conf *mdev; |
3459 | struct p_state *p = tconn->data.rbuf; | ||
3376 | union drbd_state os, ns, peer_state; | 3460 | union drbd_state os, ns, peer_state; |
3377 | enum drbd_disk_state real_peer_disk; | 3461 | enum drbd_disk_state real_peer_disk; |
3378 | enum chg_state_flags cs_flags; | 3462 | enum chg_state_flags cs_flags; |
3379 | int rv; | 3463 | int rv; |
3380 | 3464 | ||
3465 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3466 | if (!mdev) | ||
3467 | return config_unknown_volume(tconn, pi); | ||
3468 | |||
3381 | peer_state.i = be32_to_cpu(p->state); | 3469 | peer_state.i = be32_to_cpu(p->state); |
3382 | 3470 | ||
3383 | real_peer_disk = peer_state.disk; | 3471 | real_peer_disk = peer_state.disk; |
@@ -3522,9 +3610,14 @@ static int receive_state(struct drbd_conf *mdev, struct packet_info *pi) | |||
3522 | return 0; | 3610 | return 0; |
3523 | } | 3611 | } |
3524 | 3612 | ||
3525 | static int receive_sync_uuid(struct drbd_conf *mdev, struct packet_info *pi) | 3613 | static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi) |
3526 | { | 3614 | { |
3527 | struct p_rs_uuid *p = mdev->tconn->data.rbuf; | 3615 | struct drbd_conf *mdev; |
3616 | struct p_rs_uuid *p = tconn->data.rbuf; | ||
3617 | |||
3618 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3619 | if (!mdev) | ||
3620 | return -EIO; | ||
3528 | 3621 | ||
3529 | wait_event(mdev->misc_wait, | 3622 | wait_event(mdev->misc_wait, |
3530 | mdev->state.conn == C_WF_SYNC_UUID || | 3623 | mdev->state.conn == C_WF_SYNC_UUID || |
@@ -3731,11 +3824,16 @@ void INFO_bm_xfer_stats(struct drbd_conf *mdev, | |||
3731 | in order to be agnostic to the 32 vs 64 bits issue. | 3824 | in order to be agnostic to the 32 vs 64 bits issue. |
3732 | 3825 | ||
3733 | returns 0 on failure, 1 if we successfully received it. */ | 3826 | returns 0 on failure, 1 if we successfully received it. */ |
3734 | static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi) | 3827 | static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi) |
3735 | { | 3828 | { |
3829 | struct drbd_conf *mdev; | ||
3736 | struct bm_xfer_ctx c; | 3830 | struct bm_xfer_ctx c; |
3737 | int err; | 3831 | int err; |
3738 | struct p_header *h = mdev->tconn->data.rbuf; | 3832 | struct p_header *h = tconn->data.rbuf; |
3833 | |||
3834 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3835 | if (!mdev) | ||
3836 | return -EIO; | ||
3739 | 3837 | ||
3740 | drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED); | 3838 | drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED); |
3741 | /* you are supposed to send additional out-of-sync information | 3839 | /* you are supposed to send additional out-of-sync information |
@@ -3815,51 +3913,31 @@ static int receive_bitmap(struct drbd_conf *mdev, struct packet_info *pi) | |||
3815 | return err; | 3913 | return err; |
3816 | } | 3914 | } |
3817 | 3915 | ||
3818 | static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size) | 3916 | static int receive_skip(struct drbd_tconn *tconn, struct packet_info *pi) |
3819 | { | ||
3820 | /* TODO zero copy sink :) */ | ||
3821 | static char sink[128]; | ||
3822 | int size, want, r; | ||
3823 | |||
3824 | size = data_size; | ||
3825 | while (size > 0) { | ||
3826 | want = min_t(int, size, sizeof(sink)); | ||
3827 | r = drbd_recv(tconn, sink, want); | ||
3828 | if (r <= 0) | ||
3829 | break; | ||
3830 | size -= r; | ||
3831 | } | ||
3832 | return size ? -EIO : 0; | ||
3833 | } | ||
3834 | |||
3835 | static int receive_skip(struct drbd_conf *mdev, struct packet_info *pi) | ||
3836 | { | 3917 | { |
3837 | dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", | 3918 | conn_warn(tconn, "skipping unknown optional packet type %d, l: %d!\n", |
3838 | pi->cmd, pi->size); | 3919 | pi->cmd, pi->size); |
3839 | 3920 | ||
3840 | return _tconn_receive_skip(mdev->tconn, pi->size); | 3921 | return ignore_remaining_packet(tconn, pi); |
3841 | } | 3922 | } |
3842 | 3923 | ||
3843 | static int tconn_receive_skip(struct drbd_tconn *tconn, struct packet_info *pi) | 3924 | static int receive_UnplugRemote(struct drbd_tconn *tconn, struct packet_info *pi) |
3844 | { | ||
3845 | conn_warn(tconn, "skipping packet for non existing volume type %d, l: %d!\n", | ||
3846 | pi->cmd, pi->size); | ||
3847 | |||
3848 | return _tconn_receive_skip(tconn, pi->size); | ||
3849 | } | ||
3850 | |||
3851 | static int receive_UnplugRemote(struct drbd_conf *mdev, struct packet_info *pi) | ||
3852 | { | 3925 | { |
3853 | /* Make sure we've acked all the TCP data associated | 3926 | /* Make sure we've acked all the TCP data associated |
3854 | * with the data requests being unplugged */ | 3927 | * with the data requests being unplugged */ |
3855 | drbd_tcp_quickack(mdev->tconn->data.socket); | 3928 | drbd_tcp_quickack(tconn->data.socket); |
3856 | 3929 | ||
3857 | return 0; | 3930 | return 0; |
3858 | } | 3931 | } |
3859 | 3932 | ||
3860 | static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi) | 3933 | static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi) |
3861 | { | 3934 | { |
3862 | struct p_block_desc *p = mdev->tconn->data.rbuf; | 3935 | struct drbd_conf *mdev; |
3936 | struct p_block_desc *p = tconn->data.rbuf; | ||
3937 | |||
3938 | mdev = vnr_to_mdev(tconn, pi->vnr); | ||
3939 | if (!mdev) | ||
3940 | return -EIO; | ||
3863 | 3941 | ||
3864 | switch (mdev->state.conn) { | 3942 | switch (mdev->state.conn) { |
3865 | case C_WF_SYNC_UUID: | 3943 | case C_WF_SYNC_UUID: |
@@ -3879,37 +3957,33 @@ static int receive_out_of_sync(struct drbd_conf *mdev, struct packet_info *pi) | |||
3879 | struct data_cmd { | 3957 | struct data_cmd { |
3880 | int expect_payload; | 3958 | int expect_payload; |
3881 | size_t pkt_size; | 3959 | size_t pkt_size; |
3882 | enum mdev_or_conn fa_type; /* first argument's type */ | 3960 | int (*fn)(struct drbd_tconn *, struct packet_info *); |
3883 | union { | ||
3884 | int (*mdev_fn)(struct drbd_conf *, struct packet_info *); | ||
3885 | int (*conn_fn)(struct drbd_tconn *, struct packet_info *); | ||
3886 | }; | ||
3887 | }; | 3961 | }; |
3888 | 3962 | ||
3889 | static struct data_cmd drbd_cmd_handler[] = { | 3963 | static struct data_cmd drbd_cmd_handler[] = { |
3890 | [P_DATA] = { 1, sizeof(struct p_data), MDEV, { receive_Data } }, | 3964 | [P_DATA] = { 1, sizeof(struct p_data), receive_Data }, |
3891 | [P_DATA_REPLY] = { 1, sizeof(struct p_data), MDEV, { receive_DataReply } }, | 3965 | [P_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply }, |
3892 | [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), MDEV, { receive_RSDataReply } } , | 3966 | [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } , |
3893 | [P_BARRIER] = { 0, sizeof(struct p_barrier), MDEV, { receive_Barrier } } , | 3967 | [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } , |
3894 | [P_BITMAP] = { 1, sizeof(struct p_header), MDEV, { receive_bitmap } } , | 3968 | [P_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } , |
3895 | [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), MDEV, { receive_bitmap } } , | 3969 | [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } , |
3896 | [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), MDEV, { receive_UnplugRemote } }, | 3970 | [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), receive_UnplugRemote }, |
3897 | [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } }, | 3971 | [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, |
3898 | [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } }, | 3972 | [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, |
3899 | [P_SYNC_PARAM] = { 1, sizeof(struct p_header), MDEV, { receive_SyncParam } }, | 3973 | [P_SYNC_PARAM] = { 1, sizeof(struct p_header), receive_SyncParam }, |
3900 | [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), MDEV, { receive_SyncParam } }, | 3974 | [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), receive_SyncParam }, |
3901 | [P_PROTOCOL] = { 1, sizeof(struct p_protocol), CONN, { .conn_fn = receive_protocol } }, | 3975 | [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol }, |
3902 | [P_UUIDS] = { 0, sizeof(struct p_uuids), MDEV, { receive_uuids } }, | 3976 | [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids }, |
3903 | [P_SIZES] = { 0, sizeof(struct p_sizes), MDEV, { receive_sizes } }, | 3977 | [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes }, |
3904 | [P_STATE] = { 0, sizeof(struct p_state), MDEV, { receive_state } }, | 3978 | [P_STATE] = { 0, sizeof(struct p_state), receive_state }, |
3905 | [P_STATE_CHG_REQ] = { 0, sizeof(struct p_req_state), MDEV, { receive_req_state } }, | 3979 | [P_STATE_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_state }, |
3906 | [P_SYNC_UUID] = { 0, sizeof(struct p_rs_uuid), MDEV, { receive_sync_uuid } }, | 3980 | [P_SYNC_UUID] = { 0, sizeof(struct p_rs_uuid), receive_sync_uuid }, |
3907 | [P_OV_REQUEST] = { 0, sizeof(struct p_block_req), MDEV, { receive_DataRequest } }, | 3981 | [P_OV_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, |
3908 | [P_OV_REPLY] = { 1, sizeof(struct p_block_req), MDEV, { receive_DataRequest } }, | 3982 | [P_OV_REPLY] = { 1, sizeof(struct p_block_req), receive_DataRequest }, |
3909 | [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), MDEV, { receive_DataRequest } }, | 3983 | [P_CSUM_RS_REQUEST] = { 1, sizeof(struct p_block_req), receive_DataRequest }, |
3910 | [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), MDEV, { receive_skip } }, | 3984 | [P_DELAY_PROBE] = { 0, sizeof(struct p_delay_probe93), receive_skip }, |
3911 | [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), MDEV, { receive_out_of_sync } }, | 3985 | [P_OUT_OF_SYNC] = { 0, sizeof(struct p_block_desc), receive_out_of_sync }, |
3912 | [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), CONN, { .conn_fn = receive_req_conn_state } }, | 3986 | [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), receive_req_conn_state }, |
3913 | }; | 3987 | }; |
3914 | 3988 | ||
3915 | static void drbdd(struct drbd_tconn *tconn) | 3989 | static void drbdd(struct drbd_tconn *tconn) |
@@ -3927,7 +4001,7 @@ static void drbdd(struct drbd_tconn *tconn) | |||
3927 | goto err_out; | 4001 | goto err_out; |
3928 | 4002 | ||
3929 | cmd = &drbd_cmd_handler[pi.cmd]; | 4003 | cmd = &drbd_cmd_handler[pi.cmd]; |
3930 | if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->mdev_fn)) { | 4004 | if (unlikely(pi.cmd >= ARRAY_SIZE(drbd_cmd_handler) || !cmd->fn)) { |
3931 | conn_err(tconn, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size); | 4005 | conn_err(tconn, "unknown packet type %d, l: %d!\n", pi.cmd, pi.size); |
3932 | goto err_out; | 4006 | goto err_out; |
3933 | } | 4007 | } |
@@ -3945,16 +4019,8 @@ static void drbdd(struct drbd_tconn *tconn) | |||
3945 | pi.size -= shs; | 4019 | pi.size -= shs; |
3946 | } | 4020 | } |
3947 | 4021 | ||
3948 | if (cmd->fa_type == CONN) | 4022 | err = cmd->fn(tconn, &pi); |
3949 | err = cmd->conn_fn(tconn, &pi); | 4023 | if (err) { |
3950 | else { | ||
3951 | struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr); | ||
3952 | err = mdev ? | ||
3953 | cmd->mdev_fn(mdev, &pi) : | ||
3954 | tconn_receive_skip(tconn, &pi); | ||
3955 | } | ||
3956 | |||
3957 | if (unlikely(err)) { | ||
3958 | conn_err(tconn, "error receiving %s, l: %d!\n", | 4024 | conn_err(tconn, "error receiving %s, l: %d!\n", |
3959 | cmdname(pi.cmd), pi.size); | 4025 | cmdname(pi.cmd), pi.size); |
3960 | goto err_out; | 4026 | goto err_out; |