diff --git a/kernel/mars.h b/kernel/mars.h index 8dba794c..f79950cb 100644 --- a/kernel/mars.h +++ b/kernel/mars.h @@ -156,6 +156,9 @@ enum _MREF_FLAGS { _MREF_WRITE, _MREF_MAY_WRITE, _MREF_SKIP_SYNC, + _MREF_NODATA, /* only useful for chksum reading */ + /* Checksum bits, starting at the upper half */ + _MREF_CHKSUM_MD5_OLD = 16, }; #define MREF_UPTODATE (1UL << _MREF_UPTODATE) @@ -164,6 +167,9 @@ enum _MREF_FLAGS { #define MREF_WRITE (1UL << _MREF_WRITE) #define MREF_MAY_WRITE (1UL << _MREF_MAY_WRITE) #define MREF_SKIP_SYNC (1UL << _MREF_SKIP_SYNC) +#define MREF_NODATA (1UL << _MREF_NODATA) +#define MREF_CHKSUM_MD5_OLD (1UL << _MREF_CHKSUM_MD5_OLD) +#define MREF_CHKSUM_ANY (MREF_CHKSUM_MD5_OLD) #define MREF_OBJECT(OBJTYPE) \ CALLBACK_OBJECT(OBJTYPE); \ @@ -173,7 +179,6 @@ enum _MREF_FLAGS { int ref_len; \ int ref_prio; \ int ref_timeout; \ - int ref_cs_mode; /* 0 = off, 1 = checksum + data, 2 = checksum only */ \ /* shared */ \ __u32 ref_flags; \ /* maintained by the ref implementation, readable for callers */ \ @@ -187,6 +192,7 @@ enum _MREF_FLAGS { int ref_rw; \ int ref_may_write; \ bool ref_skip_sync; /* skip sync for this particular mref */ \ + int ref_cs_mode; /* 0 = off, 1 = checksum + data, 2 = checksum only */ \ /* internal */ \ atomic_trace_t ref_at; \ bool ref_initialized; /* internally used for checking */ \ diff --git a/kernel/mars_copy.c b/kernel/mars_copy.c index 5266da5d..0be2b033 100644 --- a/kernel/mars_copy.c +++ b/kernel/mars_copy.c @@ -280,7 +280,9 @@ err: } static -int _make_mref(struct copy_brick *brick, int index, int queue, void *data, loff_t pos, loff_t end_pos, __u32 flags, int cs_mode) +int _make_mref(struct copy_brick *brick, int index, int queue, void *data, + loff_t pos, loff_t end_pos, + __u32 flags) { struct mref_object *mref; struct copy_mref_aspect *mref_a; @@ -309,7 +311,6 @@ int _make_mref(struct copy_brick *brick, int index, int queue, void *data, loff_ mref->ref_flags = flags; mref->ref_data = data; mref->ref_pos = pos; - mref->ref_cs_mode = cs_mode; offset = GET_OFFSET(pos); len = COPY_CHUNK - offset; if (pos + len > end_pos) { @@ -374,6 +375,14 @@ void _update_percent(struct copy_brick *brick, bool force) } } +static inline +__u32 _make_flags(bool verify_mode) +{ + if (!verify_mode) + return 0; + return MREF_NODATA | MREF_CHKSUM_ANY; +} + /* The heart of this brick. * State transition function of the finite automaton. @@ -441,7 +450,9 @@ restart: is_read_limited(brick)) goto idle; - status = _make_mref(brick, index, 0, NULL, pos, brick->copy_end, 0, brick->verify_mode ? 2 : 0); + status = _make_mref(brick, index, 0, NULL, + pos, brick->copy_end, + _make_flags(brick->verify_mode)); if (unlikely(status < 0)) { MARS_DBG("status = %d\n", status); progress = status; @@ -456,7 +467,9 @@ restart: next_state = COPY_STATE_START2; /* fallthrough */ case COPY_STATE_START2: - status = _make_mref(brick, index, 1, NULL, pos, brick->copy_end, 0, 2); + status = _make_mref(brick, index, 1, NULL, + pos, brick->copy_end, + _make_flags(true)); if (unlikely(status < 0)) { MARS_DBG("status = %d\n", status); progress = status; @@ -491,7 +504,7 @@ restart: if (len != mref1->ref_len) { ok = false; - } else if (mref0->ref_cs_mode) { + } else if (mref0->ref_flags & MREF_CHKSUM_ANY) { static unsigned char null[sizeof(mref0->ref_checksum)]; ok = !memcmp(mref0->ref_checksum, mref1->ref_checksum, sizeof(mref0->ref_checksum)); if (ok) @@ -516,9 +529,12 @@ restart: } } - if (mref0->ref_cs_mode > 1) { // re-read, this time with data + if ((mref0->ref_flags & MREF_CHKSUM_ANY) && (mref0->ref_flags & MREF_NODATA)) { + /* re-read, this time with data */ _clear_mref(brick, index, 0); - status = _make_mref(brick, index, 0, NULL, pos, brick->copy_end, 0, 0); + status = _make_mref(brick, index, 0, NULL, + pos, brick->copy_end, + _make_flags(false)); if (unlikely(status < 0)) { MARS_DBG("status = %d\n", status); progress = status; @@ -564,7 +580,9 @@ restart: break; } /* start writeout */ - status = _make_mref(brick, index, 1, mref0->ref_data, pos, pos + mref0->ref_len, MREF_WRITE | MREF_MAY_WRITE, 0); + status = _make_mref(brick, index, 1, mref0->ref_data, + pos, pos + mref0->ref_len, + MREF_WRITE | MREF_MAY_WRITE); if (unlikely(status < 0)) { MARS_DBG("status = %d\n", status); progress = status; diff --git a/kernel/mars_generic.c b/kernel/mars_generic.c index 843e8f43..6b394b5f 100644 --- a/kernel/mars_generic.c +++ b/kernel/mars_generic.c @@ -204,7 +204,7 @@ void mref_checksum(struct mref_object *mref) unsigned char checksum[mars_digest_size]; int len; - if (mref->ref_cs_mode <= 0 || !mref->ref_data) + if (!(mref->ref_flags & MREF_CHKSUM_ANY) || !mref->ref_data) return; mars_digest(checksum, mref->ref_data, mref->ref_len); diff --git a/kernel/mars_net.c b/kernel/mars_net.c index c6cbba04..158829dc 100644 --- a/kernel/mars_net.c +++ b/kernel/mars_net.c @@ -1221,6 +1221,12 @@ static void _send_deprecated(struct mref_object *mref) if (mref->ref_flags & MREF_SKIP_SYNC) mref->ref_skip_sync = true; + + if (mref->ref_flags & MREF_CHKSUM_ANY) { + mref->ref_cs_mode = 1; + if (mref->ref_flags & MREF_NODATA) + mref->ref_cs_mode = 2; + } } int mars_send_mref(struct mars_socket *msock, struct mref_object *mref, bool cork) @@ -1235,7 +1241,9 @@ int mars_send_mref(struct mars_socket *msock, struct mref_object *mref, bool cor /* compatibility to old protocol */ _send_deprecated(mref); - if ((mref->ref_flags & MREF_WRITE) && mref->ref_data && mref->ref_cs_mode < 2) + if ((mref->ref_flags & MREF_WRITE) && + mref->ref_data && + !(mref->ref_flags & MREF_NODATA)) cmd.cmd_code |= CMD_FLAG_HAS_DATA; if (!cork || !msock->s_pos) @@ -1262,6 +1270,8 @@ EXPORT_SYMBOL_GPL(mars_send_mref); */ static void _recv_deprecated(struct mref_object *mref) { + int cs_mode; + /* compatibility to old protocol */ if (mref->ref_rw) { mref->ref_rw = 0; @@ -1276,6 +1286,14 @@ static void _recv_deprecated(struct mref_object *mref) mref->ref_skip_sync = false; mref->ref_flags |= MREF_SKIP_SYNC; } + + cs_mode = mref->ref_cs_mode; + if (cs_mode) { + mref->ref_cs_mode = 0; + mref->ref_flags |= MREF_CHKSUM_MD5_OLD; + if (cs_mode > 1) + mref->ref_flags |= MREF_NODATA; + } } int mars_recv_mref(struct mars_socket *msock, struct mref_object *mref, struct mars_cmd *cmd) @@ -1322,7 +1340,7 @@ int mars_send_cb(struct mars_socket *msock, struct mref_object *mref, bool cork) if (!(mref->ref_flags & MREF_WRITE) && mref->ref_data && - mref->ref_cs_mode < 2) + !(mref->ref_flags & MREF_NODATA)) cmd.cmd_code |= CMD_FLAG_HAS_DATA; if (!cork || !msock->s_pos) diff --git a/kernel/mars_server.c b/kernel/mars_server.c index 20d9a4d2..019239f9 100644 --- a/kernel/mars_server.c +++ b/kernel/mars_server.c @@ -257,7 +257,7 @@ int server_io(struct server_brick *brick, struct mars_socket *sock, struct mars_ SETUP_CALLBACK(mref, server_endio, mref_a); amount = 0; - if (mref->ref_cs_mode < 2) + if (!(mref->ref_flags & MREF_NODATA)) amount = (mref->ref_len - 1) / 1024 + 1; mars_limit_sleep(&server_limiter, amount);