Blame view

fs/dlm/lock.c 158 KB
e7fd41792   David Teigland   [DLM] The core of...
1
2
3
  /******************************************************************************
  *******************************************************************************
  **
7fe2b3190   David Teigland   dlm: fix ordering...
4
  **  Copyright (C) 2005-2010 Red Hat, Inc.  All rights reserved.
e7fd41792   David Teigland   [DLM] The core of...
5
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  **
  **  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.
  **
  *******************************************************************************
  ******************************************************************************/
  
  /* Central locking logic has four stages:
  
     dlm_lock()
     dlm_unlock()
  
     request_lock(ls, lkb)
     convert_lock(ls, lkb)
     unlock_lock(ls, lkb)
     cancel_lock(ls, lkb)
  
     _request_lock(r, lkb)
     _convert_lock(r, lkb)
     _unlock_lock(r, lkb)
     _cancel_lock(r, lkb)
  
     do_request(r, lkb)
     do_convert(r, lkb)
     do_unlock(r, lkb)
     do_cancel(r, lkb)
  
     Stage 1 (lock, unlock) is mainly about checking input args and
     splitting into one of the four main operations:
  
         dlm_lock          = request_lock
         dlm_lock+CONVERT  = convert_lock
         dlm_unlock        = unlock_lock
         dlm_unlock+CANCEL = cancel_lock
  
     Stage 2, xxxx_lock(), just finds and locks the relevant rsb which is
     provided to the next stage.
  
     Stage 3, _xxxx_lock(), determines if the operation is local or remote.
     When remote, it calls send_xxxx(), when local it calls do_xxxx().
  
     Stage 4, do_xxxx(), is the guts of the operation.  It manipulates the
     given rsb and lkb and queues callbacks.
  
     For remote operations, send_xxxx() results in the corresponding do_xxxx()
     function being executed on the remote node.  The connecting send/receive
     calls on local (L) and remote (R) nodes:
  
     L: send_xxxx()              ->  R: receive_xxxx()
                                     R: do_xxxx()
     L: receive_xxxx_reply()     <-  R: send_xxxx_reply()
  */
597d0cae0   David Teigland   [DLM] dlm: user l...
58
  #include <linux/types.h>
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
59
  #include <linux/rbtree.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
60
  #include <linux/slab.h>
e7fd41792   David Teigland   [DLM] The core of...
61
  #include "dlm_internal.h"
597d0cae0   David Teigland   [DLM] dlm: user l...
62
  #include <linux/dlm_device.h>
e7fd41792   David Teigland   [DLM] The core of...
63
64
65
66
67
68
69
70
71
72
73
74
  #include "memory.h"
  #include "lowcomms.h"
  #include "requestqueue.h"
  #include "util.h"
  #include "dir.h"
  #include "member.h"
  #include "lockspace.h"
  #include "ast.h"
  #include "lock.h"
  #include "rcom.h"
  #include "recover.h"
  #include "lvb_table.h"
597d0cae0   David Teigland   [DLM] dlm: user l...
75
  #include "user.h"
e7fd41792   David Teigland   [DLM] The core of...
76
77
78
79
80
81
82
83
84
85
86
  #include "config.h"
  
  static int send_request(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_grant(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int mode);
  static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb);
  static int send_remove(struct dlm_rsb *r);
  static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
3ae1acf93   David Teigland   [DLM] add lock ti...
87
  static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
e7fd41792   David Teigland   [DLM] The core of...
88
89
90
  static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
  				    struct dlm_message *ms);
  static int receive_extralen(struct dlm_message *ms);
8499137d4   David Teigland   [DLM] add orphan ...
91
  static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
3ae1acf93   David Teigland   [DLM] add lock ti...
92
  static void del_timeout(struct dlm_lkb *lkb);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
93
  static void toss_rsb(struct kref *kref);
e7fd41792   David Teigland   [DLM] The core of...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  
  /*
   * Lock compatibilty matrix - thanks Steve
   * UN = Unlocked state. Not really a state, used as a flag
   * PD = Padding. Used to make the matrix a nice power of two in size
   * Other states are the same as the VMS DLM.
   * Usage: matrix[grmode+1][rqmode+1]  (although m[rq+1][gr+1] is the same)
   */
  
  static const int __dlm_compat_matrix[8][8] = {
        /* UN NL CR CW PR PW EX PD */
          {1, 1, 1, 1, 1, 1, 1, 0},       /* UN */
          {1, 1, 1, 1, 1, 1, 1, 0},       /* NL */
          {1, 1, 1, 1, 1, 1, 0, 0},       /* CR */
          {1, 1, 1, 1, 0, 0, 0, 0},       /* CW */
          {1, 1, 1, 0, 1, 0, 0, 0},       /* PR */
          {1, 1, 1, 0, 0, 0, 0, 0},       /* PW */
          {1, 1, 0, 0, 0, 0, 0, 0},       /* EX */
          {0, 0, 0, 0, 0, 0, 0, 0}        /* PD */
  };
  
  /*
   * This defines the direction of transfer of LVB data.
   * Granted mode is the row; requested mode is the column.
   * Usage: matrix[grmode+1][rqmode+1]
   * 1 = LVB is returned to the caller
   * 0 = LVB is written to the resource
   * -1 = nothing happens to the LVB
   */
  
  const int dlm_lvb_operations[8][8] = {
          /* UN   NL  CR  CW  PR  PW  EX  PD*/
          {  -1,  1,  1,  1,  1,  1,  1, -1 }, /* UN */
          {  -1,  1,  1,  1,  1,  1,  1,  0 }, /* NL */
          {  -1, -1,  1,  1,  1,  1,  1,  0 }, /* CR */
          {  -1, -1, -1,  1,  1,  1,  1,  0 }, /* CW */
          {  -1, -1, -1, -1,  1,  1,  1,  0 }, /* PR */
          {  -1,  0,  0,  0,  0,  0,  1,  0 }, /* PW */
          {  -1,  0,  0,  0,  0,  0,  0,  0 }, /* EX */
          {  -1,  0,  0,  0,  0,  0,  0,  0 }  /* PD */
  };
e7fd41792   David Teigland   [DLM] The core of...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  
  #define modes_compat(gr, rq) \
  	__dlm_compat_matrix[(gr)->lkb_grmode + 1][(rq)->lkb_rqmode + 1]
  
  int dlm_modes_compat(int mode1, int mode2)
  {
  	return __dlm_compat_matrix[mode1 + 1][mode2 + 1];
  }
  
  /*
   * Compatibility matrix for conversions with QUECVT set.
   * Granted mode is the row; requested mode is the column.
   * Usage: matrix[grmode+1][rqmode+1]
   */
  
  static const int __quecvt_compat_matrix[8][8] = {
        /* UN NL CR CW PR PW EX PD */
          {0, 0, 0, 0, 0, 0, 0, 0},       /* UN */
          {0, 0, 1, 1, 1, 1, 1, 0},       /* NL */
          {0, 0, 0, 1, 1, 1, 1, 0},       /* CR */
          {0, 0, 0, 0, 1, 1, 1, 0},       /* CW */
          {0, 0, 0, 1, 0, 1, 1, 0},       /* PR */
          {0, 0, 0, 0, 0, 0, 1, 0},       /* PW */
          {0, 0, 0, 0, 0, 0, 0, 0},       /* EX */
          {0, 0, 0, 0, 0, 0, 0, 0}        /* PD */
  };
597d0cae0   David Teigland   [DLM] dlm: user l...
161
  void dlm_print_lkb(struct dlm_lkb *lkb)
e7fd41792   David Teigland   [DLM] The core of...
162
  {
6d40c4a70   David Teigland   dlm: improve erro...
163
  	printk(KERN_ERR "lkb: nodeid %d id %x remid %x exflags %x flags %x "
4875647a0   David Teigland   dlm: fixes for no...
164
165
  	       "sts %d rq %d gr %d wait_type %d wait_nodeid %d seq %llu
  ",
e7fd41792   David Teigland   [DLM] The core of...
166
167
  	       lkb->lkb_nodeid, lkb->lkb_id, lkb->lkb_remid, lkb->lkb_exflags,
  	       lkb->lkb_flags, lkb->lkb_status, lkb->lkb_rqmode,
4875647a0   David Teigland   dlm: fixes for no...
168
169
  	       lkb->lkb_grmode, lkb->lkb_wait_type, lkb->lkb_wait_nodeid,
  	       (unsigned long long)lkb->lkb_recover_seq);
e7fd41792   David Teigland   [DLM] The core of...
170
  }
170e19ab2   Adrian Bunk   dlm: make dlm_pri...
171
  static void dlm_print_rsb(struct dlm_rsb *r)
e7fd41792   David Teigland   [DLM] The core of...
172
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
173
174
175
176
177
178
  	printk(KERN_ERR "rsb: nodeid %d master %d dir %d flags %lx first %x "
  	       "rlc %d name %s
  ",
  	       r->res_nodeid, r->res_master_nodeid, r->res_dir_nodeid,
  	       r->res_flags, r->res_first_lkid, r->res_recover_locks_count,
  	       r->res_name);
e7fd41792   David Teigland   [DLM] The core of...
179
  }
a345da3e8   David Teigland   [DLM] dump rsb an...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  void dlm_dump_rsb(struct dlm_rsb *r)
  {
  	struct dlm_lkb *lkb;
  
  	dlm_print_rsb(r);
  
  	printk(KERN_ERR "rsb: root_list empty %d recover_list empty %d
  ",
  	       list_empty(&r->res_root_list), list_empty(&r->res_recover_list));
  	printk(KERN_ERR "rsb lookup list
  ");
  	list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup)
  		dlm_print_lkb(lkb);
  	printk(KERN_ERR "rsb grant queue:
  ");
  	list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
  		dlm_print_lkb(lkb);
  	printk(KERN_ERR "rsb convert queue:
  ");
  	list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
  		dlm_print_lkb(lkb);
  	printk(KERN_ERR "rsb wait queue:
  ");
  	list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
  		dlm_print_lkb(lkb);
  }
e7fd41792   David Teigland   [DLM] The core of...
206
  /* Threads cannot use the lockspace while it's being recovered */
85e86edf9   David Teigland   [DLM] block scand...
207
  static inline void dlm_lock_recovery(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
208
209
210
  {
  	down_read(&ls->ls_in_recovery);
  }
85e86edf9   David Teigland   [DLM] block scand...
211
  void dlm_unlock_recovery(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
212
213
214
  {
  	up_read(&ls->ls_in_recovery);
  }
85e86edf9   David Teigland   [DLM] block scand...
215
  int dlm_lock_recovery_try(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  {
  	return down_read_trylock(&ls->ls_in_recovery);
  }
  
  static inline int can_be_queued(struct dlm_lkb *lkb)
  {
  	return !(lkb->lkb_exflags & DLM_LKF_NOQUEUE);
  }
  
  static inline int force_blocking_asts(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_exflags & DLM_LKF_NOQUEUEBAST);
  }
  
  static inline int is_demoted(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_sbflags & DLM_SBF_DEMOTED);
  }
7d3c1feb8   David Teigland   [DLM] fix mode mu...
234
235
236
237
238
239
240
241
242
  static inline int is_altmode(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_sbflags & DLM_SBF_ALTMODE);
  }
  
  static inline int is_granted(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_status == DLM_LKSTS_GRANTED);
  }
e7fd41792   David Teigland   [DLM] The core of...
243
244
245
246
247
248
249
250
251
252
253
254
255
  static inline int is_remote(struct dlm_rsb *r)
  {
  	DLM_ASSERT(r->res_nodeid >= 0, dlm_print_rsb(r););
  	return !!r->res_nodeid;
  }
  
  static inline int is_process_copy(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_nodeid && !(lkb->lkb_flags & DLM_IFL_MSTCPY));
  }
  
  static inline int is_master_copy(struct dlm_lkb *lkb)
  {
901359256   David Teigland   [DLM] Update DLM ...
256
  	return (lkb->lkb_flags & DLM_IFL_MSTCPY) ? 1 : 0;
e7fd41792   David Teigland   [DLM] The core of...
257
258
259
260
261
262
  }
  
  static inline int middle_conversion(struct dlm_lkb *lkb)
  {
  	if ((lkb->lkb_grmode==DLM_LOCK_PR && lkb->lkb_rqmode==DLM_LOCK_CW) ||
  	    (lkb->lkb_rqmode==DLM_LOCK_PR && lkb->lkb_grmode==DLM_LOCK_CW))
901359256   David Teigland   [DLM] Update DLM ...
263
264
  		return 1;
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
265
266
267
268
269
270
  }
  
  static inline int down_conversion(struct dlm_lkb *lkb)
  {
  	return (!middle_conversion(lkb) && lkb->lkb_rqmode < lkb->lkb_grmode);
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  static inline int is_overlap_unlock(struct dlm_lkb *lkb)
  {
  	return lkb->lkb_flags & DLM_IFL_OVERLAP_UNLOCK;
  }
  
  static inline int is_overlap_cancel(struct dlm_lkb *lkb)
  {
  	return lkb->lkb_flags & DLM_IFL_OVERLAP_CANCEL;
  }
  
  static inline int is_overlap(struct dlm_lkb *lkb)
  {
  	return (lkb->lkb_flags & (DLM_IFL_OVERLAP_UNLOCK |
  				  DLM_IFL_OVERLAP_CANCEL));
  }
e7fd41792   David Teigland   [DLM] The core of...
286
287
288
289
  static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
  {
  	if (is_master_copy(lkb))
  		return;
3ae1acf93   David Teigland   [DLM] add lock ti...
290
  	del_timeout(lkb);
e7fd41792   David Teigland   [DLM] The core of...
291
  	DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb););
3ae1acf93   David Teigland   [DLM] add lock ti...
292
293
294
295
296
297
  	/* if the operation was a cancel, then return -DLM_ECANCEL, if a
  	   timeout caused the cancel then return -ETIMEDOUT */
  	if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) {
  		lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL;
  		rv = -ETIMEDOUT;
  	}
8b4021fa4   David Teigland   [DLM] canceling d...
298
299
300
301
  	if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_DEADLOCK_CANCEL)) {
  		lkb->lkb_flags &= ~DLM_IFL_DEADLOCK_CANCEL;
  		rv = -EDEADLK;
  	}
23e8e1aaa   David Teigland   dlm: use workqueu...
302
  	dlm_add_cb(lkb, DLM_CB_CAST, lkb->lkb_grmode, rv, lkb->lkb_sbflags);
e7fd41792   David Teigland   [DLM] The core of...
303
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
304
305
306
307
308
  static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	queue_cast(r, lkb,
  		   is_overlap_unlock(lkb) ? -DLM_EUNLOCK : -DLM_ECANCEL);
  }
e7fd41792   David Teigland   [DLM] The core of...
309
310
  static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
  {
b6fa8796b   David Teigland   dlm: use bastmode...
311
  	if (is_master_copy(lkb)) {
e7fd41792   David Teigland   [DLM] The core of...
312
  		send_bast(r, lkb, rqmode);
b6fa8796b   David Teigland   dlm: use bastmode...
313
  	} else {
23e8e1aaa   David Teigland   dlm: use workqueu...
314
  		dlm_add_cb(lkb, DLM_CB_BAST, rqmode, 0, 0);
b6fa8796b   David Teigland   dlm: use bastmode...
315
  	}
e7fd41792   David Teigland   [DLM] The core of...
316
317
318
319
320
  }
  
  /*
   * Basic operations on rsb's and lkb's
   */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
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
348
349
350
  /* This is only called to add a reference when the code already holds
     a valid reference to the rsb, so there's no need for locking. */
  
  static inline void hold_rsb(struct dlm_rsb *r)
  {
  	kref_get(&r->res_ref);
  }
  
  void dlm_hold_rsb(struct dlm_rsb *r)
  {
  	hold_rsb(r);
  }
  
  /* When all references to the rsb are gone it's transferred to
     the tossed list for later disposal. */
  
  static void put_rsb(struct dlm_rsb *r)
  {
  	struct dlm_ls *ls = r->res_ls;
  	uint32_t bucket = r->res_bucket;
  
  	spin_lock(&ls->ls_rsbtbl[bucket].lock);
  	kref_put(&r->res_ref, toss_rsb);
  	spin_unlock(&ls->ls_rsbtbl[bucket].lock);
  }
  
  void dlm_put_rsb(struct dlm_rsb *r)
  {
  	put_rsb(r);
  }
3881ac04e   David Teigland   dlm: improve rsb ...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  static int pre_rsb_struct(struct dlm_ls *ls)
  {
  	struct dlm_rsb *r1, *r2;
  	int count = 0;
  
  	spin_lock(&ls->ls_new_rsb_spin);
  	if (ls->ls_new_rsb_count > dlm_config.ci_new_rsb_count / 2) {
  		spin_unlock(&ls->ls_new_rsb_spin);
  		return 0;
  	}
  	spin_unlock(&ls->ls_new_rsb_spin);
  
  	r1 = dlm_allocate_rsb(ls);
  	r2 = dlm_allocate_rsb(ls);
  
  	spin_lock(&ls->ls_new_rsb_spin);
  	if (r1) {
  		list_add(&r1->res_hashchain, &ls->ls_new_rsb);
  		ls->ls_new_rsb_count++;
  	}
  	if (r2) {
  		list_add(&r2->res_hashchain, &ls->ls_new_rsb);
  		ls->ls_new_rsb_count++;
  	}
  	count = ls->ls_new_rsb_count;
  	spin_unlock(&ls->ls_new_rsb_spin);
  
  	if (!count)
  		return -ENOMEM;
  	return 0;
  }
  
  /* If ls->ls_new_rsb is empty, return -EAGAIN, so the caller can
     unlock any spinlocks, go back and call pre_rsb_struct again.
     Otherwise, take an rsb off the list and return it. */
  
  static int get_rsb_struct(struct dlm_ls *ls, char *name, int len,
  			  struct dlm_rsb **r_ret)
e7fd41792   David Teigland   [DLM] The core of...
389
390
  {
  	struct dlm_rsb *r;
3881ac04e   David Teigland   dlm: improve rsb ...
391
392
393
394
395
396
397
398
399
400
  	int count;
  
  	spin_lock(&ls->ls_new_rsb_spin);
  	if (list_empty(&ls->ls_new_rsb)) {
  		count = ls->ls_new_rsb_count;
  		spin_unlock(&ls->ls_new_rsb_spin);
  		log_debug(ls, "find_rsb retry %d %d %s",
  			  count, dlm_config.ci_new_rsb_count, name);
  		return -EAGAIN;
  	}
e7fd41792   David Teigland   [DLM] The core of...
401

3881ac04e   David Teigland   dlm: improve rsb ...
402
403
  	r = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb, res_hashchain);
  	list_del(&r->res_hashchain);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
404
405
  	/* Convert the empty list_head to a NULL rb_node for tree usage: */
  	memset(&r->res_hashnode, 0, sizeof(struct rb_node));
3881ac04e   David Teigland   dlm: improve rsb ...
406
407
  	ls->ls_new_rsb_count--;
  	spin_unlock(&ls->ls_new_rsb_spin);
e7fd41792   David Teigland   [DLM] The core of...
408
409
410
411
  
  	r->res_ls = ls;
  	r->res_length = len;
  	memcpy(r->res_name, name, len);
901359256   David Teigland   [DLM] Update DLM ...
412
  	mutex_init(&r->res_mutex);
e7fd41792   David Teigland   [DLM] The core of...
413
414
415
416
417
418
419
  
  	INIT_LIST_HEAD(&r->res_lookup);
  	INIT_LIST_HEAD(&r->res_grantqueue);
  	INIT_LIST_HEAD(&r->res_convertqueue);
  	INIT_LIST_HEAD(&r->res_waitqueue);
  	INIT_LIST_HEAD(&r->res_root_list);
  	INIT_LIST_HEAD(&r->res_recover_list);
3881ac04e   David Teigland   dlm: improve rsb ...
420
421
  	*r_ret = r;
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
422
  }
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
423
424
425
426
427
428
429
430
  static int rsb_cmp(struct dlm_rsb *r, const char *name, int nlen)
  {
  	char maxname[DLM_RESNAME_MAXLEN];
  
  	memset(maxname, 0, DLM_RESNAME_MAXLEN);
  	memcpy(maxname, name, nlen);
  	return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN);
  }
7210cb7a7   David Teigland   dlm: fix slow rsb...
431
  int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len,
c04fecb4d   David Teigland   dlm: use rsbtbl a...
432
  			struct dlm_rsb **r_ret)
e7fd41792   David Teigland   [DLM] The core of...
433
  {
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
434
  	struct rb_node *node = tree->rb_node;
e7fd41792   David Teigland   [DLM] The core of...
435
  	struct dlm_rsb *r;
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
436
437
438
439
440
441
442
443
444
445
  	int rc;
  
  	while (node) {
  		r = rb_entry(node, struct dlm_rsb, res_hashnode);
  		rc = rsb_cmp(r, name, len);
  		if (rc < 0)
  			node = node->rb_left;
  		else if (rc > 0)
  			node = node->rb_right;
  		else
e7fd41792   David Teigland   [DLM] The core of...
446
447
  			goto found;
  	}
18c60c0a3   Benny Halevy   dlm: fix uninitia...
448
  	*r_ret = NULL;
597d0cae0   David Teigland   [DLM] dlm: user l...
449
  	return -EBADR;
e7fd41792   David Teigland   [DLM] The core of...
450
451
  
   found:
e7fd41792   David Teigland   [DLM] The core of...
452
  	*r_ret = r;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
453
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
454
  }
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
  static int rsb_insert(struct dlm_rsb *rsb, struct rb_root *tree)
  {
  	struct rb_node **newn = &tree->rb_node;
  	struct rb_node *parent = NULL;
  	int rc;
  
  	while (*newn) {
  		struct dlm_rsb *cur = rb_entry(*newn, struct dlm_rsb,
  					       res_hashnode);
  
  		parent = *newn;
  		rc = rsb_cmp(cur, rsb->res_name, rsb->res_length);
  		if (rc < 0)
  			newn = &parent->rb_left;
  		else if (rc > 0)
  			newn = &parent->rb_right;
  		else {
  			log_print("rsb_insert match");
  			dlm_dump_rsb(rsb);
  			dlm_dump_rsb(cur);
  			return -EEXIST;
  		}
  	}
  
  	rb_link_node(&rsb->res_hashnode, parent, newn);
  	rb_insert_color(&rsb->res_hashnode, tree);
  	return 0;
  }
c04fecb4d   David Teigland   dlm: use rsbtbl a...
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  /*
   * Find rsb in rsbtbl and potentially create/add one
   *
   * Delaying the release of rsb's has a similar benefit to applications keeping
   * NL locks on an rsb, but without the guarantee that the cached master value
   * will still be valid when the rsb is reused.  Apps aren't always smart enough
   * to keep NL locks on an rsb that they may lock again shortly; this can lead
   * to excessive master lookups and removals if we don't delay the release.
   *
   * Searching for an rsb means looking through both the normal list and toss
   * list.  When found on the toss list the rsb is moved to the normal list with
   * ref count of 1; when found on normal list the ref count is incremented.
   *
   * rsb's on the keep list are being used locally and refcounted.
   * rsb's on the toss list are not being used locally, and are not refcounted.
   *
   * The toss list rsb's were either
   * - previously used locally but not any more (were on keep list, then
   *   moved to toss list when last refcount dropped)
   * - created and put on toss list as a directory record for a lookup
   *   (we are the dir node for the res, but are not using the res right now,
   *   but some other node is)
   *
   * The purpose of find_rsb() is to return a refcounted rsb for local use.
   * So, if the given rsb is on the toss list, it is moved to the keep list
   * before being returned.
   *
   * toss_rsb() happens when all local usage of the rsb is done, i.e. no
   * more refcounts exist, so the rsb is moved from the keep list to the
   * toss list.
   *
   * rsb's on both keep and toss lists are used for doing a name to master
   * lookups.  rsb's that are in use locally (and being refcounted) are on
   * the keep list, rsb's that are not in use locally (not refcounted) and
   * only exist for name/master lookups are on the toss list.
   *
   * rsb's on the toss list who's dir_nodeid is not local can have stale
   * name/master mappings.  So, remote requests on such rsb's can potentially
   * return with an error, which means the mapping is stale and needs to
   * be updated with a new lookup.  (The idea behind MASTER UNCERTAIN and
   * first_lkid is to keep only a single outstanding request on an rsb
   * while that rsb has a potentially stale master.)
   */
  
  static int find_rsb_dir(struct dlm_ls *ls, char *name, int len,
  			uint32_t hash, uint32_t b,
  			int dir_nodeid, int from_nodeid,
  			unsigned int flags, struct dlm_rsb **r_ret)
e7fd41792   David Teigland   [DLM] The core of...
531
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
532
533
534
535
536
537
  	struct dlm_rsb *r = NULL;
  	int our_nodeid = dlm_our_nodeid();
  	int from_local = 0;
  	int from_other = 0;
  	int from_dir = 0;
  	int create = 0;
e7fd41792   David Teigland   [DLM] The core of...
538
  	int error;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
  	if (flags & R_RECEIVE_REQUEST) {
  		if (from_nodeid == dir_nodeid)
  			from_dir = 1;
  		else
  			from_other = 1;
  	} else if (flags & R_REQUEST) {
  		from_local = 1;
  	}
  
  	/*
  	 * flags & R_RECEIVE_RECOVER is from dlm_recover_master_copy, so
  	 * from_nodeid has sent us a lock in dlm_recover_locks, believing
  	 * we're the new master.  Our local recovery may not have set
  	 * res_master_nodeid to our_nodeid yet, so allow either.  Don't
  	 * create the rsb; dlm_recover_process_copy() will handle EBADR
  	 * by resending.
  	 *
  	 * If someone sends us a request, we are the dir node, and we do
  	 * not find the rsb anywhere, then recreate it.  This happens if
  	 * someone sends us a request after we have removed/freed an rsb
  	 * from our toss list.  (They sent a request instead of lookup
  	 * because they are using an rsb from their toss list.)
  	 */
  
  	if (from_local || from_dir ||
  	    (from_other && (dir_nodeid == our_nodeid))) {
  		create = 1;
e7fd41792   David Teigland   [DLM] The core of...
566
  	}
57638bf3a   David Teigland   dlm: avoid unnece...
567

c04fecb4d   David Teigland   dlm: use rsbtbl a...
568
569
570
571
572
573
574
575
576
577
   retry:
  	if (create) {
  		error = pre_rsb_struct(ls);
  		if (error < 0)
  			goto out;
  	}
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
e7fd41792   David Teigland   [DLM] The core of...
578
  	if (error)
c04fecb4d   David Teigland   dlm: use rsbtbl a...
579
580
581
582
583
  		goto do_toss;
  	
  	/*
  	 * rsb is active, so we can't check master_nodeid without lock_rsb.
  	 */
e7fd41792   David Teigland   [DLM] The core of...
584

c04fecb4d   David Teigland   dlm: use rsbtbl a...
585
586
587
588
589
590
591
  	kref_get(&r->res_ref);
  	error = 0;
  	goto out_unlock;
  
  
   do_toss:
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
592
  	if (error)
c04fecb4d   David Teigland   dlm: use rsbtbl a...
593
  		goto do_new;
e7fd41792   David Teigland   [DLM] The core of...
594

c04fecb4d   David Teigland   dlm: use rsbtbl a...
595
596
597
598
599
600
  	/*
  	 * rsb found inactive (master_nodeid may be out of date unless
  	 * we are the dir_nodeid or were the master)  No other thread
  	 * is using this rsb because it's on the toss list, so we can
  	 * look at or update res_master_nodeid without lock_rsb.
  	 */
e7fd41792   David Teigland   [DLM] The core of...
601

c04fecb4d   David Teigland   dlm: use rsbtbl a...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  	if ((r->res_master_nodeid != our_nodeid) && from_other) {
  		/* our rsb was not master, and another node (not the dir node)
  		   has sent us a request */
  		log_debug(ls, "find_rsb toss from_other %d master %d dir %d %s",
  			  from_nodeid, r->res_master_nodeid, dir_nodeid,
  			  r->res_name);
  		error = -ENOTBLK;
  		goto out_unlock;
  	}
  
  	if ((r->res_master_nodeid != our_nodeid) && from_dir) {
  		/* don't think this should ever happen */
  		log_error(ls, "find_rsb toss from_dir %d master %d",
  			  from_nodeid, r->res_master_nodeid);
  		dlm_print_rsb(r);
  		/* fix it and go on */
  		r->res_master_nodeid = our_nodeid;
  		r->res_nodeid = 0;
e7fd41792   David Teigland   [DLM] The core of...
620
621
  		rsb_clear_flag(r, RSB_MASTER_UNCERTAIN);
  		r->res_first_lkid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
622
623
624
625
626
  	}
  
  	if (from_local && (r->res_master_nodeid != our_nodeid)) {
  		/* Because we have held no locks on this rsb,
  		   res_master_nodeid could have become stale. */
e7fd41792   David Teigland   [DLM] The core of...
627
628
  		rsb_set_flag(r, RSB_MASTER_UNCERTAIN);
  		r->res_first_lkid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
  	}
  
  	rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
  	error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
  	goto out_unlock;
  
  
   do_new:
  	/*
  	 * rsb not found
  	 */
  
  	if (error == -EBADR && !create)
  		goto out_unlock;
  
  	error = get_rsb_struct(ls, name, len, &r);
  	if (error == -EAGAIN) {
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		goto retry;
  	}
  	if (error)
  		goto out_unlock;
  
  	r->res_hash = hash;
  	r->res_bucket = b;
  	r->res_dir_nodeid = dir_nodeid;
  	kref_init(&r->res_ref);
  
  	if (from_dir) {
  		/* want to see how often this happens */
  		log_debug(ls, "find_rsb new from_dir %d recreate %s",
  			  from_nodeid, r->res_name);
  		r->res_master_nodeid = our_nodeid;
  		r->res_nodeid = 0;
  		goto out_add;
  	}
  
  	if (from_other && (dir_nodeid != our_nodeid)) {
  		/* should never happen */
  		log_error(ls, "find_rsb new from_other %d dir %d our %d %s",
  			  from_nodeid, dir_nodeid, our_nodeid, r->res_name);
  		dlm_free_rsb(r);
e8243f32f   Dan Carpenter   dlm: silence a ha...
671
  		r = NULL;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  		error = -ENOTBLK;
  		goto out_unlock;
  	}
  
  	if (from_other) {
  		log_debug(ls, "find_rsb new from_other %d dir %d %s",
  			  from_nodeid, dir_nodeid, r->res_name);
  	}
  
  	if (dir_nodeid == our_nodeid) {
  		/* When we are the dir nodeid, we can set the master
  		   node immediately */
  		r->res_master_nodeid = our_nodeid;
  		r->res_nodeid = 0;
e7fd41792   David Teigland   [DLM] The core of...
686
  	} else {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
  		/* set_master will send_lookup to dir_nodeid */
  		r->res_master_nodeid = 0;
  		r->res_nodeid = -1;
  	}
  
   out_add:
  	error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
   out_unlock:
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
   out:
  	*r_ret = r;
  	return error;
  }
  
  /* During recovery, other nodes can send us new MSTCPY locks (from
     dlm_recover_locks) before we've made ourself master (in
     dlm_recover_masters). */
  
  static int find_rsb_nodir(struct dlm_ls *ls, char *name, int len,
  			  uint32_t hash, uint32_t b,
  			  int dir_nodeid, int from_nodeid,
  			  unsigned int flags, struct dlm_rsb **r_ret)
  {
  	struct dlm_rsb *r = NULL;
  	int our_nodeid = dlm_our_nodeid();
  	int recover = (flags & R_RECEIVE_RECOVER);
  	int error;
  
   retry:
  	error = pre_rsb_struct(ls);
  	if (error < 0)
  		goto out;
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
  	if (error)
  		goto do_toss;
  
  	/*
  	 * rsb is active, so we can't check master_nodeid without lock_rsb.
  	 */
  
  	kref_get(&r->res_ref);
  	goto out_unlock;
  
  
   do_toss:
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  	if (error)
  		goto do_new;
  
  	/*
  	 * rsb found inactive. No other thread is using this rsb because
  	 * it's on the toss list, so we can look at or update
  	 * res_master_nodeid without lock_rsb.
  	 */
  
  	if (!recover && (r->res_master_nodeid != our_nodeid) && from_nodeid) {
  		/* our rsb is not master, and another node has sent us a
  		   request; this should never happen */
  		log_error(ls, "find_rsb toss from_nodeid %d master %d dir %d",
  			  from_nodeid, r->res_master_nodeid, dir_nodeid);
  		dlm_print_rsb(r);
  		error = -ENOTBLK;
  		goto out_unlock;
e7fd41792   David Teigland   [DLM] The core of...
753
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
  
  	if (!recover && (r->res_master_nodeid != our_nodeid) &&
  	    (dir_nodeid == our_nodeid)) {
  		/* our rsb is not master, and we are dir; may as well fix it;
  		   this should never happen */
  		log_error(ls, "find_rsb toss our %d master %d dir %d",
  			  our_nodeid, r->res_master_nodeid, dir_nodeid);
  		dlm_print_rsb(r);
  		r->res_master_nodeid = our_nodeid;
  		r->res_nodeid = 0;
  	}
  
  	rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
  	error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
  	goto out_unlock;
  
  
   do_new:
  	/*
  	 * rsb not found
  	 */
  
  	error = get_rsb_struct(ls, name, len, &r);
  	if (error == -EAGAIN) {
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		goto retry;
  	}
  	if (error)
  		goto out_unlock;
  
  	r->res_hash = hash;
  	r->res_bucket = b;
  	r->res_dir_nodeid = dir_nodeid;
  	r->res_master_nodeid = dir_nodeid;
  	r->res_nodeid = (dir_nodeid == our_nodeid) ? 0 : dir_nodeid;
  	kref_init(&r->res_ref);
  
  	error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
   out_unlock:
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
e7fd41792   David Teigland   [DLM] The core of...
794
795
796
797
   out:
  	*r_ret = r;
  	return error;
  }
c04fecb4d   David Teigland   dlm: use rsbtbl a...
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
  static int find_rsb(struct dlm_ls *ls, char *name, int len, int from_nodeid,
  		    unsigned int flags, struct dlm_rsb **r_ret)
  {
  	uint32_t hash, b;
  	int dir_nodeid;
  
  	if (len > DLM_RESNAME_MAXLEN)
  		return -EINVAL;
  
  	hash = jhash(name, len, 0);
  	b = hash & (ls->ls_rsbtbl_size - 1);
  
  	dir_nodeid = dlm_hash2nodeid(ls, hash);
  
  	if (dlm_no_directory(ls))
  		return find_rsb_nodir(ls, name, len, hash, b, dir_nodeid,
  				      from_nodeid, flags, r_ret);
  	else
  		return find_rsb_dir(ls, name, len, hash, b, dir_nodeid,
  				      from_nodeid, flags, r_ret);
  }
  
  /* we have received a request and found that res_master_nodeid != our_nodeid,
     so we need to return an error or make ourself the master */
  
  static int validate_master_nodeid(struct dlm_ls *ls, struct dlm_rsb *r,
  				  int from_nodeid)
  {
  	if (dlm_no_directory(ls)) {
  		log_error(ls, "find_rsb keep from_nodeid %d master %d dir %d",
  			  from_nodeid, r->res_master_nodeid,
  			  r->res_dir_nodeid);
  		dlm_print_rsb(r);
  		return -ENOTBLK;
  	}
  
  	if (from_nodeid != r->res_dir_nodeid) {
  		/* our rsb is not master, and another node (not the dir node)
  	   	   has sent us a request.  this is much more common when our
  	   	   master_nodeid is zero, so limit debug to non-zero.  */
  
  		if (r->res_master_nodeid) {
  			log_debug(ls, "validate master from_other %d master %d "
  				  "dir %d first %x %s", from_nodeid,
  				  r->res_master_nodeid, r->res_dir_nodeid,
  				  r->res_first_lkid, r->res_name);
  		}
  		return -ENOTBLK;
  	} else {
  		/* our rsb is not master, but the dir nodeid has sent us a
  	   	   request; this could happen with master 0 / res_nodeid -1 */
  
  		if (r->res_master_nodeid) {
  			log_error(ls, "validate master from_dir %d master %d "
  				  "first %x %s",
  				  from_nodeid, r->res_master_nodeid,
  				  r->res_first_lkid, r->res_name);
  		}
  
  		r->res_master_nodeid = dlm_our_nodeid();
  		r->res_nodeid = 0;
  		return 0;
  	}
  }
e7fd41792   David Teigland   [DLM] The core of...
862
  /*
c04fecb4d   David Teigland   dlm: use rsbtbl a...
863
864
865
866
   * We're the dir node for this res and another node wants to know the
   * master nodeid.  During normal operation (non recovery) this is only
   * called from receive_lookup(); master lookups when the local node is
   * the dir node are done by find_rsb().
e7fd41792   David Teigland   [DLM] The core of...
867
   *
c04fecb4d   David Teigland   dlm: use rsbtbl a...
868
869
870
871
872
873
   * normal operation, we are the dir node for a resource
   * . _request_lock
   * . set_master
   * . send_lookup
   * . receive_lookup
   * . dlm_master_lookup flags 0
e7fd41792   David Teigland   [DLM] The core of...
874
   *
c04fecb4d   David Teigland   dlm: use rsbtbl a...
875
876
877
878
879
880
881
882
883
884
885
886
887
888
   * recover directory, we are rebuilding dir for all resources
   * . dlm_recover_directory
   * . dlm_rcom_names
   *   remote node sends back the rsb names it is master of and we are dir of
   * . dlm_master_lookup RECOVER_DIR (fix_master 0, from_master 1)
   *   we either create new rsb setting remote node as master, or find existing
   *   rsb and set master to be the remote node.
   *
   * recover masters, we are finding the new master for resources
   * . dlm_recover_masters
   * . recover_master
   * . dlm_send_rcom_lookup
   * . receive_rcom_lookup
   * . dlm_master_lookup RECOVER_MASTER (fix_master 1, from_master 0)
e7fd41792   David Teigland   [DLM] The core of...
889
   */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
890
891
  int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, char *name, int len,
  		      unsigned int flags, int *r_nodeid, int *result)
e7fd41792   David Teigland   [DLM] The core of...
892
  {
3881ac04e   David Teigland   dlm: improve rsb ...
893
  	struct dlm_rsb *r = NULL;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
894
895
896
897
898
  	uint32_t hash, b;
  	int from_master = (flags & DLM_LU_RECOVER_DIR);
  	int fix_master = (flags & DLM_LU_RECOVER_MASTER);
  	int our_nodeid = dlm_our_nodeid();
  	int dir_nodeid, error, toss_list = 0;
ef58bccab   Al Viro   dlm: make find_rs...
899

c04fecb4d   David Teigland   dlm: use rsbtbl a...
900
901
902
903
904
905
906
  	if (len > DLM_RESNAME_MAXLEN)
  		return -EINVAL;
  
  	if (from_nodeid == our_nodeid) {
  		log_error(ls, "dlm_master_lookup from our_nodeid %d flags %x",
  			  our_nodeid, flags);
  		return -EINVAL;
3881ac04e   David Teigland   dlm: improve rsb ...
907
  	}
e7fd41792   David Teigland   [DLM] The core of...
908

c04fecb4d   David Teigland   dlm: use rsbtbl a...
909
910
  	hash = jhash(name, len, 0);
  	b = hash & (ls->ls_rsbtbl_size - 1);
e7fd41792   David Teigland   [DLM] The core of...
911

c04fecb4d   David Teigland   dlm: use rsbtbl a...
912
913
914
915
916
917
918
919
  	dir_nodeid = dlm_hash2nodeid(ls, hash);
  	if (dir_nodeid != our_nodeid) {
  		log_error(ls, "dlm_master_lookup from %d dir %d our %d h %x %d",
  			  from_nodeid, dir_nodeid, our_nodeid, hash,
  			  ls->ls_num_nodes);
  		*r_nodeid = -1;
  		return -EINVAL;
  	}
e7fd41792   David Teigland   [DLM] The core of...
920

3881ac04e   David Teigland   dlm: improve rsb ...
921
   retry:
c04fecb4d   David Teigland   dlm: use rsbtbl a...
922
923
924
925
926
927
928
929
930
931
932
933
934
935
  	error = pre_rsb_struct(ls);
  	if (error < 0)
  		return error;
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
  	if (!error) {
  		/* because the rsb is active, we need to lock_rsb before
  		   checking/changing re_master_nodeid */
  
  		hold_rsb(r);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		lock_rsb(r);
  		goto found;
3881ac04e   David Teigland   dlm: improve rsb ...
936
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
937
938
939
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  	if (error)
  		goto not_found;
3881ac04e   David Teigland   dlm: improve rsb ...
940

c04fecb4d   David Teigland   dlm: use rsbtbl a...
941
942
  	/* because the rsb is inactive (on toss list), it's not refcounted
  	   and lock_rsb is not used, but is protected by the rsbtbl lock */
e7fd41792   David Teigland   [DLM] The core of...
943

c04fecb4d   David Teigland   dlm: use rsbtbl a...
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
  	toss_list = 1;
   found:
  	if (r->res_dir_nodeid != our_nodeid) {
  		/* should not happen, but may as well fix it and carry on */
  		log_error(ls, "dlm_master_lookup res_dir %d our %d %s",
  			  r->res_dir_nodeid, our_nodeid, r->res_name);
  		r->res_dir_nodeid = our_nodeid;
  	}
  
  	if (fix_master && dlm_is_removed(ls, r->res_master_nodeid)) {
  		/* Recovery uses this function to set a new master when
  		   the previous master failed.  Setting NEW_MASTER will
  		   force dlm_recover_masters to call recover_master on this
  		   rsb even though the res_nodeid is no longer removed. */
  
  		r->res_master_nodeid = from_nodeid;
  		r->res_nodeid = from_nodeid;
  		rsb_set_flag(r, RSB_NEW_MASTER);
  
  		if (toss_list) {
  			/* I don't think we should ever find it on toss list. */
  			log_error(ls, "dlm_master_lookup fix_master on toss");
  			dlm_dump_rsb(r);
  		}
  	}
e7fd41792   David Teigland   [DLM] The core of...
969

c04fecb4d   David Teigland   dlm: use rsbtbl a...
970
971
972
973
974
975
976
977
978
979
980
981
982
  	if (from_master && (r->res_master_nodeid != from_nodeid)) {
  		/* this will happen if from_nodeid became master during
  		   a previous recovery cycle, and we aborted the previous
  		   cycle before recovering this master value */
  
  		log_limit(ls, "dlm_master_lookup from_master %d "
  			  "master_nodeid %d res_nodeid %d first %x %s",
  			  from_nodeid, r->res_master_nodeid, r->res_nodeid,
  			  r->res_first_lkid, r->res_name);
  
  		if (r->res_master_nodeid == our_nodeid) {
  			log_error(ls, "from_master %d our_master", from_nodeid);
  			dlm_dump_rsb(r);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
  			goto out_found;
  		}
  
  		r->res_master_nodeid = from_nodeid;
  		r->res_nodeid = from_nodeid;
  		rsb_set_flag(r, RSB_NEW_MASTER);
  	}
  
  	if (!r->res_master_nodeid) {
  		/* this will happen if recovery happens while we're looking
  		   up the master for this rsb */
  
  		log_debug(ls, "dlm_master_lookup master 0 to %d first %x %s",
  			  from_nodeid, r->res_first_lkid, r->res_name);
  		r->res_master_nodeid = from_nodeid;
  		r->res_nodeid = from_nodeid;
  	}
  
  	if (!from_master && !fix_master &&
  	    (r->res_master_nodeid == from_nodeid)) {
  		/* this can happen when the master sends remove, the dir node
  		   finds the rsb on the keep list and ignores the remove,
  		   and the former master sends a lookup */
  
  		log_limit(ls, "dlm_master_lookup from master %d flags %x "
  			  "first %x %s", from_nodeid, flags,
  			  r->res_first_lkid, r->res_name);
  	}
  
   out_found:
  	*r_nodeid = r->res_master_nodeid;
  	if (result)
  		*result = DLM_LU_MATCH;
  
  	if (toss_list) {
  		r->res_toss_time = jiffies;
  		/* the rsb was inactive (on toss list) */
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  	} else {
  		/* the rsb was active */
  		unlock_rsb(r);
  		put_rsb(r);
  	}
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
1027

c04fecb4d   David Teigland   dlm: use rsbtbl a...
1028
1029
   not_found:
  	error = get_rsb_struct(ls, name, len, &r);
3881ac04e   David Teigland   dlm: improve rsb ...
1030
  	if (error == -EAGAIN) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1031
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
3881ac04e   David Teigland   dlm: improve rsb ...
1032
1033
1034
1035
  		goto retry;
  	}
  	if (error)
  		goto out_unlock;
e7fd41792   David Teigland   [DLM] The core of...
1036
1037
  
  	r->res_hash = hash;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1038
1039
1040
1041
  	r->res_bucket = b;
  	r->res_dir_nodeid = our_nodeid;
  	r->res_master_nodeid = from_nodeid;
  	r->res_nodeid = from_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
1042
  	kref_init(&r->res_ref);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1043
  	r->res_toss_time = jiffies;
e7fd41792   David Teigland   [DLM] The core of...
1044

c04fecb4d   David Teigland   dlm: use rsbtbl a...
1045
1046
1047
1048
1049
1050
  	error = rsb_insert(r, &ls->ls_rsbtbl[b].toss);
  	if (error) {
  		/* should never happen */
  		dlm_free_rsb(r);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		goto retry;
e7fd41792   David Teigland   [DLM] The core of...
1051
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1052
1053
1054
1055
1056
  
  	if (result)
  		*result = DLM_LU_ADD;
  	*r_nodeid = from_nodeid;
  	error = 0;
3881ac04e   David Teigland   dlm: improve rsb ...
1057
   out_unlock:
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1058
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
e7fd41792   David Teigland   [DLM] The core of...
1059
1060
  	return error;
  }
6d40c4a70   David Teigland   dlm: improve erro...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  static void dlm_dump_rsb_hash(struct dlm_ls *ls, uint32_t hash)
  {
  	struct rb_node *n;
  	struct dlm_rsb *r;
  	int i;
  
  	for (i = 0; i < ls->ls_rsbtbl_size; i++) {
  		spin_lock(&ls->ls_rsbtbl[i].lock);
  		for (n = rb_first(&ls->ls_rsbtbl[i].keep); n; n = rb_next(n)) {
  			r = rb_entry(n, struct dlm_rsb, res_hashnode);
  			if (r->res_hash == hash)
  				dlm_dump_rsb(r);
  		}
  		spin_unlock(&ls->ls_rsbtbl[i].lock);
  	}
  }
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1077
  void dlm_dump_rsb_name(struct dlm_ls *ls, char *name, int len)
e7fd41792   David Teigland   [DLM] The core of...
1078
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1079
1080
1081
  	struct dlm_rsb *r = NULL;
  	uint32_t hash, b;
  	int error;
e7fd41792   David Teigland   [DLM] The core of...
1082

c04fecb4d   David Teigland   dlm: use rsbtbl a...
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
  	hash = jhash(name, len, 0);
  	b = hash & (ls->ls_rsbtbl_size - 1);
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
  	if (!error)
  		goto out_dump;
  
  	error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  	if (error)
  		goto out;
   out_dump:
  	dlm_dump_rsb(r);
   out:
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
e7fd41792   David Teigland   [DLM] The core of...
1098
1099
1100
1101
1102
1103
1104
1105
1106
  }
  
  static void toss_rsb(struct kref *kref)
  {
  	struct dlm_rsb *r = container_of(kref, struct dlm_rsb, res_ref);
  	struct dlm_ls *ls = r->res_ls;
  
  	DLM_ASSERT(list_empty(&r->res_root_list), dlm_print_rsb(r););
  	kref_init(&r->res_ref);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
1107
1108
  	rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[r->res_bucket].keep);
  	rsb_insert(r, &ls->ls_rsbtbl[r->res_bucket].toss);
e7fd41792   David Teigland   [DLM] The core of...
1109
  	r->res_toss_time = jiffies;
f11722834   David Teigland   dlm: avoid scanni...
1110
  	ls->ls_rsbtbl[r->res_bucket].flags |= DLM_RTF_SHRINK;
e7fd41792   David Teigland   [DLM] The core of...
1111
  	if (r->res_lvbptr) {
52bda2b5b   David Teigland   dlm: use dlm pref...
1112
  		dlm_free_lvb(r->res_lvbptr);
e7fd41792   David Teigland   [DLM] The core of...
1113
1114
1115
  		r->res_lvbptr = NULL;
  	}
  }
e7fd41792   David Teigland   [DLM] The core of...
1116
1117
1118
1119
1120
1121
  /* See comment for unhold_lkb */
  
  static void unhold_rsb(struct dlm_rsb *r)
  {
  	int rv;
  	rv = kref_put(&r->res_ref, toss_rsb);
a345da3e8   David Teigland   [DLM] dump rsb an...
1122
  	DLM_ASSERT(!rv, dlm_dump_rsb(r););
e7fd41792   David Teigland   [DLM] The core of...
1123
1124
1125
1126
1127
1128
1129
1130
  }
  
  static void kill_rsb(struct kref *kref)
  {
  	struct dlm_rsb *r = container_of(kref, struct dlm_rsb, res_ref);
  
  	/* All work is done after the return from kref_put() so we
  	   can release the write_lock before the remove and free. */
a345da3e8   David Teigland   [DLM] dump rsb an...
1131
1132
1133
1134
1135
1136
  	DLM_ASSERT(list_empty(&r->res_lookup), dlm_dump_rsb(r););
  	DLM_ASSERT(list_empty(&r->res_grantqueue), dlm_dump_rsb(r););
  	DLM_ASSERT(list_empty(&r->res_convertqueue), dlm_dump_rsb(r););
  	DLM_ASSERT(list_empty(&r->res_waitqueue), dlm_dump_rsb(r););
  	DLM_ASSERT(list_empty(&r->res_root_list), dlm_dump_rsb(r););
  	DLM_ASSERT(list_empty(&r->res_recover_list), dlm_dump_rsb(r););
e7fd41792   David Teigland   [DLM] The core of...
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
  }
  
  /* Attaching/detaching lkb's from rsb's is for rsb reference counting.
     The rsb must exist as long as any lkb's for it do. */
  
  static void attach_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	hold_rsb(r);
  	lkb->lkb_resource = r;
  }
  
  static void detach_lkb(struct dlm_lkb *lkb)
  {
  	if (lkb->lkb_resource) {
  		put_rsb(lkb->lkb_resource);
  		lkb->lkb_resource = NULL;
  	}
  }
  
  static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
  {
3d6aa675f   David Teigland   dlm: keep lkbs in...
1158
  	struct dlm_lkb *lkb;
2a86b3e74   Tejun Heo   dlm: convert to i...
1159
  	int rv;
e7fd41792   David Teigland   [DLM] The core of...
1160

52bda2b5b   David Teigland   dlm: use dlm pref...
1161
  	lkb = dlm_allocate_lkb(ls);
e7fd41792   David Teigland   [DLM] The core of...
1162
1163
1164
1165
1166
1167
  	if (!lkb)
  		return -ENOMEM;
  
  	lkb->lkb_nodeid = -1;
  	lkb->lkb_grmode = DLM_LOCK_IV;
  	kref_init(&lkb->lkb_ref);
34e22bed1   David Teigland   [DLM] fix leaking...
1168
  	INIT_LIST_HEAD(&lkb->lkb_ownqueue);
ef0c2bb05   David Teigland   [DLM] overlapping...
1169
  	INIT_LIST_HEAD(&lkb->lkb_rsb_lookup);
3ae1acf93   David Teigland   [DLM] add lock ti...
1170
  	INIT_LIST_HEAD(&lkb->lkb_time_list);
23e8e1aaa   David Teigland   dlm: use workqueu...
1171
1172
1173
  	INIT_LIST_HEAD(&lkb->lkb_cb_list);
  	mutex_init(&lkb->lkb_cb_mutex);
  	INIT_WORK(&lkb->lkb_cb_work, dlm_callback_work);
e7fd41792   David Teigland   [DLM] The core of...
1174

2a86b3e74   Tejun Heo   dlm: convert to i...
1175
  	idr_preload(GFP_NOFS);
3d6aa675f   David Teigland   dlm: keep lkbs in...
1176
  	spin_lock(&ls->ls_lkbidr_spin);
2a86b3e74   Tejun Heo   dlm: convert to i...
1177
1178
1179
  	rv = idr_alloc(&ls->ls_lkbidr, lkb, 1, 0, GFP_NOWAIT);
  	if (rv >= 0)
  		lkb->lkb_id = rv;
3d6aa675f   David Teigland   dlm: keep lkbs in...
1180
  	spin_unlock(&ls->ls_lkbidr_spin);
2a86b3e74   Tejun Heo   dlm: convert to i...
1181
  	idr_preload_end();
e7fd41792   David Teigland   [DLM] The core of...
1182

3d6aa675f   David Teigland   dlm: keep lkbs in...
1183
1184
  	if (rv < 0) {
  		log_error(ls, "create_lkb idr error %d", rv);
294776562   Vasily Averin   dlm: possible mem...
1185
  		dlm_free_lkb(lkb);
3d6aa675f   David Teigland   dlm: keep lkbs in...
1186
  		return rv;
e7fd41792   David Teigland   [DLM] The core of...
1187
  	}
e7fd41792   David Teigland   [DLM] The core of...
1188
1189
1190
  	*lkb_ret = lkb;
  	return 0;
  }
e7fd41792   David Teigland   [DLM] The core of...
1191
1192
1193
  static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
  {
  	struct dlm_lkb *lkb;
e7fd41792   David Teigland   [DLM] The core of...
1194

3d6aa675f   David Teigland   dlm: keep lkbs in...
1195
1196
  	spin_lock(&ls->ls_lkbidr_spin);
  	lkb = idr_find(&ls->ls_lkbidr, lkid);
e7fd41792   David Teigland   [DLM] The core of...
1197
1198
  	if (lkb)
  		kref_get(&lkb->lkb_ref);
3d6aa675f   David Teigland   dlm: keep lkbs in...
1199
  	spin_unlock(&ls->ls_lkbidr_spin);
e7fd41792   David Teigland   [DLM] The core of...
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  
  	*lkb_ret = lkb;
  	return lkb ? 0 : -ENOENT;
  }
  
  static void kill_lkb(struct kref *kref)
  {
  	struct dlm_lkb *lkb = container_of(kref, struct dlm_lkb, lkb_ref);
  
  	/* All work is done after the return from kref_put() so we
  	   can release the write_lock before the detach_lkb */
  
  	DLM_ASSERT(!lkb->lkb_status, dlm_print_lkb(lkb););
  }
b3f58d8f2   David Teigland   [DLM] Pass in loc...
1214
1215
1216
1217
  /* __put_lkb() is used when an lkb may not have an rsb attached to
     it so we need to provide the lockspace explicitly */
  
  static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
e7fd41792   David Teigland   [DLM] The core of...
1218
  {
3d6aa675f   David Teigland   dlm: keep lkbs in...
1219
  	uint32_t lkid = lkb->lkb_id;
e7fd41792   David Teigland   [DLM] The core of...
1220

3d6aa675f   David Teigland   dlm: keep lkbs in...
1221
  	spin_lock(&ls->ls_lkbidr_spin);
e7fd41792   David Teigland   [DLM] The core of...
1222
  	if (kref_put(&lkb->lkb_ref, kill_lkb)) {
3d6aa675f   David Teigland   dlm: keep lkbs in...
1223
1224
  		idr_remove(&ls->ls_lkbidr, lkid);
  		spin_unlock(&ls->ls_lkbidr_spin);
e7fd41792   David Teigland   [DLM] The core of...
1225
1226
1227
1228
1229
  
  		detach_lkb(lkb);
  
  		/* for local/process lkbs, lvbptr points to caller's lksb */
  		if (lkb->lkb_lvbptr && is_master_copy(lkb))
52bda2b5b   David Teigland   dlm: use dlm pref...
1230
1231
  			dlm_free_lvb(lkb->lkb_lvbptr);
  		dlm_free_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
1232
1233
  		return 1;
  	} else {
3d6aa675f   David Teigland   dlm: keep lkbs in...
1234
  		spin_unlock(&ls->ls_lkbidr_spin);
e7fd41792   David Teigland   [DLM] The core of...
1235
1236
1237
1238
1239
1240
  		return 0;
  	}
  }
  
  int dlm_put_lkb(struct dlm_lkb *lkb)
  {
b3f58d8f2   David Teigland   [DLM] Pass in loc...
1241
1242
1243
1244
1245
1246
1247
  	struct dlm_ls *ls;
  
  	DLM_ASSERT(lkb->lkb_resource, dlm_print_lkb(lkb););
  	DLM_ASSERT(lkb->lkb_resource->res_ls, dlm_print_lkb(lkb););
  
  	ls = lkb->lkb_resource->res_ls;
  	return __put_lkb(ls, lkb);
e7fd41792   David Teigland   [DLM] The core of...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  }
  
  /* This is only called to add a reference when the code already holds
     a valid reference to the lkb, so there's no need for locking. */
  
  static inline void hold_lkb(struct dlm_lkb *lkb)
  {
  	kref_get(&lkb->lkb_ref);
  }
  
  /* This is called when we need to remove a reference and are certain
     it's not the last ref.  e.g. del_lkb is always called between a
     find_lkb/put_lkb and is always the inverse of a previous add_lkb.
     put_lkb would work fine, but would involve unnecessary locking */
  
  static inline void unhold_lkb(struct dlm_lkb *lkb)
  {
  	int rv;
  	rv = kref_put(&lkb->lkb_ref, kill_lkb);
  	DLM_ASSERT(!rv, dlm_print_lkb(lkb););
  }
  
  static void lkb_add_ordered(struct list_head *new, struct list_head *head,
  			    int mode)
  {
  	struct dlm_lkb *lkb = NULL;
  
  	list_for_each_entry(lkb, head, lkb_statequeue)
  		if (lkb->lkb_rqmode < mode)
  			break;
99fb19d49   Dan Carpenter   dlm: cleanup remo...
1278
  	__list_add(new, lkb->lkb_statequeue.prev, &lkb->lkb_statequeue);
e7fd41792   David Teigland   [DLM] The core of...
1279
1280
1281
1282
1283
1284
1285
1286
1287
  }
  
  /* add/remove lkb to rsb's grant/convert/wait queue */
  
  static void add_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, int status)
  {
  	kref_get(&lkb->lkb_ref);
  
  	DLM_ASSERT(!lkb->lkb_status, dlm_print_lkb(lkb););
eeda418d8   David Teigland   dlm: change lock ...
1288
  	lkb->lkb_timestamp = ktime_get();
e7fd41792   David Teigland   [DLM] The core of...
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
  	lkb->lkb_status = status;
  
  	switch (status) {
  	case DLM_LKSTS_WAITING:
  		if (lkb->lkb_exflags & DLM_LKF_HEADQUE)
  			list_add(&lkb->lkb_statequeue, &r->res_waitqueue);
  		else
  			list_add_tail(&lkb->lkb_statequeue, &r->res_waitqueue);
  		break;
  	case DLM_LKSTS_GRANTED:
  		/* convention says granted locks kept in order of grmode */
  		lkb_add_ordered(&lkb->lkb_statequeue, &r->res_grantqueue,
  				lkb->lkb_grmode);
  		break;
  	case DLM_LKSTS_CONVERT:
  		if (lkb->lkb_exflags & DLM_LKF_HEADQUE)
  			list_add(&lkb->lkb_statequeue, &r->res_convertqueue);
  		else
  			list_add_tail(&lkb->lkb_statequeue,
  				      &r->res_convertqueue);
  		break;
  	default:
  		DLM_ASSERT(0, dlm_print_lkb(lkb); printk("sts=%d
  ", status););
  	}
  }
  
  static void del_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	lkb->lkb_status = 0;
  	list_del(&lkb->lkb_statequeue);
  	unhold_lkb(lkb);
  }
  
  static void move_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, int sts)
  {
  	hold_lkb(lkb);
  	del_lkb(r, lkb);
  	add_lkb(r, lkb, sts);
  	unhold_lkb(lkb);
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  static int msg_reply_type(int mstype)
  {
  	switch (mstype) {
  	case DLM_MSG_REQUEST:
  		return DLM_MSG_REQUEST_REPLY;
  	case DLM_MSG_CONVERT:
  		return DLM_MSG_CONVERT_REPLY;
  	case DLM_MSG_UNLOCK:
  		return DLM_MSG_UNLOCK_REPLY;
  	case DLM_MSG_CANCEL:
  		return DLM_MSG_CANCEL_REPLY;
  	case DLM_MSG_LOOKUP:
  		return DLM_MSG_LOOKUP_REPLY;
  	}
  	return -1;
  }
c6ff669ba   David Teigland   dlm: delayed repl...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
  static int nodeid_warned(int nodeid, int num_nodes, int *warned)
  {
  	int i;
  
  	for (i = 0; i < num_nodes; i++) {
  		if (!warned[i]) {
  			warned[i] = nodeid;
  			return 0;
  		}
  		if (warned[i] == nodeid)
  			return 1;
  	}
  	return 0;
  }
  
  void dlm_scan_waiters(struct dlm_ls *ls)
  {
  	struct dlm_lkb *lkb;
c6ff669ba   David Teigland   dlm: delayed repl...
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
  	s64 us;
  	s64 debug_maxus = 0;
  	u32 debug_scanned = 0;
  	u32 debug_expired = 0;
  	int num_nodes = 0;
  	int *warned = NULL;
  
  	if (!dlm_config.ci_waitwarn_us)
  		return;
  
  	mutex_lock(&ls->ls_waiters_mutex);
  
  	list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
1f3a8e49d   Thomas Gleixner   ktime: Get rid of...
1377
  		if (!lkb->lkb_wait_time)
c6ff669ba   David Teigland   dlm: delayed repl...
1378
1379
1380
1381
1382
1383
1384
1385
  			continue;
  
  		debug_scanned++;
  
  		us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_wait_time));
  
  		if (us < dlm_config.ci_waitwarn_us)
  			continue;
1f3a8e49d   Thomas Gleixner   ktime: Get rid of...
1386
  		lkb->lkb_wait_time = 0;
c6ff669ba   David Teigland   dlm: delayed repl...
1387
1388
1389
1390
1391
1392
1393
  
  		debug_expired++;
  		if (us > debug_maxus)
  			debug_maxus = us;
  
  		if (!num_nodes) {
  			num_nodes = ls->ls_num_nodes;
fbb100815   Markus Elfring   dlm: Use kcalloc(...
1394
  			warned = kcalloc(num_nodes, sizeof(int), GFP_KERNEL);
c6ff669ba   David Teigland   dlm: delayed repl...
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  		}
  		if (!warned)
  			continue;
  		if (nodeid_warned(lkb->lkb_wait_nodeid, num_nodes, warned))
  			continue;
  
  		log_error(ls, "waitwarn %x %lld %d us check connection to "
  			  "node %d", lkb->lkb_id, (long long)us,
  			  dlm_config.ci_waitwarn_us, lkb->lkb_wait_nodeid);
  	}
  	mutex_unlock(&ls->ls_waiters_mutex);
5d70828a7   Jesper Juhl   dlm: don't do poi...
1406
  	kfree(warned);
c6ff669ba   David Teigland   dlm: delayed repl...
1407
1408
1409
1410
1411
1412
  
  	if (debug_expired)
  		log_debug(ls, "scan_waiters %u warn %u over %d us max %lld us",
  			  debug_scanned, debug_expired,
  			  dlm_config.ci_waitwarn_us, (long long)debug_maxus);
  }
e7fd41792   David Teigland   [DLM] The core of...
1413
1414
  /* add/remove lkb from global waiters list of lkb's waiting for
     a reply from a remote node */
c6ff669ba   David Teigland   dlm: delayed repl...
1415
  static int add_to_waiters(struct dlm_lkb *lkb, int mstype, int to_nodeid)
e7fd41792   David Teigland   [DLM] The core of...
1416
1417
  {
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
ef0c2bb05   David Teigland   [DLM] overlapping...
1418
  	int error = 0;
e7fd41792   David Teigland   [DLM] The core of...
1419

901359256   David Teigland   [DLM] Update DLM ...
1420
  	mutex_lock(&ls->ls_waiters_mutex);
ef0c2bb05   David Teigland   [DLM] overlapping...
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
  
  	if (is_overlap_unlock(lkb) ||
  	    (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL))) {
  		error = -EINVAL;
  		goto out;
  	}
  
  	if (lkb->lkb_wait_type || is_overlap_cancel(lkb)) {
  		switch (mstype) {
  		case DLM_MSG_UNLOCK:
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
  			break;
  		case DLM_MSG_CANCEL:
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
  			break;
  		default:
  			error = -EBUSY;
  			goto out;
  		}
  		lkb->lkb_wait_count++;
  		hold_lkb(lkb);
43279e537   David Teigland   dlm: clear defunc...
1442
  		log_debug(ls, "addwait %x cur %d overlap %d count %d f %x",
ef0c2bb05   David Teigland   [DLM] overlapping...
1443
1444
  			  lkb->lkb_id, lkb->lkb_wait_type, mstype,
  			  lkb->lkb_wait_count, lkb->lkb_flags);
e7fd41792   David Teigland   [DLM] The core of...
1445
1446
  		goto out;
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
1447
1448
1449
1450
1451
1452
1453
  
  	DLM_ASSERT(!lkb->lkb_wait_count,
  		   dlm_print_lkb(lkb);
  		   printk("wait_count %d
  ", lkb->lkb_wait_count););
  
  	lkb->lkb_wait_count++;
e7fd41792   David Teigland   [DLM] The core of...
1454
  	lkb->lkb_wait_type = mstype;
c6ff669ba   David Teigland   dlm: delayed repl...
1455
1456
  	lkb->lkb_wait_time = ktime_get();
  	lkb->lkb_wait_nodeid = to_nodeid; /* for debugging */
ef0c2bb05   David Teigland   [DLM] overlapping...
1457
  	hold_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
1458
1459
  	list_add(&lkb->lkb_wait_reply, &ls->ls_waiters);
   out:
ef0c2bb05   David Teigland   [DLM] overlapping...
1460
  	if (error)
43279e537   David Teigland   dlm: clear defunc...
1461
  		log_error(ls, "addwait error %x %d flags %x %d %d %s",
ef0c2bb05   David Teigland   [DLM] overlapping...
1462
1463
  			  lkb->lkb_id, error, lkb->lkb_flags, mstype,
  			  lkb->lkb_wait_type, lkb->lkb_resource->res_name);
901359256   David Teigland   [DLM] Update DLM ...
1464
  	mutex_unlock(&ls->ls_waiters_mutex);
ef0c2bb05   David Teigland   [DLM] overlapping...
1465
  	return error;
e7fd41792   David Teigland   [DLM] The core of...
1466
  }
b790c3b7c   David Teigland   [DLM] can miss cl...
1467
1468
1469
1470
  /* We clear the RESEND flag because we might be taking an lkb off the waiters
     list as part of process_requestqueue (e.g. a lookup that has an optimized
     request reply on the requestqueue) between dlm_recover_waiters_pre() which
     set RESEND and dlm_recover_waiters_post() */
43279e537   David Teigland   dlm: clear defunc...
1471
1472
  static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype,
  				struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
1473
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
1474
1475
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
  	int overlap_done = 0;
e7fd41792   David Teigland   [DLM] The core of...
1476

ef0c2bb05   David Teigland   [DLM] overlapping...
1477
  	if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) {
43279e537   David Teigland   dlm: clear defunc...
1478
  		log_debug(ls, "remwait %x unlock_reply overlap", lkb->lkb_id);
ef0c2bb05   David Teigland   [DLM] overlapping...
1479
1480
1481
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
  		overlap_done = 1;
  		goto out_del;
e7fd41792   David Teigland   [DLM] The core of...
1482
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
1483
1484
  
  	if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) {
43279e537   David Teigland   dlm: clear defunc...
1485
  		log_debug(ls, "remwait %x cancel_reply overlap", lkb->lkb_id);
ef0c2bb05   David Teigland   [DLM] overlapping...
1486
1487
1488
1489
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		overlap_done = 1;
  		goto out_del;
  	}
43279e537   David Teigland   dlm: clear defunc...
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
  	/* Cancel state was preemptively cleared by a successful convert,
  	   see next comment, nothing to do. */
  
  	if ((mstype == DLM_MSG_CANCEL_REPLY) &&
  	    (lkb->lkb_wait_type != DLM_MSG_CANCEL)) {
  		log_debug(ls, "remwait %x cancel_reply wait_type %d",
  			  lkb->lkb_id, lkb->lkb_wait_type);
  		return -1;
  	}
  
  	/* Remove for the convert reply, and premptively remove for the
  	   cancel reply.  A convert has been granted while there's still
  	   an outstanding cancel on it (the cancel is moot and the result
  	   in the cancel reply should be 0).  We preempt the cancel reply
  	   because the app gets the convert result and then can follow up
  	   with another op, like convert.  This subsequent op would see the
  	   lingering state of the cancel and fail with -EBUSY. */
  
  	if ((mstype == DLM_MSG_CONVERT_REPLY) &&
  	    (lkb->lkb_wait_type == DLM_MSG_CONVERT) &&
  	    is_overlap_cancel(lkb) && ms && !ms->m_result) {
  		log_debug(ls, "remwait %x convert_reply zap overlap_cancel",
  			  lkb->lkb_id);
  		lkb->lkb_wait_type = 0;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		lkb->lkb_wait_count--;
  		goto out_del;
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
1518
1519
1520
1521
1522
1523
1524
  	/* N.B. type of reply may not always correspond to type of original
  	   msg due to lookup->request optimization, verify others? */
  
  	if (lkb->lkb_wait_type) {
  		lkb->lkb_wait_type = 0;
  		goto out_del;
  	}
6d40c4a70   David Teigland   dlm: improve erro...
1525
1526
1527
  	log_error(ls, "remwait error %x remote %d %x msg %d flags %x no wait",
  		  lkb->lkb_id, ms ? ms->m_header.h_nodeid : 0, lkb->lkb_remid,
  		  mstype, lkb->lkb_flags);
ef0c2bb05   David Teigland   [DLM] overlapping...
1528
1529
1530
1531
1532
1533
1534
1535
1536
  	return -1;
  
   out_del:
  	/* the force-unlock/cancel has completed and we haven't recvd a reply
  	   to the op that was in progress prior to the unlock/cancel; we
  	   give up on any reply to the earlier op.  FIXME: not sure when/how
  	   this would happen */
  
  	if (overlap_done && lkb->lkb_wait_type) {
43279e537   David Teigland   dlm: clear defunc...
1537
  		log_error(ls, "remwait error %x reply %d wait_type %d overlap",
ef0c2bb05   David Teigland   [DLM] overlapping...
1538
1539
1540
1541
1542
1543
  			  lkb->lkb_id, mstype, lkb->lkb_wait_type);
  		lkb->lkb_wait_count--;
  		lkb->lkb_wait_type = 0;
  	}
  
  	DLM_ASSERT(lkb->lkb_wait_count, dlm_print_lkb(lkb););
b790c3b7c   David Teigland   [DLM] can miss cl...
1544
  	lkb->lkb_flags &= ~DLM_IFL_RESEND;
ef0c2bb05   David Teigland   [DLM] overlapping...
1545
1546
1547
  	lkb->lkb_wait_count--;
  	if (!lkb->lkb_wait_count)
  		list_del_init(&lkb->lkb_wait_reply);
e7fd41792   David Teigland   [DLM] The core of...
1548
  	unhold_lkb(lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
1549
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
1550
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
1551
  static int remove_from_waiters(struct dlm_lkb *lkb, int mstype)
e7fd41792   David Teigland   [DLM] The core of...
1552
1553
1554
  {
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
  	int error;
901359256   David Teigland   [DLM] Update DLM ...
1555
  	mutex_lock(&ls->ls_waiters_mutex);
43279e537   David Teigland   dlm: clear defunc...
1556
  	error = _remove_from_waiters(lkb, mstype, NULL);
901359256   David Teigland   [DLM] Update DLM ...
1557
  	mutex_unlock(&ls->ls_waiters_mutex);
e7fd41792   David Teigland   [DLM] The core of...
1558
1559
  	return error;
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
1560
1561
1562
1563
1564
1565
1566
  /* Handles situations where we might be processing a "fake" or "stub" reply in
     which we can't try to take waiters_mutex again. */
  
  static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
  	int error;
2a7ce0edd   David Teigland   dlm: remove share...
1567
  	if (ms->m_flags != DLM_IFL_STUB_MS)
ef0c2bb05   David Teigland   [DLM] overlapping...
1568
  		mutex_lock(&ls->ls_waiters_mutex);
43279e537   David Teigland   dlm: clear defunc...
1569
  	error = _remove_from_waiters(lkb, ms->m_type, ms);
2a7ce0edd   David Teigland   dlm: remove share...
1570
  	if (ms->m_flags != DLM_IFL_STUB_MS)
ef0c2bb05   David Teigland   [DLM] overlapping...
1571
1572
1573
  		mutex_unlock(&ls->ls_waiters_mutex);
  	return error;
  }
05c32f47b   David Teigland   dlm: fix race bet...
1574
1575
1576
1577
  /* If there's an rsb for the same resource being removed, ensure
     that the remove message is sent before the new lookup message.
     It should be rare to need a delay here, but if not, then it may
     be worthwhile to add a proper wait mechanism rather than a delay. */
e7fd41792   David Teigland   [DLM] The core of...
1578

05c32f47b   David Teigland   dlm: fix race bet...
1579
  static void wait_pending_remove(struct dlm_rsb *r)
e7fd41792   David Teigland   [DLM] The core of...
1580
  {
05c32f47b   David Teigland   dlm: fix race bet...
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  	struct dlm_ls *ls = r->res_ls;
   restart:
  	spin_lock(&ls->ls_remove_spin);
  	if (ls->ls_remove_len &&
  	    !rsb_cmp(r, ls->ls_remove_name, ls->ls_remove_len)) {
  		log_debug(ls, "delay lookup for remove dir %d %s",
  		  	  r->res_dir_nodeid, r->res_name);
  		spin_unlock(&ls->ls_remove_spin);
  		msleep(1);
  		goto restart;
  	}
  	spin_unlock(&ls->ls_remove_spin);
  }
e7fd41792   David Teigland   [DLM] The core of...
1594

05c32f47b   David Teigland   dlm: fix race bet...
1595
1596
1597
1598
1599
1600
  /*
   * ls_remove_spin protects ls_remove_name and ls_remove_len which are
   * read by other threads in wait_pending_remove.  ls_remove_names
   * and ls_remove_lens are only used by the scan thread, so they do
   * not need protection.
   */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1601

05c32f47b   David Teigland   dlm: fix race bet...
1602
1603
1604
1605
1606
1607
1608
  static void shrink_bucket(struct dlm_ls *ls, int b)
  {
  	struct rb_node *n, *next;
  	struct dlm_rsb *r;
  	char *name;
  	int our_nodeid = dlm_our_nodeid();
  	int remote_count = 0;
f11722834   David Teigland   dlm: avoid scanni...
1609
  	int need_shrink = 0;
05c32f47b   David Teigland   dlm: fix race bet...
1610
  	int i, len, rv;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1611

05c32f47b   David Teigland   dlm: fix race bet...
1612
  	memset(&ls->ls_remove_lens, 0, sizeof(int) * DLM_REMOVE_NAMES_MAX);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1613

05c32f47b   David Teigland   dlm: fix race bet...
1614
  	spin_lock(&ls->ls_rsbtbl[b].lock);
f11722834   David Teigland   dlm: avoid scanni...
1615
1616
1617
1618
1619
  
  	if (!(ls->ls_rsbtbl[b].flags & DLM_RTF_SHRINK)) {
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		return;
  	}
05c32f47b   David Teigland   dlm: fix race bet...
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
  	for (n = rb_first(&ls->ls_rsbtbl[b].toss); n; n = next) {
  		next = rb_next(n);
  		r = rb_entry(n, struct dlm_rsb, res_hashnode);
  
  		/* If we're the directory record for this rsb, and
  		   we're not the master of it, then we need to wait
  		   for the master node to send us a dir remove for
  		   before removing the dir record. */
  
  		if (!dlm_no_directory(ls) &&
  		    (r->res_master_nodeid != our_nodeid) &&
  		    (dlm_dir_nodeid(r) == our_nodeid)) {
  			continue;
e7fd41792   David Teigland   [DLM] The core of...
1633
  		}
f11722834   David Teigland   dlm: avoid scanni...
1634
  		need_shrink = 1;
05c32f47b   David Teigland   dlm: fix race bet...
1635
1636
1637
  		if (!time_after_eq(jiffies, r->res_toss_time +
  				   dlm_config.ci_toss_secs * HZ)) {
  			continue;
e7fd41792   David Teigland   [DLM] The core of...
1638
  		}
05c32f47b   David Teigland   dlm: fix race bet...
1639
1640
1641
  		if (!dlm_no_directory(ls) &&
  		    (r->res_master_nodeid == our_nodeid) &&
  		    (dlm_dir_nodeid(r) != our_nodeid)) {
e7fd41792   David Teigland   [DLM] The core of...
1642

c04fecb4d   David Teigland   dlm: use rsbtbl a...
1643
1644
1645
  			/* We're the master of this rsb but we're not
  			   the directory record, so we need to tell the
  			   dir node to remove the dir record. */
05c32f47b   David Teigland   dlm: fix race bet...
1646
1647
1648
1649
  			ls->ls_remove_lens[remote_count] = r->res_length;
  			memcpy(ls->ls_remove_names[remote_count], r->res_name,
  			       DLM_RESNAME_MAXLEN);
  			remote_count++;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
1650

05c32f47b   David Teigland   dlm: fix race bet...
1651
1652
1653
1654
1655
1656
  			if (remote_count >= DLM_REMOVE_NAMES_MAX)
  				break;
  			continue;
  		}
  
  		if (!kref_put(&r->res_ref, kill_rsb)) {
e7fd41792   David Teigland   [DLM] The core of...
1657
  			log_error(ls, "tossed rsb in use %s", r->res_name);
05c32f47b   David Teigland   dlm: fix race bet...
1658
  			continue;
e7fd41792   David Teigland   [DLM] The core of...
1659
  		}
05c32f47b   David Teigland   dlm: fix race bet...
1660
1661
1662
  
  		rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
  		dlm_free_rsb(r);
e7fd41792   David Teigland   [DLM] The core of...
1663
  	}
f11722834   David Teigland   dlm: avoid scanni...
1664
1665
1666
1667
1668
  
  	if (need_shrink)
  		ls->ls_rsbtbl[b].flags |= DLM_RTF_SHRINK;
  	else
  		ls->ls_rsbtbl[b].flags &= ~DLM_RTF_SHRINK;
05c32f47b   David Teigland   dlm: fix race bet...
1669
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
e7fd41792   David Teigland   [DLM] The core of...
1670

05c32f47b   David Teigland   dlm: fix race bet...
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
  	/*
  	 * While searching for rsb's to free, we found some that require
  	 * remote removal.  We leave them in place and find them again here
  	 * so there is a very small gap between removing them from the toss
  	 * list and sending the removal.  Keeping this gap small is
  	 * important to keep us (the master node) from being out of sync
  	 * with the remote dir node for very long.
  	 *
  	 * From the time the rsb is removed from toss until just after
  	 * send_remove, the rsb name is saved in ls_remove_name.  A new
  	 * lookup checks this to ensure that a new lookup message for the
  	 * same resource name is not sent just before the remove message.
  	 */
  
  	for (i = 0; i < remote_count; i++) {
  		name = ls->ls_remove_names[i];
  		len = ls->ls_remove_lens[i];
  
  		spin_lock(&ls->ls_rsbtbl[b].lock);
  		rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  		if (rv) {
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			log_debug(ls, "remove_name not toss %s", name);
  			continue;
  		}
  
  		if (r->res_master_nodeid != our_nodeid) {
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			log_debug(ls, "remove_name master %d dir %d our %d %s",
  				  r->res_master_nodeid, r->res_dir_nodeid,
  				  our_nodeid, name);
  			continue;
  		}
  
  		if (r->res_dir_nodeid == our_nodeid) {
  			/* should never happen */
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			log_error(ls, "remove_name dir %d master %d our %d %s",
  				  r->res_dir_nodeid, r->res_master_nodeid,
  				  our_nodeid, name);
  			continue;
  		}
  
  		if (!time_after_eq(jiffies, r->res_toss_time +
  				   dlm_config.ci_toss_secs * HZ)) {
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			log_debug(ls, "remove_name toss_time %lu now %lu %s",
  				  r->res_toss_time, jiffies, name);
  			continue;
  		}
  
  		if (!kref_put(&r->res_ref, kill_rsb)) {
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			log_error(ls, "remove_name in use %s", name);
  			continue;
  		}
  
  		rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
  
  		/* block lookup of same name until we've sent remove */
  		spin_lock(&ls->ls_remove_spin);
  		ls->ls_remove_len = len;
  		memcpy(ls->ls_remove_name, name, DLM_RESNAME_MAXLEN);
  		spin_unlock(&ls->ls_remove_spin);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  
  		send_remove(r);
  
  		/* allow lookup of name again */
  		spin_lock(&ls->ls_remove_spin);
  		ls->ls_remove_len = 0;
  		memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);
  		spin_unlock(&ls->ls_remove_spin);
  
  		dlm_free_rsb(r);
  	}
e7fd41792   David Teigland   [DLM] The core of...
1747
1748
1749
1750
1751
  }
  
  void dlm_scan_rsbs(struct dlm_ls *ls)
  {
  	int i;
e7fd41792   David Teigland   [DLM] The core of...
1752
1753
  	for (i = 0; i < ls->ls_rsbtbl_size; i++) {
  		shrink_bucket(ls, i);
85e86edf9   David Teigland   [DLM] block scand...
1754
1755
  		if (dlm_locking_stopped(ls))
  			break;
e7fd41792   David Teigland   [DLM] The core of...
1756
1757
1758
  		cond_resched();
  	}
  }
3ae1acf93   David Teigland   [DLM] add lock ti...
1759
1760
1761
  static void add_timeout(struct dlm_lkb *lkb)
  {
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
eeda418d8   David Teigland   dlm: change lock ...
1762
  	if (is_master_copy(lkb))
3ae1acf93   David Teigland   [DLM] add lock ti...
1763
  		return;
3ae1acf93   David Teigland   [DLM] add lock ti...
1764
1765
1766
1767
1768
1769
  
  	if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) &&
  	    !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
  		lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN;
  		goto add_it;
  	}
84d8cd69a   David Teigland   [DLM] timeout fixes
1770
1771
  	if (lkb->lkb_exflags & DLM_LKF_TIMEOUT)
  		goto add_it;
3ae1acf93   David Teigland   [DLM] add lock ti...
1772
1773
1774
1775
1776
1777
  	return;
  
   add_it:
  	DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb););
  	mutex_lock(&ls->ls_timeout_mutex);
  	hold_lkb(lkb);
3ae1acf93   David Teigland   [DLM] add lock ti...
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
  	list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout);
  	mutex_unlock(&ls->ls_timeout_mutex);
  }
  
  static void del_timeout(struct dlm_lkb *lkb)
  {
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
  
  	mutex_lock(&ls->ls_timeout_mutex);
  	if (!list_empty(&lkb->lkb_time_list)) {
  		list_del_init(&lkb->lkb_time_list);
  		unhold_lkb(lkb);
  	}
  	mutex_unlock(&ls->ls_timeout_mutex);
  }
  
  /* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and
     lkb_lksb_timeout without lock_rsb?  Note: we can't lock timeout_mutex
     and then lock rsb because of lock ordering in add_timeout.  We may need
     to specify some special timeout-related bits in the lkb that are just to
     be accessed under the timeout_mutex. */
  
  void dlm_scan_timeout(struct dlm_ls *ls)
  {
  	struct dlm_rsb *r;
  	struct dlm_lkb *lkb;
  	int do_cancel, do_warn;
eeda418d8   David Teigland   dlm: change lock ...
1805
  	s64 wait_us;
3ae1acf93   David Teigland   [DLM] add lock ti...
1806
1807
1808
1809
1810
1811
1812
1813
1814
  
  	for (;;) {
  		if (dlm_locking_stopped(ls))
  			break;
  
  		do_cancel = 0;
  		do_warn = 0;
  		mutex_lock(&ls->ls_timeout_mutex);
  		list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) {
eeda418d8   David Teigland   dlm: change lock ...
1815
1816
  			wait_us = ktime_to_us(ktime_sub(ktime_get(),
  					      		lkb->lkb_timestamp));
3ae1acf93   David Teigland   [DLM] add lock ti...
1817
  			if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) &&
eeda418d8   David Teigland   dlm: change lock ...
1818
  			    wait_us >= (lkb->lkb_timeout_cs * 10000))
3ae1acf93   David Teigland   [DLM] add lock ti...
1819
1820
1821
  				do_cancel = 1;
  
  			if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
eeda418d8   David Teigland   dlm: change lock ...
1822
  			    wait_us >= dlm_config.ci_timewarn_cs * 10000)
3ae1acf93   David Teigland   [DLM] add lock ti...
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
  				do_warn = 1;
  
  			if (!do_cancel && !do_warn)
  				continue;
  			hold_lkb(lkb);
  			break;
  		}
  		mutex_unlock(&ls->ls_timeout_mutex);
  
  		if (!do_cancel && !do_warn)
  			break;
  
  		r = lkb->lkb_resource;
  		hold_rsb(r);
  		lock_rsb(r);
  
  		if (do_warn) {
  			/* clear flag so we only warn once */
  			lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
  			if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT))
  				del_timeout(lkb);
  			dlm_timeout_warn(lkb);
  		}
  
  		if (do_cancel) {
b3cab7b9a   Steven Whitehouse   [DLM] Compile fix
1848
  			log_debug(ls, "timeout cancel %x node %d %s",
639aca417   David Teigland   [DLM] fix compile...
1849
  				  lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
3ae1acf93   David Teigland   [DLM] add lock ti...
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
  			lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
  			lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL;
  			del_timeout(lkb);
  			_cancel_lock(r, lkb);
  		}
  
  		unlock_rsb(r);
  		unhold_rsb(r);
  		dlm_put_lkb(lkb);
  	}
  }
  
  /* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping
     dlm_recoverd before checking/setting ls_recover_begin. */
  
  void dlm_adjust_timeouts(struct dlm_ls *ls)
  {
  	struct dlm_lkb *lkb;
eeda418d8   David Teigland   dlm: change lock ...
1868
  	u64 adj_us = jiffies_to_usecs(jiffies - ls->ls_recover_begin);
3ae1acf93   David Teigland   [DLM] add lock ti...
1869
1870
1871
1872
  
  	ls->ls_recover_begin = 0;
  	mutex_lock(&ls->ls_timeout_mutex);
  	list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list)
eeda418d8   David Teigland   dlm: change lock ...
1873
  		lkb->lkb_timestamp = ktime_add_us(lkb->lkb_timestamp, adj_us);
3ae1acf93   David Teigland   [DLM] add lock ti...
1874
  	mutex_unlock(&ls->ls_timeout_mutex);
c6ff669ba   David Teigland   dlm: delayed repl...
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
  
  	if (!dlm_config.ci_waitwarn_us)
  		return;
  
  	mutex_lock(&ls->ls_waiters_mutex);
  	list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
  		if (ktime_to_us(lkb->lkb_wait_time))
  			lkb->lkb_wait_time = ktime_get();
  	}
  	mutex_unlock(&ls->ls_waiters_mutex);
3ae1acf93   David Teigland   [DLM] add lock ti...
1885
  }
e7fd41792   David Teigland   [DLM] The core of...
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
  /* lkb is master or local copy */
  
  static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int b, len = r->res_ls->ls_lvblen;
  
  	/* b=1 lvb returned to caller
  	   b=0 lvb written to rsb or invalidated
  	   b=-1 do nothing */
  
  	b =  dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1];
  
  	if (b == 1) {
  		if (!lkb->lkb_lvbptr)
  			return;
  
  		if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
  			return;
  
  		if (!r->res_lvbptr)
  			return;
  
  		memcpy(lkb->lkb_lvbptr, r->res_lvbptr, len);
  		lkb->lkb_lvbseq = r->res_lvbseq;
  
  	} else if (b == 0) {
  		if (lkb->lkb_exflags & DLM_LKF_IVVALBLK) {
  			rsb_set_flag(r, RSB_VALNOTVALID);
  			return;
  		}
  
  		if (!lkb->lkb_lvbptr)
  			return;
  
  		if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
  			return;
  
  		if (!r->res_lvbptr)
52bda2b5b   David Teigland   dlm: use dlm pref...
1924
  			r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
e7fd41792   David Teigland   [DLM] The core of...
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
  
  		if (!r->res_lvbptr)
  			return;
  
  		memcpy(r->res_lvbptr, lkb->lkb_lvbptr, len);
  		r->res_lvbseq++;
  		lkb->lkb_lvbseq = r->res_lvbseq;
  		rsb_clear_flag(r, RSB_VALNOTVALID);
  	}
  
  	if (rsb_flag(r, RSB_VALNOTVALID))
  		lkb->lkb_sbflags |= DLM_SBF_VALNOTVALID;
  }
  
  static void set_lvb_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	if (lkb->lkb_grmode < DLM_LOCK_PW)
  		return;
  
  	if (lkb->lkb_exflags & DLM_LKF_IVVALBLK) {
  		rsb_set_flag(r, RSB_VALNOTVALID);
  		return;
  	}
  
  	if (!lkb->lkb_lvbptr)
  		return;
  
  	if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
  		return;
  
  	if (!r->res_lvbptr)
52bda2b5b   David Teigland   dlm: use dlm pref...
1956
  		r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
e7fd41792   David Teigland   [DLM] The core of...
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
  
  	if (!r->res_lvbptr)
  		return;
  
  	memcpy(r->res_lvbptr, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
  	r->res_lvbseq++;
  	rsb_clear_flag(r, RSB_VALNOTVALID);
  }
  
  /* lkb is process copy (pc) */
  
  static void set_lvb_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			    struct dlm_message *ms)
  {
  	int b;
  
  	if (!lkb->lkb_lvbptr)
  		return;
  
  	if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
  		return;
597d0cae0   David Teigland   [DLM] dlm: user l...
1978
  	b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1];
e7fd41792   David Teigland   [DLM] The core of...
1979
1980
  	if (b == 1) {
  		int len = receive_extralen(ms);
cfa805f6f   Bart Van Assche   dlm: Avoid LVB tr...
1981
1982
  		if (len > r->res_ls->ls_lvblen)
  			len = r->res_ls->ls_lvblen;
e7fd41792   David Teigland   [DLM] The core of...
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
  		memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
  		lkb->lkb_lvbseq = ms->m_lvbseq;
  	}
  }
  
  /* Manipulate lkb's on rsb's convert/granted/waiting queues
     remove_lock -- used for unlock, removes lkb from granted
     revert_lock -- used for cancel, moves lkb from convert to granted
     grant_lock  -- used for request and convert, adds lkb to granted or
                    moves lkb from convert or waiting to granted
  
     Each of these is used for master or local copy lkb's.  There is
     also a _pc() variation used to make the corresponding change on
     a process copy (pc) lkb. */
  
  static void _remove_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	del_lkb(r, lkb);
  	lkb->lkb_grmode = DLM_LOCK_IV;
  	/* this unhold undoes the original ref from create_lkb()
  	   so this leads to the lkb being freed */
  	unhold_lkb(lkb);
  }
  
  static void remove_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	set_lvb_unlock(r, lkb);
  	_remove_lock(r, lkb);
  }
  
  static void remove_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	_remove_lock(r, lkb);
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
2017
2018
2019
2020
2021
  /* returns: 0 did nothing
  	    1 moved lock to granted
  	   -1 removed lock */
  
  static int revert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
e7fd41792   David Teigland   [DLM] The core of...
2022
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
2023
  	int rv = 0;
e7fd41792   David Teigland   [DLM] The core of...
2024
2025
2026
  	lkb->lkb_rqmode = DLM_LOCK_IV;
  
  	switch (lkb->lkb_status) {
597d0cae0   David Teigland   [DLM] dlm: user l...
2027
2028
  	case DLM_LKSTS_GRANTED:
  		break;
e7fd41792   David Teigland   [DLM] The core of...
2029
2030
  	case DLM_LKSTS_CONVERT:
  		move_lkb(r, lkb, DLM_LKSTS_GRANTED);
ef0c2bb05   David Teigland   [DLM] overlapping...
2031
  		rv = 1;
e7fd41792   David Teigland   [DLM] The core of...
2032
2033
2034
2035
2036
2037
2038
  		break;
  	case DLM_LKSTS_WAITING:
  		del_lkb(r, lkb);
  		lkb->lkb_grmode = DLM_LOCK_IV;
  		/* this unhold undoes the original ref from create_lkb()
  		   so this leads to the lkb being freed */
  		unhold_lkb(lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
2039
  		rv = -1;
e7fd41792   David Teigland   [DLM] The core of...
2040
2041
2042
2043
  		break;
  	default:
  		log_print("invalid status for revert %d", lkb->lkb_status);
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
2044
  	return rv;
e7fd41792   David Teigland   [DLM] The core of...
2045
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
2046
  static int revert_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb)
e7fd41792   David Teigland   [DLM] The core of...
2047
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
2048
  	return revert_lock(r, lkb);
e7fd41792   David Teigland   [DLM] The core of...
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
  }
  
  static void _grant_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	if (lkb->lkb_grmode != lkb->lkb_rqmode) {
  		lkb->lkb_grmode = lkb->lkb_rqmode;
  		if (lkb->lkb_status)
  			move_lkb(r, lkb, DLM_LKSTS_GRANTED);
  		else
  			add_lkb(r, lkb, DLM_LKSTS_GRANTED);
  	}
  
  	lkb->lkb_rqmode = DLM_LOCK_IV;
4875647a0   David Teigland   dlm: fixes for no...
2062
  	lkb->lkb_highbast = 0;
e7fd41792   David Teigland   [DLM] The core of...
2063
2064
2065
2066
2067
2068
  }
  
  static void grant_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	set_lvb_lock(r, lkb);
  	_grant_lock(r, lkb);
e7fd41792   David Teigland   [DLM] The core of...
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
  }
  
  static void grant_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			  struct dlm_message *ms)
  {
  	set_lvb_lock_pc(r, lkb, ms);
  	_grant_lock(r, lkb);
  }
  
  /* called by grant_pending_locks() which means an async grant message must
     be sent to the requesting node in addition to granting the lock if the
     lkb belongs to a remote node. */
  
  static void grant_lock_pending(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	grant_lock(r, lkb);
  	if (is_master_copy(lkb))
  		send_grant(r, lkb);
  	else
  		queue_cast(r, lkb, 0);
  }
7d3c1feb8   David Teigland   [DLM] fix mode mu...
2090
2091
2092
2093
2094
2095
2096
  /* The special CONVDEADLK, ALTPR and ALTCW flags allow the master to
     change the granted/requested modes.  We're munging things accordingly in
     the process copy.
     CONVDEADLK: our grmode may have been forced down to NL to resolve a
     conversion deadlock
     ALTPR/ALTCW: our rqmode may have been changed to PR or CW to become
     compatible with other granted locks */
2a7ce0edd   David Teigland   dlm: remove share...
2097
  static void munge_demoted(struct dlm_lkb *lkb)
7d3c1feb8   David Teigland   [DLM] fix mode mu...
2098
  {
7d3c1feb8   David Teigland   [DLM] fix mode mu...
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
  	if (lkb->lkb_rqmode == DLM_LOCK_IV || lkb->lkb_grmode == DLM_LOCK_IV) {
  		log_print("munge_demoted %x invalid modes gr %d rq %d",
  			  lkb->lkb_id, lkb->lkb_grmode, lkb->lkb_rqmode);
  		return;
  	}
  
  	lkb->lkb_grmode = DLM_LOCK_NL;
  }
  
  static void munge_altmode(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	if (ms->m_type != DLM_MSG_REQUEST_REPLY &&
  	    ms->m_type != DLM_MSG_GRANT) {
  		log_print("munge_altmode %x invalid reply type %d",
  			  lkb->lkb_id, ms->m_type);
  		return;
  	}
  
  	if (lkb->lkb_exflags & DLM_LKF_ALTPR)
  		lkb->lkb_rqmode = DLM_LOCK_PR;
  	else if (lkb->lkb_exflags & DLM_LKF_ALTCW)
  		lkb->lkb_rqmode = DLM_LOCK_CW;
  	else {
  		log_print("munge_altmode invalid exflags %x", lkb->lkb_exflags);
  		dlm_print_lkb(lkb);
  	}
  }
e7fd41792   David Teigland   [DLM] The core of...
2126
2127
2128
2129
2130
  static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head)
  {
  	struct dlm_lkb *first = list_entry(head->next, struct dlm_lkb,
  					   lkb_statequeue);
  	if (lkb->lkb_id == first->lkb_id)
901359256   David Teigland   [DLM] Update DLM ...
2131
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2132

901359256   David Teigland   [DLM] Update DLM ...
2133
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
2134
  }
e7fd41792   David Teigland   [DLM] The core of...
2135
2136
2137
2138
2139
2140
2141
2142
2143
  /* Check if the given lkb conflicts with another lkb on the queue. */
  
  static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb)
  {
  	struct dlm_lkb *this;
  
  	list_for_each_entry(this, head, lkb_statequeue) {
  		if (this == lkb)
  			continue;
3bcd3687f   David Teigland   [DLM] Remove rang...
2144
  		if (!modes_compat(this, lkb))
901359256   David Teigland   [DLM] Update DLM ...
2145
  			return 1;
e7fd41792   David Teigland   [DLM] The core of...
2146
  	}
901359256   David Teigland   [DLM] Update DLM ...
2147
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
2148
2149
2150
2151
2152
2153
2154
  }
  
  /*
   * "A conversion deadlock arises with a pair of lock requests in the converting
   * queue for one resource.  The granted mode of each lock blocks the requested
   * mode of the other lock."
   *
c85d65e91   David Teigland   [DLM] cancel in c...
2155
2156
   * Part 2: if the granted mode of lkb is preventing an earlier lkb in the
   * convert queue from being granted, then deadlk/demote lkb.
e7fd41792   David Teigland   [DLM] The core of...
2157
2158
2159
2160
2161
2162
2163
2164
   *
   * Example:
   * Granted Queue: empty
   * Convert Queue: NL->EX (first lock)
   *                PR->EX (second lock)
   *
   * The first lock can't be granted because of the granted mode of the second
   * lock and the second lock can't be granted because it's not first in the
c85d65e91   David Teigland   [DLM] cancel in c...
2165
2166
2167
   * list.  We either cancel lkb's conversion (PR->EX) and return EDEADLK, or we
   * demote the granted mode of lkb (from PR to NL) if it has the CONVDEADLK
   * flag set and return DEMOTED in the lksb flags.
e7fd41792   David Teigland   [DLM] The core of...
2168
   *
c85d65e91   David Teigland   [DLM] cancel in c...
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
   * Originally, this function detected conv-deadlk in a more limited scope:
   * - if !modes_compat(lkb1, lkb2) && !modes_compat(lkb2, lkb1), or
   * - if lkb1 was the first entry in the queue (not just earlier), and was
   *   blocked by the granted mode of lkb2, and there was nothing on the
   *   granted queue preventing lkb1 from being granted immediately, i.e.
   *   lkb2 was the only thing preventing lkb1 from being granted.
   *
   * That second condition meant we'd only say there was conv-deadlk if
   * resolving it (by demotion) would lead to the first lock on the convert
   * queue being granted right away.  It allowed conversion deadlocks to exist
   * between locks on the convert queue while they couldn't be granted anyway.
   *
   * Now, we detect and take action on conversion deadlocks immediately when
   * they're created, even if they may not be immediately consequential.  If
   * lkb1 exists anywhere in the convert queue and lkb2 comes in with a granted
   * mode that would prevent lkb1's conversion from being granted, we do a
   * deadlk/demote on lkb2 right away and don't let it onto the convert queue.
   * I think this means that the lkb_is_ahead condition below should always
   * be zero, i.e. there will never be conv-deadlk between two locks that are
   * both already on the convert queue.
e7fd41792   David Teigland   [DLM] The core of...
2189
   */
c85d65e91   David Teigland   [DLM] cancel in c...
2190
  static int conversion_deadlock_detect(struct dlm_rsb *r, struct dlm_lkb *lkb2)
e7fd41792   David Teigland   [DLM] The core of...
2191
  {
c85d65e91   David Teigland   [DLM] cancel in c...
2192
2193
  	struct dlm_lkb *lkb1;
  	int lkb_is_ahead = 0;
e7fd41792   David Teigland   [DLM] The core of...
2194

c85d65e91   David Teigland   [DLM] cancel in c...
2195
2196
2197
  	list_for_each_entry(lkb1, &r->res_convertqueue, lkb_statequeue) {
  		if (lkb1 == lkb2) {
  			lkb_is_ahead = 1;
e7fd41792   David Teigland   [DLM] The core of...
2198
2199
  			continue;
  		}
c85d65e91   David Teigland   [DLM] cancel in c...
2200
2201
2202
2203
2204
2205
2206
2207
  		if (!lkb_is_ahead) {
  			if (!modes_compat(lkb2, lkb1))
  				return 1;
  		} else {
  			if (!modes_compat(lkb2, lkb1) &&
  			    !modes_compat(lkb1, lkb2))
  				return 1;
  		}
e7fd41792   David Teigland   [DLM] The core of...
2208
  	}
901359256   David Teigland   [DLM] Update DLM ...
2209
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
  }
  
  /*
   * Return 1 if the lock can be granted, 0 otherwise.
   * Also detect and resolve conversion deadlocks.
   *
   * lkb is the lock to be granted
   *
   * now is 1 if the function is being called in the context of the
   * immediate request, it is 0 if called later, after the lock has been
   * queued.
   *
c503a6210   David Teigland   dlm: fix conversi...
2222
2223
2224
   * recover is 1 if dlm_recover_grant() is trying to grant conversions
   * after recovery.
   *
e7fd41792   David Teigland   [DLM] The core of...
2225
2226
   * References are from chapter 6 of "VAXcluster Principles" by Roy Davis
   */
c503a6210   David Teigland   dlm: fix conversi...
2227
2228
  static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
  			   int recover)
e7fd41792   David Teigland   [DLM] The core of...
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
  {
  	int8_t conv = (lkb->lkb_grmode != DLM_LOCK_IV);
  
  	/*
  	 * 6-10: Version 5.4 introduced an option to address the phenomenon of
  	 * a new request for a NL mode lock being blocked.
  	 *
  	 * 6-11: If the optional EXPEDITE flag is used with the new NL mode
  	 * request, then it would be granted.  In essence, the use of this flag
  	 * tells the Lock Manager to expedite theis request by not considering
  	 * what may be in the CONVERTING or WAITING queues...  As of this
  	 * writing, the EXPEDITE flag can be used only with new requests for NL
  	 * mode locks.  This flag is not valid for conversion requests.
  	 *
  	 * A shortcut.  Earlier checks return an error if EXPEDITE is used in a
  	 * conversion or used with a non-NL requested mode.  We also know an
  	 * EXPEDITE request is always granted immediately, so now must always
  	 * be 1.  The full condition to grant an expedite request: (now &&
  	 * !conv && lkb->rqmode == DLM_LOCK_NL && (flags & EXPEDITE)) can
  	 * therefore be shortened to just checking the flag.
  	 */
  
  	if (lkb->lkb_exflags & DLM_LKF_EXPEDITE)
901359256   David Teigland   [DLM] Update DLM ...
2252
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2253
2254
2255
2256
2257
2258
2259
  
  	/*
  	 * A shortcut. Without this, !queue_conflict(grantqueue, lkb) would be
  	 * added to the remaining conditions.
  	 */
  
  	if (queue_conflict(&r->res_grantqueue, lkb))
c503a6210   David Teigland   dlm: fix conversi...
2260
  		return 0;
e7fd41792   David Teigland   [DLM] The core of...
2261
2262
2263
2264
2265
2266
2267
2268
  
  	/*
  	 * 6-3: By default, a conversion request is immediately granted if the
  	 * requested mode is compatible with the modes of all other granted
  	 * locks
  	 */
  
  	if (queue_conflict(&r->res_convertqueue, lkb))
c503a6210   David Teigland   dlm: fix conversi...
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
  		return 0;
  
  	/*
  	 * The RECOVER_GRANT flag means dlm_recover_grant() is granting
  	 * locks for a recovered rsb, on which lkb's have been rebuilt.
  	 * The lkb's may have been rebuilt on the queues in a different
  	 * order than they were in on the previous master.  So, granting
  	 * queued conversions in order after recovery doesn't make sense
  	 * since the order hasn't been preserved anyway.  The new order
  	 * could also have created a new "in place" conversion deadlock.
  	 * (e.g. old, failed master held granted EX, with PR->EX, NL->EX.
  	 * After recovery, there would be no granted locks, and possibly
  	 * NL->EX, PR->EX, an in-place conversion deadlock.)  So, after
  	 * recovery, grant conversions without considering order.
  	 */
  
  	if (conv && recover)
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
  
  	/*
  	 * 6-5: But the default algorithm for deciding whether to grant or
  	 * queue conversion requests does not by itself guarantee that such
  	 * requests are serviced on a "first come first serve" basis.  This, in
  	 * turn, can lead to a phenomenon known as "indefinate postponement".
  	 *
  	 * 6-7: This issue is dealt with by using the optional QUECVT flag with
  	 * the system service employed to request a lock conversion.  This flag
  	 * forces certain conversion requests to be queued, even if they are
  	 * compatible with the granted modes of other locks on the same
  	 * resource.  Thus, the use of this flag results in conversion requests
  	 * being ordered on a "first come first servce" basis.
  	 *
  	 * DCT: This condition is all about new conversions being able to occur
  	 * "in place" while the lock remains on the granted queue (assuming
  	 * nothing else conflicts.)  IOW if QUECVT isn't set, a conversion
  	 * doesn't _have_ to go onto the convert queue where it's processed in
  	 * order.  The "now" variable is necessary to distinguish converts
  	 * being received and processed for the first time now, because once a
  	 * convert is moved to the conversion queue the condition below applies
  	 * requiring fifo granting.
  	 */
  
  	if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT))
901359256   David Teigland   [DLM] Update DLM ...
2312
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2313
2314
  
  	/*
53ad1c980   David Teigland   dlm: fix QUECVT w...
2315
2316
2317
2318
2319
2320
2321
2322
  	 * Even if the convert is compat with all granted locks,
  	 * QUECVT forces it behind other locks on the convert queue.
  	 */
  
  	if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) {
  		if (list_empty(&r->res_convertqueue))
  			return 1;
  		else
c503a6210   David Teigland   dlm: fix conversi...
2323
  			return 0;
53ad1c980   David Teigland   dlm: fix QUECVT w...
2324
2325
2326
  	}
  
  	/*
3bcd3687f   David Teigland   [DLM] Remove rang...
2327
2328
  	 * The NOORDER flag is set to avoid the standard vms rules on grant
  	 * order.
e7fd41792   David Teigland   [DLM] The core of...
2329
2330
2331
  	 */
  
  	if (lkb->lkb_exflags & DLM_LKF_NOORDER)
901359256   David Teigland   [DLM] Update DLM ...
2332
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2333
2334
2335
2336
2337
2338
2339
2340
  
  	/*
  	 * 6-3: Once in that queue [CONVERTING], a conversion request cannot be
  	 * granted until all other conversion requests ahead of it are granted
  	 * and/or canceled.
  	 */
  
  	if (!now && conv && first_in_list(lkb, &r->res_convertqueue))
901359256   David Teigland   [DLM] Update DLM ...
2341
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
  
  	/*
  	 * 6-4: By default, a new request is immediately granted only if all
  	 * three of the following conditions are satisfied when the request is
  	 * issued:
  	 * - The queue of ungranted conversion requests for the resource is
  	 *   empty.
  	 * - The queue of ungranted new requests for the resource is empty.
  	 * - The mode of the new request is compatible with the most
  	 *   restrictive mode of all granted locks on the resource.
  	 */
  
  	if (now && !conv && list_empty(&r->res_convertqueue) &&
  	    list_empty(&r->res_waitqueue))
901359256   David Teigland   [DLM] Update DLM ...
2356
  		return 1;
e7fd41792   David Teigland   [DLM] The core of...
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
  
  	/*
  	 * 6-4: Once a lock request is in the queue of ungranted new requests,
  	 * it cannot be granted until the queue of ungranted conversion
  	 * requests is empty, all ungranted new requests ahead of it are
  	 * granted and/or canceled, and it is compatible with the granted mode
  	 * of the most restrictive lock granted on the resource.
  	 */
  
  	if (!now && !conv && list_empty(&r->res_convertqueue) &&
  	    first_in_list(lkb, &r->res_waitqueue))
901359256   David Teigland   [DLM] Update DLM ...
2368
  		return 1;
c503a6210   David Teigland   dlm: fix conversi...
2369

901359256   David Teigland   [DLM] Update DLM ...
2370
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
2371
  }
c85d65e91   David Teigland   [DLM] cancel in c...
2372
  static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
c503a6210   David Teigland   dlm: fix conversi...
2373
  			  int recover, int *err)
e7fd41792   David Teigland   [DLM] The core of...
2374
  {
e7fd41792   David Teigland   [DLM] The core of...
2375
2376
  	int rv;
  	int8_t alt = 0, rqmode = lkb->lkb_rqmode;
c85d65e91   David Teigland   [DLM] cancel in c...
2377
2378
2379
2380
  	int8_t is_convert = (lkb->lkb_grmode != DLM_LOCK_IV);
  
  	if (err)
  		*err = 0;
e7fd41792   David Teigland   [DLM] The core of...
2381

c503a6210   David Teigland   dlm: fix conversi...
2382
  	rv = _can_be_granted(r, lkb, now, recover);
e7fd41792   David Teigland   [DLM] The core of...
2383
2384
  	if (rv)
  		goto out;
c85d65e91   David Teigland   [DLM] cancel in c...
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
  	/*
  	 * The CONVDEADLK flag is non-standard and tells the dlm to resolve
  	 * conversion deadlocks by demoting grmode to NL, otherwise the dlm
  	 * cancels one of the locks.
  	 */
  
  	if (is_convert && can_be_queued(lkb) &&
  	    conversion_deadlock_detect(r, lkb)) {
  		if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) {
  			lkb->lkb_grmode = DLM_LOCK_NL;
  			lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
294e7e458   tsutomu.owa@toshiba.co.jp   DLM: fix conversi...
2396
2397
2398
2399
2400
2401
  		} else if (err) {
  			*err = -EDEADLK;
  		} else {
  			log_print("can_be_granted deadlock %x now %d",
  				  lkb->lkb_id, now);
  			dlm_dump_rsb(r);
c85d65e91   David Teigland   [DLM] cancel in c...
2402
  		}
e7fd41792   David Teigland   [DLM] The core of...
2403
  		goto out;
c85d65e91   David Teigland   [DLM] cancel in c...
2404
  	}
e7fd41792   David Teigland   [DLM] The core of...
2405

c85d65e91   David Teigland   [DLM] cancel in c...
2406
2407
2408
2409
2410
2411
2412
2413
  	/*
  	 * The ALTPR and ALTCW flags are non-standard and tell the dlm to try
  	 * to grant a request in a mode other than the normal rqmode.  It's a
  	 * simple way to provide a big optimization to applications that can
  	 * use them.
  	 */
  
  	if (rqmode != DLM_LOCK_PR && (lkb->lkb_exflags & DLM_LKF_ALTPR))
e7fd41792   David Teigland   [DLM] The core of...
2414
  		alt = DLM_LOCK_PR;
c85d65e91   David Teigland   [DLM] cancel in c...
2415
  	else if (rqmode != DLM_LOCK_CW && (lkb->lkb_exflags & DLM_LKF_ALTCW))
e7fd41792   David Teigland   [DLM] The core of...
2416
2417
2418
2419
  		alt = DLM_LOCK_CW;
  
  	if (alt) {
  		lkb->lkb_rqmode = alt;
c503a6210   David Teigland   dlm: fix conversi...
2420
  		rv = _can_be_granted(r, lkb, now, 0);
e7fd41792   David Teigland   [DLM] The core of...
2421
2422
2423
2424
2425
2426
2427
2428
  		if (rv)
  			lkb->lkb_sbflags |= DLM_SBF_ALTMODE;
  		else
  			lkb->lkb_rqmode = rqmode;
  	}
   out:
  	return rv;
  }
365092589   David Teigland   [DLM] fix basts f...
2429
2430
  /* Returns the highest requested mode of all blocked conversions; sets
     cw if there's a blocked conversion to DLM_LOCK_CW. */
c85d65e91   David Teigland   [DLM] cancel in c...
2431

4875647a0   David Teigland   dlm: fixes for no...
2432
2433
  static int grant_pending_convert(struct dlm_rsb *r, int high, int *cw,
  				 unsigned int *count)
e7fd41792   David Teigland   [DLM] The core of...
2434
2435
  {
  	struct dlm_lkb *lkb, *s;
c503a6210   David Teigland   dlm: fix conversi...
2436
  	int recover = rsb_flag(r, RSB_RECOVER_GRANT);
e7fd41792   David Teigland   [DLM] The core of...
2437
  	int hi, demoted, quit, grant_restart, demote_restart;
c85d65e91   David Teigland   [DLM] cancel in c...
2438
  	int deadlk;
e7fd41792   David Teigland   [DLM] The core of...
2439
2440
2441
2442
2443
2444
2445
2446
2447
  
  	quit = 0;
   restart:
  	grant_restart = 0;
  	demote_restart = 0;
  	hi = DLM_LOCK_IV;
  
  	list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) {
  		demoted = is_demoted(lkb);
c85d65e91   David Teigland   [DLM] cancel in c...
2448
  		deadlk = 0;
c503a6210   David Teigland   dlm: fix conversi...
2449
  		if (can_be_granted(r, lkb, 0, recover, &deadlk)) {
e7fd41792   David Teigland   [DLM] The core of...
2450
2451
  			grant_lock_pending(r, lkb);
  			grant_restart = 1;
4875647a0   David Teigland   dlm: fixes for no...
2452
2453
  			if (count)
  				(*count)++;
c85d65e91   David Teigland   [DLM] cancel in c...
2454
  			continue;
e7fd41792   David Teigland   [DLM] The core of...
2455
  		}
c85d65e91   David Teigland   [DLM] cancel in c...
2456
2457
2458
2459
2460
2461
2462
2463
2464
  
  		if (!demoted && is_demoted(lkb)) {
  			log_print("WARN: pending demoted %x node %d %s",
  				  lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
  			demote_restart = 1;
  			continue;
  		}
  
  		if (deadlk) {
294e7e458   tsutomu.owa@toshiba.co.jp   DLM: fix conversi...
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
  			/*
  			 * If DLM_LKB_NODLKWT flag is set and conversion
  			 * deadlock is detected, we request blocking AST and
  			 * down (or cancel) conversion.
  			 */
  			if (lkb->lkb_exflags & DLM_LKF_NODLCKWT) {
  				if (lkb->lkb_highbast < lkb->lkb_rqmode) {
  					queue_bast(r, lkb, lkb->lkb_rqmode);
  					lkb->lkb_highbast = lkb->lkb_rqmode;
  				}
  			} else {
  				log_print("WARN: pending deadlock %x node %d %s",
  					  lkb->lkb_id, lkb->lkb_nodeid,
  					  r->res_name);
  				dlm_dump_rsb(r);
  			}
c85d65e91   David Teigland   [DLM] cancel in c...
2481
2482
2483
2484
  			continue;
  		}
  
  		hi = max_t(int, lkb->lkb_rqmode, hi);
365092589   David Teigland   [DLM] fix basts f...
2485
2486
2487
  
  		if (cw && lkb->lkb_rqmode == DLM_LOCK_CW)
  			*cw = 1;
e7fd41792   David Teigland   [DLM] The core of...
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
  	}
  
  	if (grant_restart)
  		goto restart;
  	if (demote_restart && !quit) {
  		quit = 1;
  		goto restart;
  	}
  
  	return max_t(int, high, hi);
  }
4875647a0   David Teigland   dlm: fixes for no...
2499
2500
  static int grant_pending_wait(struct dlm_rsb *r, int high, int *cw,
  			      unsigned int *count)
e7fd41792   David Teigland   [DLM] The core of...
2501
2502
2503
2504
  {
  	struct dlm_lkb *lkb, *s;
  
  	list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
c503a6210   David Teigland   dlm: fix conversi...
2505
  		if (can_be_granted(r, lkb, 0, 0, NULL)) {
e7fd41792   David Teigland   [DLM] The core of...
2506
  			grant_lock_pending(r, lkb);
4875647a0   David Teigland   dlm: fixes for no...
2507
2508
2509
  			if (count)
  				(*count)++;
  		} else {
e7fd41792   David Teigland   [DLM] The core of...
2510
  			high = max_t(int, lkb->lkb_rqmode, high);
365092589   David Teigland   [DLM] fix basts f...
2511
2512
2513
  			if (lkb->lkb_rqmode == DLM_LOCK_CW)
  				*cw = 1;
  		}
e7fd41792   David Teigland   [DLM] The core of...
2514
2515
2516
2517
  	}
  
  	return high;
  }
365092589   David Teigland   [DLM] fix basts f...
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
  /* cw of 1 means there's a lock with a rqmode of DLM_LOCK_CW that's blocked
     on either the convert or waiting queue.
     high is the largest rqmode of all locks blocked on the convert or
     waiting queue. */
  
  static int lock_requires_bast(struct dlm_lkb *gr, int high, int cw)
  {
  	if (gr->lkb_grmode == DLM_LOCK_PR && cw) {
  		if (gr->lkb_highbast < DLM_LOCK_EX)
  			return 1;
  		return 0;
  	}
  
  	if (gr->lkb_highbast < high &&
  	    !__dlm_compat_matrix[gr->lkb_grmode+1][high+1])
  		return 1;
  	return 0;
  }
4875647a0   David Teigland   dlm: fixes for no...
2536
  static void grant_pending_locks(struct dlm_rsb *r, unsigned int *count)
e7fd41792   David Teigland   [DLM] The core of...
2537
2538
2539
  {
  	struct dlm_lkb *lkb, *s;
  	int high = DLM_LOCK_IV;
365092589   David Teigland   [DLM] fix basts f...
2540
  	int cw = 0;
e7fd41792   David Teigland   [DLM] The core of...
2541

4875647a0   David Teigland   dlm: fixes for no...
2542
2543
2544
2545
2546
  	if (!is_master(r)) {
  		log_print("grant_pending_locks r nodeid %d", r->res_nodeid);
  		dlm_dump_rsb(r);
  		return;
  	}
e7fd41792   David Teigland   [DLM] The core of...
2547

4875647a0   David Teigland   dlm: fixes for no...
2548
2549
  	high = grant_pending_convert(r, high, &cw, count);
  	high = grant_pending_wait(r, high, &cw, count);
e7fd41792   David Teigland   [DLM] The core of...
2550
2551
2552
2553
2554
2555
2556
  
  	if (high == DLM_LOCK_IV)
  		return;
  
  	/*
  	 * If there are locks left on the wait/convert queue then send blocking
  	 * ASTs to granted locks based on the largest requested mode (high)
365092589   David Teigland   [DLM] fix basts f...
2557
  	 * found above.
e7fd41792   David Teigland   [DLM] The core of...
2558
2559
2560
  	 */
  
  	list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
e5dae548b   David Teigland   dlm: proper types...
2561
  		if (lkb->lkb_bastfn && lock_requires_bast(lkb, high, cw)) {
329fc4c37   David Teigland   dlm: fix basts fo...
2562
2563
  			if (cw && high == DLM_LOCK_PR &&
  			    lkb->lkb_grmode == DLM_LOCK_PR)
365092589   David Teigland   [DLM] fix basts f...
2564
2565
2566
  				queue_bast(r, lkb, DLM_LOCK_CW);
  			else
  				queue_bast(r, lkb, high);
e7fd41792   David Teigland   [DLM] The core of...
2567
2568
2569
2570
  			lkb->lkb_highbast = high;
  		}
  	}
  }
365092589   David Teigland   [DLM] fix basts f...
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
  static int modes_require_bast(struct dlm_lkb *gr, struct dlm_lkb *rq)
  {
  	if ((gr->lkb_grmode == DLM_LOCK_PR && rq->lkb_rqmode == DLM_LOCK_CW) ||
  	    (gr->lkb_grmode == DLM_LOCK_CW && rq->lkb_rqmode == DLM_LOCK_PR)) {
  		if (gr->lkb_highbast < DLM_LOCK_EX)
  			return 1;
  		return 0;
  	}
  
  	if (gr->lkb_highbast < rq->lkb_rqmode && !modes_compat(gr, rq))
  		return 1;
  	return 0;
  }
e7fd41792   David Teigland   [DLM] The core of...
2584
2585
2586
2587
2588
2589
  static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
  			    struct dlm_lkb *lkb)
  {
  	struct dlm_lkb *gr;
  
  	list_for_each_entry(gr, head, lkb_statequeue) {
314dd2a05   Steven Whitehouse   dlm: Don't send c...
2590
2591
2592
  		/* skip self when sending basts to convertqueue */
  		if (gr == lkb)
  			continue;
e5dae548b   David Teigland   dlm: proper types...
2593
  		if (gr->lkb_bastfn && modes_require_bast(gr, lkb)) {
e7fd41792   David Teigland   [DLM] The core of...
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
  			queue_bast(r, gr, lkb->lkb_rqmode);
  			gr->lkb_highbast = lkb->lkb_rqmode;
  		}
  	}
  }
  
  static void send_blocking_asts(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	send_bast_queue(r, &r->res_grantqueue, lkb);
  }
  
  static void send_blocking_asts_all(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	send_bast_queue(r, &r->res_grantqueue, lkb);
  	send_bast_queue(r, &r->res_convertqueue, lkb);
  }
  
  /* set_master(r, lkb) -- set the master nodeid of a resource
  
     The purpose of this function is to set the nodeid field in the given
     lkb using the nodeid field in the given rsb.  If the rsb's nodeid is
     known, it can just be copied to the lkb and the function will return
     0.  If the rsb's nodeid is _not_ known, it needs to be looked up
     before it can be copied to the lkb.
  
     When the rsb nodeid is being looked up remotely, the initial lkb
     causing the lookup is kept on the ls_waiters list waiting for the
     lookup reply.  Other lkb's waiting for the same rsb lookup are kept
     on the rsb's res_lookup list until the master is verified.
  
     Return values:
     0: nodeid is set in rsb/lkb and the caller should go ahead and use it
     1: the rsb master is not available and the lkb has been placed on
        a wait queue
  */
  
  static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2632
  	int our_nodeid = dlm_our_nodeid();
e7fd41792   David Teigland   [DLM] The core of...
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
  
  	if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) {
  		rsb_clear_flag(r, RSB_MASTER_UNCERTAIN);
  		r->res_first_lkid = lkb->lkb_id;
  		lkb->lkb_nodeid = r->res_nodeid;
  		return 0;
  	}
  
  	if (r->res_first_lkid && r->res_first_lkid != lkb->lkb_id) {
  		list_add_tail(&lkb->lkb_rsb_lookup, &r->res_lookup);
  		return 1;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2645
  	if (r->res_master_nodeid == our_nodeid) {
e7fd41792   David Teigland   [DLM] The core of...
2646
2647
2648
  		lkb->lkb_nodeid = 0;
  		return 0;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2649
2650
  	if (r->res_master_nodeid) {
  		lkb->lkb_nodeid = r->res_master_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
2651
2652
  		return 0;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
  	if (dlm_dir_nodeid(r) == our_nodeid) {
  		/* This is a somewhat unusual case; find_rsb will usually
  		   have set res_master_nodeid when dir nodeid is local, but
  		   there are cases where we become the dir node after we've
  		   past find_rsb and go through _request_lock again.
  		   confirm_master() or process_lookup_list() needs to be
  		   called after this. */
  		log_debug(r->res_ls, "set_master %x self master %d dir %d %s",
  			  lkb->lkb_id, r->res_master_nodeid, r->res_dir_nodeid,
  			  r->res_name);
  		r->res_master_nodeid = our_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
2664
2665
  		r->res_nodeid = 0;
  		lkb->lkb_nodeid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2666
  		return 0;
e7fd41792   David Teigland   [DLM] The core of...
2667
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2668

05c32f47b   David Teigland   dlm: fix race bet...
2669
  	wait_pending_remove(r);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
2670
2671
2672
  	r->res_first_lkid = lkb->lkb_id;
  	send_lookup(r, lkb);
  	return 1;
e7fd41792   David Teigland   [DLM] The core of...
2673
2674
2675
2676
2677
2678
2679
  }
  
  static void process_lookup_list(struct dlm_rsb *r)
  {
  	struct dlm_lkb *lkb, *safe;
  
  	list_for_each_entry_safe(lkb, safe, &r->res_lookup, lkb_rsb_lookup) {
ef0c2bb05   David Teigland   [DLM] overlapping...
2680
  		list_del_init(&lkb->lkb_rsb_lookup);
e7fd41792   David Teigland   [DLM] The core of...
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
  		_request_lock(r, lkb);
  		schedule();
  	}
  }
  
  /* confirm_master -- confirm (or deny) an rsb's master nodeid */
  
  static void confirm_master(struct dlm_rsb *r, int error)
  {
  	struct dlm_lkb *lkb;
  
  	if (!r->res_first_lkid)
  		return;
  
  	switch (error) {
  	case 0:
  	case -EINPROGRESS:
  		r->res_first_lkid = 0;
  		process_lookup_list(r);
  		break;
  
  	case -EAGAIN:
aec64e1be   David Teigland   dlm: another call...
2703
2704
2705
2706
2707
  	case -EBADR:
  	case -ENOTBLK:
  		/* the remote request failed and won't be retried (it was
  		   a NOQUEUE, or has been canceled/unlocked); make a waiting
  		   lkb the first_lkid */
e7fd41792   David Teigland   [DLM] The core of...
2708
2709
2710
2711
2712
2713
  
  		r->res_first_lkid = 0;
  
  		if (!list_empty(&r->res_lookup)) {
  			lkb = list_entry(r->res_lookup.next, struct dlm_lkb,
  					 lkb_rsb_lookup);
ef0c2bb05   David Teigland   [DLM] overlapping...
2714
  			list_del_init(&lkb->lkb_rsb_lookup);
e7fd41792   David Teigland   [DLM] The core of...
2715
2716
  			r->res_first_lkid = lkb->lkb_id;
  			_request_lock(r, lkb);
761b9d3ff   David Teigland   dlm: save master ...
2717
  		}
e7fd41792   David Teigland   [DLM] The core of...
2718
2719
2720
2721
2722
2723
2724
2725
  		break;
  
  	default:
  		log_error(r->res_ls, "confirm_master unknown error %d", error);
  	}
  }
  
  static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
e5dae548b   David Teigland   dlm: proper types...
2726
2727
2728
2729
2730
  			 int namelen, unsigned long timeout_cs,
  			 void (*ast) (void *astparam),
  			 void *astparam,
  			 void (*bast) (void *astparam, int mode),
  			 struct dlm_args *args)
e7fd41792   David Teigland   [DLM] The core of...
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
  {
  	int rv = -EINVAL;
  
  	/* check for invalid arg usage */
  
  	if (mode < 0 || mode > DLM_LOCK_EX)
  		goto out;
  
  	if (!(flags & DLM_LKF_CONVERT) && (namelen > DLM_RESNAME_MAXLEN))
  		goto out;
  
  	if (flags & DLM_LKF_CANCEL)
  		goto out;
  
  	if (flags & DLM_LKF_QUECVT && !(flags & DLM_LKF_CONVERT))
  		goto out;
  
  	if (flags & DLM_LKF_CONVDEADLK && !(flags & DLM_LKF_CONVERT))
  		goto out;
  
  	if (flags & DLM_LKF_CONVDEADLK && flags & DLM_LKF_NOQUEUE)
  		goto out;
  
  	if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_CONVERT)
  		goto out;
  
  	if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_QUECVT)
  		goto out;
  
  	if (flags & DLM_LKF_EXPEDITE && flags & DLM_LKF_NOQUEUE)
  		goto out;
  
  	if (flags & DLM_LKF_EXPEDITE && mode != DLM_LOCK_NL)
  		goto out;
  
  	if (!ast || !lksb)
  		goto out;
  
  	if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
2771
2772
2773
2774
2775
2776
2777
2778
  	if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid)
  		goto out;
  
  	/* these args will be copied to the lkb in validate_lock_args,
  	   it cannot be done now because when converting locks, fields in
  	   an active lkb cannot be modified before locking the rsb */
  
  	args->flags = flags;
e5dae548b   David Teigland   dlm: proper types...
2779
2780
2781
  	args->astfn = ast;
  	args->astparam = astparam;
  	args->bastfn = bast;
d7db923ea   David Teigland   [DLM] dlm_device ...
2782
  	args->timeout = timeout_cs;
e7fd41792   David Teigland   [DLM] The core of...
2783
2784
  	args->mode = mode;
  	args->lksb = lksb;
e7fd41792   David Teigland   [DLM] The core of...
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
  	rv = 0;
   out:
  	return rv;
  }
  
  static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args)
  {
  	if (flags & ~(DLM_LKF_CANCEL | DLM_LKF_VALBLK | DLM_LKF_IVVALBLK |
   		      DLM_LKF_FORCEUNLOCK))
  		return -EINVAL;
ef0c2bb05   David Teigland   [DLM] overlapping...
2795
2796
  	if (flags & DLM_LKF_CANCEL && flags & DLM_LKF_FORCEUNLOCK)
  		return -EINVAL;
e7fd41792   David Teigland   [DLM] The core of...
2797
  	args->flags = flags;
e5dae548b   David Teigland   dlm: proper types...
2798
  	args->astparam = astarg;
e7fd41792   David Teigland   [DLM] The core of...
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
  	return 0;
  }
  
  static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
  			      struct dlm_args *args)
  {
  	int rv = -EINVAL;
  
  	if (args->flags & DLM_LKF_CONVERT) {
  		if (lkb->lkb_flags & DLM_IFL_MSTCPY)
  			goto out;
  
  		if (args->flags & DLM_LKF_QUECVT &&
  		    !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
  			goto out;
  
  		rv = -EBUSY;
  		if (lkb->lkb_status != DLM_LKSTS_GRANTED)
  			goto out;
  
  		if (lkb->lkb_wait_type)
  			goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
2821
2822
2823
  
  		if (is_overlap(lkb))
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
2824
2825
2826
2827
  	}
  
  	lkb->lkb_exflags = args->flags;
  	lkb->lkb_sbflags = 0;
e5dae548b   David Teigland   dlm: proper types...
2828
  	lkb->lkb_astfn = args->astfn;
e7fd41792   David Teigland   [DLM] The core of...
2829
  	lkb->lkb_astparam = args->astparam;
e5dae548b   David Teigland   dlm: proper types...
2830
  	lkb->lkb_bastfn = args->bastfn;
e7fd41792   David Teigland   [DLM] The core of...
2831
2832
2833
2834
  	lkb->lkb_rqmode = args->mode;
  	lkb->lkb_lksb = args->lksb;
  	lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
  	lkb->lkb_ownpid = (int) current->pid;
d7db923ea   David Teigland   [DLM] dlm_device ...
2835
  	lkb->lkb_timeout_cs = args->timeout;
e7fd41792   David Teigland   [DLM] The core of...
2836
2837
  	rv = 0;
   out:
43279e537   David Teigland   dlm: clear defunc...
2838
2839
2840
2841
2842
  	if (rv)
  		log_debug(ls, "validate_lock_args %d %x %x %x %d %d %s",
  			  rv, lkb->lkb_id, lkb->lkb_flags, args->flags,
  			  lkb->lkb_status, lkb->lkb_wait_type,
  			  lkb->lkb_resource->res_name);
e7fd41792   David Teigland   [DLM] The core of...
2843
2844
  	return rv;
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
2845
2846
2847
2848
2849
2850
  /* when dlm_unlock() sees -EBUSY with CANCEL/FORCEUNLOCK it returns 0
     for success */
  
  /* note: it's valid for lkb_nodeid/res_nodeid to be -1 when we get here
     because there may be a lookup in progress and it's valid to do
     cancel/unlockf on it */
e7fd41792   David Teigland   [DLM] The core of...
2851
2852
  static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
2853
  	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
e7fd41792   David Teigland   [DLM] The core of...
2854
  	int rv = -EINVAL;
ef0c2bb05   David Teigland   [DLM] overlapping...
2855
2856
2857
  	if (lkb->lkb_flags & DLM_IFL_MSTCPY) {
  		log_error(ls, "unlock on MSTCPY %x", lkb->lkb_id);
  		dlm_print_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
2858
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
2859
  	}
e7fd41792   David Teigland   [DLM] The core of...
2860

ef0c2bb05   David Teigland   [DLM] overlapping...
2861
2862
2863
  	/* an lkb may still exist even though the lock is EOL'ed due to a
  	   cancel, unlock or failed noqueue request; an app can't use these
  	   locks; return same error as if the lkid had not been found at all */
e7fd41792   David Teigland   [DLM] The core of...
2864

ef0c2bb05   David Teigland   [DLM] overlapping...
2865
2866
2867
  	if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) {
  		log_debug(ls, "unlock on ENDOFLIFE %x", lkb->lkb_id);
  		rv = -ENOENT;
e7fd41792   David Teigland   [DLM] The core of...
2868
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
2869
  	}
e7fd41792   David Teigland   [DLM] The core of...
2870

ef0c2bb05   David Teigland   [DLM] overlapping...
2871
2872
  	/* an lkb may be waiting for an rsb lookup to complete where the
  	   lookup was initiated by another lock */
42dc1601a   David Teigland   dlm: reject norma...
2873
2874
  	if (!list_empty(&lkb->lkb_rsb_lookup)) {
  		if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
ef0c2bb05   David Teigland   [DLM] overlapping...
2875
2876
2877
2878
2879
2880
  			log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id);
  			list_del_init(&lkb->lkb_rsb_lookup);
  			queue_cast(lkb->lkb_resource, lkb,
  				   args->flags & DLM_LKF_CANCEL ?
  				   -DLM_ECANCEL : -DLM_EUNLOCK);
  			unhold_lkb(lkb); /* undoes create_lkb() */
ef0c2bb05   David Teigland   [DLM] overlapping...
2881
  		}
42dc1601a   David Teigland   dlm: reject norma...
2882
2883
2884
  		/* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */
  		rv = -EBUSY;
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
  	}
  
  	/* cancel not allowed with another cancel/unlock in progress */
  
  	if (args->flags & DLM_LKF_CANCEL) {
  		if (lkb->lkb_exflags & DLM_LKF_CANCEL)
  			goto out;
  
  		if (is_overlap(lkb))
  			goto out;
3ae1acf93   David Teigland   [DLM] add lock ti...
2895
2896
  		/* don't let scand try to do a cancel */
  		del_timeout(lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
2897
2898
2899
2900
2901
  		if (lkb->lkb_flags & DLM_IFL_RESEND) {
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
  			rv = -EBUSY;
  			goto out;
  		}
a536e3812   David Teigland   dlm: ignore cance...
2902
2903
2904
2905
2906
2907
  		/* there's nothing to cancel */
  		if (lkb->lkb_status == DLM_LKSTS_GRANTED &&
  		    !lkb->lkb_wait_type) {
  			rv = -EBUSY;
  			goto out;
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
  		switch (lkb->lkb_wait_type) {
  		case DLM_MSG_LOOKUP:
  		case DLM_MSG_REQUEST:
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
  			rv = -EBUSY;
  			goto out;
  		case DLM_MSG_UNLOCK:
  		case DLM_MSG_CANCEL:
  			goto out;
  		}
  		/* add_to_waiters() will set OVERLAP_CANCEL */
  		goto out_ok;
  	}
  
  	/* do we need to allow a force-unlock if there's a normal unlock
  	   already in progress?  in what conditions could the normal unlock
  	   fail such that we'd want to send a force-unlock to be sure? */
  
  	if (args->flags & DLM_LKF_FORCEUNLOCK) {
  		if (lkb->lkb_exflags & DLM_LKF_FORCEUNLOCK)
  			goto out;
  
  		if (is_overlap_unlock(lkb))
  			goto out;
e7fd41792   David Teigland   [DLM] The core of...
2932

3ae1acf93   David Teigland   [DLM] add lock ti...
2933
2934
  		/* don't let scand try to do a cancel */
  		del_timeout(lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
  		if (lkb->lkb_flags & DLM_IFL_RESEND) {
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
  			rv = -EBUSY;
  			goto out;
  		}
  
  		switch (lkb->lkb_wait_type) {
  		case DLM_MSG_LOOKUP:
  		case DLM_MSG_REQUEST:
  			lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
  			rv = -EBUSY;
  			goto out;
  		case DLM_MSG_UNLOCK:
  			goto out;
  		}
  		/* add_to_waiters() will set OVERLAP_UNLOCK */
  		goto out_ok;
  	}
  
  	/* normal unlock not allowed if there's any op in progress */
e7fd41792   David Teigland   [DLM] The core of...
2955
  	rv = -EBUSY;
ef0c2bb05   David Teigland   [DLM] overlapping...
2956
  	if (lkb->lkb_wait_type || lkb->lkb_wait_count)
e7fd41792   David Teigland   [DLM] The core of...
2957
2958
2959
  		goto out;
  
   out_ok:
ef0c2bb05   David Teigland   [DLM] overlapping...
2960
2961
  	/* an overlapping op shouldn't blow away exflags from other op */
  	lkb->lkb_exflags |= args->flags;
e7fd41792   David Teigland   [DLM] The core of...
2962
2963
  	lkb->lkb_sbflags = 0;
  	lkb->lkb_astparam = args->astparam;
e7fd41792   David Teigland   [DLM] The core of...
2964
2965
  	rv = 0;
   out:
ef0c2bb05   David Teigland   [DLM] overlapping...
2966
2967
2968
2969
2970
  	if (rv)
  		log_debug(ls, "validate_unlock_args %d %x %x %x %x %d %s", rv,
  			  lkb->lkb_id, lkb->lkb_flags, lkb->lkb_exflags,
  			  args->flags, lkb->lkb_wait_type,
  			  lkb->lkb_resource->res_name);
e7fd41792   David Teigland   [DLM] The core of...
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
  	return rv;
  }
  
  /*
   * Four stage 4 varieties:
   * do_request(), do_convert(), do_unlock(), do_cancel()
   * These are called on the master node for the given lock and
   * from the central locking logic.
   */
  
  static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error = 0;
c503a6210   David Teigland   dlm: fix conversi...
2984
  	if (can_be_granted(r, lkb, 1, 0, NULL)) {
e7fd41792   David Teigland   [DLM] The core of...
2985
2986
2987
2988
2989
2990
2991
2992
  		grant_lock(r, lkb);
  		queue_cast(r, lkb, 0);
  		goto out;
  	}
  
  	if (can_be_queued(lkb)) {
  		error = -EINPROGRESS;
  		add_lkb(r, lkb, DLM_LKSTS_WAITING);
3ae1acf93   David Teigland   [DLM] add lock ti...
2993
  		add_timeout(lkb);
e7fd41792   David Teigland   [DLM] The core of...
2994
2995
2996
2997
  		goto out;
  	}
  
  	error = -EAGAIN;
e7fd41792   David Teigland   [DLM] The core of...
2998
  	queue_cast(r, lkb, -EAGAIN);
e7fd41792   David Teigland   [DLM] The core of...
2999
3000
3001
   out:
  	return error;
  }
cf6620acc   David Teigland   dlm: send reply b...
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
  static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			       int error)
  {
  	switch (error) {
  	case -EAGAIN:
  		if (force_blocking_asts(lkb))
  			send_blocking_asts_all(r, lkb);
  		break;
  	case -EINPROGRESS:
  		send_blocking_asts(r, lkb);
  		break;
  	}
  }
e7fd41792   David Teigland   [DLM] The core of...
3015
3016
3017
  static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error = 0;
c85d65e91   David Teigland   [DLM] cancel in c...
3018
  	int deadlk = 0;
e7fd41792   David Teigland   [DLM] The core of...
3019
3020
  
  	/* changing an existing lock may allow others to be granted */
c503a6210   David Teigland   dlm: fix conversi...
3021
  	if (can_be_granted(r, lkb, 1, 0, &deadlk)) {
e7fd41792   David Teigland   [DLM] The core of...
3022
3023
  		grant_lock(r, lkb);
  		queue_cast(r, lkb, 0);
e7fd41792   David Teigland   [DLM] The core of...
3024
3025
  		goto out;
  	}
c85d65e91   David Teigland   [DLM] cancel in c...
3026
3027
3028
  	/* can_be_granted() detected that this lock would block in a conversion
  	   deadlock, so we leave it on the granted queue and return EDEADLK in
  	   the ast for the convert. */
294e7e458   tsutomu.owa@toshiba.co.jp   DLM: fix conversi...
3029
  	if (deadlk && !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
c85d65e91   David Teigland   [DLM] cancel in c...
3030
  		/* it's left on the granted queue */
c85d65e91   David Teigland   [DLM] cancel in c...
3031
3032
3033
3034
3035
  		revert_lock(r, lkb);
  		queue_cast(r, lkb, -EDEADLK);
  		error = -EDEADLK;
  		goto out;
  	}
7d3c1feb8   David Teigland   [DLM] fix mode mu...
3036
3037
3038
3039
3040
3041
3042
  	/* is_demoted() means the can_be_granted() above set the grmode
  	   to NL, and left us on the granted queue.  This auto-demotion
  	   (due to CONVDEADLK) might mean other locks, and/or this lock, are
  	   now grantable.  We have to try to grant other converting locks
  	   before we try again to grant this one. */
  
  	if (is_demoted(lkb)) {
4875647a0   David Teigland   dlm: fixes for no...
3043
  		grant_pending_convert(r, DLM_LOCK_IV, NULL, NULL);
c503a6210   David Teigland   dlm: fix conversi...
3044
  		if (_can_be_granted(r, lkb, 1, 0)) {
7d3c1feb8   David Teigland   [DLM] fix mode mu...
3045
3046
  			grant_lock(r, lkb);
  			queue_cast(r, lkb, 0);
7d3c1feb8   David Teigland   [DLM] fix mode mu...
3047
3048
3049
3050
3051
3052
  			goto out;
  		}
  		/* else fall through and move to convert queue */
  	}
  
  	if (can_be_queued(lkb)) {
e7fd41792   David Teigland   [DLM] The core of...
3053
3054
3055
  		error = -EINPROGRESS;
  		del_lkb(r, lkb);
  		add_lkb(r, lkb, DLM_LKSTS_CONVERT);
3ae1acf93   David Teigland   [DLM] add lock ti...
3056
  		add_timeout(lkb);
e7fd41792   David Teigland   [DLM] The core of...
3057
3058
3059
3060
  		goto out;
  	}
  
  	error = -EAGAIN;
e7fd41792   David Teigland   [DLM] The core of...
3061
  	queue_cast(r, lkb, -EAGAIN);
e7fd41792   David Teigland   [DLM] The core of...
3062
3063
3064
   out:
  	return error;
  }
cf6620acc   David Teigland   dlm: send reply b...
3065
3066
3067
3068
3069
  static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			       int error)
  {
  	switch (error) {
  	case 0:
4875647a0   David Teigland   dlm: fixes for no...
3070
  		grant_pending_locks(r, NULL);
cf6620acc   David Teigland   dlm: send reply b...
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
  		/* grant_pending_locks also sends basts */
  		break;
  	case -EAGAIN:
  		if (force_blocking_asts(lkb))
  			send_blocking_asts_all(r, lkb);
  		break;
  	case -EINPROGRESS:
  		send_blocking_asts(r, lkb);
  		break;
  	}
  }
e7fd41792   David Teigland   [DLM] The core of...
3082
3083
3084
3085
  static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	remove_lock(r, lkb);
  	queue_cast(r, lkb, -DLM_EUNLOCK);
e7fd41792   David Teigland   [DLM] The core of...
3086
3087
  	return -DLM_EUNLOCK;
  }
cf6620acc   David Teigland   dlm: send reply b...
3088
3089
3090
  static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			      int error)
  {
4875647a0   David Teigland   dlm: fixes for no...
3091
  	grant_pending_locks(r, NULL);
cf6620acc   David Teigland   dlm: send reply b...
3092
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
3093
  /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3094

e7fd41792   David Teigland   [DLM] The core of...
3095
3096
  static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
3097
3098
3099
3100
3101
  	int error;
  
  	error = revert_lock(r, lkb);
  	if (error) {
  		queue_cast(r, lkb, -DLM_ECANCEL);
ef0c2bb05   David Teigland   [DLM] overlapping...
3102
3103
3104
  		return -DLM_ECANCEL;
  	}
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
3105
  }
cf6620acc   David Teigland   dlm: send reply b...
3106
3107
3108
3109
  static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			      int error)
  {
  	if (error)
4875647a0   David Teigland   dlm: fixes for no...
3110
  		grant_pending_locks(r, NULL);
cf6620acc   David Teigland   dlm: send reply b...
3111
  }
e7fd41792   David Teigland   [DLM] The core of...
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
  /*
   * Four stage 3 varieties:
   * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock()
   */
  
  /* add a new lkb to a possibly new rsb, called by requesting process */
  
  static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error;
  
  	/* set_master: sets lkb nodeid from r */
  
  	error = set_master(r, lkb);
  	if (error < 0)
  		goto out;
  	if (error) {
  		error = 0;
  		goto out;
  	}
cf6620acc   David Teigland   dlm: send reply b...
3132
  	if (is_remote(r)) {
e7fd41792   David Teigland   [DLM] The core of...
3133
3134
  		/* receive_request() calls do_request() on remote node */
  		error = send_request(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3135
  	} else {
e7fd41792   David Teigland   [DLM] The core of...
3136
  		error = do_request(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3137
3138
3139
3140
  		/* for remote locks the request_reply is sent
  		   between do_request and do_request_effects */
  		do_request_effects(r, lkb, error);
  	}
e7fd41792   David Teigland   [DLM] The core of...
3141
3142
3143
   out:
  	return error;
  }
3bcd3687f   David Teigland   [DLM] Remove rang...
3144
  /* change some property of an existing lkb, e.g. mode */
e7fd41792   David Teigland   [DLM] The core of...
3145
3146
3147
3148
  
  static int _convert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error;
cf6620acc   David Teigland   dlm: send reply b...
3149
  	if (is_remote(r)) {
e7fd41792   David Teigland   [DLM] The core of...
3150
3151
  		/* receive_convert() calls do_convert() on remote node */
  		error = send_convert(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3152
  	} else {
e7fd41792   David Teigland   [DLM] The core of...
3153
  		error = do_convert(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3154
3155
3156
3157
  		/* for remote locks the convert_reply is sent
  		   between do_convert and do_convert_effects */
  		do_convert_effects(r, lkb, error);
  	}
e7fd41792   David Teigland   [DLM] The core of...
3158
3159
3160
3161
3162
3163
3164
3165
3166
  
  	return error;
  }
  
  /* remove an existing lkb from the granted queue */
  
  static int _unlock_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error;
cf6620acc   David Teigland   dlm: send reply b...
3167
  	if (is_remote(r)) {
e7fd41792   David Teigland   [DLM] The core of...
3168
3169
  		/* receive_unlock() calls do_unlock() on remote node */
  		error = send_unlock(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3170
  	} else {
e7fd41792   David Teigland   [DLM] The core of...
3171
  		error = do_unlock(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3172
3173
3174
3175
  		/* for remote locks the unlock_reply is sent
  		   between do_unlock and do_unlock_effects */
  		do_unlock_effects(r, lkb, error);
  	}
e7fd41792   David Teigland   [DLM] The core of...
3176
3177
3178
3179
3180
3181
3182
3183
3184
  
  	return error;
  }
  
  /* remove an existing lkb from the convert or wait queue */
  
  static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error;
cf6620acc   David Teigland   dlm: send reply b...
3185
  	if (is_remote(r)) {
e7fd41792   David Teigland   [DLM] The core of...
3186
3187
  		/* receive_cancel() calls do_cancel() on remote node */
  		error = send_cancel(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3188
  	} else {
e7fd41792   David Teigland   [DLM] The core of...
3189
  		error = do_cancel(r, lkb);
cf6620acc   David Teigland   dlm: send reply b...
3190
3191
3192
3193
  		/* for remote locks the cancel_reply is sent
  		   between do_cancel and do_cancel_effects */
  		do_cancel_effects(r, lkb, error);
  	}
e7fd41792   David Teigland   [DLM] The core of...
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
  
  	return error;
  }
  
  /*
   * Four stage 2 varieties:
   * request_lock(), convert_lock(), unlock_lock(), cancel_lock()
   */
  
  static int request_lock(struct dlm_ls *ls, struct dlm_lkb *lkb, char *name,
  			int len, struct dlm_args *args)
  {
  	struct dlm_rsb *r;
  	int error;
  
  	error = validate_lock_args(ls, lkb, args);
  	if (error)
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3211
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
3212

c04fecb4d   David Teigland   dlm: use rsbtbl a...
3213
  	error = find_rsb(ls, name, len, 0, R_REQUEST, &r);
e7fd41792   David Teigland   [DLM] The core of...
3214
  	if (error)
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3215
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
  
  	lock_rsb(r);
  
  	attach_lkb(r, lkb);
  	lkb->lkb_lksb->sb_lkid = lkb->lkb_id;
  
  	error = _request_lock(r, lkb);
  
  	unlock_rsb(r);
  	put_rsb(r);
e7fd41792   David Teigland   [DLM] The core of...
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
  	return error;
  }
  
  static int convert_lock(struct dlm_ls *ls, struct dlm_lkb *lkb,
  			struct dlm_args *args)
  {
  	struct dlm_rsb *r;
  	int error;
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
  
  	error = validate_lock_args(ls, lkb, args);
  	if (error)
  		goto out;
  
  	error = _convert_lock(r, lkb);
   out:
  	unlock_rsb(r);
  	put_rsb(r);
  	return error;
  }
  
  static int unlock_lock(struct dlm_ls *ls, struct dlm_lkb *lkb,
  		       struct dlm_args *args)
  {
  	struct dlm_rsb *r;
  	int error;
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
  
  	error = validate_unlock_args(lkb, args);
  	if (error)
  		goto out;
  
  	error = _unlock_lock(r, lkb);
   out:
  	unlock_rsb(r);
  	put_rsb(r);
  	return error;
  }
  
  static int cancel_lock(struct dlm_ls *ls, struct dlm_lkb *lkb,
  		       struct dlm_args *args)
  {
  	struct dlm_rsb *r;
  	int error;
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
  
  	error = validate_unlock_args(lkb, args);
  	if (error)
  		goto out;
  
  	error = _cancel_lock(r, lkb);
   out:
  	unlock_rsb(r);
  	put_rsb(r);
  	return error;
  }
  
  /*
   * Two stage 1 varieties:  dlm_lock() and dlm_unlock()
   */
  
  int dlm_lock(dlm_lockspace_t *lockspace,
  	     int mode,
  	     struct dlm_lksb *lksb,
  	     uint32_t flags,
  	     void *name,
  	     unsigned int namelen,
  	     uint32_t parent_lkid,
  	     void (*ast) (void *astarg),
  	     void *astarg,
3bcd3687f   David Teigland   [DLM] Remove rang...
3308
  	     void (*bast) (void *astarg, int mode))
e7fd41792   David Teigland   [DLM] The core of...
3309
3310
3311
3312
3313
3314
3315
3316
3317
  {
  	struct dlm_ls *ls;
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	int error, convert = flags & DLM_LKF_CONVERT;
  
  	ls = dlm_find_lockspace_local(lockspace);
  	if (!ls)
  		return -EINVAL;
85e86edf9   David Teigland   [DLM] block scand...
3318
  	dlm_lock_recovery(ls);
e7fd41792   David Teigland   [DLM] The core of...
3319
3320
3321
3322
3323
3324
3325
3326
  
  	if (convert)
  		error = find_lkb(ls, lksb->sb_lkid, &lkb);
  	else
  		error = create_lkb(ls, &lkb);
  
  	if (error)
  		goto out;
d7db923ea   David Teigland   [DLM] dlm_device ...
3327
  	error = set_lock_args(mode, lksb, flags, namelen, 0, ast,
3bcd3687f   David Teigland   [DLM] Remove rang...
3328
  			      astarg, bast, &args);
e7fd41792   David Teigland   [DLM] The core of...
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
  	if (error)
  		goto out_put;
  
  	if (convert)
  		error = convert_lock(ls, lkb, &args);
  	else
  		error = request_lock(ls, lkb, name, namelen, &args);
  
  	if (error == -EINPROGRESS)
  		error = 0;
   out_put:
  	if (convert || error)
b3f58d8f2   David Teigland   [DLM] Pass in loc...
3341
  		__put_lkb(ls, lkb);
c85d65e91   David Teigland   [DLM] cancel in c...
3342
  	if (error == -EAGAIN || error == -EDEADLK)
e7fd41792   David Teigland   [DLM] The core of...
3343
3344
  		error = 0;
   out:
85e86edf9   David Teigland   [DLM] block scand...
3345
  	dlm_unlock_recovery(ls);
e7fd41792   David Teigland   [DLM] The core of...
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
  	dlm_put_lockspace(ls);
  	return error;
  }
  
  int dlm_unlock(dlm_lockspace_t *lockspace,
  	       uint32_t lkid,
  	       uint32_t flags,
  	       struct dlm_lksb *lksb,
  	       void *astarg)
  {
  	struct dlm_ls *ls;
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	int error;
  
  	ls = dlm_find_lockspace_local(lockspace);
  	if (!ls)
  		return -EINVAL;
85e86edf9   David Teigland   [DLM] block scand...
3364
  	dlm_lock_recovery(ls);
e7fd41792   David Teigland   [DLM] The core of...
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
  
  	error = find_lkb(ls, lkid, &lkb);
  	if (error)
  		goto out;
  
  	error = set_unlock_args(flags, astarg, &args);
  	if (error)
  		goto out_put;
  
  	if (flags & DLM_LKF_CANCEL)
  		error = cancel_lock(ls, lkb, &args);
  	else
  		error = unlock_lock(ls, lkb, &args);
  
  	if (error == -DLM_EUNLOCK || error == -DLM_ECANCEL)
  		error = 0;
ef0c2bb05   David Teigland   [DLM] overlapping...
3381
3382
  	if (error == -EBUSY && (flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)))
  		error = 0;
e7fd41792   David Teigland   [DLM] The core of...
3383
   out_put:
b3f58d8f2   David Teigland   [DLM] Pass in loc...
3384
  	dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
3385
   out:
85e86edf9   David Teigland   [DLM] block scand...
3386
  	dlm_unlock_recovery(ls);
e7fd41792   David Teigland   [DLM] The core of...
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
  	dlm_put_lockspace(ls);
  	return error;
  }
  
  /*
   * send/receive routines for remote operations and replies
   *
   * send_args
   * send_common
   * send_request			receive_request
   * send_convert			receive_convert
   * send_unlock			receive_unlock
   * send_cancel			receive_cancel
   * send_grant			receive_grant
   * send_bast			receive_bast
   * send_lookup			receive_lookup
   * send_remove			receive_remove
   *
   * 				send_common_reply
   * receive_request_reply	send_request_reply
   * receive_convert_reply	send_convert_reply
   * receive_unlock_reply		send_unlock_reply
   * receive_cancel_reply		send_cancel_reply
   * receive_lookup_reply		send_lookup_reply
   */
7e4dac335   David Teigland   [DLM] split creat...
3412
3413
3414
3415
  static int _create_message(struct dlm_ls *ls, int mb_len,
  			   int to_nodeid, int mstype,
  			   struct dlm_message **ms_ret,
  			   struct dlm_mhandle **mh_ret)
e7fd41792   David Teigland   [DLM] The core of...
3416
3417
3418
3419
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	char *mb;
e7fd41792   David Teigland   [DLM] The core of...
3420
3421
3422
3423
  
  	/* get_buffer gives us a message handle (mh) that we need to
  	   pass into lowcomms_commit and a message buffer (mb) that we
  	   write our data into */
573c24c4a   David Teigland   dlm: always use G...
3424
  	mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
e7fd41792   David Teigland   [DLM] The core of...
3425
3426
3427
3428
3429
3430
3431
3432
  	if (!mh)
  		return -ENOBUFS;
  
  	memset(mb, 0, mb_len);
  
  	ms = (struct dlm_message *) mb;
  
  	ms->m_header.h_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR);
7e4dac335   David Teigland   [DLM] split creat...
3433
  	ms->m_header.h_lockspace = ls->ls_global_id;
e7fd41792   David Teigland   [DLM] The core of...
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
  	ms->m_header.h_nodeid = dlm_our_nodeid();
  	ms->m_header.h_length = mb_len;
  	ms->m_header.h_cmd = DLM_MSG;
  
  	ms->m_type = mstype;
  
  	*mh_ret = mh;
  	*ms_ret = ms;
  	return 0;
  }
7e4dac335   David Teigland   [DLM] split creat...
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
  static int create_message(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			  int to_nodeid, int mstype,
  			  struct dlm_message **ms_ret,
  			  struct dlm_mhandle **mh_ret)
  {
  	int mb_len = sizeof(struct dlm_message);
  
  	switch (mstype) {
  	case DLM_MSG_REQUEST:
  	case DLM_MSG_LOOKUP:
  	case DLM_MSG_REMOVE:
  		mb_len += r->res_length;
  		break;
  	case DLM_MSG_CONVERT:
  	case DLM_MSG_UNLOCK:
  	case DLM_MSG_REQUEST_REPLY:
  	case DLM_MSG_CONVERT_REPLY:
  	case DLM_MSG_GRANT:
  		if (lkb && lkb->lkb_lvbptr)
  			mb_len += r->res_ls->ls_lvblen;
  		break;
  	}
  
  	return _create_message(r->res_ls, mb_len, to_nodeid, mstype,
  			       ms_ret, mh_ret);
  }
e7fd41792   David Teigland   [DLM] The core of...
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
  /* further lowcomms enhancements or alternate implementations may make
     the return value from this function useful at some point */
  
  static int send_message(struct dlm_mhandle *mh, struct dlm_message *ms)
  {
  	dlm_message_out(ms);
  	dlm_lowcomms_commit_buffer(mh);
  	return 0;
  }
  
  static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb,
  		      struct dlm_message *ms)
  {
  	ms->m_nodeid   = lkb->lkb_nodeid;
  	ms->m_pid      = lkb->lkb_ownpid;
  	ms->m_lkid     = lkb->lkb_id;
  	ms->m_remid    = lkb->lkb_remid;
  	ms->m_exflags  = lkb->lkb_exflags;
  	ms->m_sbflags  = lkb->lkb_sbflags;
  	ms->m_flags    = lkb->lkb_flags;
  	ms->m_lvbseq   = lkb->lkb_lvbseq;
  	ms->m_status   = lkb->lkb_status;
  	ms->m_grmode   = lkb->lkb_grmode;
  	ms->m_rqmode   = lkb->lkb_rqmode;
  	ms->m_hash     = r->res_hash;
  
  	/* m_result and m_bastmode are set from function args,
  	   not from lkb fields */
e5dae548b   David Teigland   dlm: proper types...
3498
  	if (lkb->lkb_bastfn)
8304d6f24   David Teigland   dlm: record full ...
3499
  		ms->m_asts |= DLM_CB_BAST;
e5dae548b   David Teigland   dlm: proper types...
3500
  	if (lkb->lkb_astfn)
8304d6f24   David Teigland   dlm: record full ...
3501
  		ms->m_asts |= DLM_CB_CAST;
e7fd41792   David Teigland   [DLM] The core of...
3502

da49f36f4   David Teigland   [DLM] fix send_ar...
3503
3504
  	/* compare with switch in create_message; send_remove() doesn't
  	   use send_args() */
e7fd41792   David Teigland   [DLM] The core of...
3505

da49f36f4   David Teigland   [DLM] fix send_ar...
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
  	switch (ms->m_type) {
  	case DLM_MSG_REQUEST:
  	case DLM_MSG_LOOKUP:
  		memcpy(ms->m_extra, r->res_name, r->res_length);
  		break;
  	case DLM_MSG_CONVERT:
  	case DLM_MSG_UNLOCK:
  	case DLM_MSG_REQUEST_REPLY:
  	case DLM_MSG_CONVERT_REPLY:
  	case DLM_MSG_GRANT:
  		if (!lkb->lkb_lvbptr)
  			break;
e7fd41792   David Teigland   [DLM] The core of...
3518
  		memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
da49f36f4   David Teigland   [DLM] fix send_ar...
3519
3520
  		break;
  	}
e7fd41792   David Teigland   [DLM] The core of...
3521
3522
3523
3524
3525
3526
3527
  }
  
  static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
c6ff669ba   David Teigland   dlm: delayed repl...
3528
3529
3530
  	to_nodeid = r->res_nodeid;
  
  	error = add_to_waiters(lkb, mstype, to_nodeid);
ef0c2bb05   David Teigland   [DLM] overlapping...
3531
3532
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
3533

e7fd41792   David Teigland   [DLM] The core of...
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
  	error = create_message(r, lkb, to_nodeid, mstype, &ms, &mh);
  	if (error)
  		goto fail;
  
  	send_args(r, lkb, ms);
  
  	error = send_message(mh, ms);
  	if (error)
  		goto fail;
  	return 0;
  
   fail:
ef0c2bb05   David Teigland   [DLM] overlapping...
3546
  	remove_from_waiters(lkb, msg_reply_type(mstype));
e7fd41792   David Teigland   [DLM] The core of...
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
  	return error;
  }
  
  static int send_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	return send_common(r, lkb, DLM_MSG_REQUEST);
  }
  
  static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	int error;
  
  	error = send_common(r, lkb, DLM_MSG_CONVERT);
  
  	/* down conversions go without a reply from the master */
  	if (!error && down_conversion(lkb)) {
ef0c2bb05   David Teigland   [DLM] overlapping...
3563
  		remove_from_waiters(lkb, DLM_MSG_CONVERT_REPLY);
2a7ce0edd   David Teigland   dlm: remove share...
3564
  		r->res_ls->ls_stub_ms.m_flags = DLM_IFL_STUB_MS;
ef0c2bb05   David Teigland   [DLM] overlapping...
3565
  		r->res_ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
e7fd41792   David Teigland   [DLM] The core of...
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
  		r->res_ls->ls_stub_ms.m_result = 0;
  		__receive_convert_reply(r, lkb, &r->res_ls->ls_stub_ms);
  	}
  
  	return error;
  }
  
  /* FIXME: if this lkb is the only lock we hold on the rsb, then set
     MASTER_UNCERTAIN to force the next request on the rsb to confirm
     that the master is still correct. */
  
  static int send_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	return send_common(r, lkb, DLM_MSG_UNLOCK);
  }
  
  static int send_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	return send_common(r, lkb, DLM_MSG_CANCEL);
  }
  
  static int send_grant(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
  
  	to_nodeid = lkb->lkb_nodeid;
  
  	error = create_message(r, lkb, to_nodeid, DLM_MSG_GRANT, &ms, &mh);
  	if (error)
  		goto out;
  
  	send_args(r, lkb, ms);
  
  	ms->m_result = 0;
  
  	error = send_message(mh, ms);
   out:
  	return error;
  }
  
  static int send_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int mode)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
  
  	to_nodeid = lkb->lkb_nodeid;
  
  	error = create_message(r, NULL, to_nodeid, DLM_MSG_BAST, &ms, &mh);
  	if (error)
  		goto out;
  
  	send_args(r, lkb, ms);
  
  	ms->m_bastmode = mode;
  
  	error = send_message(mh, ms);
   out:
  	return error;
  }
  
  static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
c6ff669ba   David Teigland   dlm: delayed repl...
3634
3635
3636
  	to_nodeid = dlm_dir_nodeid(r);
  
  	error = add_to_waiters(lkb, DLM_MSG_LOOKUP, to_nodeid);
ef0c2bb05   David Teigland   [DLM] overlapping...
3637
3638
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
3639

e7fd41792   David Teigland   [DLM] The core of...
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
  	error = create_message(r, NULL, to_nodeid, DLM_MSG_LOOKUP, &ms, &mh);
  	if (error)
  		goto fail;
  
  	send_args(r, lkb, ms);
  
  	error = send_message(mh, ms);
  	if (error)
  		goto fail;
  	return 0;
  
   fail:
ef0c2bb05   David Teigland   [DLM] overlapping...
3652
  	remove_from_waiters(lkb, DLM_MSG_LOOKUP_REPLY);
e7fd41792   David Teigland   [DLM] The core of...
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
  	return error;
  }
  
  static int send_remove(struct dlm_rsb *r)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
  
  	to_nodeid = dlm_dir_nodeid(r);
  
  	error = create_message(r, NULL, to_nodeid, DLM_MSG_REMOVE, &ms, &mh);
  	if (error)
  		goto out;
  
  	memcpy(ms->m_extra, r->res_name, r->res_length);
  	ms->m_hash = r->res_hash;
  
  	error = send_message(mh, ms);
   out:
  	return error;
  }
  
  static int send_common_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
  			     int mstype, int rv)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int to_nodeid, error;
  
  	to_nodeid = lkb->lkb_nodeid;
  
  	error = create_message(r, lkb, to_nodeid, mstype, &ms, &mh);
  	if (error)
  		goto out;
  
  	send_args(r, lkb, ms);
  
  	ms->m_result = rv;
  
  	error = send_message(mh, ms);
   out:
  	return error;
  }
  
  static int send_request_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
  {
  	return send_common_reply(r, lkb, DLM_MSG_REQUEST_REPLY, rv);
  }
  
  static int send_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
  {
  	return send_common_reply(r, lkb, DLM_MSG_CONVERT_REPLY, rv);
  }
  
  static int send_unlock_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
  {
  	return send_common_reply(r, lkb, DLM_MSG_UNLOCK_REPLY, rv);
  }
  
  static int send_cancel_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
  {
  	return send_common_reply(r, lkb, DLM_MSG_CANCEL_REPLY, rv);
  }
  
  static int send_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms_in,
  			     int ret_nodeid, int rv)
  {
  	struct dlm_rsb *r = &ls->ls_stub_rsb;
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int error, nodeid = ms_in->m_header.h_nodeid;
  
  	error = create_message(r, NULL, nodeid, DLM_MSG_LOOKUP_REPLY, &ms, &mh);
  	if (error)
  		goto out;
  
  	ms->m_lkid = ms_in->m_lkid;
  	ms->m_result = rv;
  	ms->m_nodeid = ret_nodeid;
  
  	error = send_message(mh, ms);
   out:
  	return error;
  }
  
  /* which args we save from a received message depends heavily on the type
     of message, unlike the send side where we can safely send everything about
     the lkb for any type of message */
  
  static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	lkb->lkb_exflags = ms->m_exflags;
6f90a8b1b   David Teigland   [DLM] clear sbfla...
3746
  	lkb->lkb_sbflags = ms->m_sbflags;
e7fd41792   David Teigland   [DLM] The core of...
3747
3748
3749
3750
3751
3752
  	lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) |
  		         (ms->m_flags & 0x0000FFFF);
  }
  
  static void receive_flags_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
2a7ce0edd   David Teigland   dlm: remove share...
3753
3754
  	if (ms->m_flags == DLM_IFL_STUB_MS)
  		return;
e7fd41792   David Teigland   [DLM] The core of...
3755
3756
3757
3758
3759
3760
3761
3762
3763
  	lkb->lkb_sbflags = ms->m_sbflags;
  	lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) |
  		         (ms->m_flags & 0x0000FFFF);
  }
  
  static int receive_extralen(struct dlm_message *ms)
  {
  	return (ms->m_header.h_length - sizeof(struct dlm_message));
  }
e7fd41792   David Teigland   [DLM] The core of...
3764
3765
3766
3767
3768
3769
3770
  static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb,
  		       struct dlm_message *ms)
  {
  	int len;
  
  	if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
  		if (!lkb->lkb_lvbptr)
52bda2b5b   David Teigland   dlm: use dlm pref...
3771
  			lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
e7fd41792   David Teigland   [DLM] The core of...
3772
3773
3774
  		if (!lkb->lkb_lvbptr)
  			return -ENOMEM;
  		len = receive_extralen(ms);
cfa805f6f   Bart Van Assche   dlm: Avoid LVB tr...
3775
3776
  		if (len > ls->ls_lvblen)
  			len = ls->ls_lvblen;
e7fd41792   David Teigland   [DLM] The core of...
3777
3778
3779
3780
  		memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
  	}
  	return 0;
  }
e5dae548b   David Teigland   dlm: proper types...
3781
3782
3783
3784
3785
3786
3787
3788
3789
  static void fake_bastfn(void *astparam, int mode)
  {
  	log_print("fake_bastfn should not be called");
  }
  
  static void fake_astfn(void *astparam)
  {
  	log_print("fake_astfn should not be called");
  }
e7fd41792   David Teigland   [DLM] The core of...
3790
3791
3792
3793
3794
3795
3796
3797
  static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
  				struct dlm_message *ms)
  {
  	lkb->lkb_nodeid = ms->m_header.h_nodeid;
  	lkb->lkb_ownpid = ms->m_pid;
  	lkb->lkb_remid = ms->m_lkid;
  	lkb->lkb_grmode = DLM_LOCK_IV;
  	lkb->lkb_rqmode = ms->m_rqmode;
e5dae548b   David Teigland   dlm: proper types...
3798

8304d6f24   David Teigland   dlm: record full ...
3799
3800
  	lkb->lkb_bastfn = (ms->m_asts & DLM_CB_BAST) ? &fake_bastfn : NULL;
  	lkb->lkb_astfn = (ms->m_asts & DLM_CB_CAST) ? &fake_astfn : NULL;
e7fd41792   David Teigland   [DLM] The core of...
3801

8d07fd509   David Teigland   [DLM] fix receive...
3802
3803
  	if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
  		/* lkb was just created so there won't be an lvb yet */
52bda2b5b   David Teigland   dlm: use dlm pref...
3804
  		lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
8d07fd509   David Teigland   [DLM] fix receive...
3805
3806
3807
  		if (!lkb->lkb_lvbptr)
  			return -ENOMEM;
  	}
e7fd41792   David Teigland   [DLM] The core of...
3808
3809
3810
3811
3812
3813
3814
  
  	return 0;
  }
  
  static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
  				struct dlm_message *ms)
  {
e7fd41792   David Teigland   [DLM] The core of...
3815
3816
  	if (lkb->lkb_status != DLM_LKSTS_GRANTED)
  		return -EBUSY;
e7fd41792   David Teigland   [DLM] The core of...
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
  	if (receive_lvb(ls, lkb, ms))
  		return -ENOMEM;
  
  	lkb->lkb_rqmode = ms->m_rqmode;
  	lkb->lkb_lvbseq = ms->m_lvbseq;
  
  	return 0;
  }
  
  static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
  			       struct dlm_message *ms)
  {
e7fd41792   David Teigland   [DLM] The core of...
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
  	if (receive_lvb(ls, lkb, ms))
  		return -ENOMEM;
  	return 0;
  }
  
  /* We fill in the stub-lkb fields with the info that send_xxxx_reply()
     uses to send a reply and that the remote end uses to process the reply. */
  
  static void setup_stub_lkb(struct dlm_ls *ls, struct dlm_message *ms)
  {
  	struct dlm_lkb *lkb = &ls->ls_stub_lkb;
  	lkb->lkb_nodeid = ms->m_header.h_nodeid;
  	lkb->lkb_remid = ms->m_lkid;
  }
c54e04b00   David Teigland   dlm: validate mes...
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
  /* This is called after the rsb is locked so that we can safely inspect
     fields in the lkb. */
  
  static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	int from = ms->m_header.h_nodeid;
  	int error = 0;
  
  	switch (ms->m_type) {
  	case DLM_MSG_CONVERT:
  	case DLM_MSG_UNLOCK:
  	case DLM_MSG_CANCEL:
  		if (!is_master_copy(lkb) || lkb->lkb_nodeid != from)
  			error = -EINVAL;
  		break;
  
  	case DLM_MSG_CONVERT_REPLY:
  	case DLM_MSG_UNLOCK_REPLY:
  	case DLM_MSG_CANCEL_REPLY:
  	case DLM_MSG_GRANT:
  	case DLM_MSG_BAST:
  		if (!is_process_copy(lkb) || lkb->lkb_nodeid != from)
  			error = -EINVAL;
  		break;
  
  	case DLM_MSG_REQUEST_REPLY:
  		if (!is_process_copy(lkb))
  			error = -EINVAL;
  		else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from)
  			error = -EINVAL;
  		break;
  
  	default:
  		error = -EINVAL;
  	}
  
  	if (error)
  		log_error(lkb->lkb_resource->res_ls,
  			  "ignore invalid message %d from %d %x %x %x %d",
  			  ms->m_type, from, lkb->lkb_id, lkb->lkb_remid,
  			  lkb->lkb_flags, lkb->lkb_nodeid);
  	return error;
  }
96006ea6d   David Teigland   dlm: fix missing ...
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
  static void send_repeat_remove(struct dlm_ls *ls, char *ms_name, int len)
  {
  	char name[DLM_RESNAME_MAXLEN + 1];
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	struct dlm_rsb *r;
  	uint32_t hash, b;
  	int rv, dir_nodeid;
  
  	memset(name, 0, sizeof(name));
  	memcpy(name, ms_name, len);
  
  	hash = jhash(name, len, 0);
  	b = hash & (ls->ls_rsbtbl_size - 1);
  
  	dir_nodeid = dlm_hash2nodeid(ls, hash);
  
  	log_error(ls, "send_repeat_remove dir %d %s", dir_nodeid, name);
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  	rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
  	if (!rv) {
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		log_error(ls, "repeat_remove on keep %s", name);
  		return;
  	}
  
  	rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  	if (!rv) {
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		log_error(ls, "repeat_remove on toss %s", name);
  		return;
  	}
  
  	/* use ls->remove_name2 to avoid conflict with shrink? */
  
  	spin_lock(&ls->ls_remove_spin);
  	ls->ls_remove_len = len;
  	memcpy(ls->ls_remove_name, name, DLM_RESNAME_MAXLEN);
  	spin_unlock(&ls->ls_remove_spin);
  	spin_unlock(&ls->ls_rsbtbl[b].lock);
  
  	rv = _create_message(ls, sizeof(struct dlm_message) + len,
  			     dir_nodeid, DLM_MSG_REMOVE, &ms, &mh);
  	if (rv)
  		return;
  
  	memcpy(ms->m_extra, name, len);
  	ms->m_hash = hash;
  
  	send_message(mh, ms);
  
  	spin_lock(&ls->ls_remove_spin);
  	ls->ls_remove_len = 0;
  	memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);
  	spin_unlock(&ls->ls_remove_spin);
  }
6d40c4a70   David Teigland   dlm: improve erro...
3943
  static int receive_request(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
3944
3945
3946
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3947
  	int from_nodeid;
96006ea6d   David Teigland   dlm: fix missing ...
3948
  	int error, namelen = 0;
e7fd41792   David Teigland   [DLM] The core of...
3949

c04fecb4d   David Teigland   dlm: use rsbtbl a...
3950
  	from_nodeid = ms->m_header.h_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
3951
3952
3953
3954
3955
3956
3957
3958
  	error = create_lkb(ls, &lkb);
  	if (error)
  		goto fail;
  
  	receive_flags(lkb, ms);
  	lkb->lkb_flags |= DLM_IFL_MSTCPY;
  	error = receive_request_args(ls, lkb, ms);
  	if (error) {
b3f58d8f2   David Teigland   [DLM] Pass in loc...
3959
  		__put_lkb(ls, lkb);
e7fd41792   David Teigland   [DLM] The core of...
3960
3961
  		goto fail;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3962
3963
3964
3965
3966
  	/* The dir node is the authority on whether we are the master
  	   for this rsb or not, so if the master sends us a request, we should
  	   recreate the rsb if we've destroyed it.   This race happens when we
  	   send a remove message to the dir node at the same time that the dir
  	   node sends us a request for the rsb. */
e7fd41792   David Teigland   [DLM] The core of...
3967
  	namelen = receive_extralen(ms);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3968
3969
  	error = find_rsb(ls, ms->m_extra, namelen, from_nodeid,
  			 R_RECEIVE_REQUEST, &r);
e7fd41792   David Teigland   [DLM] The core of...
3970
  	if (error) {
b3f58d8f2   David Teigland   [DLM] Pass in loc...
3971
  		__put_lkb(ls, lkb);
e7fd41792   David Teigland   [DLM] The core of...
3972
3973
3974
3975
  		goto fail;
  	}
  
  	lock_rsb(r);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
3976
3977
3978
3979
3980
3981
3982
3983
3984
  	if (r->res_master_nodeid != dlm_our_nodeid()) {
  		error = validate_master_nodeid(ls, r, from_nodeid);
  		if (error) {
  			unlock_rsb(r);
  			put_rsb(r);
  			__put_lkb(ls, lkb);
  			goto fail;
  		}
  	}
e7fd41792   David Teigland   [DLM] The core of...
3985
3986
3987
  	attach_lkb(r, lkb);
  	error = do_request(r, lkb);
  	send_request_reply(r, lkb, error);
cf6620acc   David Teigland   dlm: send reply b...
3988
  	do_request_effects(r, lkb, error);
e7fd41792   David Teigland   [DLM] The core of...
3989
3990
3991
3992
3993
3994
3995
  
  	unlock_rsb(r);
  	put_rsb(r);
  
  	if (error == -EINPROGRESS)
  		error = 0;
  	if (error)
b3f58d8f2   David Teigland   [DLM] Pass in loc...
3996
  		dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
3997
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
3998
3999
  
   fail:
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
  	/* TODO: instead of returning ENOTBLK, add the lkb to res_lookup
  	   and do this receive_request again from process_lookup_list once
  	   we get the lookup reply.  This would avoid a many repeated
  	   ENOTBLK request failures when the lookup reply designating us
  	   as master is delayed. */
  
  	/* We could repeatedly return -EBADR here if our send_remove() is
  	   delayed in being sent/arriving/being processed on the dir node.
  	   Another node would repeatedly lookup up the master, and the dir
  	   node would continue returning our nodeid until our send_remove
96006ea6d   David Teigland   dlm: fix missing ...
4010
4011
4012
4013
  	   took effect.
  
  	   We send another remove message in case our previous send_remove
  	   was lost/ignored/missed somehow. */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4014
4015
4016
4017
4018
  
  	if (error != -ENOTBLK) {
  		log_limit(ls, "receive_request %x from %d %d",
  			  ms->m_lkid, from_nodeid, error);
  	}
96006ea6d   David Teigland   dlm: fix missing ...
4019
4020
4021
4022
  	if (namelen && error == -EBADR) {
  		send_repeat_remove(ls, ms->m_extra, namelen);
  		msleep(1000);
  	}
e7fd41792   David Teigland   [DLM] The core of...
4023
4024
  	setup_stub_lkb(ls, ms);
  	send_request_reply(&ls->ls_stub_rsb, &ls->ls_stub_lkb, error);
6d40c4a70   David Teigland   dlm: improve erro...
4025
  	return error;
e7fd41792   David Teigland   [DLM] The core of...
4026
  }
6d40c4a70   David Teigland   dlm: improve erro...
4027
  static int receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4028
4029
4030
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
901359256   David Teigland   [DLM] Update DLM ...
4031
  	int error, reply = 1;
e7fd41792   David Teigland   [DLM] The core of...
4032
4033
4034
4035
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
  	if (error)
  		goto fail;
6d40c4a70   David Teigland   dlm: improve erro...
4036
  	if (lkb->lkb_remid != ms->m_lkid) {
4875647a0   David Teigland   dlm: fixes for no...
4037
4038
4039
  		log_error(ls, "receive_convert %x remid %x recover_seq %llu "
  			  "remote %d %x", lkb->lkb_id, lkb->lkb_remid,
  			  (unsigned long long)lkb->lkb_recover_seq,
6d40c4a70   David Teigland   dlm: improve erro...
4040
4041
  			  ms->m_header.h_nodeid, ms->m_lkid);
  		error = -ENOENT;
c5fa01a01   Vasily Averin   dlm: lost put_lkb...
4042
  		dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4043
4044
  		goto fail;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4045
4046
4047
4048
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4049
4050
4051
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4052
  	receive_flags(lkb, ms);
cf6620acc   David Teigland   dlm: send reply b...
4053

e7fd41792   David Teigland   [DLM] The core of...
4054
  	error = receive_convert_args(ls, lkb, ms);
cf6620acc   David Teigland   dlm: send reply b...
4055
4056
4057
4058
  	if (error) {
  		send_convert_reply(r, lkb, error);
  		goto out;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4059
4060
4061
  	reply = !down_conversion(lkb);
  
  	error = do_convert(r, lkb);
e7fd41792   David Teigland   [DLM] The core of...
4062
4063
  	if (reply)
  		send_convert_reply(r, lkb, error);
cf6620acc   David Teigland   dlm: send reply b...
4064
  	do_convert_effects(r, lkb, error);
c54e04b00   David Teigland   dlm: validate mes...
4065
   out:
e7fd41792   David Teigland   [DLM] The core of...
4066
4067
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4068
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4069
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4070
4071
4072
4073
  
   fail:
  	setup_stub_lkb(ls, ms);
  	send_convert_reply(&ls->ls_stub_rsb, &ls->ls_stub_lkb, error);
6d40c4a70   David Teigland   dlm: improve erro...
4074
  	return error;
e7fd41792   David Teigland   [DLM] The core of...
4075
  }
6d40c4a70   David Teigland   dlm: improve erro...
4076
  static int receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4077
4078
4079
4080
4081
4082
4083
4084
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
  	if (error)
  		goto fail;
6d40c4a70   David Teigland   dlm: improve erro...
4085
4086
4087
4088
4089
  	if (lkb->lkb_remid != ms->m_lkid) {
  		log_error(ls, "receive_unlock %x remid %x remote %d %x",
  			  lkb->lkb_id, lkb->lkb_remid,
  			  ms->m_header.h_nodeid, ms->m_lkid);
  		error = -ENOENT;
c5fa01a01   Vasily Averin   dlm: lost put_lkb...
4090
  		dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4091
4092
  		goto fail;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4093
4094
4095
4096
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4097
4098
4099
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4100
  	receive_flags(lkb, ms);
cf6620acc   David Teigland   dlm: send reply b...
4101

e7fd41792   David Teigland   [DLM] The core of...
4102
  	error = receive_unlock_args(ls, lkb, ms);
cf6620acc   David Teigland   dlm: send reply b...
4103
4104
4105
4106
  	if (error) {
  		send_unlock_reply(r, lkb, error);
  		goto out;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4107
4108
  
  	error = do_unlock(r, lkb);
e7fd41792   David Teigland   [DLM] The core of...
4109
  	send_unlock_reply(r, lkb, error);
cf6620acc   David Teigland   dlm: send reply b...
4110
  	do_unlock_effects(r, lkb, error);
c54e04b00   David Teigland   dlm: validate mes...
4111
   out:
e7fd41792   David Teigland   [DLM] The core of...
4112
4113
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4114
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4115
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4116
4117
4118
4119
  
   fail:
  	setup_stub_lkb(ls, ms);
  	send_unlock_reply(&ls->ls_stub_rsb, &ls->ls_stub_lkb, error);
6d40c4a70   David Teigland   dlm: improve erro...
4120
  	return error;
e7fd41792   David Teigland   [DLM] The core of...
4121
  }
6d40c4a70   David Teigland   dlm: improve erro...
4122
  static int receive_cancel(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
  	if (error)
  		goto fail;
  
  	receive_flags(lkb, ms);
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4138
4139
4140
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4141
4142
  	error = do_cancel(r, lkb);
  	send_cancel_reply(r, lkb, error);
cf6620acc   David Teigland   dlm: send reply b...
4143
  	do_cancel_effects(r, lkb, error);
c54e04b00   David Teigland   dlm: validate mes...
4144
   out:
e7fd41792   David Teigland   [DLM] The core of...
4145
4146
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4147
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4148
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4149
4150
4151
4152
  
   fail:
  	setup_stub_lkb(ls, ms);
  	send_cancel_reply(&ls->ls_stub_rsb, &ls->ls_stub_lkb, error);
6d40c4a70   David Teigland   dlm: improve erro...
4153
  	return error;
e7fd41792   David Teigland   [DLM] The core of...
4154
  }
6d40c4a70   David Teigland   dlm: improve erro...
4155
  static int receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4156
4157
4158
4159
4160
4161
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4162
4163
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4164
4165
4166
4167
4168
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4169
4170
4171
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4172
  	receive_flags_reply(lkb, ms);
7d3c1feb8   David Teigland   [DLM] fix mode mu...
4173
4174
  	if (is_altmode(lkb))
  		munge_altmode(lkb, ms);
e7fd41792   David Teigland   [DLM] The core of...
4175
4176
  	grant_lock_pc(r, lkb, ms);
  	queue_cast(r, lkb, 0);
c54e04b00   David Teigland   dlm: validate mes...
4177
   out:
e7fd41792   David Teigland   [DLM] The core of...
4178
4179
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4180
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4181
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4182
  }
6d40c4a70   David Teigland   dlm: improve erro...
4183
  static int receive_bast(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4184
4185
4186
4187
4188
4189
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4190
4191
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4192
4193
4194
4195
4196
  
  	r = lkb->lkb_resource;
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4197
4198
4199
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4200

c54e04b00   David Teigland   dlm: validate mes...
4201
  	queue_bast(r, lkb, ms->m_bastmode);
4875647a0   David Teigland   dlm: fixes for no...
4202
  	lkb->lkb_highbast = ms->m_bastmode;
c54e04b00   David Teigland   dlm: validate mes...
4203
   out:
e7fd41792   David Teigland   [DLM] The core of...
4204
4205
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4206
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4207
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4208
4209
4210
4211
  }
  
  static void receive_lookup(struct dlm_ls *ls, struct dlm_message *ms)
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4212
  	int len, error, ret_nodeid, from_nodeid, our_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4213
4214
4215
4216
4217
  
  	from_nodeid = ms->m_header.h_nodeid;
  	our_nodeid = dlm_our_nodeid();
  
  	len = receive_extralen(ms);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4218
4219
  	error = dlm_master_lookup(ls, from_nodeid, ms->m_extra, len, 0,
  				  &ret_nodeid, NULL);
e7fd41792   David Teigland   [DLM] The core of...
4220
4221
4222
4223
4224
4225
  
  	/* Optimization: we're master so treat lookup as a request */
  	if (!error && ret_nodeid == our_nodeid) {
  		receive_request(ls, ms);
  		return;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4226
4227
4228
4229
4230
  	send_lookup_reply(ls, ms, ret_nodeid, error);
  }
  
  static void receive_remove(struct dlm_ls *ls, struct dlm_message *ms)
  {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4231
4232
4233
4234
  	char name[DLM_RESNAME_MAXLEN+1];
  	struct dlm_rsb *r;
  	uint32_t hash, b;
  	int rv, len, dir_nodeid, from_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4235
4236
4237
4238
  
  	from_nodeid = ms->m_header.h_nodeid;
  
  	len = receive_extralen(ms);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4239
4240
4241
4242
4243
  	if (len > DLM_RESNAME_MAXLEN) {
  		log_error(ls, "receive_remove from %d bad len %d",
  			  from_nodeid, len);
  		return;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4244
4245
  	dir_nodeid = dlm_hash2nodeid(ls, ms->m_hash);
  	if (dir_nodeid != dlm_our_nodeid()) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4246
4247
  		log_error(ls, "receive_remove from %d bad nodeid %d",
  			  from_nodeid, dir_nodeid);
e7fd41792   David Teigland   [DLM] The core of...
4248
4249
  		return;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
  	/* Look for name on rsbtbl.toss, if it's there, kill it.
  	   If it's on rsbtbl.keep, it's being used, and we should ignore this
  	   message.  This is an expected race between the dir node sending a
  	   request to the master node at the same time as the master node sends
  	   a remove to the dir node.  The resolution to that race is for the
  	   dir node to ignore the remove message, and the master node to
  	   recreate the master rsb when it gets a request from the dir node for
  	   an rsb it doesn't have. */
  
  	memset(name, 0, sizeof(name));
  	memcpy(name, ms->m_extra, len);
  
  	hash = jhash(name, len, 0);
  	b = hash & (ls->ls_rsbtbl_size - 1);
  
  	spin_lock(&ls->ls_rsbtbl[b].lock);
  
  	rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
  	if (rv) {
  		/* verify the rsb is on keep list per comment above */
  		rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
  		if (rv) {
  			/* should not happen */
  			log_error(ls, "receive_remove from %d not found %s",
  				  from_nodeid, name);
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			return;
  		}
  		if (r->res_master_nodeid != from_nodeid) {
  			/* should not happen */
  			log_error(ls, "receive_remove keep from %d master %d",
  				  from_nodeid, r->res_master_nodeid);
  			dlm_print_rsb(r);
  			spin_unlock(&ls->ls_rsbtbl[b].lock);
  			return;
  		}
  
  		log_debug(ls, "receive_remove from %d master %d first %x %s",
  			  from_nodeid, r->res_master_nodeid, r->res_first_lkid,
  			  name);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		return;
  	}
  
  	if (r->res_master_nodeid != from_nodeid) {
  		log_error(ls, "receive_remove toss from %d master %d",
  			  from_nodeid, r->res_master_nodeid);
  		dlm_print_rsb(r);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		return;
  	}
  
  	if (kref_put(&r->res_ref, kill_rsb)) {
  		rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  		dlm_free_rsb(r);
  	} else {
  		log_error(ls, "receive_remove from %d rsb ref error",
  			  from_nodeid);
  		dlm_print_rsb(r);
  		spin_unlock(&ls->ls_rsbtbl[b].lock);
  	}
e7fd41792   David Teigland   [DLM] The core of...
4312
  }
8499137d4   David Teigland   [DLM] add orphan ...
4313
4314
4315
4316
  static void receive_purge(struct dlm_ls *ls, struct dlm_message *ms)
  {
  	do_purge(ls, ms->m_nodeid, ms->m_pid);
  }
6d40c4a70   David Teigland   dlm: improve erro...
4317
  static int receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4318
4319
4320
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
ef0c2bb05   David Teigland   [DLM] overlapping...
4321
  	int error, mstype, result;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4322
  	int from_nodeid = ms->m_header.h_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4323
4324
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4325
4326
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4327

e7fd41792   David Teigland   [DLM] The core of...
4328
4329
4330
  	r = lkb->lkb_resource;
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4331
4332
4333
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
4334
4335
  	mstype = lkb->lkb_wait_type;
  	error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY);
4875647a0   David Teigland   dlm: fixes for no...
4336
4337
  	if (error) {
  		log_error(ls, "receive_request_reply %x remote %d %x result %d",
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4338
  			  lkb->lkb_id, from_nodeid, ms->m_lkid, ms->m_result);
4875647a0   David Teigland   dlm: fixes for no...
4339
  		dlm_dump_rsb(r);
ef0c2bb05   David Teigland   [DLM] overlapping...
4340
  		goto out;
4875647a0   David Teigland   dlm: fixes for no...
4341
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4342

e7fd41792   David Teigland   [DLM] The core of...
4343
4344
4345
  	/* Optimization: the dir node was also the master, so it took our
  	   lookup as a request and sent request reply instead of lookup reply */
  	if (mstype == DLM_MSG_LOOKUP) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4346
4347
4348
  		r->res_master_nodeid = from_nodeid;
  		r->res_nodeid = from_nodeid;
  		lkb->lkb_nodeid = from_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4349
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4350
4351
4352
4353
  	/* this is the value returned from do_request() on the master */
  	result = ms->m_result;
  
  	switch (result) {
e7fd41792   David Teigland   [DLM] The core of...
4354
  	case -EAGAIN:
ef0c2bb05   David Teigland   [DLM] overlapping...
4355
  		/* request would block (be queued) on remote master */
e7fd41792   David Teigland   [DLM] The core of...
4356
4357
  		queue_cast(r, lkb, -EAGAIN);
  		confirm_master(r, -EAGAIN);
ef0c2bb05   David Teigland   [DLM] overlapping...
4358
  		unhold_lkb(lkb); /* undoes create_lkb() */
e7fd41792   David Teigland   [DLM] The core of...
4359
4360
4361
4362
4363
4364
4365
  		break;
  
  	case -EINPROGRESS:
  	case 0:
  		/* request was queued or granted on remote master */
  		receive_flags_reply(lkb, ms);
  		lkb->lkb_remid = ms->m_lkid;
7d3c1feb8   David Teigland   [DLM] fix mode mu...
4366
4367
  		if (is_altmode(lkb))
  			munge_altmode(lkb, ms);
3ae1acf93   David Teigland   [DLM] add lock ti...
4368
  		if (result) {
e7fd41792   David Teigland   [DLM] The core of...
4369
  			add_lkb(r, lkb, DLM_LKSTS_WAITING);
3ae1acf93   David Teigland   [DLM] add lock ti...
4370
4371
  			add_timeout(lkb);
  		} else {
e7fd41792   David Teigland   [DLM] The core of...
4372
4373
4374
  			grant_lock_pc(r, lkb, ms);
  			queue_cast(r, lkb, 0);
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
4375
  		confirm_master(r, result);
e7fd41792   David Teigland   [DLM] The core of...
4376
  		break;
597d0cae0   David Teigland   [DLM] dlm: user l...
4377
  	case -EBADR:
e7fd41792   David Teigland   [DLM] The core of...
4378
4379
  	case -ENOTBLK:
  		/* find_rsb failed to find rsb or rsb wasn't master */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
  		log_limit(ls, "receive_request_reply %x from %d %d "
  			  "master %d dir %d first %x %s", lkb->lkb_id,
  			  from_nodeid, result, r->res_master_nodeid,
  			  r->res_dir_nodeid, r->res_first_lkid, r->res_name);
  
  		if (r->res_dir_nodeid != dlm_our_nodeid() &&
  		    r->res_master_nodeid != dlm_our_nodeid()) {
  			/* cause _request_lock->set_master->send_lookup */
  			r->res_master_nodeid = 0;
  			r->res_nodeid = -1;
  			lkb->lkb_nodeid = -1;
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
4392
4393
4394
4395
  
  		if (is_overlap(lkb)) {
  			/* we'll ignore error in cancel/unlock reply */
  			queue_cast_overlap(r, lkb);
aec64e1be   David Teigland   dlm: another call...
4396
  			confirm_master(r, result);
ef0c2bb05   David Teigland   [DLM] overlapping...
4397
  			unhold_lkb(lkb); /* undoes create_lkb() */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4398
  		} else {
ef0c2bb05   David Teigland   [DLM] overlapping...
4399
  			_request_lock(r, lkb);
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4400
4401
4402
4403
  
  			if (r->res_master_nodeid == dlm_our_nodeid())
  				confirm_master(r, 0);
  		}
e7fd41792   David Teigland   [DLM] The core of...
4404
4405
4406
  		break;
  
  	default:
ef0c2bb05   David Teigland   [DLM] overlapping...
4407
4408
  		log_error(ls, "receive_request_reply %x error %d",
  			  lkb->lkb_id, result);
e7fd41792   David Teigland   [DLM] The core of...
4409
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
  	if (is_overlap_unlock(lkb) && (result == 0 || result == -EINPROGRESS)) {
  		log_debug(ls, "receive_request_reply %x result %d unlock",
  			  lkb->lkb_id, result);
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		send_unlock(r, lkb);
  	} else if (is_overlap_cancel(lkb) && (result == -EINPROGRESS)) {
  		log_debug(ls, "receive_request_reply %x cancel", lkb->lkb_id);
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		send_cancel(r, lkb);
  	} else {
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
  	}
   out:
e7fd41792   David Teigland   [DLM] The core of...
4426
4427
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4428
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4429
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4430
4431
4432
4433
4434
  }
  
  static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
  				    struct dlm_message *ms)
  {
e7fd41792   David Teigland   [DLM] The core of...
4435
  	/* this is the value returned from do_convert() on the master */
ef0c2bb05   David Teigland   [DLM] overlapping...
4436
  	switch (ms->m_result) {
e7fd41792   David Teigland   [DLM] The core of...
4437
4438
4439
4440
  	case -EAGAIN:
  		/* convert would block (be queued) on remote master */
  		queue_cast(r, lkb, -EAGAIN);
  		break;
c85d65e91   David Teigland   [DLM] cancel in c...
4441
4442
4443
4444
4445
  	case -EDEADLK:
  		receive_flags_reply(lkb, ms);
  		revert_lock_pc(r, lkb);
  		queue_cast(r, lkb, -EDEADLK);
  		break;
e7fd41792   David Teigland   [DLM] The core of...
4446
4447
  	case -EINPROGRESS:
  		/* convert was queued on remote master */
7d3c1feb8   David Teigland   [DLM] fix mode mu...
4448
4449
  		receive_flags_reply(lkb, ms);
  		if (is_demoted(lkb))
2a7ce0edd   David Teigland   dlm: remove share...
4450
  			munge_demoted(lkb);
e7fd41792   David Teigland   [DLM] The core of...
4451
4452
  		del_lkb(r, lkb);
  		add_lkb(r, lkb, DLM_LKSTS_CONVERT);
3ae1acf93   David Teigland   [DLM] add lock ti...
4453
  		add_timeout(lkb);
e7fd41792   David Teigland   [DLM] The core of...
4454
4455
4456
4457
4458
  		break;
  
  	case 0:
  		/* convert was granted on remote master */
  		receive_flags_reply(lkb, ms);
7d3c1feb8   David Teigland   [DLM] fix mode mu...
4459
  		if (is_demoted(lkb))
2a7ce0edd   David Teigland   dlm: remove share...
4460
  			munge_demoted(lkb);
e7fd41792   David Teigland   [DLM] The core of...
4461
4462
4463
4464
4465
  		grant_lock_pc(r, lkb, ms);
  		queue_cast(r, lkb, 0);
  		break;
  
  	default:
6d40c4a70   David Teigland   dlm: improve erro...
4466
4467
4468
4469
4470
  		log_error(r->res_ls, "receive_convert_reply %x remote %d %x %d",
  			  lkb->lkb_id, ms->m_header.h_nodeid, ms->m_lkid,
  			  ms->m_result);
  		dlm_print_rsb(r);
  		dlm_print_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
4471
4472
4473
4474
4475
4476
  	}
  }
  
  static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	struct dlm_rsb *r = lkb->lkb_resource;
ef0c2bb05   David Teigland   [DLM] overlapping...
4477
  	int error;
e7fd41792   David Teigland   [DLM] The core of...
4478
4479
4480
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4481
4482
4483
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
4484
4485
4486
4487
  	/* stub reply can happen with waiters_mutex held */
  	error = remove_from_waiters_ms(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4488

ef0c2bb05   David Teigland   [DLM] overlapping...
4489
4490
  	__receive_convert_reply(r, lkb, ms);
   out:
e7fd41792   David Teigland   [DLM] The core of...
4491
4492
4493
  	unlock_rsb(r);
  	put_rsb(r);
  }
6d40c4a70   David Teigland   dlm: improve erro...
4494
  static int receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4495
4496
4497
4498
4499
  {
  	struct dlm_lkb *lkb;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4500
4501
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4502

e7fd41792   David Teigland   [DLM] The core of...
4503
  	_receive_convert_reply(lkb, ms);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4504
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4505
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4506
4507
4508
4509
4510
  }
  
  static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	struct dlm_rsb *r = lkb->lkb_resource;
ef0c2bb05   David Teigland   [DLM] overlapping...
4511
  	int error;
e7fd41792   David Teigland   [DLM] The core of...
4512
4513
4514
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4515
4516
4517
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
4518
4519
4520
4521
  	/* stub reply can happen with waiters_mutex held */
  	error = remove_from_waiters_ms(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4522
  	/* this is the value returned from do_unlock() on the master */
ef0c2bb05   David Teigland   [DLM] overlapping...
4523
  	switch (ms->m_result) {
e7fd41792   David Teigland   [DLM] The core of...
4524
4525
4526
4527
4528
  	case -DLM_EUNLOCK:
  		receive_flags_reply(lkb, ms);
  		remove_lock_pc(r, lkb);
  		queue_cast(r, lkb, -DLM_EUNLOCK);
  		break;
ef0c2bb05   David Teigland   [DLM] overlapping...
4529
4530
  	case -ENOENT:
  		break;
e7fd41792   David Teigland   [DLM] The core of...
4531
  	default:
ef0c2bb05   David Teigland   [DLM] overlapping...
4532
4533
  		log_error(r->res_ls, "receive_unlock_reply %x error %d",
  			  lkb->lkb_id, ms->m_result);
e7fd41792   David Teigland   [DLM] The core of...
4534
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4535
   out:
e7fd41792   David Teigland   [DLM] The core of...
4536
4537
4538
  	unlock_rsb(r);
  	put_rsb(r);
  }
6d40c4a70   David Teigland   dlm: improve erro...
4539
  static int receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4540
4541
4542
4543
4544
  {
  	struct dlm_lkb *lkb;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4545
4546
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4547

e7fd41792   David Teigland   [DLM] The core of...
4548
  	_receive_unlock_reply(lkb, ms);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4549
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4550
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4551
4552
4553
4554
4555
  }
  
  static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
  {
  	struct dlm_rsb *r = lkb->lkb_resource;
ef0c2bb05   David Teigland   [DLM] overlapping...
4556
  	int error;
e7fd41792   David Teigland   [DLM] The core of...
4557
4558
4559
  
  	hold_rsb(r);
  	lock_rsb(r);
c54e04b00   David Teigland   dlm: validate mes...
4560
4561
4562
  	error = validate_message(lkb, ms);
  	if (error)
  		goto out;
ef0c2bb05   David Teigland   [DLM] overlapping...
4563
4564
4565
4566
  	/* stub reply can happen with waiters_mutex held */
  	error = remove_from_waiters_ms(lkb, ms);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4567
  	/* this is the value returned from do_cancel() on the master */
ef0c2bb05   David Teigland   [DLM] overlapping...
4568
  	switch (ms->m_result) {
e7fd41792   David Teigland   [DLM] The core of...
4569
4570
4571
  	case -DLM_ECANCEL:
  		receive_flags_reply(lkb, ms);
  		revert_lock_pc(r, lkb);
84d8cd69a   David Teigland   [DLM] timeout fixes
4572
  		queue_cast(r, lkb, -DLM_ECANCEL);
ef0c2bb05   David Teigland   [DLM] overlapping...
4573
4574
  		break;
  	case 0:
e7fd41792   David Teigland   [DLM] The core of...
4575
4576
  		break;
  	default:
ef0c2bb05   David Teigland   [DLM] overlapping...
4577
4578
  		log_error(r->res_ls, "receive_cancel_reply %x error %d",
  			  lkb->lkb_id, ms->m_result);
e7fd41792   David Teigland   [DLM] The core of...
4579
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4580
   out:
e7fd41792   David Teigland   [DLM] The core of...
4581
4582
4583
  	unlock_rsb(r);
  	put_rsb(r);
  }
6d40c4a70   David Teigland   dlm: improve erro...
4584
  static int receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms)
e7fd41792   David Teigland   [DLM] The core of...
4585
4586
4587
4588
4589
  {
  	struct dlm_lkb *lkb;
  	int error;
  
  	error = find_lkb(ls, ms->m_remid, &lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4590
4591
  	if (error)
  		return error;
e7fd41792   David Teigland   [DLM] The core of...
4592

e7fd41792   David Teigland   [DLM] The core of...
4593
  	_receive_cancel_reply(lkb, ms);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4594
  	dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
4595
  	return 0;
e7fd41792   David Teigland   [DLM] The core of...
4596
4597
4598
4599
4600
4601
4602
  }
  
  static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
  	int error, ret_nodeid;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4603
  	int do_lookup_list = 0;
e7fd41792   David Teigland   [DLM] The core of...
4604
4605
4606
  
  	error = find_lkb(ls, ms->m_lkid, &lkb);
  	if (error) {
6d40c4a70   David Teigland   dlm: improve erro...
4607
  		log_error(ls, "receive_lookup_reply no lkid %x", ms->m_lkid);
e7fd41792   David Teigland   [DLM] The core of...
4608
4609
  		return;
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4610
  	/* ms->m_result is the value returned by dlm_master_lookup on dir node
e7fd41792   David Teigland   [DLM] The core of...
4611
  	   FIXME: will a non-zero error ever be returned? */
e7fd41792   David Teigland   [DLM] The core of...
4612
4613
4614
4615
  
  	r = lkb->lkb_resource;
  	hold_rsb(r);
  	lock_rsb(r);
ef0c2bb05   David Teigland   [DLM] overlapping...
4616
4617
4618
  	error = remove_from_waiters(lkb, DLM_MSG_LOOKUP_REPLY);
  	if (error)
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
4619
  	ret_nodeid = ms->m_nodeid;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
  
  	/* We sometimes receive a request from the dir node for this
  	   rsb before we've received the dir node's loookup_reply for it.
  	   The request from the dir node implies we're the master, so we set
  	   ourself as master in receive_request_reply, and verify here that
  	   we are indeed the master. */
  
  	if (r->res_master_nodeid && (r->res_master_nodeid != ret_nodeid)) {
  		/* This should never happen */
  		log_error(ls, "receive_lookup_reply %x from %d ret %d "
  			  "master %d dir %d our %d first %x %s",
  			  lkb->lkb_id, ms->m_header.h_nodeid, ret_nodeid,
  			  r->res_master_nodeid, r->res_dir_nodeid,
  			  dlm_our_nodeid(), r->res_first_lkid, r->res_name);
  	}
e7fd41792   David Teigland   [DLM] The core of...
4635
  	if (ret_nodeid == dlm_our_nodeid()) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4636
  		r->res_master_nodeid = ret_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4637
  		r->res_nodeid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4638
  		do_lookup_list = 1;
e7fd41792   David Teigland   [DLM] The core of...
4639
  		r->res_first_lkid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4640
4641
4642
4643
4644
4645
4646
  	} else if (ret_nodeid == -1) {
  		/* the remote node doesn't believe it's the dir node */
  		log_error(ls, "receive_lookup_reply %x from %d bad ret_nodeid",
  			  lkb->lkb_id, ms->m_header.h_nodeid);
  		r->res_master_nodeid = 0;
  		r->res_nodeid = -1;
  		lkb->lkb_nodeid = -1;
e7fd41792   David Teigland   [DLM] The core of...
4647
  	} else {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4648
4649
  		/* set_master() will set lkb_nodeid from r */
  		r->res_master_nodeid = ret_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4650
4651
  		r->res_nodeid = ret_nodeid;
  	}
ef0c2bb05   David Teigland   [DLM] overlapping...
4652
4653
4654
4655
4656
4657
4658
  	if (is_overlap(lkb)) {
  		log_debug(ls, "receive_lookup_reply %x unlock %x",
  			  lkb->lkb_id, lkb->lkb_flags);
  		queue_cast_overlap(r, lkb);
  		unhold_lkb(lkb); /* undoes create_lkb() */
  		goto out_list;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4659
  	_request_lock(r, lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
4660
   out_list:
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4661
  	if (do_lookup_list)
e7fd41792   David Teigland   [DLM] The core of...
4662
  		process_lookup_list(r);
ef0c2bb05   David Teigland   [DLM] overlapping...
4663
   out:
e7fd41792   David Teigland   [DLM] The core of...
4664
4665
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
4666
  	dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
4667
  }
6d40c4a70   David Teigland   dlm: improve erro...
4668
4669
  static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms,
  			     uint32_t saved_seq)
e7fd41792   David Teigland   [DLM] The core of...
4670
  {
6d40c4a70   David Teigland   dlm: improve erro...
4671
  	int error = 0, noent = 0;
46b43eed7   David Teigland   dlm: reject messa...
4672
  	if (!dlm_is_member(ls, ms->m_header.h_nodeid)) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4673
  		log_limit(ls, "receive %d from non-member %d %x %x %d",
46b43eed7   David Teigland   dlm: reject messa...
4674
4675
4676
4677
  			  ms->m_type, ms->m_header.h_nodeid, ms->m_lkid,
  			  ms->m_remid, ms->m_result);
  		return;
  	}
e7fd41792   David Teigland   [DLM] The core of...
4678
4679
4680
4681
4682
  	switch (ms->m_type) {
  
  	/* messages sent to a master node */
  
  	case DLM_MSG_REQUEST:
6d40c4a70   David Teigland   dlm: improve erro...
4683
  		error = receive_request(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4684
4685
4686
  		break;
  
  	case DLM_MSG_CONVERT:
6d40c4a70   David Teigland   dlm: improve erro...
4687
  		error = receive_convert(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4688
4689
4690
  		break;
  
  	case DLM_MSG_UNLOCK:
6d40c4a70   David Teigland   dlm: improve erro...
4691
  		error = receive_unlock(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4692
4693
4694
  		break;
  
  	case DLM_MSG_CANCEL:
6d40c4a70   David Teigland   dlm: improve erro...
4695
4696
  		noent = 1;
  		error = receive_cancel(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4697
4698
4699
4700
4701
  		break;
  
  	/* messages sent from a master node (replies to above) */
  
  	case DLM_MSG_REQUEST_REPLY:
6d40c4a70   David Teigland   dlm: improve erro...
4702
  		error = receive_request_reply(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4703
4704
4705
  		break;
  
  	case DLM_MSG_CONVERT_REPLY:
6d40c4a70   David Teigland   dlm: improve erro...
4706
  		error = receive_convert_reply(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4707
4708
4709
  		break;
  
  	case DLM_MSG_UNLOCK_REPLY:
6d40c4a70   David Teigland   dlm: improve erro...
4710
  		error = receive_unlock_reply(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4711
4712
4713
  		break;
  
  	case DLM_MSG_CANCEL_REPLY:
6d40c4a70   David Teigland   dlm: improve erro...
4714
  		error = receive_cancel_reply(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4715
4716
4717
4718
4719
  		break;
  
  	/* messages sent from a master node (only two types of async msg) */
  
  	case DLM_MSG_GRANT:
6d40c4a70   David Teigland   dlm: improve erro...
4720
4721
  		noent = 1;
  		error = receive_grant(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4722
4723
4724
  		break;
  
  	case DLM_MSG_BAST:
6d40c4a70   David Teigland   dlm: improve erro...
4725
4726
  		noent = 1;
  		error = receive_bast(ls, ms);
e7fd41792   David Teigland   [DLM] The core of...
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
  		break;
  
  	/* messages sent to a dir node */
  
  	case DLM_MSG_LOOKUP:
  		receive_lookup(ls, ms);
  		break;
  
  	case DLM_MSG_REMOVE:
  		receive_remove(ls, ms);
  		break;
  
  	/* messages sent from a dir node (remove has no reply) */
  
  	case DLM_MSG_LOOKUP_REPLY:
  		receive_lookup_reply(ls, ms);
  		break;
8499137d4   David Teigland   [DLM] add orphan ...
4744
4745
4746
4747
4748
  	/* other messages */
  
  	case DLM_MSG_PURGE:
  		receive_purge(ls, ms);
  		break;
e7fd41792   David Teigland   [DLM] The core of...
4749
4750
4751
  	default:
  		log_error(ls, "unknown message type %d", ms->m_type);
  	}
6d40c4a70   David Teigland   dlm: improve erro...
4752
4753
4754
4755
4756
4757
4758
4759
4760
  
  	/*
  	 * When checking for ENOENT, we're checking the result of
  	 * find_lkb(m_remid):
  	 *
  	 * The lock id referenced in the message wasn't found.  This may
  	 * happen in normal usage for the async messages and cancel, so
  	 * only use log_debug for them.
  	 *
4875647a0   David Teigland   dlm: fixes for no...
4761
  	 * Some errors are expected and normal.
6d40c4a70   David Teigland   dlm: improve erro...
4762
4763
4764
  	 */
  
  	if (error == -ENOENT && noent) {
4875647a0   David Teigland   dlm: fixes for no...
4765
  		log_debug(ls, "receive %d no %x remote %d %x saved_seq %u",
6d40c4a70   David Teigland   dlm: improve erro...
4766
4767
4768
  			  ms->m_type, ms->m_remid, ms->m_header.h_nodeid,
  			  ms->m_lkid, saved_seq);
  	} else if (error == -ENOENT) {
4875647a0   David Teigland   dlm: fixes for no...
4769
  		log_error(ls, "receive %d no %x remote %d %x saved_seq %u",
6d40c4a70   David Teigland   dlm: improve erro...
4770
4771
4772
4773
4774
4775
  			  ms->m_type, ms->m_remid, ms->m_header.h_nodeid,
  			  ms->m_lkid, saved_seq);
  
  		if (ms->m_type == DLM_MSG_CONVERT)
  			dlm_dump_rsb_hash(ls, ms->m_hash);
  	}
4875647a0   David Teigland   dlm: fixes for no...
4776
4777
4778
4779
4780
4781
4782
  
  	if (error == -EINVAL) {
  		log_error(ls, "receive %d inval from %d lkid %x remid %x "
  			  "saved_seq %u",
  			  ms->m_type, ms->m_header.h_nodeid,
  			  ms->m_lkid, ms->m_remid, saved_seq);
  	}
e7fd41792   David Teigland   [DLM] The core of...
4783
  }
c36258b59   David Teigland   [DLM] block dlm_r...
4784
4785
4786
4787
4788
4789
4790
  /* If the lockspace is in recovery mode (locking stopped), then normal
     messages are saved on the requestqueue for processing after recovery is
     done.  When not in recovery mode, we wait for dlm_recoverd to drain saved
     messages off the requestqueue before we process new ones. This occurs right
     after recovery completes when we transition from saving all messages on
     requestqueue, to processing all the saved messages, to processing new
     messages as they arrive. */
e7fd41792   David Teigland   [DLM] The core of...
4791

c36258b59   David Teigland   [DLM] block dlm_r...
4792
4793
4794
4795
  static void dlm_receive_message(struct dlm_ls *ls, struct dlm_message *ms,
  				int nodeid)
  {
  	if (dlm_locking_stopped(ls)) {
c04fecb4d   David Teigland   dlm: use rsbtbl a...
4796
4797
4798
4799
4800
4801
4802
4803
  		/* If we were a member of this lockspace, left, and rejoined,
  		   other nodes may still be sending us messages from the
  		   lockspace generation before we left. */
  		if (!ls->ls_generation) {
  			log_limit(ls, "receive %d from %d ignore old gen",
  				  ms->m_type, nodeid);
  			return;
  		}
8b0d8e03f   Al Viro   dlm: use proper C...
4804
  		dlm_add_requestqueue(ls, nodeid, ms);
c36258b59   David Teigland   [DLM] block dlm_r...
4805
4806
  	} else {
  		dlm_wait_requestqueue(ls);
6d40c4a70   David Teigland   dlm: improve erro...
4807
  		_receive_message(ls, ms, 0);
c36258b59   David Teigland   [DLM] block dlm_r...
4808
4809
4810
4811
4812
  	}
  }
  
  /* This is called by dlm_recoverd to process messages that were saved on
     the requestqueue. */
6d40c4a70   David Teigland   dlm: improve erro...
4813
4814
  void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms,
  			       uint32_t saved_seq)
c36258b59   David Teigland   [DLM] block dlm_r...
4815
  {
6d40c4a70   David Teigland   dlm: improve erro...
4816
  	_receive_message(ls, ms, saved_seq);
c36258b59   David Teigland   [DLM] block dlm_r...
4817
4818
4819
4820
4821
4822
  }
  
  /* This is called by the midcomms layer when something is received for
     the lockspace.  It could be either a MSG (normal message sent as part of
     standard locking activity) or an RCOM (recovery message sent as part of
     lockspace recovery). */
eef7d739c   Al Viro   dlm: dlm_process_...
4823
  void dlm_receive_buffer(union dlm_packet *p, int nodeid)
c36258b59   David Teigland   [DLM] block dlm_r...
4824
  {
eef7d739c   Al Viro   dlm: dlm_process_...
4825
  	struct dlm_header *hd = &p->header;
c36258b59   David Teigland   [DLM] block dlm_r...
4826
4827
4828
4829
4830
  	struct dlm_ls *ls;
  	int type = 0;
  
  	switch (hd->h_cmd) {
  	case DLM_MSG:
eef7d739c   Al Viro   dlm: dlm_process_...
4831
4832
  		dlm_message_in(&p->message);
  		type = p->message.m_type;
c36258b59   David Teigland   [DLM] block dlm_r...
4833
4834
  		break;
  	case DLM_RCOM:
eef7d739c   Al Viro   dlm: dlm_process_...
4835
4836
  		dlm_rcom_in(&p->rcom);
  		type = p->rcom.rc_type;
c36258b59   David Teigland   [DLM] block dlm_r...
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
  		break;
  	default:
  		log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid);
  		return;
  	}
  
  	if (hd->h_nodeid != nodeid) {
  		log_print("invalid h_nodeid %d from %d lockspace %x",
  			  hd->h_nodeid, nodeid, hd->h_lockspace);
  		return;
  	}
  
  	ls = dlm_find_lockspace_global(hd->h_lockspace);
  	if (!ls) {
4875647a0   David Teigland   dlm: fixes for no...
4851
4852
4853
4854
4855
4856
  		if (dlm_config.ci_log_debug) {
  			printk_ratelimited(KERN_DEBUG "dlm: invalid lockspace "
  				"%u from %d cmd %d type %d
  ",
  				hd->h_lockspace, nodeid, hd->h_cmd, type);
  		}
c36258b59   David Teigland   [DLM] block dlm_r...
4857
4858
  
  		if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
eef7d739c   Al Viro   dlm: dlm_process_...
4859
  			dlm_send_ls_not_ready(nodeid, &p->rcom);
c36258b59   David Teigland   [DLM] block dlm_r...
4860
4861
4862
4863
4864
4865
4866
4867
  		return;
  	}
  
  	/* this rwsem allows dlm_ls_stop() to wait for all dlm_recv threads to
  	   be inactive (in this ls) before transitioning to recovery mode */
  
  	down_read(&ls->ls_recv_active);
  	if (hd->h_cmd == DLM_MSG)
eef7d739c   Al Viro   dlm: dlm_process_...
4868
  		dlm_receive_message(ls, &p->message, nodeid);
c36258b59   David Teigland   [DLM] block dlm_r...
4869
  	else
eef7d739c   Al Viro   dlm: dlm_process_...
4870
  		dlm_receive_rcom(ls, &p->rcom, nodeid);
c36258b59   David Teigland   [DLM] block dlm_r...
4871
4872
4873
4874
  	up_read(&ls->ls_recv_active);
  
  	dlm_put_lockspace(ls);
  }
e7fd41792   David Teigland   [DLM] The core of...
4875

2a7ce0edd   David Teigland   dlm: remove share...
4876
4877
  static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb,
  				   struct dlm_message *ms_stub)
e7fd41792   David Teigland   [DLM] The core of...
4878
4879
4880
  {
  	if (middle_conversion(lkb)) {
  		hold_lkb(lkb);
2a7ce0edd   David Teigland   dlm: remove share...
4881
4882
4883
4884
4885
4886
  		memset(ms_stub, 0, sizeof(struct dlm_message));
  		ms_stub->m_flags = DLM_IFL_STUB_MS;
  		ms_stub->m_type = DLM_MSG_CONVERT_REPLY;
  		ms_stub->m_result = -EINPROGRESS;
  		ms_stub->m_header.h_nodeid = lkb->lkb_nodeid;
  		_receive_convert_reply(lkb, ms_stub);
e7fd41792   David Teigland   [DLM] The core of...
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
  
  		/* Same special case as in receive_rcom_lock_args() */
  		lkb->lkb_grmode = DLM_LOCK_IV;
  		rsb_set_flag(lkb->lkb_resource, RSB_RECOVER_CONVERT);
  		unhold_lkb(lkb);
  
  	} else if (lkb->lkb_rqmode >= lkb->lkb_grmode) {
  		lkb->lkb_flags |= DLM_IFL_RESEND;
  	}
  
  	/* lkb->lkb_rqmode < lkb->lkb_grmode shouldn't happen since down
  	   conversions are async; there's no reply from the remote master */
  }
  
  /* A waiting lkb needs recovery if the master node has failed, or
     the master node is changing (only when no directory is used) */
13ef11110   David Teigland   dlm: fix waiter r...
4903
4904
  static int waiter_needs_recovery(struct dlm_ls *ls, struct dlm_lkb *lkb,
  				 int dir_nodeid)
e7fd41792   David Teigland   [DLM] The core of...
4905
  {
4875647a0   David Teigland   dlm: fixes for no...
4906
  	if (dlm_no_directory(ls))
13ef11110   David Teigland   dlm: fix waiter r...
4907
  		return 1;
4875647a0   David Teigland   dlm: fixes for no...
4908
  	if (dlm_is_removed(ls, lkb->lkb_wait_nodeid))
e7fd41792   David Teigland   [DLM] The core of...
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
  		return 1;
  
  	return 0;
  }
  
  /* Recovery for locks that are waiting for replies from nodes that are now
     gone.  We can just complete unlocks and cancels by faking a reply from the
     dead node.  Requests and up-conversions we flag to be resent after
     recovery.  Down-conversions can just be completed with a fake reply like
     unlocks.  Conversions between PR and CW need special attention. */
  
  void dlm_recover_waiters_pre(struct dlm_ls *ls)
  {
  	struct dlm_lkb *lkb, *safe;
2a7ce0edd   David Teigland   dlm: remove share...
4923
  	struct dlm_message *ms_stub;
601342ce0   David Teigland   dlm: recover lock...
4924
  	int wait_type, stub_unlock_result, stub_cancel_result;
13ef11110   David Teigland   dlm: fix waiter r...
4925
  	int dir_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
4926

102e67d4e   Markus Elfring   dlm: Improve a si...
4927
  	ms_stub = kmalloc(sizeof(*ms_stub), GFP_KERNEL);
0d37eca75   Markus Elfring   dlm: Delete an er...
4928
  	if (!ms_stub)
2a7ce0edd   David Teigland   dlm: remove share...
4929
  		return;
2a7ce0edd   David Teigland   dlm: remove share...
4930

901359256   David Teigland   [DLM] Update DLM ...
4931
  	mutex_lock(&ls->ls_waiters_mutex);
e7fd41792   David Teigland   [DLM] The core of...
4932
4933
  
  	list_for_each_entry_safe(lkb, safe, &ls->ls_waiters, lkb_wait_reply) {
2a7ce0edd   David Teigland   dlm: remove share...
4934

13ef11110   David Teigland   dlm: fix waiter r...
4935
  		dir_nodeid = dlm_dir_nodeid(lkb->lkb_resource);
2a7ce0edd   David Teigland   dlm: remove share...
4936
4937
4938
4939
  		/* exclude debug messages about unlocks because there can be so
  		   many and they aren't very interesting */
  
  		if (lkb->lkb_wait_type != DLM_MSG_UNLOCK) {
13ef11110   David Teigland   dlm: fix waiter r...
4940
4941
4942
4943
4944
4945
4946
4947
4948
  			log_debug(ls, "waiter %x remote %x msg %d r_nodeid %d "
  				  "lkb_nodeid %d wait_nodeid %d dir_nodeid %d",
  				  lkb->lkb_id,
  				  lkb->lkb_remid,
  				  lkb->lkb_wait_type,
  				  lkb->lkb_resource->res_nodeid,
  				  lkb->lkb_nodeid,
  				  lkb->lkb_wait_nodeid,
  				  dir_nodeid);
2a7ce0edd   David Teigland   dlm: remove share...
4949
  		}
e7fd41792   David Teigland   [DLM] The core of...
4950
4951
4952
4953
4954
4955
4956
4957
  
  		/* all outstanding lookups, regardless of destination  will be
  		   resent after recovery is done */
  
  		if (lkb->lkb_wait_type == DLM_MSG_LOOKUP) {
  			lkb->lkb_flags |= DLM_IFL_RESEND;
  			continue;
  		}
13ef11110   David Teigland   dlm: fix waiter r...
4958
  		if (!waiter_needs_recovery(ls, lkb, dir_nodeid))
e7fd41792   David Teigland   [DLM] The core of...
4959
  			continue;
601342ce0   David Teigland   dlm: recover lock...
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
  		wait_type = lkb->lkb_wait_type;
  		stub_unlock_result = -DLM_EUNLOCK;
  		stub_cancel_result = -DLM_ECANCEL;
  
  		/* Main reply may have been received leaving a zero wait_type,
  		   but a reply for the overlapping op may not have been
  		   received.  In that case we need to fake the appropriate
  		   reply for the overlap op. */
  
  		if (!wait_type) {
  			if (is_overlap_cancel(lkb)) {
  				wait_type = DLM_MSG_CANCEL;
  				if (lkb->lkb_grmode == DLM_LOCK_IV)
  					stub_cancel_result = 0;
  			}
  			if (is_overlap_unlock(lkb)) {
  				wait_type = DLM_MSG_UNLOCK;
  				if (lkb->lkb_grmode == DLM_LOCK_IV)
  					stub_unlock_result = -ENOENT;
  			}
  
  			log_debug(ls, "rwpre overlap %x %x %d %d %d",
  				  lkb->lkb_id, lkb->lkb_flags, wait_type,
  				  stub_cancel_result, stub_unlock_result);
  		}
  
  		switch (wait_type) {
e7fd41792   David Teigland   [DLM] The core of...
4987
4988
4989
4990
4991
4992
  
  		case DLM_MSG_REQUEST:
  			lkb->lkb_flags |= DLM_IFL_RESEND;
  			break;
  
  		case DLM_MSG_CONVERT:
2a7ce0edd   David Teigland   dlm: remove share...
4993
  			recover_convert_waiter(ls, lkb, ms_stub);
e7fd41792   David Teigland   [DLM] The core of...
4994
4995
4996
4997
  			break;
  
  		case DLM_MSG_UNLOCK:
  			hold_lkb(lkb);
2a7ce0edd   David Teigland   dlm: remove share...
4998
4999
5000
5001
5002
5003
  			memset(ms_stub, 0, sizeof(struct dlm_message));
  			ms_stub->m_flags = DLM_IFL_STUB_MS;
  			ms_stub->m_type = DLM_MSG_UNLOCK_REPLY;
  			ms_stub->m_result = stub_unlock_result;
  			ms_stub->m_header.h_nodeid = lkb->lkb_nodeid;
  			_receive_unlock_reply(lkb, ms_stub);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
5004
  			dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
5005
5006
5007
5008
  			break;
  
  		case DLM_MSG_CANCEL:
  			hold_lkb(lkb);
2a7ce0edd   David Teigland   dlm: remove share...
5009
5010
5011
5012
5013
5014
  			memset(ms_stub, 0, sizeof(struct dlm_message));
  			ms_stub->m_flags = DLM_IFL_STUB_MS;
  			ms_stub->m_type = DLM_MSG_CANCEL_REPLY;
  			ms_stub->m_result = stub_cancel_result;
  			ms_stub->m_header.h_nodeid = lkb->lkb_nodeid;
  			_receive_cancel_reply(lkb, ms_stub);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
5015
  			dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
5016
5017
5018
  			break;
  
  		default:
601342ce0   David Teigland   dlm: recover lock...
5019
5020
  			log_error(ls, "invalid lkb wait_type %d %d",
  				  lkb->lkb_wait_type, wait_type);
e7fd41792   David Teigland   [DLM] The core of...
5021
  		}
81456807a   David Teigland   [DLM] schedule du...
5022
  		schedule();
e7fd41792   David Teigland   [DLM] The core of...
5023
  	}
901359256   David Teigland   [DLM] Update DLM ...
5024
  	mutex_unlock(&ls->ls_waiters_mutex);
2a7ce0edd   David Teigland   dlm: remove share...
5025
  	kfree(ms_stub);
e7fd41792   David Teigland   [DLM] The core of...
5026
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
5027
  static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
5028
5029
  {
  	struct dlm_lkb *lkb;
ef0c2bb05   David Teigland   [DLM] overlapping...
5030
  	int found = 0;
e7fd41792   David Teigland   [DLM] The core of...
5031

901359256   David Teigland   [DLM] Update DLM ...
5032
  	mutex_lock(&ls->ls_waiters_mutex);
e7fd41792   David Teigland   [DLM] The core of...
5033
5034
  	list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
  		if (lkb->lkb_flags & DLM_IFL_RESEND) {
ef0c2bb05   David Teigland   [DLM] overlapping...
5035
5036
  			hold_lkb(lkb);
  			found = 1;
e7fd41792   David Teigland   [DLM] The core of...
5037
5038
5039
  			break;
  		}
  	}
901359256   David Teigland   [DLM] Update DLM ...
5040
  	mutex_unlock(&ls->ls_waiters_mutex);
e7fd41792   David Teigland   [DLM] The core of...
5041

ef0c2bb05   David Teigland   [DLM] overlapping...
5042
  	if (!found)
e7fd41792   David Teigland   [DLM] The core of...
5043
  		lkb = NULL;
ef0c2bb05   David Teigland   [DLM] overlapping...
5044
  	return lkb;
e7fd41792   David Teigland   [DLM] The core of...
5045
5046
5047
5048
5049
  }
  
  /* Deal with lookups and lkb's marked RESEND from _pre.  We may now be the
     master or dir-node for r.  Processing the lkb may result in it being placed
     back on waiters. */
ef0c2bb05   David Teigland   [DLM] overlapping...
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
  /* We do this after normal locking has been enabled and any saved messages
     (in requestqueue) have been processed.  We should be confident that at
     this point we won't get or process a reply to any of these waiting
     operations.  But, new ops may be coming in on the rsbs/locks here from
     userspace or remotely. */
  
  /* there may have been an overlap unlock/cancel prior to recovery or after
     recovery.  if before, the lkb may still have a pos wait_count; if after, the
     overlap flag would just have been set and nothing new sent.  we can be
     confident here than any replies to either the initial op or overlap ops
     prior to recovery have been received. */
e7fd41792   David Teigland   [DLM] The core of...
5061
5062
5063
5064
  int dlm_recover_waiters_post(struct dlm_ls *ls)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_rsb *r;
ef0c2bb05   David Teigland   [DLM] overlapping...
5065
  	int error = 0, mstype, err, oc, ou;
e7fd41792   David Teigland   [DLM] The core of...
5066
5067
5068
5069
5070
5071
5072
  
  	while (1) {
  		if (dlm_locking_stopped(ls)) {
  			log_debug(ls, "recover_waiters_post aborted");
  			error = -EINTR;
  			break;
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
5073
5074
  		lkb = find_resend_waiter(ls);
  		if (!lkb)
e7fd41792   David Teigland   [DLM] The core of...
5075
5076
5077
  			break;
  
  		r = lkb->lkb_resource;
ef0c2bb05   David Teigland   [DLM] overlapping...
5078
5079
5080
5081
5082
5083
5084
  		hold_rsb(r);
  		lock_rsb(r);
  
  		mstype = lkb->lkb_wait_type;
  		oc = is_overlap_cancel(lkb);
  		ou = is_overlap_unlock(lkb);
  		err = 0;
e7fd41792   David Teigland   [DLM] The core of...
5085

13ef11110   David Teigland   dlm: fix waiter r...
5086
5087
5088
5089
5090
  		log_debug(ls, "waiter %x remote %x msg %d r_nodeid %d "
  			  "lkb_nodeid %d wait_nodeid %d dir_nodeid %d "
  			  "overlap %d %d", lkb->lkb_id, lkb->lkb_remid, mstype,
  			  r->res_nodeid, lkb->lkb_nodeid, lkb->lkb_wait_nodeid,
  			  dlm_dir_nodeid(r), oc, ou);
e7fd41792   David Teigland   [DLM] The core of...
5091

ef0c2bb05   David Teigland   [DLM] overlapping...
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
  		/* At this point we assume that we won't get a reply to any
  		   previous op or overlap op on this lock.  First, do a big
  		   remove_from_waiters() for all previous ops. */
  
  		lkb->lkb_flags &= ~DLM_IFL_RESEND;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
  		lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
  		lkb->lkb_wait_type = 0;
  		lkb->lkb_wait_count = 0;
  		mutex_lock(&ls->ls_waiters_mutex);
  		list_del_init(&lkb->lkb_wait_reply);
  		mutex_unlock(&ls->ls_waiters_mutex);
  		unhold_lkb(lkb); /* for waiters list */
  
  		if (oc || ou) {
  			/* do an unlock or cancel instead of resending */
  			switch (mstype) {
  			case DLM_MSG_LOOKUP:
  			case DLM_MSG_REQUEST:
  				queue_cast(r, lkb, ou ? -DLM_EUNLOCK :
  							-DLM_ECANCEL);
  				unhold_lkb(lkb); /* undoes create_lkb() */
  				break;
  			case DLM_MSG_CONVERT:
  				if (oc) {
  					queue_cast(r, lkb, -DLM_ECANCEL);
  				} else {
  					lkb->lkb_exflags |= DLM_LKF_FORCEUNLOCK;
  					_unlock_lock(r, lkb);
  				}
  				break;
  			default:
  				err = 1;
  			}
  		} else {
  			switch (mstype) {
  			case DLM_MSG_LOOKUP:
  			case DLM_MSG_REQUEST:
  				_request_lock(r, lkb);
  				if (is_master(r))
  					confirm_master(r, 0);
  				break;
  			case DLM_MSG_CONVERT:
  				_convert_lock(r, lkb);
  				break;
  			default:
  				err = 1;
  			}
e7fd41792   David Teigland   [DLM] The core of...
5140
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
5141

13ef11110   David Teigland   dlm: fix waiter r...
5142
5143
5144
5145
5146
5147
  		if (err) {
  			log_error(ls, "waiter %x msg %d r_nodeid %d "
  				  "dir_nodeid %d overlap %d %d",
  				  lkb->lkb_id, mstype, r->res_nodeid,
  				  dlm_dir_nodeid(r), oc, ou);
  		}
ef0c2bb05   David Teigland   [DLM] overlapping...
5148
5149
5150
  		unlock_rsb(r);
  		put_rsb(r);
  		dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
5151
5152
5153
5154
  	}
  
  	return error;
  }
4875647a0   David Teigland   dlm: fixes for no...
5155
5156
  static void purge_mstcpy_list(struct dlm_ls *ls, struct dlm_rsb *r,
  			      struct list_head *list)
e7fd41792   David Teigland   [DLM] The core of...
5157
  {
e7fd41792   David Teigland   [DLM] The core of...
5158
  	struct dlm_lkb *lkb, *safe;
4875647a0   David Teigland   dlm: fixes for no...
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
  	list_for_each_entry_safe(lkb, safe, list, lkb_statequeue) {
  		if (!is_master_copy(lkb))
  			continue;
  
  		/* don't purge lkbs we've added in recover_master_copy for
  		   the current recovery seq */
  
  		if (lkb->lkb_recover_seq == ls->ls_recover_seq)
  			continue;
  
  		del_lkb(r, lkb);
  
  		/* this put should free the lkb */
  		if (!dlm_put_lkb(lkb))
  			log_error(ls, "purged mstcpy lkb not released");
e7fd41792   David Teigland   [DLM] The core of...
5174
5175
  	}
  }
4875647a0   David Teigland   dlm: fixes for no...
5176
  void dlm_purge_mstcpy_locks(struct dlm_rsb *r)
e7fd41792   David Teigland   [DLM] The core of...
5177
  {
4875647a0   David Teigland   dlm: fixes for no...
5178
  	struct dlm_ls *ls = r->res_ls;
e7fd41792   David Teigland   [DLM] The core of...
5179

4875647a0   David Teigland   dlm: fixes for no...
5180
5181
5182
  	purge_mstcpy_list(ls, r, &r->res_grantqueue);
  	purge_mstcpy_list(ls, r, &r->res_convertqueue);
  	purge_mstcpy_list(ls, r, &r->res_waitqueue);
e7fd41792   David Teigland   [DLM] The core of...
5183
  }
4875647a0   David Teigland   dlm: fixes for no...
5184
5185
5186
  static void purge_dead_list(struct dlm_ls *ls, struct dlm_rsb *r,
  			    struct list_head *list,
  			    int nodeid_gone, unsigned int *count)
e7fd41792   David Teigland   [DLM] The core of...
5187
  {
4875647a0   David Teigland   dlm: fixes for no...
5188
  	struct dlm_lkb *lkb, *safe;
e7fd41792   David Teigland   [DLM] The core of...
5189

4875647a0   David Teigland   dlm: fixes for no...
5190
5191
5192
5193
5194
5195
  	list_for_each_entry_safe(lkb, safe, list, lkb_statequeue) {
  		if (!is_master_copy(lkb))
  			continue;
  
  		if ((lkb->lkb_nodeid == nodeid_gone) ||
  		    dlm_is_removed(ls, lkb->lkb_nodeid)) {
da8c66638   David Teigland   dlm: fix lvb inva...
5196
5197
5198
5199
5200
5201
  			/* tell recover_lvb to invalidate the lvb
  			   because a node holding EX/PW failed */
  			if ((lkb->lkb_exflags & DLM_LKF_VALBLK) &&
  			    (lkb->lkb_grmode >= DLM_LOCK_PW)) {
  				rsb_set_flag(r, RSB_RECOVER_LVB_INVAL);
  			}
4875647a0   David Teigland   dlm: fixes for no...
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
  			del_lkb(r, lkb);
  
  			/* this put should free the lkb */
  			if (!dlm_put_lkb(lkb))
  				log_error(ls, "purged dead lkb not released");
  
  			rsb_set_flag(r, RSB_RECOVER_GRANT);
  
  			(*count)++;
  		}
  	}
e7fd41792   David Teigland   [DLM] The core of...
5213
5214
5215
  }
  
  /* Get rid of locks held by nodes that are gone. */
4875647a0   David Teigland   dlm: fixes for no...
5216
  void dlm_recover_purge(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
5217
5218
  {
  	struct dlm_rsb *r;
4875647a0   David Teigland   dlm: fixes for no...
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
  	struct dlm_member *memb;
  	int nodes_count = 0;
  	int nodeid_gone = 0;
  	unsigned int lkb_count = 0;
  
  	/* cache one removed nodeid to optimize the common
  	   case of a single node removed */
  
  	list_for_each_entry(memb, &ls->ls_nodes_gone, list) {
  		nodes_count++;
  		nodeid_gone = memb->nodeid;
  	}
e7fd41792   David Teigland   [DLM] The core of...
5231

4875647a0   David Teigland   dlm: fixes for no...
5232
5233
  	if (!nodes_count)
  		return;
e7fd41792   David Teigland   [DLM] The core of...
5234
5235
5236
5237
5238
  
  	down_write(&ls->ls_root_sem);
  	list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
  		hold_rsb(r);
  		lock_rsb(r);
4875647a0   David Teigland   dlm: fixes for no...
5239
5240
5241
5242
5243
5244
5245
5246
  		if (is_master(r)) {
  			purge_dead_list(ls, r, &r->res_grantqueue,
  					nodeid_gone, &lkb_count);
  			purge_dead_list(ls, r, &r->res_convertqueue,
  					nodeid_gone, &lkb_count);
  			purge_dead_list(ls, r, &r->res_waitqueue,
  					nodeid_gone, &lkb_count);
  		}
e7fd41792   David Teigland   [DLM] The core of...
5247
5248
  		unlock_rsb(r);
  		unhold_rsb(r);
4875647a0   David Teigland   dlm: fixes for no...
5249
  		cond_resched();
e7fd41792   David Teigland   [DLM] The core of...
5250
5251
  	}
  	up_write(&ls->ls_root_sem);
4875647a0   David Teigland   dlm: fixes for no...
5252
  	if (lkb_count)
075f01775   David Teigland   dlm: use INFO for...
5253
  		log_rinfo(ls, "dlm_recover_purge %u locks for %u nodes",
4875647a0   David Teigland   dlm: fixes for no...
5254
  			  lkb_count, nodes_count);
e7fd41792   David Teigland   [DLM] The core of...
5255
  }
4875647a0   David Teigland   dlm: fixes for no...
5256
  static struct dlm_rsb *find_grant_rsb(struct dlm_ls *ls, int bucket)
97a35d1e5   David Teigland   [DLM] fix grant_a...
5257
  {
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
5258
  	struct rb_node *n;
4875647a0   David Teigland   dlm: fixes for no...
5259
  	struct dlm_rsb *r;
97a35d1e5   David Teigland   [DLM] fix grant_a...
5260

c7be761a8   David Teigland   dlm: change rsbtb...
5261
  	spin_lock(&ls->ls_rsbtbl[bucket].lock);
9beb3bf5a   Bob Peterson   dlm: convert rsb ...
5262
5263
  	for (n = rb_first(&ls->ls_rsbtbl[bucket].keep); n; n = rb_next(n)) {
  		r = rb_entry(n, struct dlm_rsb, res_hashnode);
4875647a0   David Teigland   dlm: fixes for no...
5264
5265
5266
  
  		if (!rsb_flag(r, RSB_RECOVER_GRANT))
  			continue;
c503a6210   David Teigland   dlm: fix conversi...
5267
5268
  		if (!is_master(r)) {
  			rsb_clear_flag(r, RSB_RECOVER_GRANT);
97a35d1e5   David Teigland   [DLM] fix grant_a...
5269
  			continue;
c503a6210   David Teigland   dlm: fix conversi...
5270
  		}
97a35d1e5   David Teigland   [DLM] fix grant_a...
5271
  		hold_rsb(r);
4875647a0   David Teigland   dlm: fixes for no...
5272
5273
  		spin_unlock(&ls->ls_rsbtbl[bucket].lock);
  		return r;
97a35d1e5   David Teigland   [DLM] fix grant_a...
5274
  	}
c7be761a8   David Teigland   dlm: change rsbtb...
5275
  	spin_unlock(&ls->ls_rsbtbl[bucket].lock);
4875647a0   David Teigland   dlm: fixes for no...
5276
  	return NULL;
97a35d1e5   David Teigland   [DLM] fix grant_a...
5277
  }
4875647a0   David Teigland   dlm: fixes for no...
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
  /*
   * Attempt to grant locks on resources that we are the master of.
   * Locks may have become grantable during recovery because locks
   * from departed nodes have been purged (or not rebuilt), allowing
   * previously blocked locks to now be granted.  The subset of rsb's
   * we are interested in are those with lkb's on either the convert or
   * waiting queues.
   *
   * Simplest would be to go through each master rsb and check for non-empty
   * convert or waiting queues, and attempt to grant on those rsbs.
   * Checking the queues requires lock_rsb, though, for which we'd need
   * to release the rsbtbl lock.  This would make iterating through all
   * rsb's very inefficient.  So, we rely on earlier recovery routines
   * to set RECOVER_GRANT on any rsb's that we should attempt to grant
   * locks for.
   */
  
  void dlm_recover_grant(struct dlm_ls *ls)
e7fd41792   David Teigland   [DLM] The core of...
5296
5297
  {
  	struct dlm_rsb *r;
2b4e926aa   David Teigland   [DLM] fix loop in...
5298
  	int bucket = 0;
4875647a0   David Teigland   dlm: fixes for no...
5299
5300
5301
  	unsigned int count = 0;
  	unsigned int rsb_count = 0;
  	unsigned int lkb_count = 0;
e7fd41792   David Teigland   [DLM] The core of...
5302

2b4e926aa   David Teigland   [DLM] fix loop in...
5303
  	while (1) {
4875647a0   David Teigland   dlm: fixes for no...
5304
  		r = find_grant_rsb(ls, bucket);
2b4e926aa   David Teigland   [DLM] fix loop in...
5305
5306
5307
5308
  		if (!r) {
  			if (bucket == ls->ls_rsbtbl_size - 1)
  				break;
  			bucket++;
97a35d1e5   David Teigland   [DLM] fix grant_a...
5309
  			continue;
2b4e926aa   David Teigland   [DLM] fix loop in...
5310
  		}
4875647a0   David Teigland   dlm: fixes for no...
5311
5312
  		rsb_count++;
  		count = 0;
97a35d1e5   David Teigland   [DLM] fix grant_a...
5313
  		lock_rsb(r);
c503a6210   David Teigland   dlm: fix conversi...
5314
  		/* the RECOVER_GRANT flag is checked in the grant path */
4875647a0   David Teigland   dlm: fixes for no...
5315
  		grant_pending_locks(r, &count);
c503a6210   David Teigland   dlm: fix conversi...
5316
  		rsb_clear_flag(r, RSB_RECOVER_GRANT);
4875647a0   David Teigland   dlm: fixes for no...
5317
5318
  		lkb_count += count;
  		confirm_master(r, 0);
97a35d1e5   David Teigland   [DLM] fix grant_a...
5319
5320
  		unlock_rsb(r);
  		put_rsb(r);
4875647a0   David Teigland   dlm: fixes for no...
5321
  		cond_resched();
e7fd41792   David Teigland   [DLM] The core of...
5322
  	}
4875647a0   David Teigland   dlm: fixes for no...
5323
5324
  
  	if (lkb_count)
075f01775   David Teigland   dlm: use INFO for...
5325
  		log_rinfo(ls, "dlm_recover_grant %u locks on %u resources",
4875647a0   David Teigland   dlm: fixes for no...
5326
  			  lkb_count, rsb_count);
e7fd41792   David Teigland   [DLM] The core of...
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
  }
  
  static struct dlm_lkb *search_remid_list(struct list_head *head, int nodeid,
  					 uint32_t remid)
  {
  	struct dlm_lkb *lkb;
  
  	list_for_each_entry(lkb, head, lkb_statequeue) {
  		if (lkb->lkb_nodeid == nodeid && lkb->lkb_remid == remid)
  			return lkb;
  	}
  	return NULL;
  }
  
  static struct dlm_lkb *search_remid(struct dlm_rsb *r, int nodeid,
  				    uint32_t remid)
  {
  	struct dlm_lkb *lkb;
  
  	lkb = search_remid_list(&r->res_grantqueue, nodeid, remid);
  	if (lkb)
  		return lkb;
  	lkb = search_remid_list(&r->res_convertqueue, nodeid, remid);
  	if (lkb)
  		return lkb;
  	lkb = search_remid_list(&r->res_waitqueue, nodeid, remid);
  	if (lkb)
  		return lkb;
  	return NULL;
  }
ae773d0b7   Al Viro   dlm: verify that ...
5357
  /* needs at least dlm_rcom + rcom_lock */
e7fd41792   David Teigland   [DLM] The core of...
5358
5359
5360
5361
  static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
  				  struct dlm_rsb *r, struct dlm_rcom *rc)
  {
  	struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
e7fd41792   David Teigland   [DLM] The core of...
5362
5363
  
  	lkb->lkb_nodeid = rc->rc_header.h_nodeid;
163a1859e   Al Viro   dlm: do not bytes...
5364
5365
5366
5367
  	lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid);
  	lkb->lkb_remid = le32_to_cpu(rl->rl_lkid);
  	lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags);
  	lkb->lkb_flags = le32_to_cpu(rl->rl_flags) & 0x0000FFFF;
e7fd41792   David Teigland   [DLM] The core of...
5368
  	lkb->lkb_flags |= DLM_IFL_MSTCPY;
163a1859e   Al Viro   dlm: do not bytes...
5369
  	lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq);
e7fd41792   David Teigland   [DLM] The core of...
5370
5371
5372
  	lkb->lkb_rqmode = rl->rl_rqmode;
  	lkb->lkb_grmode = rl->rl_grmode;
  	/* don't set lkb_status because add_lkb wants to itself */
8304d6f24   David Teigland   dlm: record full ...
5373
5374
  	lkb->lkb_bastfn = (rl->rl_asts & DLM_CB_BAST) ? &fake_bastfn : NULL;
  	lkb->lkb_astfn = (rl->rl_asts & DLM_CB_CAST) ? &fake_astfn : NULL;
e7fd41792   David Teigland   [DLM] The core of...
5375

e7fd41792   David Teigland   [DLM] The core of...
5376
  	if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
a5dd06313   Al Viro   dlm: receive_rcom...
5377
5378
5379
5380
  		int lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
  			 sizeof(struct rcom_lock);
  		if (lvblen > ls->ls_lvblen)
  			return -EINVAL;
52bda2b5b   David Teigland   dlm: use dlm pref...
5381
  		lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
e7fd41792   David Teigland   [DLM] The core of...
5382
5383
  		if (!lkb->lkb_lvbptr)
  			return -ENOMEM;
e7fd41792   David Teigland   [DLM] The core of...
5384
5385
5386
5387
5388
5389
  		memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen);
  	}
  
  	/* Conversions between PR and CW (middle modes) need special handling.
  	   The real granted mode of these converting locks cannot be determined
  	   until all locks have been rebuilt on the rsb (recover_conversion) */
163a1859e   Al Viro   dlm: do not bytes...
5390
5391
  	if (rl->rl_wait_type == cpu_to_le16(DLM_MSG_CONVERT) &&
  	    middle_conversion(lkb)) {
e7fd41792   David Teigland   [DLM] The core of...
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
  		rl->rl_status = DLM_LKSTS_CONVERT;
  		lkb->lkb_grmode = DLM_LOCK_IV;
  		rsb_set_flag(r, RSB_RECOVER_CONVERT);
  	}
  
  	return 0;
  }
  
  /* This lkb may have been recovered in a previous aborted recovery so we need
     to check if the rsb already has an lkb with the given remote nodeid/lkid.
     If so we just send back a standard reply.  If not, we create a new lkb with
     the given values and send back our lkid.  We send back our lkid by sending
     back the rcom_lock struct we got but with the remid field filled in. */
ae773d0b7   Al Viro   dlm: verify that ...
5405
  /* needs at least dlm_rcom + rcom_lock */
e7fd41792   David Teigland   [DLM] The core of...
5406
5407
5408
5409
5410
  int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
  {
  	struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
  	struct dlm_rsb *r;
  	struct dlm_lkb *lkb;
6d40c4a70   David Teigland   dlm: improve erro...
5411
  	uint32_t remid = 0;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5412
  	int from_nodeid = rc->rc_header.h_nodeid;
e7fd41792   David Teigland   [DLM] The core of...
5413
5414
5415
5416
5417
5418
  	int error;
  
  	if (rl->rl_parent_lkid) {
  		error = -EOPNOTSUPP;
  		goto out;
  	}
6d40c4a70   David Teigland   dlm: improve erro...
5419
  	remid = le32_to_cpu(rl->rl_lkid);
4875647a0   David Teigland   dlm: fixes for no...
5420
5421
5422
5423
5424
5425
5426
  	/* In general we expect the rsb returned to be R_MASTER, but we don't
  	   have to require it.  Recovery of masters on one node can overlap
  	   recovery of locks on another node, so one node can send us MSTCPY
  	   locks before we've made ourselves master of this rsb.  We can still
  	   add new MSTCPY locks that we receive here without any harm; when
  	   we make ourselves master, dlm_recover_masters() won't touch the
  	   MSTCPY locks we've received early. */
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5427
5428
  	error = find_rsb(ls, rl->rl_name, le16_to_cpu(rl->rl_namelen),
  			 from_nodeid, R_RECEIVE_RECOVER, &r);
e7fd41792   David Teigland   [DLM] The core of...
5429
5430
  	if (error)
  		goto out;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5431
  	lock_rsb(r);
4875647a0   David Teigland   dlm: fixes for no...
5432
5433
  	if (dlm_no_directory(ls) && (dlm_dir_nodeid(r) != dlm_our_nodeid())) {
  		log_error(ls, "dlm_recover_master_copy remote %d %x not dir",
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5434
  			  from_nodeid, remid);
4875647a0   David Teigland   dlm: fixes for no...
5435
  		error = -EBADR;
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5436
  		goto out_unlock;
4875647a0   David Teigland   dlm: fixes for no...
5437
  	}
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5438
  	lkb = search_remid(r, from_nodeid, remid);
e7fd41792   David Teigland   [DLM] The core of...
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
  	if (lkb) {
  		error = -EEXIST;
  		goto out_remid;
  	}
  
  	error = create_lkb(ls, &lkb);
  	if (error)
  		goto out_unlock;
  
  	error = receive_rcom_lock_args(ls, lkb, r, rc);
  	if (error) {
b3f58d8f2   David Teigland   [DLM] Pass in loc...
5450
  		__put_lkb(ls, lkb);
e7fd41792   David Teigland   [DLM] The core of...
5451
5452
5453
5454
5455
5456
  		goto out_unlock;
  	}
  
  	attach_lkb(r, lkb);
  	add_lkb(r, lkb, rl->rl_status);
  	error = 0;
4875647a0   David Teigland   dlm: fixes for no...
5457
5458
5459
5460
  	ls->ls_recover_locks_in++;
  
  	if (!list_empty(&r->res_waitqueue) || !list_empty(&r->res_convertqueue))
  		rsb_set_flag(r, RSB_RECOVER_GRANT);
e7fd41792   David Teigland   [DLM] The core of...
5461
5462
5463
5464
  
   out_remid:
  	/* this is the new value returned to the lock holder for
  	   saving in its process-copy lkb */
163a1859e   Al Viro   dlm: do not bytes...
5465
  	rl->rl_remid = cpu_to_le32(lkb->lkb_id);
e7fd41792   David Teigland   [DLM] The core of...
5466

4875647a0   David Teigland   dlm: fixes for no...
5467
  	lkb->lkb_recover_seq = ls->ls_recover_seq;
e7fd41792   David Teigland   [DLM] The core of...
5468
5469
5470
5471
   out_unlock:
  	unlock_rsb(r);
  	put_rsb(r);
   out:
6d40c4a70   David Teigland   dlm: improve erro...
5472
  	if (error && error != -EEXIST)
075f01775   David Teigland   dlm: use INFO for...
5473
  		log_rinfo(ls, "dlm_recover_master_copy remote %d %x error %d",
c04fecb4d   David Teigland   dlm: use rsbtbl a...
5474
  			  from_nodeid, remid, error);
163a1859e   Al Viro   dlm: do not bytes...
5475
  	rl->rl_result = cpu_to_le32(error);
e7fd41792   David Teigland   [DLM] The core of...
5476
5477
  	return error;
  }
ae773d0b7   Al Viro   dlm: verify that ...
5478
  /* needs at least dlm_rcom + rcom_lock */
e7fd41792   David Teigland   [DLM] The core of...
5479
5480
5481
5482
5483
  int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
  {
  	struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
  	struct dlm_rsb *r;
  	struct dlm_lkb *lkb;
6d40c4a70   David Teigland   dlm: improve erro...
5484
5485
5486
5487
5488
5489
  	uint32_t lkid, remid;
  	int error, result;
  
  	lkid = le32_to_cpu(rl->rl_lkid);
  	remid = le32_to_cpu(rl->rl_remid);
  	result = le32_to_cpu(rl->rl_result);
e7fd41792   David Teigland   [DLM] The core of...
5490

6d40c4a70   David Teigland   dlm: improve erro...
5491
  	error = find_lkb(ls, lkid, &lkb);
e7fd41792   David Teigland   [DLM] The core of...
5492
  	if (error) {
6d40c4a70   David Teigland   dlm: improve erro...
5493
5494
  		log_error(ls, "dlm_recover_process_copy no %x remote %d %x %d",
  			  lkid, rc->rc_header.h_nodeid, remid, result);
e7fd41792   David Teigland   [DLM] The core of...
5495
5496
  		return error;
  	}
4875647a0   David Teigland   dlm: fixes for no...
5497
5498
5499
  	r = lkb->lkb_resource;
  	hold_rsb(r);
  	lock_rsb(r);
6d40c4a70   David Teigland   dlm: improve erro...
5500
5501
5502
  	if (!is_process_copy(lkb)) {
  		log_error(ls, "dlm_recover_process_copy bad %x remote %d %x %d",
  			  lkid, rc->rc_header.h_nodeid, remid, result);
4875647a0   David Teigland   dlm: fixes for no...
5503
5504
5505
5506
  		dlm_dump_rsb(r);
  		unlock_rsb(r);
  		put_rsb(r);
  		dlm_put_lkb(lkb);
6d40c4a70   David Teigland   dlm: improve erro...
5507
5508
  		return -EINVAL;
  	}
e7fd41792   David Teigland   [DLM] The core of...
5509

6d40c4a70   David Teigland   dlm: improve erro...
5510
  	switch (result) {
dc200a884   David Teigland   [DLM] fix resend ...
5511
5512
5513
5514
  	case -EBADR:
  		/* There's a chance the new master received our lock before
  		   dlm_recover_master_reply(), this wouldn't happen if we did
  		   a barrier between recover_masters and recover_locks. */
6d40c4a70   David Teigland   dlm: improve erro...
5515
5516
5517
5518
  
  		log_debug(ls, "dlm_recover_process_copy %x remote %d %x %d",
  			  lkid, rc->rc_header.h_nodeid, remid, result);
  	
dc200a884   David Teigland   [DLM] fix resend ...
5519
5520
  		dlm_send_rcom_lock(r, lkb);
  		goto out;
e7fd41792   David Teigland   [DLM] The core of...
5521
  	case -EEXIST:
e7fd41792   David Teigland   [DLM] The core of...
5522
  	case 0:
6d40c4a70   David Teigland   dlm: improve erro...
5523
  		lkb->lkb_remid = remid;
e7fd41792   David Teigland   [DLM] The core of...
5524
5525
  		break;
  	default:
6d40c4a70   David Teigland   dlm: improve erro...
5526
5527
  		log_error(ls, "dlm_recover_process_copy %x remote %d %x %d unk",
  			  lkid, rc->rc_header.h_nodeid, remid, result);
e7fd41792   David Teigland   [DLM] The core of...
5528
5529
5530
5531
5532
  	}
  
  	/* an ack for dlm_recover_locks() which waits for replies from
  	   all the locks it sends to new masters */
  	dlm_recovered_lock(r);
dc200a884   David Teigland   [DLM] fix resend ...
5533
   out:
e7fd41792   David Teigland   [DLM] The core of...
5534
5535
  	unlock_rsb(r);
  	put_rsb(r);
b3f58d8f2   David Teigland   [DLM] Pass in loc...
5536
  	dlm_put_lkb(lkb);
e7fd41792   David Teigland   [DLM] The core of...
5537
5538
5539
  
  	return 0;
  }
597d0cae0   David Teigland   [DLM] dlm: user l...
5540
5541
  int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
  		     int mode, uint32_t flags, void *name, unsigned int namelen,
d7db923ea   David Teigland   [DLM] dlm_device ...
5542
  		     unsigned long timeout_cs)
597d0cae0   David Teigland   [DLM] dlm: user l...
5543
5544
5545
5546
  {
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	int error;
85e86edf9   David Teigland   [DLM] block scand...
5547
  	dlm_lock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5548
5549
5550
5551
5552
5553
5554
5555
  
  	error = create_lkb(ls, &lkb);
  	if (error) {
  		kfree(ua);
  		goto out;
  	}
  
  	if (flags & DLM_LKF_VALBLK) {
573c24c4a   David Teigland   dlm: always use G...
5556
  		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
597d0cae0   David Teigland   [DLM] dlm: user l...
5557
5558
5559
5560
5561
5562
5563
  		if (!ua->lksb.sb_lvbptr) {
  			kfree(ua);
  			__put_lkb(ls, lkb);
  			error = -ENOMEM;
  			goto out;
  		}
  	}
d7db923ea   David Teigland   [DLM] dlm_device ...
5564
  	error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
e5dae548b   David Teigland   dlm: proper types...
5565
  			      fake_astfn, ua, fake_bastfn, &args);
597d0cae0   David Teigland   [DLM] dlm: user l...
5566
  	if (error) {
30d3dfd4c   Vasily Averin   dlm: memory leaks...
5567
5568
5569
  		kfree(ua->lksb.sb_lvbptr);
  		ua->lksb.sb_lvbptr = NULL;
  		kfree(ua);
597d0cae0   David Teigland   [DLM] dlm: user l...
5570
5571
5572
  		__put_lkb(ls, lkb);
  		goto out;
  	}
30d3dfd4c   Vasily Averin   dlm: memory leaks...
5573
5574
5575
5576
  	/* After ua is attached to lkb it will be freed by dlm_free_lkb().
  	   When DLM_IFL_USER is set, the dlm knows that this is a userspace
  	   lock and that lkb_astparam is the dlm_user_args structure. */
  	lkb->lkb_flags |= DLM_IFL_USER;
597d0cae0   David Teigland   [DLM] dlm: user l...
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
  	error = request_lock(ls, lkb, name, namelen, &args);
  
  	switch (error) {
  	case 0:
  		break;
  	case -EINPROGRESS:
  		error = 0;
  		break;
  	case -EAGAIN:
  		error = 0;
  		/* fall through */
  	default:
  		__put_lkb(ls, lkb);
  		goto out;
  	}
  
  	/* add this new lkb to the per-process list of locks */
  	spin_lock(&ua->proc->locks_spin);
ef0c2bb05   David Teigland   [DLM] overlapping...
5595
  	hold_lkb(lkb);
597d0cae0   David Teigland   [DLM] dlm: user l...
5596
5597
5598
  	list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
  	spin_unlock(&ua->proc->locks_spin);
   out:
85e86edf9   David Teigland   [DLM] block scand...
5599
  	dlm_unlock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5600
5601
5602
5603
  	return error;
  }
  
  int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
d7db923ea   David Teigland   [DLM] dlm_device ...
5604
5605
  		     int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
  		     unsigned long timeout_cs)
597d0cae0   David Teigland   [DLM] dlm: user l...
5606
5607
5608
5609
5610
  {
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	struct dlm_user_args *ua;
  	int error;
85e86edf9   David Teigland   [DLM] block scand...
5611
  	dlm_lock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5612
5613
5614
5615
5616
5617
5618
  
  	error = find_lkb(ls, lkid, &lkb);
  	if (error)
  		goto out;
  
  	/* user can change the params on its lock when it converts it, or
  	   add an lvb that didn't exist before */
d292c0cc4   David Teigland   dlm: eliminate as...
5619
  	ua = lkb->lkb_ua;
597d0cae0   David Teigland   [DLM] dlm: user l...
5620
5621
  
  	if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
573c24c4a   David Teigland   dlm: always use G...
5622
  		ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
597d0cae0   David Teigland   [DLM] dlm: user l...
5623
5624
5625
5626
5627
5628
5629
  		if (!ua->lksb.sb_lvbptr) {
  			error = -ENOMEM;
  			goto out_put;
  		}
  	}
  	if (lvb_in && ua->lksb.sb_lvbptr)
  		memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
d7db923ea   David Teigland   [DLM] dlm_device ...
5630
  	ua->xid = ua_tmp->xid;
597d0cae0   David Teigland   [DLM] dlm: user l...
5631
5632
5633
5634
  	ua->castparam = ua_tmp->castparam;
  	ua->castaddr = ua_tmp->castaddr;
  	ua->bastparam = ua_tmp->bastparam;
  	ua->bastaddr = ua_tmp->bastaddr;
10948eb4e   Patrick Caulfield   [DLM] preserve lk...
5635
  	ua->user_lksb = ua_tmp->user_lksb;
597d0cae0   David Teigland   [DLM] dlm: user l...
5636

d7db923ea   David Teigland   [DLM] dlm_device ...
5637
  	error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
e5dae548b   David Teigland   dlm: proper types...
5638
  			      fake_astfn, ua, fake_bastfn, &args);
597d0cae0   David Teigland   [DLM] dlm: user l...
5639
5640
5641
5642
  	if (error)
  		goto out_put;
  
  	error = convert_lock(ls, lkb, &args);
c85d65e91   David Teigland   [DLM] cancel in c...
5643
  	if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK)
597d0cae0   David Teigland   [DLM] dlm: user l...
5644
5645
5646
5647
  		error = 0;
   out_put:
  	dlm_put_lkb(lkb);
   out:
85e86edf9   David Teigland   [DLM] block scand...
5648
  	dlm_unlock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5649
5650
5651
  	kfree(ua_tmp);
  	return error;
  }
2ab4bd8ea   David Teigland   dlm: adopt orphan...
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
  /*
   * The caller asks for an orphan lock on a given resource with a given mode.
   * If a matching lock exists, it's moved to the owner's list of locks and
   * the lkid is returned.
   */
  
  int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
  		     int mode, uint32_t flags, void *name, unsigned int namelen,
  		     unsigned long timeout_cs, uint32_t *lkid)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_user_args *ua;
  	int found_other_mode = 0;
  	int found = 0;
  	int rv = 0;
  
  	mutex_lock(&ls->ls_orphans_mutex);
  	list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) {
  		if (lkb->lkb_resource->res_length != namelen)
  			continue;
  		if (memcmp(lkb->lkb_resource->res_name, name, namelen))
  			continue;
  		if (lkb->lkb_grmode != mode) {
  			found_other_mode = 1;
  			continue;
  		}
  
  		found = 1;
  		list_del_init(&lkb->lkb_ownqueue);
  		lkb->lkb_flags &= ~DLM_IFL_ORPHAN;
  		*lkid = lkb->lkb_id;
  		break;
  	}
  	mutex_unlock(&ls->ls_orphans_mutex);
  
  	if (!found && found_other_mode) {
  		rv = -EAGAIN;
  		goto out;
  	}
  
  	if (!found) {
  		rv = -ENOENT;
  		goto out;
  	}
  
  	lkb->lkb_exflags = flags;
  	lkb->lkb_ownpid = (int) current->pid;
  
  	ua = lkb->lkb_ua;
  
  	ua->proc = ua_tmp->proc;
  	ua->xid = ua_tmp->xid;
  	ua->castparam = ua_tmp->castparam;
  	ua->castaddr = ua_tmp->castaddr;
  	ua->bastparam = ua_tmp->bastparam;
  	ua->bastaddr = ua_tmp->bastaddr;
  	ua->user_lksb = ua_tmp->user_lksb;
  
  	/*
  	 * The lkb reference from the ls_orphans list was not
  	 * removed above, and is now considered the reference
  	 * for the proc locks list.
  	 */
  
  	spin_lock(&ua->proc->locks_spin);
  	list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
  	spin_unlock(&ua->proc->locks_spin);
   out:
  	kfree(ua_tmp);
  	return rv;
  }
597d0cae0   David Teigland   [DLM] dlm: user l...
5723
5724
5725
5726
5727
5728
5729
  int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
  		    uint32_t flags, uint32_t lkid, char *lvb_in)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	struct dlm_user_args *ua;
  	int error;
85e86edf9   David Teigland   [DLM] block scand...
5730
  	dlm_lock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5731
5732
5733
5734
  
  	error = find_lkb(ls, lkid, &lkb);
  	if (error)
  		goto out;
d292c0cc4   David Teigland   dlm: eliminate as...
5735
  	ua = lkb->lkb_ua;
597d0cae0   David Teigland   [DLM] dlm: user l...
5736
5737
5738
  
  	if (lvb_in && ua->lksb.sb_lvbptr)
  		memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
b434eda6f   Patrick Caulfield   [DLM] don't overw...
5739
5740
  	if (ua_tmp->castparam)
  		ua->castparam = ua_tmp->castparam;
cc346d555   Patrick Caulfield   [DLM] fix userlan...
5741
  	ua->user_lksb = ua_tmp->user_lksb;
597d0cae0   David Teigland   [DLM] dlm: user l...
5742
5743
5744
5745
5746
5747
5748
5749
5750
  
  	error = set_unlock_args(flags, ua, &args);
  	if (error)
  		goto out_put;
  
  	error = unlock_lock(ls, lkb, &args);
  
  	if (error == -DLM_EUNLOCK)
  		error = 0;
ef0c2bb05   David Teigland   [DLM] overlapping...
5751
5752
5753
  	/* from validate_unlock_args() */
  	if (error == -EBUSY && (flags & DLM_LKF_FORCEUNLOCK))
  		error = 0;
597d0cae0   David Teigland   [DLM] dlm: user l...
5754
5755
5756
5757
  	if (error)
  		goto out_put;
  
  	spin_lock(&ua->proc->locks_spin);
23e8e1aaa   David Teigland   dlm: use workqueu...
5758
  	/* dlm_user_add_cb() may have already taken lkb off the proc list */
a1bc86e6b   David Teigland   [DLM] fix user un...
5759
5760
  	if (!list_empty(&lkb->lkb_ownqueue))
  		list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
597d0cae0   David Teigland   [DLM] dlm: user l...
5761
  	spin_unlock(&ua->proc->locks_spin);
597d0cae0   David Teigland   [DLM] dlm: user l...
5762
5763
5764
   out_put:
  	dlm_put_lkb(lkb);
   out:
85e86edf9   David Teigland   [DLM] block scand...
5765
  	dlm_unlock_recovery(ls);
ef0c2bb05   David Teigland   [DLM] overlapping...
5766
  	kfree(ua_tmp);
597d0cae0   David Teigland   [DLM] dlm: user l...
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
  	return error;
  }
  
  int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
  		    uint32_t flags, uint32_t lkid)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	struct dlm_user_args *ua;
  	int error;
85e86edf9   David Teigland   [DLM] block scand...
5777
  	dlm_lock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5778
5779
5780
5781
  
  	error = find_lkb(ls, lkid, &lkb);
  	if (error)
  		goto out;
d292c0cc4   David Teigland   dlm: eliminate as...
5782
  	ua = lkb->lkb_ua;
b434eda6f   Patrick Caulfield   [DLM] don't overw...
5783
5784
  	if (ua_tmp->castparam)
  		ua->castparam = ua_tmp->castparam;
c059f70e3   Patrick Caulfield   [DLM] down conver...
5785
  	ua->user_lksb = ua_tmp->user_lksb;
597d0cae0   David Teigland   [DLM] dlm: user l...
5786
5787
5788
5789
5790
5791
5792
5793
5794
  
  	error = set_unlock_args(flags, ua, &args);
  	if (error)
  		goto out_put;
  
  	error = cancel_lock(ls, lkb, &args);
  
  	if (error == -DLM_ECANCEL)
  		error = 0;
ef0c2bb05   David Teigland   [DLM] overlapping...
5795
5796
5797
  	/* from validate_unlock_args() */
  	if (error == -EBUSY)
  		error = 0;
597d0cae0   David Teigland   [DLM] dlm: user l...
5798
5799
5800
   out_put:
  	dlm_put_lkb(lkb);
   out:
85e86edf9   David Teigland   [DLM] block scand...
5801
  	dlm_unlock_recovery(ls);
ef0c2bb05   David Teigland   [DLM] overlapping...
5802
  	kfree(ua_tmp);
597d0cae0   David Teigland   [DLM] dlm: user l...
5803
5804
  	return error;
  }
8b4021fa4   David Teigland   [DLM] canceling d...
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
  int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid)
  {
  	struct dlm_lkb *lkb;
  	struct dlm_args args;
  	struct dlm_user_args *ua;
  	struct dlm_rsb *r;
  	int error;
  
  	dlm_lock_recovery(ls);
  
  	error = find_lkb(ls, lkid, &lkb);
  	if (error)
  		goto out;
d292c0cc4   David Teigland   dlm: eliminate as...
5818
  	ua = lkb->lkb_ua;
8b4021fa4   David Teigland   [DLM] canceling d...
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
  
  	error = set_unlock_args(flags, ua, &args);
  	if (error)
  		goto out_put;
  
  	/* same as cancel_lock(), but set DEADLOCK_CANCEL after lock_rsb */
  
  	r = lkb->lkb_resource;
  	hold_rsb(r);
  	lock_rsb(r);
  
  	error = validate_unlock_args(lkb, &args);
  	if (error)
  		goto out_r;
  	lkb->lkb_flags |= DLM_IFL_DEADLOCK_CANCEL;
  
  	error = _cancel_lock(r, lkb);
   out_r:
  	unlock_rsb(r);
  	put_rsb(r);
  
  	if (error == -DLM_ECANCEL)
  		error = 0;
  	/* from validate_unlock_args() */
  	if (error == -EBUSY)
  		error = 0;
   out_put:
  	dlm_put_lkb(lkb);
   out:
  	dlm_unlock_recovery(ls);
  	return error;
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
5851
5852
  /* lkb's that are removed from the waiters list by revert are just left on the
     orphans list with the granted orphan locks, to be freed by purge */
597d0cae0   David Teigland   [DLM] dlm: user l...
5853
5854
  static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
  {
ef0c2bb05   David Teigland   [DLM] overlapping...
5855
5856
  	struct dlm_args args;
  	int error;
597d0cae0   David Teigland   [DLM] dlm: user l...
5857

2ab4bd8ea   David Teigland   dlm: adopt orphan...
5858
  	hold_lkb(lkb); /* reference for the ls_orphans list */
ef0c2bb05   David Teigland   [DLM] overlapping...
5859
5860
5861
  	mutex_lock(&ls->ls_orphans_mutex);
  	list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
  	mutex_unlock(&ls->ls_orphans_mutex);
597d0cae0   David Teigland   [DLM] dlm: user l...
5862

d292c0cc4   David Teigland   dlm: eliminate as...
5863
  	set_unlock_args(0, lkb->lkb_ua, &args);
ef0c2bb05   David Teigland   [DLM] overlapping...
5864
5865
5866
5867
5868
  
  	error = cancel_lock(ls, lkb, &args);
  	if (error == -DLM_ECANCEL)
  		error = 0;
  	return error;
597d0cae0   David Teigland   [DLM] dlm: user l...
5869
  }
da8c66638   David Teigland   dlm: fix lvb inva...
5870
5871
5872
5873
  /* The FORCEUNLOCK flag allows the unlock to go ahead even if the lkb isn't
     granted.  Regardless of what rsb queue the lock is on, it's removed and
     freed.  The IVVALBLK flag causes the lvb on the resource to be invalidated
     if our lock is PW/EX (it's ignored if our granted mode is smaller.) */
597d0cae0   David Teigland   [DLM] dlm: user l...
5874
5875
5876
  
  static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
  {
597d0cae0   David Teigland   [DLM] dlm: user l...
5877
5878
  	struct dlm_args args;
  	int error;
da8c66638   David Teigland   dlm: fix lvb inva...
5879
5880
  	set_unlock_args(DLM_LKF_FORCEUNLOCK | DLM_LKF_IVVALBLK,
  			lkb->lkb_ua, &args);
597d0cae0   David Teigland   [DLM] dlm: user l...
5881
5882
5883
5884
5885
5886
  
  	error = unlock_lock(ls, lkb, &args);
  	if (error == -DLM_EUNLOCK)
  		error = 0;
  	return error;
  }
ef0c2bb05   David Teigland   [DLM] overlapping...
5887
5888
  /* We have to release clear_proc_locks mutex before calling unlock_proc_lock()
     (which does lock_rsb) due to deadlock with receiving a message that does
23e8e1aaa   David Teigland   dlm: use workqueu...
5889
     lock_rsb followed by dlm_user_add_cb() */
ef0c2bb05   David Teigland   [DLM] overlapping...
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
  
  static struct dlm_lkb *del_proc_lock(struct dlm_ls *ls,
  				     struct dlm_user_proc *proc)
  {
  	struct dlm_lkb *lkb = NULL;
  
  	mutex_lock(&ls->ls_clear_proc_locks);
  	if (list_empty(&proc->locks))
  		goto out;
  
  	lkb = list_entry(proc->locks.next, struct dlm_lkb, lkb_ownqueue);
  	list_del_init(&lkb->lkb_ownqueue);
  
  	if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
  		lkb->lkb_flags |= DLM_IFL_ORPHAN;
  	else
  		lkb->lkb_flags |= DLM_IFL_DEAD;
   out:
  	mutex_unlock(&ls->ls_clear_proc_locks);
  	return lkb;
  }
23e8e1aaa   David Teigland   dlm: use workqueu...
5911
  /* The ls_clear_proc_locks mutex protects against dlm_user_add_cb() which
597d0cae0   David Teigland   [DLM] dlm: user l...
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
     1) references lkb->ua which we free here and 2) adds lkbs to proc->asts,
     which we clear here. */
  
  /* proc CLOSING flag is set so no more device_reads should look at proc->asts
     list, and no more device_writes should add lkb's to proc->locks list; so we
     shouldn't need to take asts_spin or locks_spin here.  this assumes that
     device reads/writes/closes are serialized -- FIXME: we may need to serialize
     them ourself. */
  
  void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
  {
  	struct dlm_lkb *lkb, *safe;
85e86edf9   David Teigland   [DLM] block scand...
5924
  	dlm_lock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5925

ef0c2bb05   David Teigland   [DLM] overlapping...
5926
5927
5928
5929
  	while (1) {
  		lkb = del_proc_lock(ls, proc);
  		if (!lkb)
  			break;
84d8cd69a   David Teigland   [DLM] timeout fixes
5930
  		del_timeout(lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
5931
  		if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
597d0cae0   David Teigland   [DLM] dlm: user l...
5932
  			orphan_proc_lock(ls, lkb);
ef0c2bb05   David Teigland   [DLM] overlapping...
5933
  		else
597d0cae0   David Teigland   [DLM] dlm: user l...
5934
  			unlock_proc_lock(ls, lkb);
597d0cae0   David Teigland   [DLM] dlm: user l...
5935
5936
5937
5938
5939
5940
5941
  
  		/* this removes the reference for the proc->locks list
  		   added by dlm_user_request, it may result in the lkb
  		   being freed */
  
  		dlm_put_lkb(lkb);
  	}
a1bc86e6b   David Teigland   [DLM] fix user un...
5942

ef0c2bb05   David Teigland   [DLM] overlapping...
5943
  	mutex_lock(&ls->ls_clear_proc_locks);
a1bc86e6b   David Teigland   [DLM] fix user un...
5944
5945
5946
5947
5948
5949
  	/* in-progress unlocks */
  	list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
  		list_del_init(&lkb->lkb_ownqueue);
  		lkb->lkb_flags |= DLM_IFL_DEAD;
  		dlm_put_lkb(lkb);
  	}
23e8e1aaa   David Teigland   dlm: use workqueu...
5950
  	list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_cb_list) {
8304d6f24   David Teigland   dlm: record full ...
5951
5952
  		memset(&lkb->lkb_callbacks, 0,
  		       sizeof(struct dlm_callback) * DLM_CALLBACKS_SIZE);
23e8e1aaa   David Teigland   dlm: use workqueu...
5953
  		list_del_init(&lkb->lkb_cb_list);
a1bc86e6b   David Teigland   [DLM] fix user un...
5954
5955
  		dlm_put_lkb(lkb);
  	}
597d0cae0   David Teigland   [DLM] dlm: user l...
5956
  	mutex_unlock(&ls->ls_clear_proc_locks);
85e86edf9   David Teigland   [DLM] block scand...
5957
  	dlm_unlock_recovery(ls);
597d0cae0   David Teigland   [DLM] dlm: user l...
5958
  }
a1bc86e6b   David Teigland   [DLM] fix user un...
5959

8499137d4   David Teigland   [DLM] add orphan ...
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
  static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
  {
  	struct dlm_lkb *lkb, *safe;
  
  	while (1) {
  		lkb = NULL;
  		spin_lock(&proc->locks_spin);
  		if (!list_empty(&proc->locks)) {
  			lkb = list_entry(proc->locks.next, struct dlm_lkb,
  					 lkb_ownqueue);
  			list_del_init(&lkb->lkb_ownqueue);
  		}
  		spin_unlock(&proc->locks_spin);
  
  		if (!lkb)
  			break;
  
  		lkb->lkb_flags |= DLM_IFL_DEAD;
  		unlock_proc_lock(ls, lkb);
  		dlm_put_lkb(lkb); /* ref from proc->locks list */
  	}
  
  	spin_lock(&proc->locks_spin);
  	list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
  		list_del_init(&lkb->lkb_ownqueue);
  		lkb->lkb_flags |= DLM_IFL_DEAD;
  		dlm_put_lkb(lkb);
  	}
  	spin_unlock(&proc->locks_spin);
  
  	spin_lock(&proc->asts_spin);
23e8e1aaa   David Teigland   dlm: use workqueu...
5991
  	list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_cb_list) {
8304d6f24   David Teigland   dlm: record full ...
5992
5993
  		memset(&lkb->lkb_callbacks, 0,
  		       sizeof(struct dlm_callback) * DLM_CALLBACKS_SIZE);
23e8e1aaa   David Teigland   dlm: use workqueu...
5994
  		list_del_init(&lkb->lkb_cb_list);
8499137d4   David Teigland   [DLM] add orphan ...
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
  		dlm_put_lkb(lkb);
  	}
  	spin_unlock(&proc->asts_spin);
  }
  
  /* pid of 0 means purge all orphans */
  
  static void do_purge(struct dlm_ls *ls, int nodeid, int pid)
  {
  	struct dlm_lkb *lkb, *safe;
  
  	mutex_lock(&ls->ls_orphans_mutex);
  	list_for_each_entry_safe(lkb, safe, &ls->ls_orphans, lkb_ownqueue) {
  		if (pid && lkb->lkb_ownpid != pid)
  			continue;
  		unlock_proc_lock(ls, lkb);
  		list_del_init(&lkb->lkb_ownqueue);
  		dlm_put_lkb(lkb);
  	}
  	mutex_unlock(&ls->ls_orphans_mutex);
  }
  
  static int send_purge(struct dlm_ls *ls, int nodeid, int pid)
  {
  	struct dlm_message *ms;
  	struct dlm_mhandle *mh;
  	int error;
  
  	error = _create_message(ls, sizeof(struct dlm_message), nodeid,
  				DLM_MSG_PURGE, &ms, &mh);
  	if (error)
  		return error;
  	ms->m_nodeid = nodeid;
  	ms->m_pid = pid;
  
  	return send_message(mh, ms);
  }
  
  int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
  		   int nodeid, int pid)
  {
  	int error = 0;
2ab4bd8ea   David Teigland   dlm: adopt orphan...
6037
  	if (nodeid && (nodeid != dlm_our_nodeid())) {
8499137d4   David Teigland   [DLM] add orphan ...
6038
6039
  		error = send_purge(ls, nodeid, pid);
  	} else {
85e86edf9   David Teigland   [DLM] block scand...
6040
  		dlm_lock_recovery(ls);
8499137d4   David Teigland   [DLM] add orphan ...
6041
6042
6043
6044
  		if (pid == current->pid)
  			purge_proc_locks(ls, proc);
  		else
  			do_purge(ls, nodeid, pid);
85e86edf9   David Teigland   [DLM] block scand...
6045
  		dlm_unlock_recovery(ls);
8499137d4   David Teigland   [DLM] add orphan ...
6046
6047
6048
  	}
  	return error;
  }