diff --git a/mars.h b/mars.h index bc86d93e..43775588 100644 --- a/mars.h +++ b/mars.h @@ -346,6 +346,7 @@ static inline void unuse_fake_mm(void) {} extern int mars_digest_size; extern void mars_digest(unsigned char *digest, void *data, int len); +extern void mref_checksum(struct mref_object *mref); ///////////////////////////////////////////////////////////////////////// diff --git a/mars_aio.c b/mars_aio.c index e121cced..2f6e87a8 100644 --- a/mars_aio.c +++ b/mars_aio.c @@ -208,6 +208,7 @@ void _complete(struct aio_output *output, struct mref_object *mref, int err) if (err < 0) { MARS_ERR("IO error %d at pos=%lld len=%d (mref=%p ref_data=%p)\n", err, mref->ref_pos, mref->ref_len, mref, mref->ref_data); } else { + mref_checksum(mref); mref->ref_flags |= MREF_UPTODATE; } diff --git a/mars_bio.c b/mars_bio.c index 3f359ef5..d668ecf5 100644 --- a/mars_bio.c +++ b/mars_bio.c @@ -441,6 +441,7 @@ static int bio_thread(void *data) if (code < 0) { MARS_ERR("IO error %d\n", code); } else { + mref_checksum(mref); mref->ref_flags |= MREF_UPTODATE; } diff --git a/mars_client.c b/mars_client.c index 0c797d88..6a94e999 100644 --- a/mars_client.c +++ b/mars_client.c @@ -262,7 +262,7 @@ int receiver_thread(void *data) if (status < 0) goto done; - switch (cmd.cmd_code) { + switch (cmd.cmd_code & CMD_FLAG_MASK) { case CMD_NOTIFY: mars_trigger(); break; @@ -303,7 +303,7 @@ int receiver_thread(void *data) MARS_IO("got callback id = %d, old pos = %lld len = %d rw = %d\n", mref->ref_id, mref->ref_pos, mref->ref_len, mref->ref_rw); - status = mars_recv_cb(&output->socket, mref); + status = mars_recv_cb(&output->socket, mref, &cmd); MARS_IO("new status = %d, pos = %lld len = %d rw = %d\n", status, mref->ref_pos, mref->ref_len, mref->ref_rw); if (status < 0) { MARS_WRN("interrupted data transfer during callback, status = %d\n", status); diff --git a/mars_generic.c b/mars_generic.c index 0f268351..a0c73e9b 100644 --- a/mars_generic.c +++ b/mars_generic.c @@ -123,6 +123,23 @@ void mars_digest(unsigned char *digest, void *data, int len) } EXPORT_SYMBOL_GPL(mars_digest); +void mref_checksum(struct mref_object *mref) +{ + unsigned char checksum[mars_digest_size]; + int len; + + if (mref->ref_cs_mode <= 0 || !mref->ref_data) + return; + + mars_digest(checksum, mref->ref_data, mref->ref_len); + + len = sizeof(mref->ref_checksum); + if (len > mars_digest_size) + len = mars_digest_size; + memcpy(&mref->ref_checksum, checksum, len); +} +EXPORT_SYMBOL_GPL(mref_checksum); + ///////////////////////////////////////////////////////////////////// // tracing diff --git a/mars_net.c b/mars_net.c index be60d579..e0bdc959 100644 --- a/mars_net.c +++ b/mars_net.c @@ -762,16 +762,19 @@ int mars_send_mref(struct mars_socket *msock, struct mref_object *mref) int seq = 0; int status; + if (mref->ref_rw != 0 && mref->ref_data && mref->ref_cs_mode < 2) + cmd.cmd_code |= CMD_FLAG_HAS_DATA; + status = _mars_send_struct(msock, &cmd, mars_cmd_meta, &seq, true); if (status < 0) goto done; seq = 0; - status = _mars_send_struct(msock, mref, mars_mref_meta, &seq, mref->ref_rw != 0); + status = _mars_send_struct(msock, mref, mars_mref_meta, &seq, cmd.cmd_code & CMD_FLAG_HAS_DATA); if (status < 0) goto done; - if (mref->ref_rw != 0) { + if (cmd.cmd_code & CMD_FLAG_HAS_DATA) { status = mars_send_raw(msock, mref->ref_data, mref->ref_len, false); } done: @@ -779,7 +782,7 @@ done: } EXPORT_SYMBOL_GPL(mars_send_mref); -int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref) +int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd) { int seq = 0; int status; @@ -787,7 +790,8 @@ int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref) status = _mars_recv_struct(msock, mref, mars_mref_meta, &seq, __LINE__); if (status < 0) goto done; - if (mref->ref_rw) { + + if (cmd->cmd_code & CMD_FLAG_HAS_DATA) { if (!mref->ref_data) mref->ref_data = brick_zmem_alloc(mref->ref_len); if (!mref->ref_data) { @@ -812,16 +816,19 @@ int mars_send_cb(struct mars_socket *msock, struct mref_object *mref) int seq = 0; int status; + if (mref->ref_rw == 0 && mref->ref_data && mref->ref_cs_mode < 2) + cmd.cmd_code |= CMD_FLAG_HAS_DATA; + status = _mars_send_struct(msock, &cmd, mars_cmd_meta, &seq, true); if (status < 0) goto done; seq = 0; - status = _mars_send_struct(msock, mref, mars_mref_meta, &seq, !mref->ref_rw); + status = _mars_send_struct(msock, mref, mars_mref_meta, &seq, cmd.cmd_code & CMD_FLAG_HAS_DATA); if (status < 0) goto done; - if (!mref->ref_rw) { + if (cmd.cmd_code & CMD_FLAG_HAS_DATA) { MARS_IO("#%d sending blocklen = %d\n", msock->s_debug_nr, mref->ref_len); status = mars_send_raw(msock, mref->ref_data, mref->ref_len, false); } @@ -830,7 +837,7 @@ done: } EXPORT_SYMBOL_GPL(mars_send_cb); -int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref) +int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd) { int seq = 0; int status; @@ -838,7 +845,8 @@ int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref) status = _mars_recv_struct(msock, mref, mars_mref_meta, &seq, __LINE__); if (status < 0) goto done; - if (!mref->ref_rw) { + + if (cmd->cmd_code & CMD_FLAG_HAS_DATA) { if (!mref->ref_data) { MARS_WRN("#%d no internal buffer available\n", msock->s_debug_nr); status = -EINVAL; diff --git a/mars_net.h b/mars_net.h index 3dd4d4da..943417dd 100644 --- a/mars_net.h +++ b/mars_net.h @@ -43,6 +43,9 @@ enum { CMD_CB, }; +#define CMD_FLAG_MASK 255 +#define CMD_FLAG_HAS_DATA 256 + struct mars_cmd { struct timespec cmd_stamp; // for automatic lamport clock int cmd_code; @@ -88,9 +91,9 @@ extern int mars_send_dent_list(struct mars_socket *msock, struct list_head *anch extern int mars_recv_dent_list(struct mars_socket *msock, struct list_head *anchor); extern int mars_send_mref(struct mars_socket *msock, struct mref_object *mref); -extern int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref); +extern int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd); extern int mars_send_cb(struct mars_socket *msock, struct mref_object *mref); -extern int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref); +extern int mars_recv_cb(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd); ///////////////////////////////////////////////////////////////////////// diff --git a/mars_server.c b/mars_server.c index 1a5dc9d9..fc312e97 100644 --- a/mars_server.c +++ b/mars_server.c @@ -139,7 +139,7 @@ err: MARS_FAT("cannot handle callback - giving up\n"); } -int server_io(struct server_brick *brick, struct mars_socket *sock) +int server_io(struct server_brick *brick, struct mars_socket *sock, struct mars_cmd *cmd) { struct mref_object *mref; struct server_mref_aspect *mref_a; @@ -159,7 +159,7 @@ int server_io(struct server_brick *brick, struct mars_socket *sock) goto done; } - status = mars_recv_mref(sock, mref); + status = mars_recv_mref(sock, mref, cmd); if (status < 0) { mars_free_mref(mref); goto done; @@ -299,7 +299,7 @@ int handler_thread(void *data) MARS_IO("cmd = %d\n", cmd.cmd_code); status = -EPROTO; - switch (cmd.cmd_code) { + switch (cmd.cmd_code & CMD_FLAG_MASK) { case CMD_NOP: MARS_DBG("got NOP operation\n"); status = 0; @@ -393,7 +393,7 @@ int handler_thread(void *data) break; } #endif - status = server_io(brick, sock); + status = server_io(brick, sock, &cmd); break; } case CMD_CB: diff --git a/mars_sio.c b/mars_sio.c index fa994897..de3ff6f0 100644 --- a/mars_sio.c +++ b/mars_sio.c @@ -324,6 +324,7 @@ void _complete(struct sio_output *output, struct mref_object *mref, int err) if (err < 0) { MARS_ERR("IO error %d at pos=%lld len=%d (mref=%p ref_data=%p)\n", err, mref->ref_pos, mref->ref_len, mref, mref->ref_data); } else { + mref_checksum(mref); mref->ref_flags |= MREF_UPTODATE; } diff --git a/mars_trans_logger.c b/mars_trans_logger.c index c09e2aae..7b13eed7 100644 --- a/mars_trans_logger.c +++ b/mars_trans_logger.c @@ -1264,6 +1264,7 @@ void _complete(struct trans_logger_brick *brick, struct trans_logger_mref_aspect orig_mref_a->is_completed = true; if (likely(error >= 0)) { + mref_checksum(orig_mref); orig_mref->ref_flags &= ~MREF_WRITING; orig_mref->ref_flags |= MREF_UPTODATE; }