[DRBD-cvs] svn commit by phil - r3055 - in branches/drbd-8.2: drbd
user - The first time the "data-integrity-alg" feature is work
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Thu Sep 6 17:31:52 CEST 2007
Author: phil
Date: 2007-09-06 17:31:41 +0200 (Thu, 06 Sep 2007)
New Revision: 3055
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_wrappers.h
branches/drbd-8.2/user/drbdsetup.c
Log:
The first time the "data-integrity-alg" feature is working.
* The 86 protocol seems to be broken somehow currently.
* More testing and debugging needed.
Modified: branches/drbd-8.2/drbd/drbd_int.h
===================================================================
--- branches/drbd-8.2/drbd/drbd_int.h 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/drbd/drbd_int.h 2007-09-06 15:31:41 UTC (rev 3055)
@@ -877,7 +877,9 @@
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;
+ void *int_dig_out;
+ void *int_dig_in;
+ void *int_dig_vv;
wait_queue_head_t seq_wait;
atomic_t packet_seq;
unsigned int peer_seq;
@@ -1336,6 +1338,7 @@
/* maybe rather drbd_main.c ? */
extern int drbd_md_sync_page_io(struct drbd_conf *mdev,
struct drbd_backing_dev *bdev, sector_t sector, int rw);
+void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *);
/* worker callbacks */
extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int);
extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int);
Modified: branches/drbd-8.2/drbd/drbd_main.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_main.c 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/drbd/drbd_main.c 2007-09-06 15:31:41 UTC (rev 3055)
@@ -1762,7 +1762,7 @@
ok = (sizeof(p) ==
drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE));
if (ok && dgs) {
- dgb = mdev->integrity_digest;
+ dgb = mdev->int_dig_out;
drbd_csum(mdev, mdev->integrity_tfm, req->master_bio, dgb);
ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
}
@@ -1812,7 +1812,7 @@
ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p,
sizeof(p), MSG_MORE);
if (ok && dgs) {
- dgb = mdev->integrity_digest;
+ dgb = mdev->int_dig_out;
drbd_csum(mdev, mdev->integrity_tfm, e->private_bio, dgb);
ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
}
@@ -2371,7 +2371,9 @@
kfree(mdev->p_uuid);
mdev->p_uuid = NULL;
- kfree(mdev->integrity_digest);
+ kfree(mdev->int_dig_out);
+ kfree(mdev->int_dig_in);
+ kfree(mdev->int_dig_vv);
}
drbd_destroy_mempools();
}
Modified: branches/drbd-8.2/drbd/drbd_nl.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_nl.c 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/drbd/drbd_nl.c 2007-09-06 15:31:41 UTC (rev 3055)
@@ -1218,14 +1218,26 @@
if (mdev->integrity_tfm) {
crypto_free_hash(mdev->integrity_tfm);
- kfree(mdev->integrity_digest);
+ kfree(mdev->int_dig_out);
+ kfree(mdev->int_dig_in);
+ kfree(mdev->int_dig_vv);
if (integrity_tfm) {
i = crypto_hash_digestsize(integrity_tfm);
- mdev->integrity_digest = kmalloc(i, GFP_KERNEL);
- if (!mdev->integrity_digest) {
+ mdev->int_dig_out = kmalloc(i, GFP_KERNEL);
+ if (!mdev->int_dig_out) {
retcode = KMallocFailed;
goto fail;
}
+ mdev->int_dig_in = kmalloc(i, GFP_KERNEL);
+ if (!mdev->int_dig_in) {
+ retcode = KMallocFailed;
+ goto fail;
+ }
+ mdev->int_dig_vv = kmalloc(i, GFP_KERNEL);
+ if (!mdev->int_dig_vv) {
+ retcode = KMallocFailed;
+ goto fail;
+ }
}
}
mdev->cram_hmac_tfm = integrity_tfm;
Modified: branches/drbd-8.2/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-8.2/drbd/drbd_receiver.c 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/drbd/drbd_receiver.c 2007-09-06 15:31:41 UTC (rev 3055)
@@ -876,8 +876,27 @@
struct bio_vec *bvec;
struct page *page;
struct bio *bio;
- int ds, i, rr;
+ int dgs, ds, i, rr;
+ void *dig_in = mdev->int_dig_in;
+ void *dig_vv = mdev->int_dig_vv;
+ dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->integrity_tfm) : 0;
+
+ if (dgs) {
+ rr = drbd_recv(mdev, dig_in, dgs);
+ if ( rr != dgs ) {
+ WARN("short read receiving data: read %d expected %d\n",
+ rr, dgs);
+ return NULL;
+ }
+ }
+
+ data_size -= dgs;
+
+ ERR_IF(data_size & 0x1ff) return NULL;
+ ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return NULL;
+
e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_KERNEL);
if (!e)
return 0;
@@ -896,6 +915,13 @@
ds -= rr;
}
+ if (dgs) {
+ drbd_csum(mdev, mdev->integrity_tfm, bio, dig_vv);
+ if (memcmp(dig_in,dig_vv,dgs)) {
+ ERR("Digest integrity check failed. Broken NICs?\n");
+ return 0;
+ }
+ }
mdev->recv_cnt += data_size>>9;
return e;
}
@@ -945,8 +971,24 @@
{
struct bio_vec *bvec;
struct bio *bio;
- int rr, i, expect;
+ int dgs, rr, i, expect;
+ void *dig_in = mdev->int_dig_in;
+ void *dig_vv = mdev->int_dig_vv;
+ dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_tfm) ?
+ crypto_hash_digestsize(mdev->integrity_tfm) : 0;
+
+ if (dgs) {
+ rr = drbd_recv(mdev, dig_in, dgs);
+ if ( rr != dgs ) {
+ WARN("short read receiving data: read %d expected %d\n",
+ rr, dgs);
+ return 0;
+ }
+ }
+
+ data_size -= dgs;
+
bio = req->master_bio;
D_ASSERT( sector == bio->bi_sector );
@@ -965,6 +1007,14 @@
data_size -= rr;
}
+ if (dgs) {
+ drbd_csum(mdev, mdev->integrity_tfm, bio, dig_vv);
+ if (memcmp(dig_in,dig_vv,dgs)) {
+ ERR("Digest integrity check failed. Broken NICs?\n");
+ return 0;
+ }
+ }
+
D_ASSERT(data_size == 0);
/* FIXME recv_cnt accounting ?? */
return 1;
@@ -1043,8 +1093,6 @@
* and no more than DRBD_MAX_SEGMENT_SIZE.
* is this too restrictive? */
ERR_IF(data_size == 0) return FALSE;
- ERR_IF(data_size & 0x1ff) return FALSE;
- ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return FALSE;
if (drbd_recv(mdev, h->payload, header_size) != header_size)
return FALSE;
@@ -1255,8 +1303,6 @@
data_size = h->length - header_size;
ERR_IF(data_size == 0) return FALSE;
- ERR_IF(data_size & 0x1ff) return FALSE;
- ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return FALSE;
if (drbd_recv(mdev, h->payload, header_size) != header_size)
return FALSE;
Modified: branches/drbd-8.2/drbd/drbd_wrappers.h
===================================================================
--- branches/drbd-8.2/drbd/drbd_wrappers.h 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/drbd/drbd_wrappers.h 2007-09-06 15:31:41 UTC (rev 3055)
@@ -289,11 +289,20 @@
// "hmac(xxx)" is in alg_name we need that xxx.
closing_bracket = strchr(alg_name,')');
- if(!closing_bracket) return NULL;
- if(closing_bracket-alg_name < 6) return NULL;
+ if(!closing_bracket) {
+ ch = kmalloc(sizeof(struct crypto_hash),GFP_KERNEL);
+ if(!ch) return ERR_PTR(-ENOMEM);
+ ch->base = crypto_alloc_tfm(alg_name, 0);
+ if (ch->base == NULL) {
+ kfree(ch);
+ return ERR_PTR(-ENOMEM);
+ }
+ return ch;
+ }
+ if(closing_bracket-alg_name < 6) return ERR_PTR(-ENOENT);
ch = kmalloc(sizeof(struct crypto_hash),GFP_KERNEL);
- if(!ch) return NULL;
+ if(!ch) return ERR_PTR(-ENOMEM);
*closing_bracket = 0;
ch->base = crypto_alloc_tfm(alg_name + 5, 0);
@@ -301,7 +310,7 @@
if (ch->base == NULL) {
kfree(ch);
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
return ch;
@@ -344,6 +353,28 @@
return tfm->base;
}
+static inline int crypto_hash_init(struct hash_desc *desc)
+{
+ crypto_digest_init(desc->tfm->base);
+ return 0;
+}
+
+static inline int crypto_hash_update(struct hash_desc *desc,
+ struct scatterlist *sg,
+ unsigned int nbytes)
+{
+ crypto_digest_update(desc->tfm->base,sg,1 /* ! */ );
+ /* ! this is not generic. Would need to convert nbytes -> nsg */
+
+ return 0;
+}
+
+static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
+{
+ crypto_digest_final(desc->tfm->base, out);
+ return 0;
+}
+
#endif
#ifdef NEED_BACKPORT_OF_KZALLOC
Modified: branches/drbd-8.2/user/drbdsetup.c
===================================================================
--- branches/drbd-8.2/user/drbdsetup.c 2007-09-06 15:25:55 UTC (rev 3054)
+++ branches/drbd-8.2/user/drbdsetup.c 2007-09-06 15:31:41 UTC (rev 3055)
@@ -309,7 +309,7 @@
{ "rr-conflict",'R', T_rr_conflict,EH(rrcf_n,RR_CONFLICT) },
{ "ping-timeout",'p', T_ping_timeo, EN(PING_TIMEO,1,"1/10 seconds") },
{ "discard-my-data",'D', T_want_lose, EB },
- { "data-integrity-alg",'d', T_want_lose, EB },
+ { "data-integrity-alg",'d', T_integrity_alg, ES },
CLOSE_OPTIONS }} }, },
{"disconnect", P_disconnect, F_CONFIG_CMD, {{NULL, NULL}} },
More information about the drbd-cvs
mailing list