hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/gfs2/lock_dlm.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
34 * 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.
85 */
96
107 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -19,6 +16,8 @@
1916
2017 #include "incore.h"
2118 #include "glock.h"
19
+#include "glops.h"
20
+#include "recovery.h"
2221 #include "util.h"
2322 #include "sys.h"
2423 #include "trace_gfs2.h"
....@@ -127,6 +126,8 @@
127126
128127 switch (gl->gl_lksb.sb_status) {
129128 case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
129
+ if (gl->gl_ops->go_free)
130
+ gl->gl_ops->go_free(gl);
130131 gfs2_glock_free(gl);
131132 return;
132133 case -DLM_ECANCEL: /* Cancel while getting lock */
....@@ -178,14 +179,14 @@
178179 gfs2_glock_cb(gl, LM_ST_SHARED);
179180 break;
180181 default:
181
- pr_err("unknown bast mode %d\n", mode);
182
+ fs_err(gl->gl_name.ln_sbd, "unknown bast mode %d\n", mode);
182183 BUG();
183184 }
184185 }
185186
186187 /* convert gfs lock-state to dlm lock-mode */
187188
188
-static int make_mode(const unsigned int lmstate)
189
+static int make_mode(struct gfs2_sbd *sdp, const unsigned int lmstate)
189190 {
190191 switch (lmstate) {
191192 case LM_ST_UNLOCKED:
....@@ -197,7 +198,7 @@
197198 case LM_ST_SHARED:
198199 return DLM_LOCK_PR;
199200 }
200
- pr_err("unknown LM state %d\n", lmstate);
201
+ fs_err(sdp, "unknown LM state %d\n", lmstate);
201202 BUG();
202203 return -1;
203204 }
....@@ -258,7 +259,7 @@
258259 u32 lkf;
259260 char strname[GDLM_STRNAME_BYTES] = "";
260261
261
- req = make_mode(req_state);
262
+ req = make_mode(gl->gl_name.ln_sbd, req_state);
262263 lkf = make_flags(gl, flags, req);
263264 gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
264265 gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
....@@ -311,7 +312,7 @@
311312 error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
312313 NULL, gl);
313314 if (error) {
314
- pr_err("gdlm_unlock %x,%llx err=%d\n",
315
+ fs_err(sdp, "gdlm_unlock %x,%llx err=%d\n",
315316 gl->gl_name.ln_type,
316317 (unsigned long long)gl->gl_name.ln_number, error);
317318 return;
....@@ -327,6 +328,7 @@
327328 /*
328329 * dlm/gfs2 recovery coordination using dlm_recover callbacks
329330 *
331
+ * 0. gfs2 checks for another cluster node withdraw, needing journal replay
330332 * 1. dlm_controld sees lockspace members change
331333 * 2. dlm_controld blocks dlm-kernel locking activity
332334 * 3. dlm_controld within dlm-kernel notifies gfs2 (recover_prep)
....@@ -575,6 +577,28 @@
575577 &ls->ls_control_lksb, "control_lock");
576578 }
577579
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
+
578602 static void gfs2_control_func(struct work_struct *work)
579603 {
580604 struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work);
....@@ -584,6 +608,13 @@
584608 int write_lvb = 0;
585609 int recover_size;
586610 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
+ }
587618
588619 spin_lock(&ls->ls_recover_spin);
589620 /*
....@@ -1039,11 +1070,11 @@
10391070 }
10401071
10411072 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)
10441077 return 0;
1045
-
1046
- new_size = old_size + RECOVER_SIZE_INC;
10471078
10481079 submit = kcalloc(new_size, sizeof(uint32_t), GFP_NOFS);
10491080 result = kcalloc(new_size, sizeof(uint32_t), GFP_NOFS);
....@@ -1083,6 +1114,10 @@
10831114 struct gfs2_sbd *sdp = arg;
10841115 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
10851116
1117
+ if (gfs2_withdrawn(sdp)) {
1118
+ fs_err(sdp, "recover_prep ignored due to withdraw.\n");
1119
+ return;
1120
+ }
10861121 spin_lock(&ls->ls_recover_spin);
10871122 ls->ls_recover_block = ls->ls_recover_start;
10881123 set_bit(DFL_DLM_RECOVERY, &ls->ls_recover_flags);
....@@ -1105,6 +1140,11 @@
11051140 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
11061141 int jid = slot->slot - 1;
11071142
1143
+ if (gfs2_withdrawn(sdp)) {
1144
+ fs_err(sdp, "recover_slot jid %d ignored due to withdraw.\n",
1145
+ jid);
1146
+ return;
1147
+ }
11081148 spin_lock(&ls->ls_recover_spin);
11091149 if (ls->ls_recover_size < jid + 1) {
11101150 fs_err(sdp, "recover_slot jid %d gen %u short size %d\n",
....@@ -1129,6 +1169,10 @@
11291169 struct gfs2_sbd *sdp = arg;
11301170 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
11311171
1172
+ if (gfs2_withdrawn(sdp)) {
1173
+ fs_err(sdp, "recover_done ignored due to withdraw.\n");
1174
+ return;
1175
+ }
11321176 /* ensure the ls jid arrays are large enough */
11331177 set_recover_size(sdp, slots, num_slots);
11341178
....@@ -1156,6 +1200,11 @@
11561200 {
11571201 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
11581202
1203
+ if (gfs2_withdrawn(sdp)) {
1204
+ fs_err(sdp, "recovery_result jid %d ignored due to withdraw.\n",
1205
+ jid);
1206
+ return;
1207
+ }
11591208 if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
11601209 return;
11611210