| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
|---|
| 3 | 4 | * Copyright 2004-2011 Red Hat, Inc. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This copyrighted material is made available to anyone wishing to use, |
|---|
| 6 | | - * modify, copy, or redistribute it subject to the terms and conditions |
|---|
| 7 | | - * of the GNU General Public License version 2. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 19 | 16 | |
|---|
| 20 | 17 | #include "incore.h" |
|---|
| 21 | 18 | #include "glock.h" |
|---|
| 19 | +#include "glops.h" |
|---|
| 20 | +#include "recovery.h" |
|---|
| 22 | 21 | #include "util.h" |
|---|
| 23 | 22 | #include "sys.h" |
|---|
| 24 | 23 | #include "trace_gfs2.h" |
|---|
| .. | .. |
|---|
| 127 | 126 | |
|---|
| 128 | 127 | switch (gl->gl_lksb.sb_status) { |
|---|
| 129 | 128 | case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */ |
|---|
| 129 | + if (gl->gl_ops->go_free) |
|---|
| 130 | + gl->gl_ops->go_free(gl); |
|---|
| 130 | 131 | gfs2_glock_free(gl); |
|---|
| 131 | 132 | return; |
|---|
| 132 | 133 | case -DLM_ECANCEL: /* Cancel while getting lock */ |
|---|
| .. | .. |
|---|
| 178 | 179 | gfs2_glock_cb(gl, LM_ST_SHARED); |
|---|
| 179 | 180 | break; |
|---|
| 180 | 181 | default: |
|---|
| 181 | | - pr_err("unknown bast mode %d\n", mode); |
|---|
| 182 | + fs_err(gl->gl_name.ln_sbd, "unknown bast mode %d\n", mode); |
|---|
| 182 | 183 | BUG(); |
|---|
| 183 | 184 | } |
|---|
| 184 | 185 | } |
|---|
| 185 | 186 | |
|---|
| 186 | 187 | /* convert gfs lock-state to dlm lock-mode */ |
|---|
| 187 | 188 | |
|---|
| 188 | | -static int make_mode(const unsigned int lmstate) |
|---|
| 189 | +static int make_mode(struct gfs2_sbd *sdp, const unsigned int lmstate) |
|---|
| 189 | 190 | { |
|---|
| 190 | 191 | switch (lmstate) { |
|---|
| 191 | 192 | case LM_ST_UNLOCKED: |
|---|
| .. | .. |
|---|
| 197 | 198 | case LM_ST_SHARED: |
|---|
| 198 | 199 | return DLM_LOCK_PR; |
|---|
| 199 | 200 | } |
|---|
| 200 | | - pr_err("unknown LM state %d\n", lmstate); |
|---|
| 201 | + fs_err(sdp, "unknown LM state %d\n", lmstate); |
|---|
| 201 | 202 | BUG(); |
|---|
| 202 | 203 | return -1; |
|---|
| 203 | 204 | } |
|---|
| .. | .. |
|---|
| 258 | 259 | u32 lkf; |
|---|
| 259 | 260 | char strname[GDLM_STRNAME_BYTES] = ""; |
|---|
| 260 | 261 | |
|---|
| 261 | | - req = make_mode(req_state); |
|---|
| 262 | + req = make_mode(gl->gl_name.ln_sbd, req_state); |
|---|
| 262 | 263 | lkf = make_flags(gl, flags, req); |
|---|
| 263 | 264 | gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT); |
|---|
| 264 | 265 | gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); |
|---|
| .. | .. |
|---|
| 311 | 312 | error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK, |
|---|
| 312 | 313 | NULL, gl); |
|---|
| 313 | 314 | if (error) { |
|---|
| 314 | | - pr_err("gdlm_unlock %x,%llx err=%d\n", |
|---|
| 315 | + fs_err(sdp, "gdlm_unlock %x,%llx err=%d\n", |
|---|
| 315 | 316 | gl->gl_name.ln_type, |
|---|
| 316 | 317 | (unsigned long long)gl->gl_name.ln_number, error); |
|---|
| 317 | 318 | return; |
|---|
| .. | .. |
|---|
| 327 | 328 | /* |
|---|
| 328 | 329 | * dlm/gfs2 recovery coordination using dlm_recover callbacks |
|---|
| 329 | 330 | * |
|---|
| 331 | + * 0. gfs2 checks for another cluster node withdraw, needing journal replay |
|---|
| 330 | 332 | * 1. dlm_controld sees lockspace members change |
|---|
| 331 | 333 | * 2. dlm_controld blocks dlm-kernel locking activity |
|---|
| 332 | 334 | * 3. dlm_controld within dlm-kernel notifies gfs2 (recover_prep) |
|---|
| .. | .. |
|---|
| 575 | 577 | &ls->ls_control_lksb, "control_lock"); |
|---|
| 576 | 578 | } |
|---|
| 577 | 579 | |
|---|
| 580 | +/** |
|---|
| 581 | + * remote_withdraw - react to a node withdrawing from the file system |
|---|
| 582 | + * @sdp: The superblock |
|---|
| 583 | + */ |
|---|
| 584 | +static void remote_withdraw(struct gfs2_sbd *sdp) |
|---|
| 585 | +{ |
|---|
| 586 | + struct gfs2_jdesc *jd; |
|---|
| 587 | + int ret = 0, count = 0; |
|---|
| 588 | + |
|---|
| 589 | + list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
|---|
| 590 | + if (jd->jd_jid == sdp->sd_lockstruct.ls_jid) |
|---|
| 591 | + continue; |
|---|
| 592 | + ret = gfs2_recover_journal(jd, true); |
|---|
| 593 | + if (ret) |
|---|
| 594 | + break; |
|---|
| 595 | + count++; |
|---|
| 596 | + } |
|---|
| 597 | + |
|---|
| 598 | + /* Now drop the additional reference we acquired */ |
|---|
| 599 | + fs_err(sdp, "Journals checked: %d, ret = %d.\n", count, ret); |
|---|
| 600 | +} |
|---|
| 601 | + |
|---|
| 578 | 602 | static void gfs2_control_func(struct work_struct *work) |
|---|
| 579 | 603 | { |
|---|
| 580 | 604 | struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); |
|---|
| .. | .. |
|---|
| 584 | 608 | int write_lvb = 0; |
|---|
| 585 | 609 | int recover_size; |
|---|
| 586 | 610 | int i, error; |
|---|
| 611 | + |
|---|
| 612 | + /* First check for other nodes that may have done a withdraw. */ |
|---|
| 613 | + if (test_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags)) { |
|---|
| 614 | + remote_withdraw(sdp); |
|---|
| 615 | + clear_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags); |
|---|
| 616 | + return; |
|---|
| 617 | + } |
|---|
| 587 | 618 | |
|---|
| 588 | 619 | spin_lock(&ls->ls_recover_spin); |
|---|
| 589 | 620 | /* |
|---|
| .. | .. |
|---|
| 1039 | 1070 | } |
|---|
| 1040 | 1071 | |
|---|
| 1041 | 1072 | old_size = ls->ls_recover_size; |
|---|
| 1042 | | - |
|---|
| 1043 | | - if (old_size >= max_jid + 1) |
|---|
| 1073 | + new_size = old_size; |
|---|
| 1074 | + while (new_size < max_jid + 1) |
|---|
| 1075 | + new_size += RECOVER_SIZE_INC; |
|---|
| 1076 | + if (new_size == old_size) |
|---|
| 1044 | 1077 | return 0; |
|---|
| 1045 | | - |
|---|
| 1046 | | - new_size = old_size + RECOVER_SIZE_INC; |
|---|
| 1047 | 1078 | |
|---|
| 1048 | 1079 | submit = kcalloc(new_size, sizeof(uint32_t), GFP_NOFS); |
|---|
| 1049 | 1080 | result = kcalloc(new_size, sizeof(uint32_t), GFP_NOFS); |
|---|
| .. | .. |
|---|
| 1083 | 1114 | struct gfs2_sbd *sdp = arg; |
|---|
| 1084 | 1115 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
|---|
| 1085 | 1116 | |
|---|
| 1117 | + if (gfs2_withdrawn(sdp)) { |
|---|
| 1118 | + fs_err(sdp, "recover_prep ignored due to withdraw.\n"); |
|---|
| 1119 | + return; |
|---|
| 1120 | + } |
|---|
| 1086 | 1121 | spin_lock(&ls->ls_recover_spin); |
|---|
| 1087 | 1122 | ls->ls_recover_block = ls->ls_recover_start; |
|---|
| 1088 | 1123 | set_bit(DFL_DLM_RECOVERY, &ls->ls_recover_flags); |
|---|
| .. | .. |
|---|
| 1105 | 1140 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
|---|
| 1106 | 1141 | int jid = slot->slot - 1; |
|---|
| 1107 | 1142 | |
|---|
| 1143 | + if (gfs2_withdrawn(sdp)) { |
|---|
| 1144 | + fs_err(sdp, "recover_slot jid %d ignored due to withdraw.\n", |
|---|
| 1145 | + jid); |
|---|
| 1146 | + return; |
|---|
| 1147 | + } |
|---|
| 1108 | 1148 | spin_lock(&ls->ls_recover_spin); |
|---|
| 1109 | 1149 | if (ls->ls_recover_size < jid + 1) { |
|---|
| 1110 | 1150 | fs_err(sdp, "recover_slot jid %d gen %u short size %d\n", |
|---|
| .. | .. |
|---|
| 1129 | 1169 | struct gfs2_sbd *sdp = arg; |
|---|
| 1130 | 1170 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
|---|
| 1131 | 1171 | |
|---|
| 1172 | + if (gfs2_withdrawn(sdp)) { |
|---|
| 1173 | + fs_err(sdp, "recover_done ignored due to withdraw.\n"); |
|---|
| 1174 | + return; |
|---|
| 1175 | + } |
|---|
| 1132 | 1176 | /* ensure the ls jid arrays are large enough */ |
|---|
| 1133 | 1177 | set_recover_size(sdp, slots, num_slots); |
|---|
| 1134 | 1178 | |
|---|
| .. | .. |
|---|
| 1156 | 1200 | { |
|---|
| 1157 | 1201 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
|---|
| 1158 | 1202 | |
|---|
| 1203 | + if (gfs2_withdrawn(sdp)) { |
|---|
| 1204 | + fs_err(sdp, "recovery_result jid %d ignored due to withdraw.\n", |
|---|
| 1205 | + jid); |
|---|
| 1206 | + return; |
|---|
| 1207 | + } |
|---|
| 1159 | 1208 | if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags)) |
|---|
| 1160 | 1209 | return; |
|---|
| 1161 | 1210 | |
|---|