mirror of
https://github.com/schoebel/mars
synced 2025-02-28 02:20:39 +00:00
copy: stabilize table for race prevention
This commit is contained in:
parent
e6a1197432
commit
28ceff2388
@ -230,27 +230,19 @@ void copy_endio(struct generic_callback *cb)
|
|||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
st->active[queue] = false;
|
if (unlikely(st->table[queue] != mref)) {
|
||||||
if (unlikely(st->table[queue])) {
|
|
||||||
MARS_ERR("table corruption at %d %d (%p => %p)\n", index, queue, st->table[queue], mref);
|
MARS_ERR("table corruption at %d %d (%p => %p)\n", index, queue, st->table[queue], mref);
|
||||||
error = -EEXIST;
|
error = -EEXIST;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (unlikely(cb->cb_error < 0)) {
|
if (unlikely(cb->cb_error < 0)) {
|
||||||
error = cb->cb_error;
|
error = cb->cb_error;
|
||||||
__clear_mref(brick, mref, queue);
|
|
||||||
/* This is racy, but does no harm.
|
/* This is racy, but does no harm.
|
||||||
* Worst case just produces more error output.
|
* Worst case just produces more error output.
|
||||||
*/
|
*/
|
||||||
if (!brick->copy_error_count++) {
|
if (!brick->copy_error_count++) {
|
||||||
MARS_WRN("IO error %d on index %d, old state = %d\n", cb->cb_error, index, st->state);
|
MARS_WRN("IO error %d on index %d, old state = %d\n", cb->cb_error, index, st->state);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (unlikely(st->table[queue])) {
|
|
||||||
MARS_ERR("overwriting index %d, state = %d\n", index, st->state);
|
|
||||||
_clear_mref(brick, index, queue);
|
|
||||||
}
|
|
||||||
st->table[queue] = mref;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@ -258,6 +250,7 @@ exit:
|
|||||||
st->error = error;
|
st->error = error;
|
||||||
_clash(brick);
|
_clash(brick);
|
||||||
}
|
}
|
||||||
|
st->active[queue] = false;
|
||||||
if (mref->ref_rw) {
|
if (mref->ref_rw) {
|
||||||
atomic_dec(&brick->copy_write_flight);
|
atomic_dec(&brick->copy_write_flight);
|
||||||
} else {
|
} else {
|
||||||
@ -277,6 +270,7 @@ int _make_mref(struct copy_brick *brick, int index, int queue, void *data, loff_
|
|||||||
struct mref_object *mref;
|
struct mref_object *mref;
|
||||||
struct copy_mref_aspect *mref_a;
|
struct copy_mref_aspect *mref_a;
|
||||||
struct copy_input *input;
|
struct copy_input *input;
|
||||||
|
struct copy_state *st;
|
||||||
int offset;
|
int offset;
|
||||||
int len;
|
int len;
|
||||||
int status = -EAGAIN;
|
int status = -EAGAIN;
|
||||||
@ -335,7 +329,10 @@ int _make_mref(struct copy_brick *brick, int index, int queue, void *data, loff_
|
|||||||
|
|
||||||
//MARS_IO("queue = %d index = %d pos = %lld len = %d rw = %d\n", queue, index, mref->ref_pos, mref->ref_len, rw);
|
//MARS_IO("queue = %d index = %d pos = %lld len = %d rw = %d\n", queue, index, mref->ref_pos, mref->ref_len, rw);
|
||||||
|
|
||||||
GET_STATE(brick, index).active[queue] = true;
|
st = &GET_STATE(brick, index);
|
||||||
|
st->table[queue] = mref;
|
||||||
|
st->active[queue] = true;
|
||||||
|
|
||||||
if (rw) {
|
if (rw) {
|
||||||
atomic_inc(&brick->copy_write_flight);
|
atomic_inc(&brick->copy_write_flight);
|
||||||
} else {
|
} else {
|
||||||
@ -422,8 +419,6 @@ restart:
|
|||||||
goto idle;
|
goto idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
_clear_mref(brick, index, 1);
|
|
||||||
_clear_mref(brick, index, 0);
|
|
||||||
st->writeout = false;
|
st->writeout = false;
|
||||||
st->error = 0;
|
st->error = 0;
|
||||||
|
|
||||||
@ -455,17 +450,16 @@ restart:
|
|||||||
next_state = COPY_STATE_READ2;
|
next_state = COPY_STATE_READ2;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case COPY_STATE_READ2:
|
case COPY_STATE_READ2:
|
||||||
mref1 = st->table[1];
|
if (st->active[1]) { // idempotence: wait by unchanged state
|
||||||
if (!mref1) { // idempotence: wait by unchanged state
|
|
||||||
goto idle;
|
goto idle;
|
||||||
}
|
}
|
||||||
/* fallthrough => wait for both mrefs to appear */
|
/* fallthrough => wait for both mrefs to appear */
|
||||||
case COPY_STATE_READ1:
|
case COPY_STATE_READ1:
|
||||||
case COPY_STATE_READ3:
|
case COPY_STATE_READ3:
|
||||||
mref0 = st->table[0];
|
if (st->active[0]) { // idempotence: wait by unchanged state
|
||||||
if (!mref0) { // idempotence: wait by unchanged state
|
|
||||||
goto idle;
|
goto idle;
|
||||||
}
|
}
|
||||||
|
mref0 = st->table[0];
|
||||||
if (brick->copy_limiter) {
|
if (brick->copy_limiter) {
|
||||||
int amount = (mref0->ref_len - 1) / 1024 + 1;
|
int amount = (mref0->ref_len - 1) / 1024 + 1;
|
||||||
mars_limit_sleep(brick->copy_limiter, amount);
|
mars_limit_sleep(brick->copy_limiter, amount);
|
||||||
@ -543,6 +537,11 @@ restart:
|
|||||||
progress = -EILSEQ;
|
progress = -EILSEQ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (unlikely(st->active[0])) {
|
||||||
|
MARS_ERR("src buffer for write is active, state %d at index %d\n", state, index);
|
||||||
|
progress = -EILSEQ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (unlikely(brick->is_aborting)) {
|
if (unlikely(brick->is_aborting)) {
|
||||||
progress = -EINTR;
|
progress = -EINTR;
|
||||||
break;
|
break;
|
||||||
@ -565,8 +564,7 @@ restart:
|
|||||||
next_state = COPY_STATE_WRITTEN;
|
next_state = COPY_STATE_WRITTEN;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case COPY_STATE_WRITTEN:
|
case COPY_STATE_WRITTEN:
|
||||||
mref1 = st->table[1];
|
if (st->active[1]) { // idempotence: wait by unchanged state
|
||||||
if (!mref1) { // idempotence: wait by unchanged state
|
|
||||||
MARS_IO("irrelevant\n");
|
MARS_IO("irrelevant\n");
|
||||||
goto idle;
|
goto idle;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user