drbd_state.c (drbd-9.1.8) | : | drbd_state.c (drbd-9.1.9) | ||
---|---|---|---|---|
skipping to change at line 809 | skipping to change at line 809 | |||
device->cached_state_unstable = !state_is_stable(device); | device->cached_state_unstable = !state_is_stable(device); | |||
device->cached_err_io = | device->cached_err_io = | |||
(o->on_no_quorum == ONQ_IO_ERROR && !device->have_quorum[ NOW]) || | (o->on_no_quorum == ONQ_IO_ERROR && !device->have_quorum[ NOW]) || | |||
(o->on_no_data == OND_IO_ERROR && !drbd_data_accessible(d evice, NOW)) || | (o->on_no_data == OND_IO_ERROR && !drbd_data_accessible(d evice, NOW)) || | |||
resource->fail_io[NEW]; | resource->fail_io[NEW]; | |||
} | } | |||
resource->cached_all_devices_have_quorum = all_devs_have_quorum; | resource->cached_all_devices_have_quorum = all_devs_have_quorum; | |||
smp_wmb(); /* Make the NEW_CUR_UUID bit visible after the state change! * / | smp_wmb(); /* Make the NEW_CUR_UUID bit visible after the state change! * / | |||
idr_for_each_entry(&resource->devices, device, vnr) { | idr_for_each_entry(&resource->devices, device, vnr) { | |||
struct drbd_peer_device *peer_device; | ||||
if (test_bit(__NEW_CUR_UUID, &device->flags)) { | if (test_bit(__NEW_CUR_UUID, &device->flags)) { | |||
clear_bit(__NEW_CUR_UUID, &device->flags); | clear_bit(__NEW_CUR_UUID, &device->flags); | |||
set_bit(NEW_CUR_UUID, &device->flags); | set_bit(NEW_CUR_UUID, &device->flags); | |||
} | } | |||
wake_up(&device->al_wait); | wake_up(&device->al_wait); | |||
wake_up(&device->misc_wait); | wake_up(&device->misc_wait); | |||
for_each_peer_device(peer_device, device) { | ||||
if (test_and_clear_bit(HOLDING_UUID_READ_LOCK, &peer_devi | ||||
ce->flags)) | ||||
up_read_non_owner(&device->uuid_sem); | ||||
} | ||||
} | } | |||
wake_up(&resource->state_wait); | wake_up(&resource->state_wait); | |||
out: | out: | |||
rcu_read_unlock(); | rcu_read_unlock(); | |||
if ((flags & CS_TWOPC) && !(flags & CS_PREPARE)) | if ((flags & CS_TWOPC) && !(flags & CS_PREPARE)) | |||
__clear_remote_state_change(resource); | __clear_remote_state_change(resource); | |||
resource->state_change_err_str = NULL; | resource->state_change_err_str = NULL; | |||
skipping to change at line 2073 | skipping to change at line 2079 | |||
/* Implications of the repl state on the disk states */ | /* Implications of the repl state on the disk states */ | |||
min_disk_state = D_DISKLESS; | min_disk_state = D_DISKLESS; | |||
max_disk_state = D_UP_TO_DATE; | max_disk_state = D_UP_TO_DATE; | |||
min_peer_disk_state = D_INCONSISTENT; | min_peer_disk_state = D_INCONSISTENT; | |||
max_peer_disk_state = D_UNKNOWN; | max_peer_disk_state = D_UNKNOWN; | |||
switch (repl_state[NEW]) { | switch (repl_state[NEW]) { | |||
case L_OFF: | case L_OFF: | |||
/* values from above */ | /* values from above */ | |||
break; | break; | |||
case L_WF_BITMAP_T: | case L_WF_BITMAP_T: | |||
case L_PAUSED_SYNC_T: | ||||
case L_STARTING_SYNC_T: | case L_STARTING_SYNC_T: | |||
case L_WF_SYNC_UUID: | case L_WF_SYNC_UUID: | |||
case L_BEHIND: | case L_BEHIND: | |||
min_disk_state = D_INCONSISTENT; | min_disk_state = D_INCONSISTENT; | |||
max_disk_state = D_OUTDATED; | max_disk_state = D_OUTDATED; | |||
min_peer_disk_state = D_INCONSISTENT; | min_peer_disk_state = D_INCONSISTENT; | |||
max_peer_disk_state = D_UP_TO_DATE; | max_peer_disk_state = D_UP_TO_DATE; | |||
break; | break; | |||
case L_VERIFY_S: | case L_VERIFY_S: | |||
case L_VERIFY_T: | case L_VERIFY_T: | |||
skipping to change at line 2104 | skipping to change at line 2109 | |||
break; | break; | |||
case L_WF_BITMAP_S: | case L_WF_BITMAP_S: | |||
case L_PAUSED_SYNC_S: | case L_PAUSED_SYNC_S: | |||
case L_STARTING_SYNC_S: | case L_STARTING_SYNC_S: | |||
case L_AHEAD: | case L_AHEAD: | |||
min_disk_state = D_INCONSISTENT; | min_disk_state = D_INCONSISTENT; | |||
max_disk_state = D_UP_TO_DATE; | max_disk_state = D_UP_TO_DATE; | |||
min_peer_disk_state = D_INCONSISTENT; | min_peer_disk_state = D_INCONSISTENT; | |||
max_peer_disk_state = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/ | max_peer_disk_state = D_CONSISTENT; /* D_OUTDATED would be nice. But explicit outdate necessary*/ | |||
break; | break; | |||
case L_PAUSED_SYNC_T: | ||||
case L_SYNC_TARGET: | case L_SYNC_TARGET: | |||
min_disk_state = D_INCONSISTENT; | min_disk_state = D_INCONSISTENT; | |||
max_disk_state = D_INCONSISTENT; | max_disk_state = D_INCONSISTENT; | |||
min_peer_disk_state = D_OUTDATED; | min_peer_disk_state = D_OUTDATED; | |||
max_peer_disk_state = D_UP_TO_DATE; | max_peer_disk_state = D_UP_TO_DATE; | |||
break; | break; | |||
case L_SYNC_SOURCE: | case L_SYNC_SOURCE: | |||
min_disk_state = D_INCONSISTENT; | min_disk_state = D_INCONSISTENT; | |||
max_disk_state = D_UP_TO_DATE; | max_disk_state = D_UP_TO_DATE; | |||
min_peer_disk_state = D_INCONSISTENT; | min_peer_disk_state = D_INCONSISTENT; | |||
skipping to change at line 3505 | skipping to change at line 3511 | |||
enum drbd_disk_state *peer_disk_state = peer_device_state _change->disk_state; | enum drbd_disk_state *peer_disk_state = peer_device_state _change->disk_state; | |||
enum drbd_repl_state *repl_state = peer_device_state_chan ge->repl_state; | enum drbd_repl_state *repl_state = peer_device_state_chan ge->repl_state; | |||
if ((repl_state[OLD] == L_SYNC_TARGET || repl_state[OLD] == L_PAUSED_SYNC_T) && | if ((repl_state[OLD] == L_SYNC_TARGET || repl_state[OLD] == L_PAUSED_SYNC_T) && | |||
repl_state[NEW] == L_ESTABLISHED) | repl_state[NEW] == L_ESTABLISHED) | |||
resync_finished = true; | resync_finished = true; | |||
if (disk_state[OLD] == D_INCONSISTENT && disk_state[NEW] == D_UP_TO_DATE && | if (disk_state[OLD] == D_INCONSISTENT && disk_state[NEW] == D_UP_TO_DATE && | |||
peer_disk_state[OLD] == D_INCONSISTENT && peer_disk_s tate[NEW] == D_UP_TO_DATE) | peer_disk_state[OLD] == D_INCONSISTENT && peer_disk_s tate[NEW] == D_UP_TO_DATE) | |||
send_state_others = peer_device; | send_state_others = peer_device; | |||
/* connect without resync or remote attach without resync | ||||
*/ | ||||
if (disk_state[NOW] >= D_OUTDATED && repl_state[NEW] == L | ||||
_ESTABLISHED && | ||||
((repl_state[OLD] == L_OFF && | ||||
(peer_disk_state[NEW] >= D_OUTDATED || | ||||
(peer_disk_state[NEW] == D_DISKLESS && !want_bitma | ||||
p(peer_device)))) || | ||||
(peer_disk_state[OLD] == D_DISKLESS && peer_disk_sta | ||||
te[NEW] >= D_OUTDATED))) { | ||||
u64 peer_current_uuid = peer_device->current_uuid | ||||
& ~UUID_PRIMARY; | ||||
u64 my_current_uuid = drbd_current_uuid(device) & | ||||
~UUID_PRIMARY; | ||||
if (peer_current_uuid == my_current_uuid && get_l | ||||
dev(device)) { | ||||
down_write(&device->uuid_sem); | ||||
drbd_uuid_set_bitmap(peer_device, 0); | ||||
up_write(&device->uuid_sem); | ||||
drbd_print_uuids(peer_device, "cleared bm | ||||
UUID and bitmap"); | ||||
drbd_bitmap_io_from_worker(device, &drbd_ | ||||
bmio_clear_one_peer, | ||||
"clearing bm o | ||||
ne peer", BM_LOCK_CLEAR | BM_LOCK_BULK, | ||||
peer_device); | ||||
put_ldev(device); | ||||
} | ||||
} | ||||
} | } | |||
for (n_connection = 0; n_connection < state_change->n_connections ; n_connection++) { | for (n_connection = 0; n_connection < state_change->n_connections ; n_connection++) { | |||
struct drbd_connection_state_change *connection_state_cha nge = &state_change->connections[n_connection]; | struct drbd_connection_state_change *connection_state_cha nge = &state_change->connections[n_connection]; | |||
struct drbd_connection *connection = connection_state_cha nge->connection; | struct drbd_connection *connection = connection_state_cha nge->connection; | |||
enum drbd_conn_state *cstate = connection_state_change->c state; | enum drbd_conn_state *cstate = connection_state_change->c state; | |||
enum drbd_role *peer_role = connection_state_change->peer _role; | enum drbd_role *peer_role = connection_state_change->peer _role; | |||
struct drbd_peer_device_state_change *peer_device_state_c hange = | struct drbd_peer_device_state_change *peer_device_state_c hange = | |||
&state_change->peer_devices[ | &state_change->peer_devices[ | |||
n_device * state_change->n_connections + n_connection]; | n_device * state_change->n_connections + n_connection]; | |||
struct drbd_peer_device *peer_device = peer_device_state_ change->peer_device; | struct drbd_peer_device *peer_device = peer_device_state_ change->peer_device; | |||
enum drbd_repl_state *repl_state = peer_device_state_chan ge->repl_state; | enum drbd_repl_state *repl_state = peer_device_state_chan ge->repl_state; | |||
enum drbd_disk_state *peer_disk_state = peer_device_state _change->disk_state; | enum drbd_disk_state *peer_disk_state = peer_device_state _change->disk_state; | |||
bool *resync_susp_user = peer_device_state_change->resync _susp_user; | bool *resync_susp_user = peer_device_state_change->resync _susp_user; | |||
bool *resync_susp_peer = peer_device_state_change->resync _susp_peer; | bool *resync_susp_peer = peer_device_state_change->resync _susp_peer; | |||
bool *resync_susp_dependency = peer_device_state_change-> resync_susp_dependency; | bool *resync_susp_dependency = peer_device_state_change-> resync_susp_dependency; | |||
union drbd_state new_state = | union drbd_state new_state = | |||
state_change_word(state_change, n_device, n_conne ction, NEW); | state_change_word(state_change, n_device, n_conne ction, NEW); | |||
bool send_uuids, send_state = false; | bool send_uuids, send_state = false; | |||
if (repl_state[OLD] == L_OFF && | ||||
(peer_disk_state[NOW] == D_UP_TO_DATE || !want_bitmap | ||||
(peer_device)) && | ||||
drbd_bitmap_uuid(peer_device) && get_ldev(device)) { | ||||
down_write(&device->uuid_sem); | ||||
drbd_uuid_set_bitmap(peer_device, 0); | ||||
up_write(&device->uuid_sem); | ||||
drbd_print_uuids(peer_device, "cleared bm UUID"); | ||||
put_ldev(device); | ||||
} | ||||
/* In case we finished a resync as resync-target update a ll neighbors | /* In case we finished a resync as resync-target update a ll neighbors | |||
about having a bitmap_uuid of 0 towards the previous s ync-source. | about having a bitmap_uuid of 0 towards the previous s ync-source. | |||
That needs to go out before sending the new disk state | That needs to go out before sending the new disk state | |||
(To avoid a race where the other node might downgrade our disk | (To avoid a race where the other node might downgrade our disk | |||
state due to old UUID valued) */ | state due to old UUID valued) */ | |||
send_uuids = resync_finished && peer_disk_state[NEW] != D _UNKNOWN; | send_uuids = resync_finished && peer_disk_state[NEW] != D _UNKNOWN; | |||
/* Send UUIDs again if they changed while establishing th e connection */ | /* Send UUIDs again if they changed while establishing th e connection */ | |||
if (repl_state[OLD] == L_OFF && repl_state[NEW] > L_OFF & & | if (repl_state[OLD] == L_OFF && repl_state[NEW] > L_OFF & & | |||
peer_device->comm_current_uuid != drbd_resolved_uuid( peer_device, NULL)) | peer_device->comm_current_uuid != drbd_resolved_uuid( peer_device, NULL)) | |||
skipping to change at line 5222 | skipping to change at line 5239 | |||
static bool do_change_disk_state(struct change_context *context, enum change_pha se phase) | static bool do_change_disk_state(struct change_context *context, enum change_pha se phase) | |||
{ | { | |||
struct drbd_device *device = | struct drbd_device *device = | |||
container_of(context, struct change_disk_state_context, context)- >device; | container_of(context, struct change_disk_state_context, context)- >device; | |||
bool cluster_wide_state_change = false; | bool cluster_wide_state_change = false; | |||
if (device->disk_state[NOW] == D_ATTACHING && | if (device->disk_state[NOW] == D_ATTACHING && | |||
context->val.disk == D_NEGOTIATING) { | context->val.disk == D_NEGOTIATING) { | |||
if (device_has_peer_devices_with_disk(device)) { | if (device_has_peer_devices_with_disk(device)) { | |||
struct drbd_connection *connection = | ||||
first_connection(device->resource); | ||||
cluster_wide_state_change = | cluster_wide_state_change = | |||
connection && connection->agreed_pro_version >= 1 10; | supports_two_phase_commit(device->resource); | |||
} else { | } else { | |||
/* very last part of attach */ | /* very last part of attach */ | |||
context->val.disk = disk_state_from_md(device); | context->val.disk = disk_state_from_md(device); | |||
restore_outdated_in_pdsk(device); | restore_outdated_in_pdsk(device); | |||
} | } | |||
} else if (device->disk_state[NOW] != D_DETACHING && | } else if (device->disk_state[NOW] != D_DETACHING && | |||
context->val.disk == D_DETACHING && | context->val.disk == D_DETACHING && | |||
device_has_connected_peer_devices(device)) { | device_has_connected_peer_devices(device)) { | |||
cluster_wide_state_change = true; | cluster_wide_state_change = true; | |||
} | } | |||
End of changes. 8 change blocks. | ||||
15 lines changed or deleted | 40 lines changed or added |