Blame view

fs/dlm/rcom.c 13 KB
e7fd41792   David Teigland   [DLM] The core of...
1
2
3
4
  /******************************************************************************
  *******************************************************************************
  **
  **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
dbcfc3473   David Teigland   dlm: clean ups
5
  **  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
e7fd41792   David Teigland   [DLM] The core of...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  **
  **  This copyrighted material is made available to anyone wishing to use,
  **  modify, copy, or redistribute it subject to the terms and conditions
  **  of the GNU General Public License v.2.
  **
  *******************************************************************************
  ******************************************************************************/
  
  #include "dlm_internal.h"
  #include "lockspace.h"
  #include "member.h"
  #include "lowcomms.h"
  #include "midcomms.h"
  #include "rcom.h"
  #include "recover.h"
  #include "dir.h"
  #include "config.h"
  #include "memory.h"
  #include "lock.h"
  #include "util.h"
  
  
  static int rcom_response(struct dlm_ls *ls)
  {
  	return test_bit(LSFL_RCOM_READY, &ls->ls_flags);
  }
  
  static int create_rcom(struct dlm_ls *ls, int to_nodeid, int type, int len,
  		       struct dlm_rcom **rc_ret, struct dlm_mhandle **mh_ret)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	char *mb;
  	int mb_len = sizeof(struct dlm_rcom) + len;
573c24c4a   David Teigland   dlm: always use G...
40
  	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
e7fd41792   David Teigland   [DLM] The core of...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  	if (!mh) {
  		log_print("create_rcom to %d type %d len %d ENOBUFS",
  			  to_nodeid, type, len);
  		return -ENOBUFS;
  	}
  	memset(mb, 0, mb_len);
  
  	rc = (struct dlm_rcom *) mb;
  
  	rc->rc_header.h_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR);
  	rc->rc_header.h_lockspace = ls->ls_global_id;
  	rc->rc_header.h_nodeid = dlm_our_nodeid();
  	rc->rc_header.h_length = mb_len;
  	rc->rc_header.h_cmd = DLM_RCOM;
  
  	rc->rc_type = type;
38aa8b0c5   David Teigland   [DLM] fix old rco...
57
58
59
  	spin_lock(&ls->ls_recover_lock);
  	rc->rc_seq = ls->ls_recover_seq;
  	spin_unlock(&ls->ls_recover_lock);
e7fd41792   David Teigland   [DLM] The core of...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  	*mh_ret = mh;
  	*rc_ret = rc;
  	return 0;
  }
  
  static void send_rcom(struct dlm_ls *ls, struct dlm_mhandle *mh,
  		      struct dlm_rcom *rc)
  {
  	dlm_rcom_out(rc);
  	dlm_lowcomms_commit_buffer(mh);
  }
  
  /* When replying to a status request, a node also sends back its
     configuration values.  The requesting node then checks that the remote
     node is configured the same way as itself. */
  
  static void make_config(struct dlm_ls *ls, struct rcom_config *rf)
  {
93ff2971e   Al Viro   dlm: do not bytes...
78
79
  	rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen);
  	rf->rf_lsflags = cpu_to_le32(ls->ls_exflags);
e7fd41792   David Teigland   [DLM] The core of...
80
  }
9e971b715   David Teigland   [DLM] add version...
81
  static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
e7fd41792   David Teigland   [DLM] The core of...
82
  {
9e971b715   David Teigland   [DLM] add version...
83
  	struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
02ed16b64   Al Viro   dlm: missing leng...
84
  	size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
9e971b715   David Teigland   [DLM] add version...
85
86
87
88
89
  
  	if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) {
  		log_error(ls, "version mismatch: %x nodeid %d: %x",
  			  DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid,
  			  rc->rc_header.h_version);
8b0e7b2cf   David Teigland   [DLM] wait for co...
90
  		return -EPROTO;
9e971b715   David Teigland   [DLM] add version...
91
  	}
02ed16b64   Al Viro   dlm: missing leng...
92
93
94
95
96
  	if (rc->rc_header.h_length < conf_size) {
  		log_error(ls, "config too short: %d nodeid %d",
  			  rc->rc_header.h_length, nodeid);
  		return -EPROTO;
  	}
93ff2971e   Al Viro   dlm: do not bytes...
97
98
  	if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen ||
  	    le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) {
e7fd41792   David Teigland   [DLM] The core of...
99
  		log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
93ff2971e   Al Viro   dlm: do not bytes...
100
101
102
  			  ls->ls_lvblen, ls->ls_exflags, nodeid,
  			  le32_to_cpu(rf->rf_lvblen),
  			  le32_to_cpu(rf->rf_lsflags));
8b0e7b2cf   David Teigland   [DLM] wait for co...
103
  		return -EPROTO;
e7fd41792   David Teigland   [DLM] The core of...
104
105
106
  	}
  	return 0;
  }
98f176fb3   David Teigland   [DLM] don't accep...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  static void allow_sync_reply(struct dlm_ls *ls, uint64_t *new_seq)
  {
  	spin_lock(&ls->ls_rcom_spin);
  	*new_seq = ++ls->ls_rcom_seq;
  	set_bit(LSFL_RCOM_WAIT, &ls->ls_flags);
  	spin_unlock(&ls->ls_rcom_spin);
  }
  
  static void disallow_sync_reply(struct dlm_ls *ls)
  {
  	spin_lock(&ls->ls_rcom_spin);
  	clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags);
  	clear_bit(LSFL_RCOM_READY, &ls->ls_flags);
  	spin_unlock(&ls->ls_rcom_spin);
  }
e7fd41792   David Teigland   [DLM] The core of...
122
123
124
125
126
  int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	int error = 0;
faa0f2677   David Teigland   [DLM] show nodeid...
127
  	ls->ls_recover_nodeid = nodeid;
e7fd41792   David Teigland   [DLM] The core of...
128
129
  
  	if (nodeid == dlm_our_nodeid()) {
4007685c6   Al Viro   dlm: use proper t...
130
  		rc = ls->ls_recover_buf;
e7fd41792   David Teigland   [DLM] The core of...
131
132
133
134
135
136
137
  		rc->rc_result = dlm_recover_status(ls);
  		goto out;
  	}
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh);
  	if (error)
  		goto out;
98f176fb3   David Teigland   [DLM] don't accep...
138
139
  
  	allow_sync_reply(ls, &rc->rc_id);
68c817a1c   David Teigland   [DLM] rename dlm_...
140
  	memset(ls->ls_recover_buf, 0, dlm_config.ci_buffer_size);
e7fd41792   David Teigland   [DLM] The core of...
141
142
143
144
  
  	send_rcom(ls, mh, rc);
  
  	error = dlm_wait_function(ls, &rcom_response);
98f176fb3   David Teigland   [DLM] don't accep...
145
  	disallow_sync_reply(ls);
e7fd41792   David Teigland   [DLM] The core of...
146
147
  	if (error)
  		goto out;
4007685c6   Al Viro   dlm: use proper t...
148
  	rc = ls->ls_recover_buf;
e7fd41792   David Teigland   [DLM] The core of...
149
150
151
152
153
154
  
  	if (rc->rc_result == -ESRCH) {
  		/* we pretend the remote lockspace exists with 0 status */
  		log_debug(ls, "remote node %d not ready", nodeid);
  		rc->rc_result = 0;
  	} else
9e971b715   David Teigland   [DLM] add version...
155
  		error = check_config(ls, rc, nodeid);
e7fd41792   David Teigland   [DLM] The core of...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  	/* the caller looks at rc_result for the remote recovery status */
   out:
  	return error;
  }
  
  static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	int error, nodeid = rc_in->rc_header.h_nodeid;
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_STATUS_REPLY,
  			    sizeof(struct rcom_config), &rc, &mh);
  	if (error)
  		return;
4a99c3d9d   David Teigland   [DLM] reject repl...
171
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
172
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
173
174
175
176
177
  	rc->rc_result = dlm_recover_status(ls);
  	make_config(ls, (struct rcom_config *) rc->rc_buf);
  
  	send_rcom(ls, mh, rc);
  }
4a99c3d9d   David Teigland   [DLM] reject repl...
178
  static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
e7fd41792   David Teigland   [DLM] The core of...
179
  {
98f176fb3   David Teigland   [DLM] don't accep...
180
181
182
183
184
  	spin_lock(&ls->ls_rcom_spin);
  	if (!test_bit(LSFL_RCOM_WAIT, &ls->ls_flags) ||
  	    rc_in->rc_id != ls->ls_rcom_seq) {
  		log_debug(ls, "reject reply %d from %d seq %llx expect %llx",
  			  rc_in->rc_type, rc_in->rc_header.h_nodeid,
57adf7eed   Ryusuke Konishi   [DLM] fix format ...
185
186
  			  (unsigned long long)rc_in->rc_id,
  			  (unsigned long long)ls->ls_rcom_seq);
98f176fb3   David Teigland   [DLM] don't accep...
187
  		goto out;
4a99c3d9d   David Teigland   [DLM] reject repl...
188
  	}
e7fd41792   David Teigland   [DLM] The core of...
189
190
  	memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length);
  	set_bit(LSFL_RCOM_READY, &ls->ls_flags);
98f176fb3   David Teigland   [DLM] don't accep...
191
  	clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags);
e7fd41792   David Teigland   [DLM] The core of...
192
  	wake_up(&ls->ls_wait_general);
98f176fb3   David Teigland   [DLM] don't accep...
193
194
   out:
  	spin_unlock(&ls->ls_rcom_spin);
e7fd41792   David Teigland   [DLM] The core of...
195
196
197
198
199
200
  }
  
  int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
4007685c6   Al Viro   dlm: use proper t...
201
202
  	int error = 0;
  	int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
e7fd41792   David Teigland   [DLM] The core of...
203

faa0f2677   David Teigland   [DLM] show nodeid...
204
  	ls->ls_recover_nodeid = nodeid;
e7fd41792   David Teigland   [DLM] The core of...
205
206
  
  	if (nodeid == dlm_our_nodeid()) {
599e0f584   David Teigland   dlm: fix rcom_nam...
207
208
  		ls->ls_recover_buf->rc_header.h_length =
  			dlm_config.ci_buffer_size;
e7fd41792   David Teigland   [DLM] The core of...
209
  		dlm_copy_master_names(ls, last_name, last_len,
4007685c6   Al Viro   dlm: use proper t...
210
211
  		                      ls->ls_recover_buf->rc_buf,
  		                      max_size, nodeid);
e7fd41792   David Teigland   [DLM] The core of...
212
213
214
215
216
217
218
  		goto out;
  	}
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_NAMES, last_len, &rc, &mh);
  	if (error)
  		goto out;
  	memcpy(rc->rc_buf, last_name, last_len);
98f176fb3   David Teigland   [DLM] don't accep...
219
220
  
  	allow_sync_reply(ls, &rc->rc_id);
68c817a1c   David Teigland   [DLM] rename dlm_...
221
  	memset(ls->ls_recover_buf, 0, dlm_config.ci_buffer_size);
e7fd41792   David Teigland   [DLM] The core of...
222
223
224
225
  
  	send_rcom(ls, mh, rc);
  
  	error = dlm_wait_function(ls, &rcom_response);
98f176fb3   David Teigland   [DLM] don't accep...
226
  	disallow_sync_reply(ls);
e7fd41792   David Teigland   [DLM] The core of...
227
228
229
230
231
232
233
234
   out:
  	return error;
  }
  
  static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
38aa8b0c5   David Teigland   [DLM] fix old rco...
235
  	int error, inlen, outlen, nodeid;
e7fd41792   David Teigland   [DLM] The core of...
236
237
238
  
  	nodeid = rc_in->rc_header.h_nodeid;
  	inlen = rc_in->rc_header.h_length - sizeof(struct dlm_rcom);
68c817a1c   David Teigland   [DLM] rename dlm_...
239
  	outlen = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
e7fd41792   David Teigland   [DLM] The core of...
240
241
242
243
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_NAMES_REPLY, outlen, &rc, &mh);
  	if (error)
  		return;
4a99c3d9d   David Teigland   [DLM] reject repl...
244
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
245
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
246
247
248
249
250
  
  	dlm_copy_master_names(ls, rc_in->rc_buf, inlen, rc->rc_buf, outlen,
  			      nodeid);
  	send_rcom(ls, mh, rc);
  }
e7fd41792   David Teigland   [DLM] The core of...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	struct dlm_ls *ls = r->res_ls;
  	int error;
  
  	error = create_rcom(ls, dir_nodeid, DLM_RCOM_LOOKUP, r->res_length,
  			    &rc, &mh);
  	if (error)
  		goto out;
  	memcpy(rc->rc_buf, r->res_name, r->res_length);
  	rc->rc_id = (unsigned long) r;
  
  	send_rcom(ls, mh, rc);
   out:
  	return error;
  }
  
  static void receive_rcom_lookup(struct dlm_ls *ls, struct dlm_rcom *rc_in)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	int error, ret_nodeid, nodeid = rc_in->rc_header.h_nodeid;
  	int len = rc_in->rc_header.h_length - sizeof(struct dlm_rcom);
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_LOOKUP_REPLY, 0, &rc, &mh);
  	if (error)
  		return;
  
  	error = dlm_dir_lookup(ls, nodeid, rc_in->rc_buf, len, &ret_nodeid);
  	if (error)
  		ret_nodeid = error;
  	rc->rc_result = ret_nodeid;
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
286
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
287
288
289
290
291
292
293
294
295
296
297
298
299
  
  	send_rcom(ls, mh, rc);
  }
  
  static void receive_rcom_lookup_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
  {
  	dlm_recover_master_reply(ls, rc_in);
  }
  
  static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			   struct rcom_lock *rl)
  {
  	memset(rl, 0, sizeof(*rl));
163a1859e   Al Viro   dlm: do not bytes...
300
301
302
303
304
  	rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid);
  	rl->rl_lkid = cpu_to_le32(lkb->lkb_id);
  	rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags);
  	rl->rl_flags = cpu_to_le32(lkb->lkb_flags);
  	rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq);
e7fd41792   David Teigland   [DLM] The core of...
305
306
307
  	rl->rl_rqmode = lkb->lkb_rqmode;
  	rl->rl_grmode = lkb->lkb_grmode;
  	rl->rl_status = lkb->lkb_status;
163a1859e   Al Viro   dlm: do not bytes...
308
  	rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type);
e7fd41792   David Teigland   [DLM] The core of...
309

e5dae548b   David Teigland   dlm: proper types...
310
  	if (lkb->lkb_bastfn)
8304d6f24   David Teigland   dlm: record full ...
311
  		rl->rl_asts |= DLM_CB_BAST;
e5dae548b   David Teigland   dlm: proper types...
312
  	if (lkb->lkb_astfn)
8304d6f24   David Teigland   dlm: record full ...
313
  		rl->rl_asts |= DLM_CB_CAST;
e7fd41792   David Teigland   [DLM] The core of...
314

163a1859e   Al Viro   dlm: do not bytes...
315
  	rl->rl_namelen = cpu_to_le16(r->res_length);
e7fd41792   David Teigland   [DLM] The core of...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  	memcpy(rl->rl_name, r->res_name, r->res_length);
  
  	/* FIXME: might we have an lvb without DLM_LKF_VALBLK set ?
  	   If so, receive_rcom_lock_args() won't take this copy. */
  
  	if (lkb->lkb_lvbptr)
  		memcpy(rl->rl_lvb, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
  }
  
  int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	struct dlm_ls *ls = r->res_ls;
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	struct rcom_lock *rl;
  	int error, len = sizeof(struct rcom_lock);
  
  	if (lkb->lkb_lvbptr)
  		len += ls->ls_lvblen;
  
  	error = create_rcom(ls, r->res_nodeid, DLM_RCOM_LOCK, len, &rc, &mh);
  	if (error)
  		goto out;
  
  	rl = (struct rcom_lock *) rc->rc_buf;
  	pack_rcom_lock(r, lkb, rl);
  	rc->rc_id = (unsigned long) r;
  
  	send_rcom(ls, mh, rc);
   out:
  	return error;
  }
ae773d0b7   Al Viro   dlm: verify that ...
348
  /* needs at least dlm_rcom + rcom_lock */
e7fd41792   David Teigland   [DLM] The core of...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	int error, nodeid = rc_in->rc_header.h_nodeid;
  
  	dlm_recover_master_copy(ls, rc_in);
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_LOCK_REPLY,
  			    sizeof(struct rcom_lock), &rc, &mh);
  	if (error)
  		return;
  
  	/* We send back the same rcom_lock struct we received, but
  	   dlm_recover_master_copy() has filled in rl_remid and rl_result */
  
  	memcpy(rc->rc_buf, rc_in->rc_buf, sizeof(struct rcom_lock));
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
367
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
368
369
370
  
  	send_rcom(ls, mh, rc);
  }
c36258b59   David Teigland   [DLM] block dlm_r...
371
372
373
374
  /* If the lockspace doesn't exist then still send a status message
     back; it's possible that it just doesn't have its global_id yet. */
  
  int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
e7fd41792   David Teigland   [DLM] The core of...
375
376
  {
  	struct dlm_rcom *rc;
1babdb453   David Teigland   [DLM] fix size of...
377
  	struct rcom_config *rf;
e7fd41792   David Teigland   [DLM] The core of...
378
379
  	struct dlm_mhandle *mh;
  	char *mb;
1babdb453   David Teigland   [DLM] fix size of...
380
  	int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
e7fd41792   David Teigland   [DLM] The core of...
381

41684f954   David Teigland   [DLM] fix NULL ls...
382
  	mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb);
e7fd41792   David Teigland   [DLM] The core of...
383
384
385
386
387
388
389
390
391
392
393
394
395
  	if (!mh)
  		return -ENOBUFS;
  	memset(mb, 0, mb_len);
  
  	rc = (struct dlm_rcom *) mb;
  
  	rc->rc_header.h_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR);
  	rc->rc_header.h_lockspace = rc_in->rc_header.h_lockspace;
  	rc->rc_header.h_nodeid = dlm_our_nodeid();
  	rc->rc_header.h_length = mb_len;
  	rc->rc_header.h_cmd = DLM_RCOM;
  
  	rc->rc_type = DLM_RCOM_STATUS_REPLY;
f5888750a   David Teigland   [DLM] sequence nu...
396
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
397
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
398
  	rc->rc_result = -ESRCH;
1babdb453   David Teigland   [DLM] fix size of...
399
  	rf = (struct rcom_config *) rc->rc_buf;
93ff2971e   Al Viro   dlm: do not bytes...
400
  	rf->rf_lvblen = cpu_to_le32(~0U);
1babdb453   David Teigland   [DLM] fix size of...
401

e7fd41792   David Teigland   [DLM] The core of...
402
403
404
405
406
  	dlm_rcom_out(rc);
  	dlm_lowcomms_commit_buffer(mh);
  
  	return 0;
  }
38aa8b0c5   David Teigland   [DLM] fix old rco...
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
  {
  	uint64_t seq;
  	int rv = 0;
  
  	switch (rc->rc_type) {
  	case DLM_RCOM_STATUS_REPLY:
  	case DLM_RCOM_NAMES_REPLY:
  	case DLM_RCOM_LOOKUP_REPLY:
  	case DLM_RCOM_LOCK_REPLY:
  		spin_lock(&ls->ls_recover_lock);
  		seq = ls->ls_recover_seq;
  		spin_unlock(&ls->ls_recover_lock);
  		if (rc->rc_seq_reply != seq) {
8ec688674   David Teigland   [DLM] change some...
421
  			log_debug(ls, "ignoring old reply %x from %d "
38aa8b0c5   David Teigland   [DLM] fix old rco...
422
423
424
425
426
427
428
429
430
  				      "seq_reply %llx expect %llx",
  				      rc->rc_type, rc->rc_header.h_nodeid,
  				      (unsigned long long)rc->rc_seq_reply,
  				      (unsigned long long)seq);
  			rv = 1;
  		}
  	}
  	return rv;
  }
c36258b59   David Teigland   [DLM] block dlm_r...
431
  /* Called by dlm_recv; corresponds to dlm_receive_message() but special
e7fd41792   David Teigland   [DLM] The core of...
432
     recovery-only comms are sent through here. */
c36258b59   David Teigland   [DLM] block dlm_r...
433
  void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
e7fd41792   David Teigland   [DLM] The core of...
434
  {
ae773d0b7   Al Viro   dlm: verify that ...
435
  	int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock);
e7fd41792   David Teigland   [DLM] The core of...
436
  	if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
8ec688674   David Teigland   [DLM] change some...
437
  		log_debug(ls, "ignoring recovery message %x from %d",
e7fd41792   David Teigland   [DLM] The core of...
438
439
440
  			  rc->rc_type, nodeid);
  		goto out;
  	}
38aa8b0c5   David Teigland   [DLM] fix old rco...
441
442
  	if (is_old_reply(ls, rc))
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  	switch (rc->rc_type) {
  	case DLM_RCOM_STATUS:
  		receive_rcom_status(ls, rc);
  		break;
  
  	case DLM_RCOM_NAMES:
  		receive_rcom_names(ls, rc);
  		break;
  
  	case DLM_RCOM_LOOKUP:
  		receive_rcom_lookup(ls, rc);
  		break;
  
  	case DLM_RCOM_LOCK:
ae773d0b7   Al Viro   dlm: verify that ...
457
458
  		if (rc->rc_header.h_length < lock_size)
  			goto Eshort;
e7fd41792   David Teigland   [DLM] The core of...
459
460
461
462
  		receive_rcom_lock(ls, rc);
  		break;
  
  	case DLM_RCOM_STATUS_REPLY:
dbcfc3473   David Teigland   dlm: clean ups
463
  		receive_sync_reply(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
464
465
466
  		break;
  
  	case DLM_RCOM_NAMES_REPLY:
dbcfc3473   David Teigland   dlm: clean ups
467
  		receive_sync_reply(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
468
469
470
471
472
473
474
  		break;
  
  	case DLM_RCOM_LOOKUP_REPLY:
  		receive_rcom_lookup_reply(ls, rc);
  		break;
  
  	case DLM_RCOM_LOCK_REPLY:
ae773d0b7   Al Viro   dlm: verify that ...
475
476
  		if (rc->rc_header.h_length < lock_size)
  			goto Eshort;
dbcfc3473   David Teigland   dlm: clean ups
477
  		dlm_recover_process_copy(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
478
479
480
  		break;
  
  	default:
dbcfc3473   David Teigland   dlm: clean ups
481
  		log_error(ls, "receive_rcom bad type %d", rc->rc_type);
e7fd41792   David Teigland   [DLM] The core of...
482
  	}
ae773d0b7   Al Viro   dlm: verify that ...
483
  out:
c36258b59   David Teigland   [DLM] block dlm_r...
484
  	return;
ae773d0b7   Al Viro   dlm: verify that ...
485
486
487
  Eshort:
  	log_error(ls, "recovery message %x from %d is too short",
  			  rc->rc_type, nodeid);
e7fd41792   David Teigland   [DLM] The core of...
488
  }