Commit 82bc0194 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner

drbd: Make all command handlers return 0 upon success and an error code otherwise

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent c6967746
...@@ -1246,7 +1246,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1246,7 +1246,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
switch (mdev->write_ordering) { switch (mdev->write_ordering) {
case WO_none: case WO_none:
if (rv == FE_RECYCLED) if (rv == FE_RECYCLED)
return true; return 0;
/* receiver context, in the writeout path of the other node. /* receiver context, in the writeout path of the other node.
* avoid potential distributed deadlock */ * avoid potential distributed deadlock */
...@@ -1274,10 +1274,10 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1274,10 +1274,10 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
D_ASSERT(atomic_read(&epoch->active) == 0); D_ASSERT(atomic_read(&epoch->active) == 0);
D_ASSERT(epoch->flags == 0); D_ASSERT(epoch->flags == 0);
return true; return 0;
default: default:
dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering); dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering);
return false; return -EIO;
} }
epoch->flags = 0; epoch->flags = 0;
...@@ -1295,7 +1295,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1295,7 +1295,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
} }
spin_unlock(&mdev->epoch_lock); spin_unlock(&mdev->epoch_lock);
return true; return 0;
} }
/* used from receive_RSDataReply (recv_resync_read) /* used from receive_RSDataReply (recv_resync_read)
...@@ -1564,7 +1564,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1564,7 +1564,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
{ {
struct drbd_request *req; struct drbd_request *req;
sector_t sector; sector_t sector;
int ok; int err;
struct p_data *p = &mdev->tconn->data.rbuf.data; struct p_data *p = &mdev->tconn->data.rbuf.data;
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
...@@ -1573,27 +1573,26 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1573,27 +1573,26 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
req = find_request(mdev, &mdev->read_requests, p->block_id, sector, false, __func__); req = find_request(mdev, &mdev->read_requests, p->block_id, sector, false, __func__);
spin_unlock_irq(&mdev->tconn->req_lock); spin_unlock_irq(&mdev->tconn->req_lock);
if (unlikely(!req)) if (unlikely(!req))
return false; return -EIO;
/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
* special casing it there for the various failure cases. * special casing it there for the various failure cases.
* still no race with drbd_fail_pending_reads */ * still no race with drbd_fail_pending_reads */
ok = !recv_dless_read(mdev, req, sector, data_size); err = recv_dless_read(mdev, req, sector, data_size);
if (!err)
if (ok)
req_mod(req, DATA_RECEIVED); req_mod(req, DATA_RECEIVED);
/* else: nothing. handled from drbd_disconnect... /* else: nothing. handled from drbd_disconnect...
* I don't think we may complete this just yet * I don't think we may complete this just yet
* in case we are "on-disconnect: freeze" */ * in case we are "on-disconnect: freeze" */
return ok; return err;
} }
static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int data_size) unsigned int data_size)
{ {
sector_t sector; sector_t sector;
int ok; int err;
struct p_data *p = &mdev->tconn->data.rbuf.data; struct p_data *p = &mdev->tconn->data.rbuf.data;
sector = be64_to_cpu(p->sector); sector = be64_to_cpu(p->sector);
...@@ -1603,19 +1602,19 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1603,19 +1602,19 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd,
/* data is submitted to disk within recv_resync_read. /* data is submitted to disk within recv_resync_read.
* corresponding put_ldev done below on error, * corresponding put_ldev done below on error,
* or in drbd_peer_request_endio. */ * or in drbd_peer_request_endio. */
ok = !recv_resync_read(mdev, sector, data_size); err = recv_resync_read(mdev, sector, data_size);
} else { } else {
if (__ratelimit(&drbd_ratelimit_state)) if (__ratelimit(&drbd_ratelimit_state))
dev_err(DEV, "Can not write resync data to local disk.\n"); dev_err(DEV, "Can not write resync data to local disk.\n");
ok = !drbd_drain_block(mdev, data_size); err = drbd_drain_block(mdev, data_size);
drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size); drbd_send_ack_dp(mdev, P_NEG_ACK, p, data_size);
} }
atomic_add(data_size >> 9, &mdev->rs_sect_in); atomic_add(data_size >> 9, &mdev->rs_sect_in);
return ok; return err;
} }
static int w_restart_write(struct drbd_work *w, int cancel) static int w_restart_write(struct drbd_work *w, int cancel)
...@@ -1989,12 +1988,16 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -1989,12 +1988,16 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
u32 dp_flags; u32 dp_flags;
int err; int err;
if (!get_ldev(mdev)) { if (!get_ldev(mdev)) {
int err2;
err = wait_for_and_update_peer_seq(mdev, peer_seq); 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, data_size);
atomic_inc(&mdev->current_epoch->epoch_size); atomic_inc(&mdev->current_epoch->epoch_size);
return !drbd_drain_block(mdev, data_size) && err == 0; err2 = drbd_drain_block(mdev, data_size);
if (!err)
err = err2;
return err;
} }
/* /*
...@@ -2007,7 +2010,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2007,7 +2010,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
peer_req = read_in_block(mdev, p->block_id, sector, data_size); peer_req = read_in_block(mdev, p->block_id, sector, data_size);
if (!peer_req) { if (!peer_req) {
put_ldev(mdev); put_ldev(mdev);
return false; return -EIO;
} }
peer_req->w.cb = e_end_block; peer_req->w.cb = e_end_block;
...@@ -2034,7 +2037,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2034,7 +2037,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
spin_unlock_irq(&mdev->tconn->req_lock); spin_unlock_irq(&mdev->tconn->req_lock);
if (err == -ENOENT) { if (err == -ENOENT) {
put_ldev(mdev); put_ldev(mdev);
return true; return 0;
} }
goto out_interrupted; goto out_interrupted;
} }
...@@ -2067,8 +2070,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2067,8 +2070,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_al_begin_io(mdev, peer_req->i.sector); drbd_al_begin_io(mdev, peer_req->i.sector);
} }
if (drbd_submit_peer_request(mdev, peer_req, rw, DRBD_FAULT_DT_WR) == 0) err = drbd_submit_peer_request(mdev, peer_req, rw, DRBD_FAULT_DT_WR);
return true; if (!err)
return 0;
/* don't care for the reason here */ /* don't care for the reason here */
dev_err(DEV, "submit failed, triggering re-connect\n"); dev_err(DEV, "submit failed, triggering re-connect\n");
...@@ -2083,7 +2087,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2083,7 +2087,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_may_finish_epoch(mdev, peer_req->epoch, EV_PUT + EV_CLEANUP); drbd_may_finish_epoch(mdev, peer_req->epoch, EV_PUT + EV_CLEANUP);
put_ldev(mdev); put_ldev(mdev);
drbd_free_ee(mdev, peer_req); drbd_free_ee(mdev, peer_req);
return false; return err;
} }
/* We may throttle resync, if the lower device seems to be busy, /* We may throttle resync, if the lower device seems to be busy,
...@@ -2170,12 +2174,12 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2170,12 +2174,12 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) { if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) {
dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
(unsigned long long)sector, size); (unsigned long long)sector, size);
return false; return -EINVAL;
} }
if (sector + (size>>9) > capacity) { if (sector + (size>>9) > capacity) {
dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
(unsigned long long)sector, size); (unsigned long long)sector, size);
return false; return -EINVAL;
} }
if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) { if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) {
...@@ -2203,7 +2207,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2203,7 +2207,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
"no local data.\n"); "no local data.\n");
/* drain possibly payload */ /* drain possibly payload */
return !drbd_drain_block(mdev, digest_size); return drbd_drain_block(mdev, digest_size);
} }
/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
...@@ -2212,7 +2216,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2212,7 +2216,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
peer_req = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO); peer_req = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO);
if (!peer_req) { if (!peer_req) {
put_ldev(mdev); put_ldev(mdev);
return false; return -ENOMEM;
} }
switch (cmd) { switch (cmd) {
...@@ -2325,7 +2329,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2325,7 +2329,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
spin_unlock_irq(&mdev->tconn->req_lock); spin_unlock_irq(&mdev->tconn->req_lock);
if (drbd_submit_peer_request(mdev, peer_req, READ, fault_type) == 0) if (drbd_submit_peer_request(mdev, peer_req, READ, fault_type) == 0)
return true; return 0;
/* don't care for the reason here */ /* don't care for the reason here */
dev_err(DEV, "submit failed, triggering re-connect\n"); dev_err(DEV, "submit failed, triggering re-connect\n");
...@@ -2337,7 +2341,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2337,7 +2341,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd,
out_free_e: out_free_e:
put_ldev(mdev); put_ldev(mdev);
drbd_free_ee(mdev, peer_req); drbd_free_ee(mdev, peer_req);
return false; return -EIO;
} }
static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local) static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
...@@ -2932,9 +2936,11 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd, ...@@ -2932,9 +2936,11 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
if (tconn->agreed_pro_version >= 87) { if (tconn->agreed_pro_version >= 87) {
unsigned char *my_alg = tconn->net_conf->integrity_alg; unsigned char *my_alg = tconn->net_conf->integrity_alg;
int err;
if (drbd_recv(tconn, p_integrity_alg, data_size) != data_size) err = drbd_recv_all(tconn, p_integrity_alg, data_size);
return false; if (err)
return err;
p_integrity_alg[SHARED_SECRET_MAX-1] = 0; p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
if (strcmp(p_integrity_alg, my_alg)) { if (strcmp(p_integrity_alg, my_alg)) {
...@@ -2945,11 +2951,11 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd, ...@@ -2945,11 +2951,11 @@ static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd,
my_alg[0] ? my_alg : (unsigned char *)"<not-used>"); my_alg[0] ? my_alg : (unsigned char *)"<not-used>");
} }
return true; return 0;
disconnect: disconnect:
conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(tconn, NS(conn, C_DISCONNECTING), CS_HARD);
return false; return -EIO;
} }
/* helper function /* helper function
...@@ -2982,7 +2988,6 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev, ...@@ -2982,7 +2988,6 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
unsigned int packet_size) unsigned int packet_size)
{ {
int ok = true;
struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95; struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95;
unsigned int header_size, data_size, exp_max_sz; unsigned int header_size, data_size, exp_max_sz;
struct crypto_hash *verify_tfm = NULL; struct crypto_hash *verify_tfm = NULL;
...@@ -2990,6 +2995,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -2990,6 +2995,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
const int apv = mdev->tconn->agreed_pro_version; const int apv = mdev->tconn->agreed_pro_version;
int *rs_plan_s = NULL; int *rs_plan_s = NULL;
int fifo_size = 0; int fifo_size = 0;
int err;
exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param) exp_max_sz = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param) : apv == 88 ? sizeof(struct p_rs_param)
...@@ -3000,7 +3006,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3000,7 +3006,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
if (packet_size > exp_max_sz) { if (packet_size > exp_max_sz) {
dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n", dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n",
packet_size, exp_max_sz); packet_size, exp_max_sz);
return false; return -EIO;
} }
if (apv <= 88) { if (apv <= 88) {
...@@ -3019,8 +3025,9 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3019,8 +3025,9 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
/* initialize verify_alg and csums_alg */ /* initialize verify_alg and csums_alg */
memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
if (drbd_recv(mdev->tconn, &p->head.payload, header_size) != header_size) err = drbd_recv_all(mdev->tconn, &p->head.payload, header_size);
return false; if (err)
return err;
if (get_ldev(mdev)) { if (get_ldev(mdev)) {
mdev->ldev->dc.resync_rate = be32_to_cpu(p->rate); mdev->ldev->dc.resync_rate = be32_to_cpu(p->rate);
...@@ -3033,11 +3040,12 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3033,11 +3040,12 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
dev_err(DEV, "verify-alg too long, " dev_err(DEV, "verify-alg too long, "
"peer wants %u, accepting only %u byte\n", "peer wants %u, accepting only %u byte\n",
data_size, SHARED_SECRET_MAX); data_size, SHARED_SECRET_MAX);
return false; return -EIO;
} }
if (drbd_recv(mdev->tconn, p->verify_alg, data_size) != data_size) err = drbd_recv_all(mdev->tconn, p->verify_alg, data_size);
return false; if (err)
return err;
/* we expect NUL terminated string */ /* we expect NUL terminated string */
/* but just in case someone tries to be evil */ /* but just in case someone tries to be evil */
...@@ -3124,8 +3132,8 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3124,8 +3132,8 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
} }
spin_unlock(&mdev->peer_seq_lock); spin_unlock(&mdev->peer_seq_lock);
} }
return 0;
return ok;
disconnect: disconnect:
/* just for completeness: actually not needed, /* just for completeness: actually not needed,
* as this is not reached if csums_tfm was ok. */ * as this is not reached if csums_tfm was ok. */
...@@ -3133,7 +3141,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3133,7 +3141,7 @@ static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd,
/* but free the verify_tfm again, if csums_tfm did not work out */ /* but free the verify_tfm again, if csums_tfm did not work out */
crypto_free_hash(verify_tfm); crypto_free_hash(verify_tfm);
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
return false; return -EIO;
} }
/* warn if the arguments differ by more than 12.5% */ /* warn if the arguments differ by more than 12.5% */
...@@ -3195,7 +3203,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3195,7 +3203,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
mdev->ldev->dc.disk_size = my_usize; mdev->ldev->dc.disk_size = my_usize;
put_ldev(mdev); put_ldev(mdev);
return false; return -EIO;
} }
put_ldev(mdev); put_ldev(mdev);
} }
...@@ -3205,7 +3213,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3205,7 +3213,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
dd = drbd_determine_dev_size(mdev, ddsf); dd = drbd_determine_dev_size(mdev, ddsf);
put_ldev(mdev); put_ldev(mdev);
if (dd == dev_size_error) if (dd == dev_size_error)
return false; return -EIO;
drbd_md_sync(mdev); drbd_md_sync(mdev);
} else { } else {
/* I am diskless, need to accept the peer's size. */ /* I am diskless, need to accept the peer's size. */
...@@ -3244,7 +3252,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3244,7 +3252,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd,
} }
} }
return true; return 0;
} }
static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
...@@ -3269,7 +3277,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3269,7 +3277,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
dev_err(DEV, "Can only connect to data with current UUID=%016llX\n", dev_err(DEV, "Can only connect to data with current UUID=%016llX\n",
(unsigned long long)mdev->ed_uuid); (unsigned long long)mdev->ed_uuid);
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
return false; return -EIO;
} }
if (get_ldev(mdev)) { if (get_ldev(mdev)) {
...@@ -3310,7 +3318,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3310,7 +3318,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd,
if (updated_uuids) if (updated_uuids)
drbd_print_uuids(mdev, "receiver updated UUIDs to"); drbd_print_uuids(mdev, "receiver updated UUIDs to");
return true; return 0;
} }
/** /**
...@@ -3356,7 +3364,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3356,7 +3364,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
if (test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags) && if (test_bit(DISCARD_CONCURRENT, &mdev->tconn->flags) &&
mutex_is_locked(mdev->state_mutex)) { mutex_is_locked(mdev->state_mutex)) {
drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG); drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG);
return true; return 0;
} }
mask = convert_state(mask); mask = convert_state(mask);
...@@ -3367,7 +3375,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3367,7 +3375,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_md_sync(mdev); drbd_md_sync(mdev);
return true; return 0;
} }
static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd, static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd,
...@@ -3383,7 +3391,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd ...@@ -3383,7 +3391,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd
if (test_bit(DISCARD_CONCURRENT, &tconn->flags) && if (test_bit(DISCARD_CONCURRENT, &tconn->flags) &&
mutex_is_locked(&tconn->cstate_mutex)) { mutex_is_locked(&tconn->cstate_mutex)) {
conn_send_sr_reply(tconn, SS_CONCURRENT_ST_CHG); conn_send_sr_reply(tconn, SS_CONCURRENT_ST_CHG);
return true; return 0;
} }
mask = convert_state(mask); mask = convert_state(mask);
...@@ -3392,7 +3400,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd ...@@ -3392,7 +3400,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd
rv = conn_request_state(tconn, mask, val, CS_VERBOSE | CS_LOCAL_ONLY); rv = conn_request_state(tconn, mask, val, CS_VERBOSE | CS_LOCAL_ONLY);
conn_send_sr_reply(tconn, rv); conn_send_sr_reply(tconn, rv);
return true; return 0;
} }
static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
...@@ -3438,7 +3446,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3438,7 +3446,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
peer_state.conn == C_CONNECTED) { peer_state.conn == C_CONNECTED) {
if (drbd_bm_total_weight(mdev) <= mdev->rs_failed) if (drbd_bm_total_weight(mdev) <= mdev->rs_failed)
drbd_resync_finished(mdev); drbd_resync_finished(mdev);
return true; return 0;
} }
} }
...@@ -3491,10 +3499,10 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3491,10 +3499,10 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
real_peer_disk = D_DISKLESS; real_peer_disk = D_DISKLESS;
} else { } else {
if (test_and_clear_bit(CONN_DRY_RUN, &mdev->tconn->flags)) if (test_and_clear_bit(CONN_DRY_RUN, &mdev->tconn->flags))
return false; return -EIO;
D_ASSERT(os.conn == C_WF_REPORT_PARAMS); D_ASSERT(os.conn == C_WF_REPORT_PARAMS);
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
return false; return -EIO;
} }
} }
} }
...@@ -3519,7 +3527,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3519,7 +3527,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_uuid_new_current(mdev); drbd_uuid_new_current(mdev);
clear_bit(NEW_CUR_UUID, &mdev->flags); clear_bit(NEW_CUR_UUID, &mdev->flags);
conn_request_state(mdev->tconn, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD); conn_request_state(mdev->tconn, NS2(conn, C_PROTOCOL_ERROR, susp, 0), CS_HARD);
return false; return -EIO;
} }
rv = _drbd_set_state(mdev, ns, cs_flags, NULL); rv = _drbd_set_state(mdev, ns, cs_flags, NULL);
ns = mdev->state; ns = mdev->state;
...@@ -3527,7 +3535,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3527,7 +3535,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
if (rv < SS_SUCCESS) { if (rv < SS_SUCCESS) {
conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD); conn_request_state(mdev->tconn, NS(conn, C_DISCONNECTING), CS_HARD);
return false; return -EIO;
} }
if (os.conn > C_WF_REPORT_PARAMS) { if (os.conn > C_WF_REPORT_PARAMS) {
...@@ -3545,7 +3553,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3545,7 +3553,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_md_sync(mdev); /* update connected indicator, la_size, ... */ drbd_md_sync(mdev); /* update connected indicator, la_size, ... */
return true; return 0;
} }
static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
...@@ -3574,7 +3582,7 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3574,7 +3582,7 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd,
} else } else
dev_err(DEV, "Ignoring SyncUUID packet!\n"); dev_err(DEV, "Ignoring SyncUUID packet!\n");
return true; return 0;
} }
/** /**
...@@ -3597,12 +3605,9 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size, ...@@ -3597,12 +3605,9 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int data_size,
} }
if (want == 0) if (want == 0)
return 0; return 0;
err = drbd_recv(mdev->tconn, buffer, want); err = drbd_recv_all(mdev->tconn, buffer, want);
if (err != want) { if (err)
if (err >= 0)
err = -EIO;
return err; return err;
}
drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer); drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer);
...@@ -3751,7 +3756,6 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3751,7 +3756,6 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
struct bm_xfer_ctx c; struct bm_xfer_ctx c;
void *buffer; void *buffer;
int err; int err;
int ok = false;
struct p_header *h = &mdev->tconn->data.rbuf.header; struct p_header *h = &mdev->tconn->data.rbuf.header;
struct packet_info pi; struct packet_info pi;
...@@ -3764,6 +3768,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3764,6 +3768,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
buffer = (unsigned long *) __get_free_page(GFP_NOIO); buffer = (unsigned long *) __get_free_page(GFP_NOIO);
if (!buffer) { if (!buffer) {
dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__); dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
err = -ENOMEM;
goto out; goto out;
} }
...@@ -3782,20 +3787,24 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3782,20 +3787,24 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
if (data_size > BM_PACKET_PAYLOAD_BYTES) { if (data_size > BM_PACKET_PAYLOAD_BYTES) {
dev_err(DEV, "ReportCBitmap packet too large\n"); dev_err(DEV, "ReportCBitmap packet too large\n");
err = -EIO;
goto out; goto out;
} }
/* use the page buff */ /* use the page buff */
p = buffer; p = buffer;
memcpy(p, h, sizeof(*h)); memcpy(p, h, sizeof(*h));
if (drbd_recv(mdev->tconn, p->head.payload, data_size) != data_size) err = drbd_recv_all(mdev->tconn, p->head.payload, data_size);
goto out; if (err)
goto out;
if (data_size <= (sizeof(*p) - sizeof(p->head))) { if (data_size <= (sizeof(*p) - sizeof(p->head))) {
dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size); dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", data_size);
err = -EIO;
goto out; goto out;
} }
err = decode_bitmap_c(mdev, p, &c, data_size); err = decode_bitmap_c(mdev, p, &c, data_size);
} else { } 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)", cmd);
err = -EIO;
goto out; goto out;
} }
...@@ -3807,7 +3816,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3807,7 +3816,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
goto out; goto out;
break; break;
} }
if (drbd_recv_header(mdev->tconn, &pi)) err = drbd_recv_header(mdev->tconn, &pi);
if (err)
goto out; goto out;
cmd = pi.cmd; cmd = pi.cmd;
data_size = pi.size; data_size = pi.size;
...@@ -3818,8 +3828,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3818,8 +3828,8 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
if (mdev->state.conn == C_WF_BITMAP_T) { if (mdev->state.conn == C_WF_BITMAP_T) {
enum drbd_state_rv rv; enum drbd_state_rv rv;
ok = !drbd_send_bitmap(mdev); err = drbd_send_bitmap(mdev);
if (!ok) if (err)
goto out; goto out;
/* Omit CS_ORDERED with this state transition to avoid deadlocks. */ /* Omit CS_ORDERED with this state transition to avoid deadlocks. */
rv = _drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE); rv = _drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
...@@ -3830,14 +3840,14 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3830,14 +3840,14 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd,
dev_info(DEV, "unexpected cstate (%s) in receive_bitmap\n", dev_info(DEV, "unexpected cstate (%s) in receive_bitmap\n",
drbd_conn_str(mdev->state.conn)); drbd_conn_str(mdev->state.conn));
} }
err = 0;
ok = true;
out: out:
drbd_bm_unlock(mdev); drbd_bm_unlock(mdev);
if (ok && mdev->state.conn == C_WF_BITMAP_S) if (!err && mdev->state.conn == C_WF_BITMAP_S)
drbd_start_resync(mdev, C_SYNC_SOURCE); drbd_start_resync(mdev, C_SYNC_SOURCE);
free_page((unsigned long) buffer); free_page((unsigned long) buffer);
return ok; return err;
} }
static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size) static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size)
...@@ -3854,7 +3864,7 @@ static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size) ...@@ -3854,7 +3864,7 @@ static int _tconn_receive_skip(struct drbd_tconn *tconn, unsigned int data_size)
break; break;
size -= r; size -= r;
} }
return size == 0; return size ? -EIO : 0;
} }
static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_skip(struct drbd_conf *mdev, enum drbd_packet cmd,
...@@ -3881,7 +3891,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3881,7 +3891,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd,
* with the data requests being unplugged */ * with the data requests being unplugged */
drbd_tcp_quickack(mdev->tconn->data.socket); drbd_tcp_quickack(mdev->tconn->data.socket);
return true; return 0;
} }
static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
...@@ -3901,7 +3911,7 @@ static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd, ...@@ -3901,7 +3911,7 @@ static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd,
drbd_set_out_of_sync(mdev, be64_to_cpu(p->sector), be32_to_cpu(p->blksize)); drbd_set_out_of_sync(mdev, be64_to_cpu(p->sector), be32_to_cpu(p->blksize));
return true; return 0;
} }
struct data_cmd { struct data_cmd {
...@@ -3954,7 +3964,7 @@ static void drbdd(struct drbd_tconn *tconn) ...@@ -3954,7 +3964,7 @@ static void drbdd(struct drbd_tconn *tconn)
struct p_header *header = &tconn->data.rbuf.header; struct p_header *header = &tconn->data.rbuf.header;
struct packet_info pi; struct packet_info pi;
size_t shs; /* sub header size */ size_t shs; /* sub header size */
int rv; int err;
while (get_t_state(&tconn->receiver) == RUNNING) { while (get_t_state(&tconn->receiver) == RUNNING) {
drbd_thread_current_set_cpu(&tconn->receiver); drbd_thread_current_set_cpu(&tconn->receiver);
...@@ -3974,34 +3984,33 @@ static void drbdd(struct drbd_tconn *tconn) ...@@ -3974,34 +3984,33 @@ static void drbdd(struct drbd_tconn *tconn)
} }
if (shs) { if (shs) {
rv = drbd_recv(tconn, &header->payload, shs); err = drbd_recv_all(tconn, &header->payload, shs);
if (unlikely(rv != shs)) { if (err) {
if (!signal_pending(current)) if (!signal_pending(current))
conn_warn(tconn, "short read while reading sub header: rv=%d\n", rv); conn_warn(tconn, "short read while reading sub header: rv=%d\n", err);
goto err_out; goto err_out;
} }
} }
if (drbd_cmd_handler[pi.cmd].fa_type == CONN) { if (drbd_cmd_handler[pi.cmd].fa_type == CONN) {
rv = drbd_cmd_handler[pi.cmd].conn_fn(tconn, pi.cmd, pi.size - shs); err = drbd_cmd_handler[pi.cmd].conn_fn(tconn, pi.cmd, pi.size - shs);
} else { } else {
struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr); struct drbd_conf *mdev = vnr_to_mdev(tconn, pi.vnr);
rv = mdev ? err = mdev ?
drbd_cmd_handler[pi.cmd].mdev_fn(mdev, pi.cmd, pi.size - shs) : drbd_cmd_handler[pi.cmd].mdev_fn(mdev, pi.cmd, pi.size - shs) :
tconn_receive_skip(tconn, pi.cmd, pi.size - shs); tconn_receive_skip(tconn, pi.cmd, pi.size - shs);
} }
if (unlikely(!rv)) { if (unlikely(err)) {
conn_err(tconn, "error receiving %s, l: %d!\n", conn_err(tconn, "error receiving %s, l: %d!\n",
cmdname(pi.cmd), pi.size); cmdname(pi.cmd), pi.size);
goto err_out; goto err_out;
} }
} }
return;
if (0) { err_out:
err_out: conn_request_state(tconn, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
conn_request_state(tconn, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
}
} }
void conn_flush_workqueue(struct drbd_tconn *tconn) void conn_flush_workqueue(struct drbd_tconn *tconn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment