Blame view

fs/dlm/rcom.c 14.6 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
  **
  **  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"
757a42719   David Teigland   dlm: add node slo...
26
  #include "member.h"
e7fd41792   David Teigland   [DLM] The core of...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  
  
  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...
41
  	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
e7fd41792   David Teigland   [DLM] The core of...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  	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...
58
59
60
  	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...
61
62
63
64
65
66
67
68
69
70
71
  	*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);
  }
757a42719   David Teigland   dlm: add node slo...
72
73
74
75
76
  static void set_rcom_status(struct dlm_ls *ls, struct rcom_status *rs,
  			    uint32_t flags)
  {
  	rs->rs_flags = cpu_to_le32(flags);
  }
e7fd41792   David Teigland   [DLM] The core of...
77
78
79
  /* 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. */
757a42719   David Teigland   dlm: add node slo...
80
81
  static void set_rcom_config(struct dlm_ls *ls, struct rcom_config *rf,
  			    uint32_t num_slots)
e7fd41792   David Teigland   [DLM] The core of...
82
  {
93ff2971e   Al Viro   dlm: do not bytes...
83
84
  	rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen);
  	rf->rf_lsflags = cpu_to_le32(ls->ls_exflags);
757a42719   David Teigland   dlm: add node slo...
85
86
87
88
  
  	rf->rf_our_slot = cpu_to_le16(ls->ls_slot);
  	rf->rf_num_slots = cpu_to_le16(num_slots);
  	rf->rf_generation =  cpu_to_le32(ls->ls_generation);
e7fd41792   David Teigland   [DLM] The core of...
89
  }
757a42719   David Teigland   dlm: add node slo...
90
  static int check_rcom_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
e7fd41792   David Teigland   [DLM] The core of...
91
  {
9e971b715   David Teigland   [DLM] add version...
92
93
94
95
96
97
  	struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
  
  	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...
98
  		return -EPROTO;
9e971b715   David Teigland   [DLM] add version...
99
  	}
93ff2971e   Al Viro   dlm: do not bytes...
100
101
  	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...
102
  		log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
93ff2971e   Al Viro   dlm: do not bytes...
103
104
105
  			  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...
106
  		return -EPROTO;
e7fd41792   David Teigland   [DLM] The core of...
107
108
109
  	}
  	return 0;
  }
98f176fb3   David Teigland   [DLM] don't accep...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  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);
  }
757a42719   David Teigland   dlm: add node slo...
125
126
127
128
129
130
131
132
133
134
135
136
  /*
   * low nodeid gathers one slot value at a time from each node.
   * it sets need_slots=0, and saves rf_our_slot returned from each
   * rcom_config.
   *
   * other nodes gather all slot values at once from the low nodeid.
   * they set need_slots=1, and ignore the rf_our_slot returned from each
   * rcom_config.  they use the rf_num_slots returned from the low
   * node's rcom_config.
   */
  
  int dlm_rcom_status(struct dlm_ls *ls, int nodeid, uint32_t status_flags)
e7fd41792   David Teigland   [DLM] The core of...
137
138
139
140
  {
  	struct dlm_rcom *rc;
  	struct dlm_mhandle *mh;
  	int error = 0;
faa0f2677   David Teigland   [DLM] show nodeid...
141
  	ls->ls_recover_nodeid = nodeid;
e7fd41792   David Teigland   [DLM] The core of...
142
143
  
  	if (nodeid == dlm_our_nodeid()) {
4007685c6   Al Viro   dlm: use proper t...
144
  		rc = ls->ls_recover_buf;
e7fd41792   David Teigland   [DLM] The core of...
145
146
147
  		rc->rc_result = dlm_recover_status(ls);
  		goto out;
  	}
757a42719   David Teigland   dlm: add node slo...
148
149
  	error = create_rcom(ls, nodeid, DLM_RCOM_STATUS,
  			    sizeof(struct rcom_status), &rc, &mh);
e7fd41792   David Teigland   [DLM] The core of...
150
151
  	if (error)
  		goto out;
98f176fb3   David Teigland   [DLM] don't accep...
152

757a42719   David Teigland   dlm: add node slo...
153
  	set_rcom_status(ls, (struct rcom_status *)rc->rc_buf, status_flags);
98f176fb3   David Teigland   [DLM] don't accep...
154
  	allow_sync_reply(ls, &rc->rc_id);
68c817a1c   David Teigland   [DLM] rename dlm_...
155
  	memset(ls->ls_recover_buf, 0, dlm_config.ci_buffer_size);
e7fd41792   David Teigland   [DLM] The core of...
156
157
158
159
  
  	send_rcom(ls, mh, rc);
  
  	error = dlm_wait_function(ls, &rcom_response);
98f176fb3   David Teigland   [DLM] don't accep...
160
  	disallow_sync_reply(ls);
e7fd41792   David Teigland   [DLM] The core of...
161
162
  	if (error)
  		goto out;
4007685c6   Al Viro   dlm: use proper t...
163
  	rc = ls->ls_recover_buf;
e7fd41792   David Teigland   [DLM] The core of...
164
165
166
167
168
  
  	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;
757a42719   David Teigland   dlm: add node slo...
169
170
171
172
  		error = 0;
  	} else {
  		error = check_rcom_config(ls, rc, nodeid);
  	}
e7fd41792   David Teigland   [DLM] The core of...
173
174
175
176
177
178
179
180
181
  	/* 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;
757a42719   David Teigland   dlm: add node slo...
182
183
184
185
186
187
188
189
190
191
192
193
194
  	struct rcom_status *rs;
  	uint32_t status;
  	int nodeid = rc_in->rc_header.h_nodeid;
  	int len = sizeof(struct rcom_config);
  	int num_slots = 0;
  	int error;
  
  	if (!dlm_slots_version(&rc_in->rc_header)) {
  		status = dlm_recover_status(ls);
  		goto do_create;
  	}
  
  	rs = (struct rcom_status *)rc_in->rc_buf;
e7fd41792   David Teigland   [DLM] The core of...
195

757a42719   David Teigland   dlm: add node slo...
196
197
198
199
200
201
202
203
204
205
206
207
  	if (!(rs->rs_flags & DLM_RSF_NEED_SLOTS)) {
  		status = dlm_recover_status(ls);
  		goto do_create;
  	}
  
  	spin_lock(&ls->ls_recover_lock);
  	status = ls->ls_recover_status;
  	num_slots = ls->ls_num_slots;
  	spin_unlock(&ls->ls_recover_lock);
  	len += num_slots * sizeof(struct rcom_slot);
  
   do_create:
e7fd41792   David Teigland   [DLM] The core of...
208
  	error = create_rcom(ls, nodeid, DLM_RCOM_STATUS_REPLY,
757a42719   David Teigland   dlm: add node slo...
209
  			    len, &rc, &mh);
e7fd41792   David Teigland   [DLM] The core of...
210
211
  	if (error)
  		return;
757a42719   David Teigland   dlm: add node slo...
212

4a99c3d9d   David Teigland   [DLM] reject repl...
213
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
214
  	rc->rc_seq_reply = rc_in->rc_seq;
757a42719   David Teigland   dlm: add node slo...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  	rc->rc_result = status;
  
  	set_rcom_config(ls, (struct rcom_config *)rc->rc_buf, num_slots);
  
  	if (!num_slots)
  		goto do_send;
  
  	spin_lock(&ls->ls_recover_lock);
  	if (ls->ls_num_slots != num_slots) {
  		spin_unlock(&ls->ls_recover_lock);
  		log_debug(ls, "receive_rcom_status num_slots %d to %d",
  			  num_slots, ls->ls_num_slots);
  		rc->rc_result = 0;
  		set_rcom_config(ls, (struct rcom_config *)rc->rc_buf, 0);
  		goto do_send;
  	}
  
  	dlm_slots_copy_out(ls, rc);
  	spin_unlock(&ls->ls_recover_lock);
e7fd41792   David Teigland   [DLM] The core of...
234

757a42719   David Teigland   dlm: add node slo...
235
   do_send:
e7fd41792   David Teigland   [DLM] The core of...
236
237
  	send_rcom(ls, mh, rc);
  }
4a99c3d9d   David Teigland   [DLM] reject repl...
238
  static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
e7fd41792   David Teigland   [DLM] The core of...
239
  {
98f176fb3   David Teigland   [DLM] don't accep...
240
241
242
243
244
  	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 ...
245
246
  			  (unsigned long long)rc_in->rc_id,
  			  (unsigned long long)ls->ls_rcom_seq);
98f176fb3   David Teigland   [DLM] don't accep...
247
  		goto out;
4a99c3d9d   David Teigland   [DLM] reject repl...
248
  	}
e7fd41792   David Teigland   [DLM] The core of...
249
250
  	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...
251
  	clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags);
e7fd41792   David Teigland   [DLM] The core of...
252
  	wake_up(&ls->ls_wait_general);
98f176fb3   David Teigland   [DLM] don't accep...
253
254
   out:
  	spin_unlock(&ls->ls_rcom_spin);
e7fd41792   David Teigland   [DLM] The core of...
255
256
257
258
259
260
  }
  
  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...
261
262
  	int error = 0;
  	int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
e7fd41792   David Teigland   [DLM] The core of...
263

faa0f2677   David Teigland   [DLM] show nodeid...
264
  	ls->ls_recover_nodeid = nodeid;
e7fd41792   David Teigland   [DLM] The core of...
265
266
  
  	if (nodeid == dlm_our_nodeid()) {
599e0f584   David Teigland   dlm: fix rcom_nam...
267
268
  		ls->ls_recover_buf->rc_header.h_length =
  			dlm_config.ci_buffer_size;
e7fd41792   David Teigland   [DLM] The core of...
269
  		dlm_copy_master_names(ls, last_name, last_len,
4007685c6   Al Viro   dlm: use proper t...
270
271
  		                      ls->ls_recover_buf->rc_buf,
  		                      max_size, nodeid);
e7fd41792   David Teigland   [DLM] The core of...
272
273
274
275
276
277
278
  		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...
279
280
  
  	allow_sync_reply(ls, &rc->rc_id);
68c817a1c   David Teigland   [DLM] rename dlm_...
281
  	memset(ls->ls_recover_buf, 0, dlm_config.ci_buffer_size);
e7fd41792   David Teigland   [DLM] The core of...
282
283
284
285
  
  	send_rcom(ls, mh, rc);
  
  	error = dlm_wait_function(ls, &rcom_response);
98f176fb3   David Teigland   [DLM] don't accep...
286
  	disallow_sync_reply(ls);
e7fd41792   David Teigland   [DLM] The core of...
287
288
289
290
291
292
293
294
   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...
295
  	int error, inlen, outlen, nodeid;
e7fd41792   David Teigland   [DLM] The core of...
296
297
298
  
  	nodeid = rc_in->rc_header.h_nodeid;
  	inlen = rc_in->rc_header.h_length - sizeof(struct dlm_rcom);
68c817a1c   David Teigland   [DLM] rename dlm_...
299
  	outlen = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
e7fd41792   David Teigland   [DLM] The core of...
300
301
302
303
  
  	error = create_rcom(ls, nodeid, DLM_RCOM_NAMES_REPLY, outlen, &rc, &mh);
  	if (error)
  		return;
4a99c3d9d   David Teigland   [DLM] reject repl...
304
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
305
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
306
307
308
309
310
  
  	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...
311
312
313
314
315
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
  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...
346
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
347
348
349
350
351
352
353
354
355
356
357
358
359
  
  	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...
360
361
362
363
364
  	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...
365
366
367
  	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...
368
  	rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type);
e7fd41792   David Teigland   [DLM] The core of...
369

e5dae548b   David Teigland   dlm: proper types...
370
  	if (lkb->lkb_bastfn)
8304d6f24   David Teigland   dlm: record full ...
371
  		rl->rl_asts |= DLM_CB_BAST;
e5dae548b   David Teigland   dlm: proper types...
372
  	if (lkb->lkb_astfn)
8304d6f24   David Teigland   dlm: record full ...
373
  		rl->rl_asts |= DLM_CB_CAST;
e7fd41792   David Teigland   [DLM] The core of...
374

163a1859e   Al Viro   dlm: do not bytes...
375
  	rl->rl_namelen = cpu_to_le16(r->res_length);
e7fd41792   David Teigland   [DLM] The core of...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  	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 ...
408
  /* needs at least dlm_rcom + rcom_lock */
e7fd41792   David Teigland   [DLM] The core of...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
  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...
427
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
428
429
430
  
  	send_rcom(ls, mh, rc);
  }
c36258b59   David Teigland   [DLM] block dlm_r...
431
432
433
434
  /* 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...
435
436
  {
  	struct dlm_rcom *rc;
1babdb453   David Teigland   [DLM] fix size of...
437
  	struct rcom_config *rf;
e7fd41792   David Teigland   [DLM] The core of...
438
439
  	struct dlm_mhandle *mh;
  	char *mb;
1babdb453   David Teigland   [DLM] fix size of...
440
  	int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
e7fd41792   David Teigland   [DLM] The core of...
441

41684f954   David Teigland   [DLM] fix NULL ls...
442
  	mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb);
e7fd41792   David Teigland   [DLM] The core of...
443
444
445
446
447
448
449
450
451
452
453
454
455
  	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...
456
  	rc->rc_id = rc_in->rc_id;
38aa8b0c5   David Teigland   [DLM] fix old rco...
457
  	rc->rc_seq_reply = rc_in->rc_seq;
e7fd41792   David Teigland   [DLM] The core of...
458
  	rc->rc_result = -ESRCH;
1babdb453   David Teigland   [DLM] fix size of...
459
  	rf = (struct rcom_config *) rc->rc_buf;
93ff2971e   Al Viro   dlm: do not bytes...
460
  	rf->rf_lvblen = cpu_to_le32(~0U);
1babdb453   David Teigland   [DLM] fix size of...
461

e7fd41792   David Teigland   [DLM] The core of...
462
463
464
465
466
  	dlm_rcom_out(rc);
  	dlm_lowcomms_commit_buffer(mh);
  
  	return 0;
  }
38aa8b0c5   David Teigland   [DLM] fix old rco...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  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...
481
  			log_debug(ls, "ignoring old reply %x from %d "
38aa8b0c5   David Teigland   [DLM] fix old rco...
482
483
484
485
486
487
488
489
490
  				      "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...
491
  /* Called by dlm_recv; corresponds to dlm_receive_message() but special
e7fd41792   David Teigland   [DLM] The core of...
492
     recovery-only comms are sent through here. */
c36258b59   David Teigland   [DLM] block dlm_r...
493
  void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
e7fd41792   David Teigland   [DLM] The core of...
494
  {
ae773d0b7   Al Viro   dlm: verify that ...
495
  	int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock);
e7fd41792   David Teigland   [DLM] The core of...
496
  	if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
8ec688674   David Teigland   [DLM] change some...
497
  		log_debug(ls, "ignoring recovery message %x from %d",
e7fd41792   David Teigland   [DLM] The core of...
498
499
500
  			  rc->rc_type, nodeid);
  		goto out;
  	}
38aa8b0c5   David Teigland   [DLM] fix old rco...
501
502
  	if (is_old_reply(ls, rc))
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  	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 ...
517
518
  		if (rc->rc_header.h_length < lock_size)
  			goto Eshort;
e7fd41792   David Teigland   [DLM] The core of...
519
520
521
522
  		receive_rcom_lock(ls, rc);
  		break;
  
  	case DLM_RCOM_STATUS_REPLY:
dbcfc3473   David Teigland   dlm: clean ups
523
  		receive_sync_reply(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
524
525
526
  		break;
  
  	case DLM_RCOM_NAMES_REPLY:
dbcfc3473   David Teigland   dlm: clean ups
527
  		receive_sync_reply(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
528
529
530
531
532
533
534
  		break;
  
  	case DLM_RCOM_LOOKUP_REPLY:
  		receive_rcom_lookup_reply(ls, rc);
  		break;
  
  	case DLM_RCOM_LOCK_REPLY:
ae773d0b7   Al Viro   dlm: verify that ...
535
536
  		if (rc->rc_header.h_length < lock_size)
  			goto Eshort;
dbcfc3473   David Teigland   dlm: clean ups
537
  		dlm_recover_process_copy(ls, rc);
e7fd41792   David Teigland   [DLM] The core of...
538
539
540
  		break;
  
  	default:
dbcfc3473   David Teigland   dlm: clean ups
541
  		log_error(ls, "receive_rcom bad type %d", rc->rc_type);
e7fd41792   David Teigland   [DLM] The core of...
542
  	}
ae773d0b7   Al Viro   dlm: verify that ...
543
  out:
c36258b59   David Teigland   [DLM] block dlm_r...
544
  	return;
ae773d0b7   Al Viro   dlm: verify that ...
545
546
547
  Eshort:
  	log_error(ls, "recovery message %x from %d is too short",
  			  rc->rc_type, nodeid);
e7fd41792   David Teigland   [DLM] The core of...
548
  }