mirror of https://github.com/schoebel/mars
trans_logger: disallow KEEP_UNIQUE data buffer modification after IO has started
This commit is contained in:
parent
8601114229
commit
df950fe505
|
@ -244,7 +244,7 @@ int hash_fn(loff_t pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct trans_logger_mref_aspect *_hash_find(struct list_head *start, loff_t pos, int *max_len, struct timespec *elder, bool use_collect_head)
|
struct trans_logger_mref_aspect *_hash_find(struct list_head *start, loff_t pos, int *max_len, struct timespec *elder, bool use_collect_head, bool find_unstable)
|
||||||
{
|
{
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
struct trans_logger_mref_aspect *res = NULL;
|
struct trans_logger_mref_aspect *res = NULL;
|
||||||
|
@ -289,6 +289,10 @@ struct trans_logger_mref_aspect *_hash_find(struct list_head *start, loff_t pos,
|
||||||
continue; // not relevant
|
continue; // not relevant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// searching for unstable elements (only in special cases)
|
||||||
|
if (find_unstable && test_a->is_stable)
|
||||||
|
break;
|
||||||
|
|
||||||
diff = test->ref_pos - pos;
|
diff = test->ref_pos - pos;
|
||||||
if (diff <= 0) {
|
if (diff <= 0) {
|
||||||
int restlen = test->ref_len + diff;
|
int restlen = test->ref_len + diff;
|
||||||
|
@ -308,7 +312,7 @@ struct trans_logger_mref_aspect *_hash_find(struct list_head *start, loff_t pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
static noinline
|
static noinline
|
||||||
struct trans_logger_mref_aspect *hash_find(struct trans_logger_brick *brick, loff_t pos, int *max_len)
|
struct trans_logger_mref_aspect *hash_find(struct trans_logger_brick *brick, loff_t pos, int *max_len, bool find_unstable)
|
||||||
{
|
{
|
||||||
|
|
||||||
int hash = hash_fn(pos);
|
int hash = hash_fn(pos);
|
||||||
|
@ -320,7 +324,7 @@ struct trans_logger_mref_aspect *hash_find(struct trans_logger_brick *brick, lof
|
||||||
|
|
||||||
down_read(&start->hash_mutex);
|
down_read(&start->hash_mutex);
|
||||||
|
|
||||||
res = _hash_find(&start->hash_anchor, pos, max_len, NULL, false);
|
res = _hash_find(&start->hash_anchor, pos, max_len, NULL, false, find_unstable);
|
||||||
|
|
||||||
/* Ensure the found mref can't go away...
|
/* Ensure the found mref can't go away...
|
||||||
*/
|
*/
|
||||||
|
@ -513,6 +517,22 @@ err:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void hash_ensure_stableness(struct trans_logger_brick *brick, struct trans_logger_mref_aspect *mref_a)
|
||||||
|
{
|
||||||
|
if (!mref_a->is_stable) {
|
||||||
|
struct mref_object *mref = mref_a->object;
|
||||||
|
int hash = hash_fn(mref->ref_pos);
|
||||||
|
struct hash_anchor *start = &brick->hash_table[hash];
|
||||||
|
|
||||||
|
down_write(&start->hash_mutex);
|
||||||
|
|
||||||
|
mref_a->is_stable = true;
|
||||||
|
|
||||||
|
up_write(&start->hash_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void _inf_callback(struct trans_logger_input *input, bool force)
|
void _inf_callback(struct trans_logger_input *input, bool force)
|
||||||
{
|
{
|
||||||
|
@ -621,7 +641,7 @@ int _read_ref_get(struct trans_logger_output *output, struct trans_logger_mref_a
|
||||||
* the old one.
|
* the old one.
|
||||||
* When a shadow is found, use it as buffer for the mref.
|
* When a shadow is found, use it as buffer for the mref.
|
||||||
*/
|
*/
|
||||||
mshadow_a = hash_find(brick, mref->ref_pos, &mref->ref_len);
|
mshadow_a = hash_find(brick, mref->ref_pos, &mref->ref_len, false);
|
||||||
if (!mshadow_a) {
|
if (!mshadow_a) {
|
||||||
return GENERIC_INPUT_CALL(input, mref_get, mref);
|
return GENERIC_INPUT_CALL(input, mref_get, mref);
|
||||||
}
|
}
|
||||||
|
@ -647,7 +667,7 @@ int _write_ref_get(struct trans_logger_output *output, struct trans_logger_mref_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef KEEP_UNIQUE
|
#ifdef KEEP_UNIQUE
|
||||||
mshadow_a = hash_find(brick, mref->ref_pos, &mref->ref_len);
|
mshadow_a = hash_find(brick, mref->ref_pos, &mref->ref_len, true);
|
||||||
if (mshadow_a) {
|
if (mshadow_a) {
|
||||||
return _make_sshadow(output, mref_a, mshadow_a);
|
return _make_sshadow(output, mref_a, mshadow_a);
|
||||||
}
|
}
|
||||||
|
@ -1214,7 +1234,7 @@ struct writeback_info *make_writeback(struct trans_logger_brick *brick, loff_t p
|
||||||
|
|
||||||
atomic_inc(&brick->total_hash_find_count);
|
atomic_inc(&brick->total_hash_find_count);
|
||||||
|
|
||||||
orig_mref_a = _hash_find(&wb->w_collect_list, pos, &this_len, elder, true);
|
orig_mref_a = _hash_find(&wb->w_collect_list, pos, &this_len, elder, true, false);
|
||||||
if (unlikely(!orig_mref_a)) {
|
if (unlikely(!orig_mref_a)) {
|
||||||
MARS_FAT("could not find data\n");
|
MARS_FAT("could not find data\n");
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -1488,6 +1508,8 @@ bool phase0_startio(struct trans_logger_mref_aspect *orig_mref_a)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash_ensure_stableness(brick, orig_mref_a);
|
||||||
|
|
||||||
memcpy(data, orig_mref_a->shadow_data, orig_mref->ref_len);
|
memcpy(data, orig_mref_a->shadow_data, orig_mref->ref_len);
|
||||||
|
|
||||||
ok = log_finalize(logst, orig_mref->ref_len, phase0_preio, phase0_endio, orig_mref_a);
|
ok = log_finalize(logst, orig_mref->ref_len, phase0_preio, phase0_endio, orig_mref_a);
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct trans_logger_mref_aspect {
|
||||||
bool do_dealloc;
|
bool do_dealloc;
|
||||||
bool do_buffered;
|
bool do_buffered;
|
||||||
bool is_hashed;
|
bool is_hashed;
|
||||||
|
bool is_stable;
|
||||||
bool is_dirty;
|
bool is_dirty;
|
||||||
bool is_collected;
|
bool is_collected;
|
||||||
bool is_fired;
|
bool is_fired;
|
||||||
|
|
Loading…
Reference in New Issue