[DRBD-cvs] svn commit by phil - r3052 - in branches/drbd-8.2/drbd:
. linux - More unfinished work on the integrity check sum feature
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Wed Sep 5 17:04:02 CEST 2007
Author: phil
Date: 2007-09-05 17:03:58 +0200 (Wed, 05 Sep 2007)
New Revision: 3052
Modified:
branches/drbd-8.2/drbd/drbd_int.h
branches/drbd-8.2/drbd/drbd_main.c
branches/drbd-8.2/drbd/drbd_nl.c
branches/drbd-8.2/drbd/drbd_receiver.c
branches/drbd-8.2/drbd/drbd_worker.c
branches/drbd-8.2/drbd/linux/drbd.h
Log:
More unfinished work on the integrity check sum feature...
Modified: branches/drbd-8.2/drbd/drbd_int.h
===================================================================
--- branches/drbd-8.2/drbd/drbd_int.h 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/drbd_int.h 2007-09-05 15:03:58 UTC (rev 3052)
@@ -347,7 +347,6 @@
[BarrierAck] = "BarrierAck",
[StateChgRequest] = "StateChgRequest",
[StateChgReply] = "StateChgReply",
- [IntegrityAlg] = "IntegrityAlg"
};
if (Data > cmd || cmd >= MAX_CMD) {
@@ -489,6 +488,7 @@
u32 after_sb_2p;
u32 want_lose;
u32 two_primaries;
+ char integrity_alg[0]; /* Since protocol version 87 and higher. */
} __attribute((packed));
struct Drbd_GenCnt_Packet {
@@ -876,6 +876,8 @@
int al_tr_cycle;
int al_tr_pos; /* position of the next transaction in the journal */
struct crypto_hash *cram_hmac_tfm;
+ struct crypto_hash *integrity_tfm;
+ void *integrity_digest;
wait_queue_head_t seq_wait;
atomic_t packet_seq;
unsigned int peer_seq;
Modified: branches/drbd-8.2/drbd/drbd_main.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_main.c 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/drbd_main.c 2007-09-05 15:03:58 UTC (rev 3052)
@@ -1312,25 +1312,30 @@
int drbd_send_protocol(struct drbd_conf *mdev)
{
- int rv;
- struct Drbd_Protocol_Packet p;
+ struct Drbd_Protocol_Packet *p;
+ int size,rv;
- p.protocol = cpu_to_be32(mdev->net_conf->wire_protocol);
- p.after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p);
- p.after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p);
- p.after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p);
- p.want_lose = cpu_to_be32(mdev->net_conf->want_lose);
- p.two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
+ size = sizeof(struct Drbd_Protocol_Packet);
- if (mdev->agreed_pro_version >= 87) {
- rv = drbd_send_cmd2(mdev, USE_DATA_SOCKET, ReportProtocol,
- (struct Drbd_Header *)&p, sizeof(p),
- mdev->net_conf->integrity_alg,
- strlen(mdev->net_conf->integrity_alg));
- } else {
- rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportProtocol,
- (struct Drbd_Header *)&p, sizeof(p));
- }
+ if (mdev->agreed_pro_version >= 87)
+ size += strlen(mdev->net_conf->integrity_alg) + 1;
+
+ if ((p = kmalloc(size, GFP_KERNEL)) == NULL)
+ return 0;
+
+ p->protocol = cpu_to_be32(mdev->net_conf->wire_protocol);
+ p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p);
+ p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p);
+ p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p);
+ p->want_lose = cpu_to_be32(mdev->net_conf->want_lose);
+ p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
+
+ if (mdev->agreed_pro_version >= 87)
+ strcpy(p->integrity_alg,mdev->net_conf->integrity_alg);
+
+ rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportProtocol,
+ (struct Drbd_Header *)p, size);
+ kfree(p);
return rv;
}
@@ -1724,14 +1729,19 @@
int ok = 1;
struct Drbd_Data_Packet p;
unsigned int dp_flags = 0;
+ void *dgb;
+ int dgs;
if (!drbd_get_data_sock(mdev))
return 0;
+ dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->integrity_tfm) : 0;
+
p.head.magic = BE_DRBD_MAGIC;
p.head.command = cpu_to_be16(Data);
- p.head.length = cpu_to_be16(sizeof(p)
- -sizeof(struct Drbd_Header)+req->size);
+ p.head.length = cpu_to_be16( sizeof(p)
+ -sizeof(struct Drbd_Header)+dgs+req->size);
p.sector = cpu_to_be64(req->sector);
p.block_id = (unsigned long)req;
@@ -1751,6 +1761,11 @@
set_bit(UNPLUG_REMOTE, &mdev->flags);
ok = (sizeof(p) ==
drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE));
+ if (ok && dgs) {
+ dgb = mdev->integrity_digest;
+ drbd_csum(mdev, mdev->integrity_tfm, req->master_bio, dgb);
+ ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
+ }
if (ok) {
if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
ok = _drbd_send_bio(mdev, req->master_bio);
@@ -1771,11 +1786,16 @@
{
int ok;
struct Drbd_Data_Packet p;
+ void *dgb;
+ int dgs;
+ dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->integrity_tfm) : 0;
+
p.head.magic = BE_DRBD_MAGIC;
p.head.command = cpu_to_be16(cmd);
p.head.length = cpu_to_be16( sizeof(p)
- -sizeof(struct Drbd_Header) + e->size);
+ -sizeof(struct Drbd_Header) + dgs + e->size);
p.sector = cpu_to_be64(e->sector);
p.block_id = e->block_id;
@@ -1791,6 +1811,11 @@
dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__);
ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p,
sizeof(p), MSG_MORE);
+ if (ok && dgs) {
+ dgb = mdev->integrity_digest;
+ drbd_csum(mdev, mdev->integrity_tfm, e->private_bio, dgb);
+ ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
+ }
if (ok)
ok = _drbd_send_zc_bio(mdev, e->private_bio);
@@ -2345,6 +2370,8 @@
kfree(mdev->p_uuid);
mdev->p_uuid = NULL;
+
+ kfree(mdev->integrity_digest);
}
drbd_destroy_mempools();
}
@@ -2502,8 +2529,8 @@
#endif
printk(KERN_INFO "drbd: initialised. "
- "Version: " REL_VERSION " (api:%d/proto:%d)\n",
- API_VERSION, PRO_VERSION);
+ "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
+ API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
printk(KERN_INFO "drbd: %s\n", drbd_buildtag());
printk(KERN_INFO "drbd: registered as block device major %d\n",
DRBD_MAJOR);
Modified: branches/drbd-8.2/drbd/drbd_nl.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_nl.c 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/drbd_nl.c 2007-09-05 15:03:58 UTC (rev 3052)
@@ -1036,6 +1036,7 @@
enum ret_codes retcode;
struct net_conf *new_conf = NULL;
struct crypto_hash *tfm = NULL;
+ struct crypto_hash *integrity_tfm = NULL;
struct hlist_head *new_tl_hash = NULL;
struct hlist_head *new_ee_hash = NULL;
struct drbd_conf *odev;
@@ -1136,7 +1137,19 @@
}
}
+ if (new_conf->integrity_alg[0]) {
+ integrity_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(integrity_tfm)) {
+ retcode=IntegrityAlgNotAvail;
+ goto fail;
+ }
+ if (crypto_tfm_alg_type(crypto_hash_tfm(integrity_tfm)) != CRYPTO_ALG_TYPE_DIGEST) {
+ retcode=IntegrityAlgNotDigest;
+ goto fail;
+ }
+ }
+
ns = new_conf->max_epoch_size/8;
if (mdev->tl_hash_s != ns) {
new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
@@ -1203,6 +1216,20 @@
crypto_free_hash(mdev->cram_hmac_tfm);
mdev->cram_hmac_tfm = tfm;
+ if (mdev->integrity_tfm) {
+ crypto_free_hash(mdev->integrity_tfm);
+ kfree(mdev->integrity_digest);
+ if (integrity_tfm) {
+ i = crypto_hash_digestsize(integrity_tfm);
+ mdev->integrity_digest = kmalloc(i, GFP_KERNEL);
+ if (!mdev->integrity_digest) {
+ retcode = KMallocFailed;
+ goto fail;
+ }
+ }
+ }
+ mdev->cram_hmac_tfm = integrity_tfm;
+
retcode = drbd_request_state(mdev, NS(conn, Unconnected));
reply->ret_code = retcode;
@@ -1210,6 +1237,7 @@
fail:
crypto_free_hash(tfm);
+ crypto_free_hash(integrity_tfm);
kfree(new_tl_hash);
kfree(new_ee_hash);
kfree(new_conf);
Modified: branches/drbd-8.2/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_receiver.c 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/drbd_receiver.c 2007-09-05 15:03:58 UTC (rev 3052)
@@ -49,13 +49,6 @@
#include "drbd_int.h"
#include "drbd_req.h"
-#if defined(__arch_um__) && !defined(HAVE_UML_TO_VIRT)
-static inline void *to_virt(unsigned long phys)
-{
- return((void *) uml_physmem + phys);
-}
-#endif
-
#ifdef DBG_ASSERTS
void drbd_assert_breakpoint(struct drbd_conf *mdev, char *exp,
char *file, int line)
@@ -2101,14 +2094,15 @@
}
if (mdev->agreed_pro_version >= 87) {
- if (drbd_recv(mdev, integrity_alg, data_size) != data_size)
+ if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size)
return FALSE;
- integrity_alg[SHARED_SECRET_MAX-1]=0;
- if(strcmp(integrity_alg, mdev->net_conf->integrity_alg)) {
+ p_integrity_alg[SHARED_SECRET_MAX-1]=0;
+ if(strcmp(p_integrity_alg, mdev->net_conf->integrity_alg)) {
ERR("incompatible setting of the data-integrity-alg\n");
goto disconnect;
}
+ WARN("data-integrity-alg: %s\n",mdev->net_conf->integrity_alg);
}
return TRUE;
@@ -2840,7 +2834,7 @@
if (PRO_VERSION_MAX < p->protocol_min ) goto incompat;
if (PRO_VERSION_MIN > p->protocol_max ) goto incompat;
- mdev->agreed_pro_version = min(PRO_VERSION_MAX,p->protocol_max);
+ mdev->agreed_pro_version = min_t(int,PRO_VERSION_MAX,p->protocol_max);
INFO("Handshake successful: "
"Agreed network protocol version %d\n", mdev->agreed_pro_version);
Modified: branches/drbd-8.2/drbd/drbd_worker.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_worker.c 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/drbd_worker.c 2007-09-05 15:03:58 UTC (rev 3052)
@@ -287,6 +287,29 @@
return 1; /* Simply ignore this! */
}
+void drbd_csum(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest)
+{
+ struct hash_desc desc;
+ struct scatterlist sg;
+ struct bio_vec *bvec;
+ int i;
+
+ desc.tfm=tfm;
+ desc.flags=0;
+
+ // Improve in generic Kernel ?
+ // sg and bvec have exactly the same purpose
+
+ crypto_hash_init(&desc);
+ __bio_for_each_segment(bvec, bio, i, 0) {
+ sg.page = bvec->bv_page;
+ sg.offset = bvec->bv_offset;
+ sg.length = bvec->bv_len;
+ crypto_hash_update(&desc,&sg,sg.length);
+ }
+ crypto_hash_final(&desc,digest);
+}
+
void resync_timer_fn(unsigned long data)
{
unsigned long flags;
Modified: branches/drbd-8.2/drbd/linux/drbd.h
===================================================================
--- branches/drbd-8.2/drbd/linux/drbd.h 2007-09-05 12:29:47 UTC (rev 3051)
+++ branches/drbd-8.2/drbd/linux/drbd.h 2007-09-05 15:03:58 UTC (rev 3052)
@@ -112,6 +112,8 @@
UnknownNetLinkPacket,
HaveNoDiskConfig,
ProtocolCRequired,
+ IntegrityAlgNotAvail,
+ IntegrityAlgNotDigest,
/* insert new ones above this line */
AfterLastRetCode
More information about the drbd-cvs
mailing list