Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346119
b: refs/heads/master
c: 7d4c782
h: refs/heads/master
i:
  346117: 9916ef7
  346115: 12a602d
  346111: d15aff1
v: v3
  • Loading branch information
Andreas Gruenbacher authored and Philipp Reisner committed Nov 8, 2012
1 parent 1ad6f87 commit 5fd5d6d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 91 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 71fc7eedb37585ab2f1bec2e615202908bd4f4b7
refs/heads/master: 7d4c782cbda4af0d7dc39cb8e7d50a927781aa1f
6 changes: 2 additions & 4 deletions trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1775,8 +1775,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)

sock = &mdev->tconn->data;
p = drbd_prepare_command(mdev, sock);
dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_tfm) ?
crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;
dgs = mdev->tconn->integrity_tfm ? crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;

if (!p)
return -EIO;
Expand Down Expand Up @@ -1849,8 +1848,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packet cmd,
sock = &mdev->tconn->data;
p = drbd_prepare_command(mdev, sock);

dgs = (mdev->tconn->agreed_pro_version >= 87 && mdev->tconn->integrity_tfm) ?
crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;
dgs = mdev->tconn->integrity_tfm ? crypto_hash_digestsize(mdev->tconn->integrity_tfm) : 0;

if (!p)
return -EIO;
Expand Down
20 changes: 0 additions & 20 deletions trunk/drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1824,8 +1824,6 @@ struct crypto {
struct crypto_hash *csums_tfm;
struct crypto_hash *cram_hmac_tfm;
struct crypto_hash *integrity_tfm;
void *int_dig_in;
void *int_dig_vv;
};

static int
Expand All @@ -1848,7 +1846,6 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
{
char hmac_name[CRYPTO_MAX_ALG_NAME];
enum drbd_ret_code rv;
int hash_size;

rv = alloc_hash(&crypto->csums_tfm, new_conf->csums_alg,
ERR_CSUMS_ALG);
Expand All @@ -1869,23 +1866,12 @@ alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
rv = alloc_hash(&crypto->cram_hmac_tfm, hmac_name,
ERR_AUTH_ALG);
}
if (crypto->integrity_tfm) {
hash_size = crypto_hash_digestsize(crypto->integrity_tfm);
crypto->int_dig_in = kmalloc(hash_size, GFP_KERNEL);
if (!crypto->int_dig_in)
return ERR_NOMEM;
crypto->int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
if (!crypto->int_dig_vv)
return ERR_NOMEM;
}

return rv;
}

static void free_crypto(struct crypto *crypto)
{
kfree(crypto->int_dig_in);
kfree(crypto->int_dig_vv);
crypto_free_hash(crypto->cram_hmac_tfm);
crypto_free_hash(crypto->integrity_tfm);
crypto_free_hash(crypto->csums_tfm);
Expand Down Expand Up @@ -1974,10 +1960,6 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
crypto.verify_tfm = NULL;
}

kfree(tconn->int_dig_in);
tconn->int_dig_in = crypto.int_dig_in;
kfree(tconn->int_dig_vv);
tconn->int_dig_vv = crypto.int_dig_vv;
crypto_free_hash(tconn->integrity_tfm);
tconn->integrity_tfm = crypto.integrity_tfm;
if (tconn->cstate >= C_WF_REPORT_PARAMS && tconn->agreed_pro_version >= 100)
Expand Down Expand Up @@ -2094,8 +2076,6 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
rcu_assign_pointer(tconn->net_conf, new_conf);

conn_free_crypto(tconn);
tconn->int_dig_in = crypto.int_dig_in;
tconn->int_dig_vv = crypto.int_dig_vv;
tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
tconn->integrity_tfm = crypto.integrity_tfm;
tconn->csums_tfm = crypto.csums_tfm;
Expand Down
130 changes: 64 additions & 66 deletions trunk/drivers/block/drbd/drbd_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3024,72 +3024,7 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)
integrity_alg[SHARED_SECRET_MAX - 1] = 0;
}

if (pi->cmd == P_PROTOCOL_UPDATE) {
if (integrity_alg[0]) {
int hash_size;

/*
* We can only change the peer data integrity algorithm
* here. Changing our own data integrity algorithm
* requires that we send a P_PROTOCOL_UPDATE packet at
* the same time; otherwise, the peer has no way to
* tell between which packets the algorithm should
* change.
*/

peer_integrity_tfm = crypto_alloc_hash(integrity_alg, 0, CRYPTO_ALG_ASYNC);
if (!peer_integrity_tfm) {
conn_err(tconn, "peer data-integrity-alg %s not supported\n",
integrity_alg);
goto disconnect;
}

hash_size = crypto_hash_digestsize(peer_integrity_tfm);
int_dig_in = kmalloc(hash_size, GFP_KERNEL);
int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
if (!(int_dig_in && int_dig_vv)) {
conn_err(tconn, "Allocation of buffers for data integrity checking failed\n");
goto disconnect;
}
}

new_net_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL);
if (!new_net_conf) {
conn_err(tconn, "Allocation of new net_conf failed\n");
goto disconnect;
}

mutex_lock(&tconn->data.mutex);
mutex_lock(&tconn->conf_update);
old_net_conf = tconn->net_conf;
*new_net_conf = *old_net_conf;

new_net_conf->wire_protocol = p_proto;
new_net_conf->after_sb_0p = convert_after_sb(p_after_sb_0p);
new_net_conf->after_sb_1p = convert_after_sb(p_after_sb_1p);
new_net_conf->after_sb_2p = convert_after_sb(p_after_sb_2p);
new_net_conf->two_primaries = p_two_primaries;
strcpy(new_net_conf->integrity_alg, integrity_alg);
new_net_conf->integrity_alg_len = strlen(integrity_alg) + 1;

rcu_assign_pointer(tconn->net_conf, new_net_conf);
mutex_unlock(&tconn->conf_update);
mutex_unlock(&tconn->data.mutex);

crypto_free_hash(tconn->peer_integrity_tfm);
kfree(tconn->int_dig_in);
kfree(tconn->int_dig_vv);
tconn->peer_integrity_tfm = peer_integrity_tfm;
tconn->int_dig_in = int_dig_in;
tconn->int_dig_vv = int_dig_vv;

if (strcmp(old_net_conf->integrity_alg, integrity_alg))
conn_info(tconn, "peer data-integrity-alg: %s\n",
integrity_alg[0] ? integrity_alg : "(none)");

synchronize_rcu();
kfree(old_net_conf);
} else {
if (pi->cmd != P_PROTOCOL_UPDATE) {
clear_bit(CONN_DRY_RUN, &tconn->flags);

if (cf & CF_DRY_RUN)
Expand Down Expand Up @@ -3135,6 +3070,69 @@ static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi)

rcu_read_unlock();
}

if (integrity_alg[0]) {
int hash_size;

/*
* We can only change the peer data integrity algorithm
* here. Changing our own data integrity algorithm
* requires that we send a P_PROTOCOL_UPDATE packet at
* the same time; otherwise, the peer has no way to
* tell between which packets the algorithm should
* change.
*/

peer_integrity_tfm = crypto_alloc_hash(integrity_alg, 0, CRYPTO_ALG_ASYNC);
if (!peer_integrity_tfm) {
conn_err(tconn, "peer data-integrity-alg %s not supported\n",
integrity_alg);
goto disconnect;
}

hash_size = crypto_hash_digestsize(peer_integrity_tfm);
int_dig_in = kmalloc(hash_size, GFP_KERNEL);
int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
if (!(int_dig_in && int_dig_vv)) {
conn_err(tconn, "Allocation of buffers for data integrity checking failed\n");
goto disconnect;
}
}

new_net_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL);
if (!new_net_conf) {
conn_err(tconn, "Allocation of new net_conf failed\n");
goto disconnect;
}

mutex_lock(&tconn->data.mutex);
mutex_lock(&tconn->conf_update);
old_net_conf = tconn->net_conf;
*new_net_conf = *old_net_conf;

new_net_conf->wire_protocol = p_proto;
new_net_conf->after_sb_0p = convert_after_sb(p_after_sb_0p);
new_net_conf->after_sb_1p = convert_after_sb(p_after_sb_1p);
new_net_conf->after_sb_2p = convert_after_sb(p_after_sb_2p);
new_net_conf->two_primaries = p_two_primaries;

rcu_assign_pointer(tconn->net_conf, new_net_conf);
mutex_unlock(&tconn->conf_update);
mutex_unlock(&tconn->data.mutex);

crypto_free_hash(tconn->peer_integrity_tfm);
kfree(tconn->int_dig_in);
kfree(tconn->int_dig_vv);
tconn->peer_integrity_tfm = peer_integrity_tfm;
tconn->int_dig_in = int_dig_in;
tconn->int_dig_vv = int_dig_vv;

if (strcmp(old_net_conf->integrity_alg, integrity_alg))
conn_info(tconn, "peer data-integrity-alg: %s\n",
integrity_alg[0] ? integrity_alg : "(none)");

synchronize_rcu();
kfree(old_net_conf);
return 0;

disconnect_rcu_unlock:
Expand Down

0 comments on commit 5fd5d6d

Please sign in to comment.