ldlm_lock.c 81.3 KB
Newer Older
1
/*
kalpak's avatar
   
kalpak committed
2
 * GPL HEADER START
3
 *
kalpak's avatar
   
kalpak committed
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
 *
kalpak's avatar
   
kalpak committed
6
7
8
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
9
 *
kalpak's avatar
   
kalpak committed
10
11
12
13
14
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
15
 *
kalpak's avatar
   
kalpak committed
16
 * You should have received a copy of the GNU General Public License
kalpak's avatar
   
kalpak committed
17
 * version 2 along with this program; If not, see
18
 * http://www.gnu.org/licenses/gpl-2.0.html
kalpak's avatar
   
kalpak committed
19
20
21
22
 *
 * GPL HEADER END
 */
/*
23
 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
kalpak's avatar
   
kalpak committed
24
 * Use is subject to license terms.
25
 *
26
 * Copyright (c) 2010, 2017, Intel Corporation.
kalpak's avatar
   
kalpak committed
27
28
29
30
31
32
33
34
35
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/ldlm/ldlm_lock.c
 *
 * Author: Peter Braam <braam@clusterfs.com>
 * Author: Phil Schwan <phil@clusterfs.com>
36
37
38
39
 */

#define DEBUG_SUBSYSTEM S_LDLM

40
#include <libcfs/libcfs.h>
41
42

#include <lustre_swab.h>
nathan's avatar
nathan committed
43
#include <obd_class.h>
44

45
#include "ldlm_internal.h"
46

47
48
49
struct kmem_cache *ldlm_glimpse_work_kmem;
EXPORT_SYMBOL(ldlm_glimpse_work_kmem);

50
51
/* lock types */
char *ldlm_lockname[] = {
52
53
54
55
56
57
58
59
60
	[0] = "--",
	[LCK_EX] = "EX",
	[LCK_PW] = "PW",
	[LCK_PR] = "PR",
	[LCK_CW] = "CW",
	[LCK_CR] = "CR",
	[LCK_NL] = "NL",
	[LCK_GROUP] = "GROUP",
	[LCK_COS] = "COS"
61
};
62
EXPORT_SYMBOL(ldlm_lockname);
nathan's avatar
nathan committed
63

64
char *ldlm_typename[] = {
65
66
67
68
	[LDLM_PLAIN] = "PLN",
	[LDLM_EXTENT] = "EXT",
	[LDLM_FLOCK] = "FLK",
	[LDLM_IBITS] = "IBT",
69
};
70

71
static ldlm_policy_wire_to_local_t ldlm_policy_wire_to_local[] = {
72
73
	[LDLM_PLAIN - LDLM_MIN_TYPE]  = ldlm_plain_policy_wire_to_local,
	[LDLM_EXTENT - LDLM_MIN_TYPE] = ldlm_extent_policy_wire_to_local,
74
	[LDLM_FLOCK - LDLM_MIN_TYPE]  = ldlm_flock_policy_wire_to_local,
75
	[LDLM_IBITS - LDLM_MIN_TYPE]  = ldlm_ibits_policy_wire_to_local,
76
77
78
};

static ldlm_policy_local_to_wire_t ldlm_policy_local_to_wire[] = {
79
80
81
82
	[LDLM_PLAIN - LDLM_MIN_TYPE]  = ldlm_plain_policy_local_to_wire,
	[LDLM_EXTENT - LDLM_MIN_TYPE] = ldlm_extent_policy_local_to_wire,
	[LDLM_FLOCK - LDLM_MIN_TYPE]  = ldlm_flock_policy_local_to_wire,
	[LDLM_IBITS - LDLM_MIN_TYPE]  = ldlm_ibits_policy_local_to_wire,
83
84
85
86
87
};

/**
 * Converts lock policy from local format to on the wire lock_desc format
 */
88
89
90
void ldlm_convert_policy_to_wire(enum ldlm_type type,
				 const union ldlm_policy_data *lpolicy,
				 union ldlm_wire_policy_data *wpolicy)
91
{
92
	ldlm_policy_local_to_wire_t convert;
93

94
	convert = ldlm_policy_local_to_wire[type - LDLM_MIN_TYPE];
95

96
	convert(lpolicy, wpolicy);
97
98
99
100
101
}

/**
 * Converts lock policy from on the wire lock_desc format to local format
 */
102
103
104
void ldlm_convert_policy_to_local(struct obd_export *exp, enum ldlm_type type,
				  const union ldlm_wire_policy_data *wpolicy,
				  union ldlm_policy_data *lpolicy)
105
{
106
	ldlm_policy_wire_to_local_t convert;
107

108
	convert = ldlm_policy_wire_to_local[type - LDLM_MIN_TYPE];
109

110
	convert(wpolicy, lpolicy);
111
112
}

113
const char *ldlm_it2str(enum ldlm_intent_flags it)
114
{
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
	switch (it) {
	case IT_OPEN:
		return "open";
	case IT_CREAT:
		return "creat";
	case (IT_OPEN | IT_CREAT):
		return "open|creat";
	case IT_READDIR:
		return "readdir";
	case IT_GETATTR:
		return "getattr";
	case IT_LOOKUP:
		return "lookup";
	case IT_GETXATTR:
		return "getxattr";
	case IT_LAYOUT:
		return "layout";
	default:
		CERROR("Unknown intent 0x%08x\n", it);
		return "UNKNOWN";
	}
136
}
137
EXPORT_SYMBOL(ldlm_it2str);
138

139
extern struct kmem_cache *ldlm_lock_slab;
140

141
#ifdef HAVE_SERVER_SUPPORT
142
static ldlm_processing_policy ldlm_processing_policy_table[] = {
143
144
145
146
	[LDLM_PLAIN]	= ldlm_process_plain_lock,
	[LDLM_EXTENT]	= ldlm_process_extent_lock,
	[LDLM_FLOCK]	= ldlm_process_flock_lock,
	[LDLM_IBITS]	= ldlm_process_inodebits_lock,
braam's avatar
braam committed
147
148
};

phil's avatar
phil committed
149
ldlm_processing_policy ldlm_get_processing_policy(struct ldlm_resource *res)
150
{
phil's avatar
phil committed
151
        return ldlm_processing_policy_table[res->lr_type];
152
}
153
EXPORT_SYMBOL(ldlm_get_processing_policy);
154
155
156
157
158
159
160
161
162
163
164
165
166

static ldlm_reprocessing_policy ldlm_reprocessing_policy_table[] = {
	[LDLM_PLAIN]	= ldlm_reprocess_queue,
	[LDLM_EXTENT]	= ldlm_reprocess_queue,
	[LDLM_FLOCK]	= ldlm_reprocess_queue,
	[LDLM_IBITS]	= ldlm_reprocess_inodebits_queue,
};

ldlm_reprocessing_policy ldlm_get_reprocessing_policy(struct ldlm_resource *res)
{
	return ldlm_reprocessing_policy_table[res->lr_type];
}

167
#endif /* HAVE_SERVER_SUPPORT */
168

phil's avatar
phil committed
169
void ldlm_register_intent(struct ldlm_namespace *ns, ldlm_res_policy arg)
170
{
phil's avatar
phil committed
171
        ns->ns_policy = arg;
172
}
173
EXPORT_SYMBOL(ldlm_register_intent);
174

175
176
/*
 * REFCOUNTED LOCK OBJECTS
177
 */
178
179


Ned Bass's avatar
Ned Bass committed
180
181
182
/**
 * Get a reference on a lock.
 *
183
 * Lock refcounts, during creation:
184
185
186
187
 *   - one special one for allocation, dec'd only once in destroy
 *   - one for being a lock that's in-use
 *   - one for the addref associated with a new lock
 */
188
189
struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock)
{
190
	atomic_inc(&lock->l_refc);
191
192
        return lock;
}
193
EXPORT_SYMBOL(ldlm_lock_get);
194

Ned Bass's avatar
Ned Bass committed
195
196
197
198
199
/**
 * Release lock reference.
 *
 * Also frees the lock if it was last reference.
 */
200
201
202
203
void ldlm_lock_put(struct ldlm_lock *lock)
{
        ENTRY;

alex's avatar
b=3984    
alex committed
204
        LASSERT(lock->l_resource != LP_POISON);
205
206
	LASSERT(atomic_read(&lock->l_refc) > 0);
	if (atomic_dec_and_test(&lock->l_refc)) {
alex's avatar
b=7200    
alex committed
207
                struct ldlm_resource *res;
208

tappro's avatar
tappro committed
209
210
                LDLM_DEBUG(lock,
                           "final lock_put on destroyed lock, freeing it.");
alex's avatar
b=3984    
alex committed
211

alex's avatar
b=7200    
alex committed
212
                res = lock->l_resource;
213
		LASSERT(ldlm_is_destroyed(lock));
214
		LASSERT(list_empty(&lock->l_exp_list));
215
216
		LASSERT(list_empty(&lock->l_res_link));
		LASSERT(list_empty(&lock->l_pending_chain));
pschwan's avatar
pschwan committed
217

218
219
                lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
                                     LDLM_NSS_LOCKS);
220
                lu_ref_del(&res->lr_reference, "lock", lock);
tappro's avatar
tappro committed
221
                if (lock->l_export) {
zam's avatar
zam committed
222
                        class_export_lock_put(lock->l_export, lock);
tappro's avatar
tappro committed
223
224
                        lock->l_export = NULL;
                }
pschwan's avatar
   
pschwan committed
225

phil's avatar
phil committed
226
                if (lock->l_lvb_data != NULL)
227
                        OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len);
phil's avatar
phil committed
228

229
230
231
232
233
234
235
236
237
		if (res->lr_type == LDLM_EXTENT) {
			ldlm_interval_free(ldlm_interval_detach(lock));
		} else if (res->lr_type == LDLM_IBITS) {
			if (lock->l_ibits_node != NULL)
				OBD_SLAB_FREE_PTR(lock->l_ibits_node,
						  ldlm_inodebits_slab);
		}
		ldlm_resource_putref(res);
		lock->l_resource = NULL;
238
                lu_ref_fini(&lock->l_reference);
239
		OBD_FREE_RCU(lock, sizeof(*lock), &lock->l_handle);
pschwan's avatar
   
pschwan committed
240
        }
pschwan's avatar
pschwan committed
241

242
243
        EXIT;
}
244
EXPORT_SYMBOL(ldlm_lock_put);
245

Ned Bass's avatar
Ned Bass committed
246
247
248
/**
 * Removes LDLM lock \a lock from LRU. Assumes LRU is already locked.
 */
nathan's avatar
nathan committed
249
int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
pschwan's avatar
pschwan committed
250
{
251
	int rc = 0;
252
	if (!list_empty(&lock->l_lru)) {
253
254
255
		struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);

		LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
256
257
		if (ns->ns_last_pos == &lock->l_lru)
			ns->ns_last_pos = lock->l_lru.prev;
258
		list_del_init(&lock->l_lru);
259
260
261
262
263
		LASSERT(ns->ns_nr_unused > 0);
		ns->ns_nr_unused--;
		rc = 1;
	}
	return rc;
nathan's avatar
nathan committed
264
265
}

Ned Bass's avatar
Ned Bass committed
266
267
/**
 * Removes LDLM lock \a lock from LRU. Obtains the LRU lock first.
268
269
270
271
272
273
274
275
 *
 * If \a last_use is non-zero, it will remove the lock from LRU only if
 * it matches lock's l_last_used.
 *
 * \retval 0 if \a last_use is set, the lock is not in LRU list or \a last_use
 *           doesn't match lock's l_last_used;
 *           otherwise, the lock hasn't been in the LRU list.
 * \retval 1 the lock was in LRU list and removed.
Ned Bass's avatar
Ned Bass committed
276
 */
277
int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, ktime_t last_use)
nathan's avatar
nathan committed
278
{
279
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
280
	int rc = 0;
281

282
	ENTRY;
283
	if (ldlm_is_ns_srv(lock)) {
284
		LASSERT(list_empty(&lock->l_lru));
285
286
		RETURN(0);
	}
287

288
	spin_lock(&ns->ns_lock);
289
290
	if (!ktime_compare(last_use, ktime_set(0, 0)) ||
	    !ktime_compare(last_use, lock->l_last_used))
291
		rc = ldlm_lock_remove_from_lru_nolock(lock);
292
	spin_unlock(&ns->ns_lock);
293
294

	RETURN(rc);
pschwan's avatar
pschwan committed
295
296
}

Ned Bass's avatar
Ned Bass committed
297
298
299
/**
 * Adds LDLM lock \a lock to namespace LRU. Assumes LRU is already locked.
 */
yury's avatar
b=2262    
yury committed
300
301
void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock)
{
302
303
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);

304
	lock->l_last_used = ktime_get();
305
	LASSERT(list_empty(&lock->l_lru));
306
	LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
307
	list_add_tail(&lock->l_lru, &ns->ns_unused_list);
308
309
	LASSERT(ns->ns_nr_unused >= 0);
	ns->ns_nr_unused++;
yury's avatar
b=2262    
yury committed
310
311
}

Ned Bass's avatar
Ned Bass committed
312
313
314
315
/**
 * Adds LDLM lock \a lock to namespace LRU. Obtains necessary LRU locks
 * first.
 */
yury's avatar
b=2262    
yury committed
316
317
void ldlm_lock_add_to_lru(struct ldlm_lock *lock)
{
318
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
319

320
321
322
323
324
	ENTRY;
	spin_lock(&ns->ns_lock);
	ldlm_lock_add_to_lru_nolock(lock);
	spin_unlock(&ns->ns_lock);
	EXIT;
yury's avatar
b=2262    
yury committed
325
326
}

Ned Bass's avatar
Ned Bass committed
327
328
329
330
/**
 * Moves LDLM lock \a lock that is already in namespace LRU to the tail of
 * the LRU. Performs necessary LRU locking
 */
yury's avatar
b=2262    
yury committed
331
332
void ldlm_lock_touch_in_lru(struct ldlm_lock *lock)
{
333
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
334

335
	ENTRY;
336
	if (ldlm_is_ns_srv(lock)) {
337
		LASSERT(list_empty(&lock->l_lru));
338
339
340
		EXIT;
		return;
	}
341

342
	spin_lock(&ns->ns_lock);
343
	if (!list_empty(&lock->l_lru)) {
344
345
346
347
348
		ldlm_lock_remove_from_lru_nolock(lock);
		ldlm_lock_add_to_lru_nolock(lock);
	}
	spin_unlock(&ns->ns_lock);
	EXIT;
yury's avatar
b=2262    
yury committed
349
350
}

Ned Bass's avatar
Ned Bass committed
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/**
 * Helper to destroy a locked lock.
 *
 * Used by ldlm_lock_destroy and ldlm_lock_destroy_nolock
 * Must be called with l_lock and lr_lock held.
 *
 * Does not actually free the lock data, but rather marks the lock as
 * destroyed by setting l_destroyed field in the lock to 1.  Destroys a
 * handle->lock association too, so that the lock can no longer be found
 * and removes the lock from LRU list.  Actual lock freeing occurs when
 * last lock reference goes away.
 *
 * Original comment (of some historical value):
 * This used to have a 'strict' flag, which recovery would use to mark an
pschwan's avatar
pschwan committed
365
366
367
 * in-use lock as needing-to-die.  Lest I am ever tempted to put it back, I
 * shall explain why it's gone: with the new hash table scheme, once you call
 * ldlm_lock_destroy, you can never drop your final references on this lock.
Ned Bass's avatar
Ned Bass committed
368
369
 * Because it's not in the hash table anymore.  -phil
 */
370
static int ldlm_lock_destroy_internal(struct ldlm_lock *lock)
371
372
{
        ENTRY;
alex's avatar
b=3984    
alex committed
373

374
        if (lock->l_readers || lock->l_writers) {
pschwan's avatar
pschwan committed
375
376
                LDLM_ERROR(lock, "lock still has references");
                LBUG();
377
378
        }

379
	if (!list_empty(&lock->l_res_link)) {
phil's avatar
phil committed
380
                LDLM_ERROR(lock, "lock still on resource");
381
                LBUG();
382
        }
383

384
	if (ldlm_is_destroyed(lock)) {
385
		LASSERT(list_empty(&lock->l_lru));
386
387
388
		EXIT;
		return 0;
	}
389
	ldlm_set_destroyed(lock);
390

391
392
393
	if (lock->l_export && lock->l_export->exp_lock_hash) {
		/* NB: it's safe to call cfs_hash_del() even lock isn't
		 * in exp_lock_hash. */
394
395
396
		/* In the function below, .hs_keycmp resolves to
		 * ldlm_export_lock_keycmp() */
		/* coverity[overrun-buffer-val] */
397
398
399
		cfs_hash_del(lock->l_export->exp_lock_hash,
			     &lock->l_remote_handle, &lock->l_exp_hash);
	}
alex's avatar
b=3984    
alex committed
400

pschwan's avatar
pschwan committed
401
        ldlm_lock_remove_from_lru(lock);
402
        class_handle_unhash(&lock->l_handle);
shaver's avatar
shaver committed
403

nathan's avatar
nathan committed
404
405
406
        EXIT;
        return 1;
}
407

Ned Bass's avatar
Ned Bass committed
408
409
410
/**
 * Destroys a LDLM lock \a lock. Performs necessary locking first.
 */
nathan's avatar
nathan committed
411
412
413
414
415
416
void ldlm_lock_destroy(struct ldlm_lock *lock)
{
        int first;
        ENTRY;
        lock_res_and_lock(lock);
        first = ldlm_lock_destroy_internal(lock);
alex's avatar
b=7200    
alex committed
417
        unlock_res_and_lock(lock);
nathan's avatar
nathan committed
418
419

        /* drop reference from hashtable only for first destroy */
420
421
422
423
        if (first) {
                lu_ref_del(&lock->l_reference, "hash", lock);
                LDLM_LOCK_RELEASE(lock);
        }
nathan's avatar
nathan committed
424
425
426
        EXIT;
}

Ned Bass's avatar
Ned Bass committed
427
428
429
/**
 * Destroys a LDLM lock \a lock that is already locked.
 */
nathan's avatar
nathan committed
430
431
432
433
434
435
void ldlm_lock_destroy_nolock(struct ldlm_lock *lock)
{
        int first;
        ENTRY;
        first = ldlm_lock_destroy_internal(lock);
        /* drop reference from hashtable only for first destroy */
436
437
438
439
        if (first) {
                lu_ref_del(&lock->l_reference, "hash", lock);
                LDLM_LOCK_RELEASE(lock);
        }
440
441
        EXIT;
}
442

pschwan's avatar
   
pschwan committed
443
444
445
/* this is called by portals_handle2object with the handle lock taken */
static void lock_handle_addref(void *lock)
{
pschwan's avatar
pschwan committed
446
        LDLM_LOCK_GET((struct ldlm_lock *)lock);
pschwan's avatar
   
pschwan committed
447
448
}

449
450
451
452
453
454
static void lock_handle_free(void *lock, int size)
{
	LASSERT(size == sizeof(struct ldlm_lock));
	OBD_SLAB_FREE(lock, ldlm_lock_slab, size);
}

455
static struct portals_handle_ops lock_handle_ops = {
456
457
458
459
	.hop_addref = lock_handle_addref,
	.hop_free   = lock_handle_free,
};

Ned Bass's avatar
Ned Bass committed
460
461
462
463
/**
 *
 * Allocate and initialize new lock structure.
 *
pschwan's avatar
   
pschwan committed
464
 * usage: pass in a resource on which you have done ldlm_resource_get
465
 *        new lock will take over the refcount.
466
 * returns: lock with refcount 2 - one for current caller and one for remote
pschwan's avatar
   
pschwan committed
467
 */
vitaly's avatar
vitaly committed
468
static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource)
469
{
470
471
	struct ldlm_lock *lock;
	ENTRY;
472

473
474
	if (resource == NULL)
		LBUG();
475

476
477
478
	OBD_SLAB_ALLOC_PTR_GFP(lock, ldlm_lock_slab, GFP_NOFS);
	if (lock == NULL)
		RETURN(NULL);
479

480
	spin_lock_init(&lock->l_lock);
481
482
	lock->l_resource = resource;
	lu_ref_add(&resource->lr_reference, "lock", lock);
483

484
	atomic_set(&lock->l_refc, 2);
485
486
487
488
489
490
	INIT_LIST_HEAD(&lock->l_res_link);
	INIT_LIST_HEAD(&lock->l_lru);
	INIT_LIST_HEAD(&lock->l_pending_chain);
	INIT_LIST_HEAD(&lock->l_bl_ast);
	INIT_LIST_HEAD(&lock->l_cp_ast);
	INIT_LIST_HEAD(&lock->l_rk_ast);
491
492
	init_waitqueue_head(&lock->l_waitq);
	lock->l_blocking_lock = NULL;
493
494
495
496
	INIT_LIST_HEAD(&lock->l_sl_mode);
	INIT_LIST_HEAD(&lock->l_sl_policy);
	INIT_HLIST_NODE(&lock->l_exp_hash);
	INIT_HLIST_NODE(&lock->l_exp_flock_hash);
497

498
499
        lprocfs_counter_incr(ldlm_res_to_ns(resource)->ns_stats,
                             LDLM_NSS_LOCKS);
500
	INIT_LIST_HEAD_RCU(&lock->l_handle.h_link);
501
	class_handle_hash(&lock->l_handle, &lock_handle_ops);
502

503
504
        lu_ref_init(&lock->l_reference);
        lu_ref_add(&lock->l_reference, "hash", lock);
vitaly's avatar
vitaly committed
505
        lock->l_callback_timeout = 0;
506
	lock->l_activity = 0;
507

zam's avatar
zam committed
508
#if LUSTRE_TRACKS_LOCK_EXP_REFS
509
	INIT_LIST_HEAD(&lock->l_exp_refs_link);
zam's avatar
zam committed
510
511
512
        lock->l_exp_refs_nr = 0;
        lock->l_exp_refs_target = NULL;
#endif
513
	INIT_LIST_HEAD(&lock->l_exp_list);
zam's avatar
zam committed
514

515
516
517
        RETURN(lock);
}

Ned Bass's avatar
Ned Bass committed
518
519
520
521
522
/**
 * Moves LDLM lock \a lock to another resource.
 * This is used on client when server returns some other lock than requested
 * (typically as a result of intent operation)
 */
523
int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
tappro's avatar
tappro committed
524
                              const struct ldlm_res_id *new_resid)
525
{
526
        struct ldlm_resource *oldres = lock->l_resource;
alex's avatar
b=7200    
alex committed
527
528
        struct ldlm_resource *newres;
        int type;
529
530
        ENTRY;

yury's avatar
b=13872    
yury committed
531
        LASSERT(ns_is_client(ns));
alex's avatar
b=7200    
alex committed
532
533

        lock_res_and_lock(lock);
tappro's avatar
tappro committed
534
        if (memcmp(new_resid, &lock->l_resource->lr_name,
535
536
                   sizeof(lock->l_resource->lr_name)) == 0) {
                /* Nothing to do */
alex's avatar
b=7200    
alex committed
537
                unlock_res_and_lock(lock);
538
539
                RETURN(0);
        }
540

tappro's avatar
tappro committed
541
        LASSERT(new_resid->name[0] != 0);
pschwan's avatar
pschwan committed
542
543

        /* This function assumes that the lock isn't on any lists */
544
	LASSERT(list_empty(&lock->l_res_link));
pschwan's avatar
pschwan committed
545

alex's avatar
b=7200    
alex committed
546
        type = oldres->lr_type;
nathan's avatar
nathan committed
547
548
        unlock_res_and_lock(lock);

549
550
551
	newres = ldlm_resource_get(ns, NULL, new_resid, type, 1);
	if (IS_ERR(newres))
		RETURN(PTR_ERR(newres));
552
553

        lu_ref_add(&newres->lr_reference, "lock", lock);
554
555
556
557
558
559
        /*
         * To flip the lock from the old to the new resource, lock, oldres and
         * newres have to be locked. Resource spin-locks are nested within
         * lock->l_lock, and are taken in the memory address order to avoid
         * dead-locks.
         */
560
	spin_lock(&lock->l_lock);
561
562
563
564
565
        oldres = lock->l_resource;
        if (oldres < newres) {
                lock_res(oldres);
                lock_res_nested(newres, LRT_NEW);
        } else {
nikita's avatar
nikita committed
566
                lock_res(newres);
567
568
569
570
                lock_res_nested(oldres, LRT_NEW);
        }
        LASSERT(memcmp(new_resid, &oldres->lr_name,
                       sizeof oldres->lr_name) != 0);
alex's avatar
b=7200    
alex committed
571
        lock->l_resource = newres;
alex's avatar
b=3984    
alex committed
572
        unlock_res(oldres);
jxiong's avatar
   
jxiong committed
573
        unlock_res_and_lock(lock);
alex's avatar
b=3984    
alex committed
574

pschwan's avatar
   
pschwan committed
575
        /* ...and the flowers are still standing! */
576
        lu_ref_del(&oldres->lr_reference, "lock", lock);
pschwan's avatar
   
pschwan committed
577
        ldlm_resource_putref(oldres);
578
579
580
581

        RETURN(0);
}

Ned Bass's avatar
Ned Bass committed
582
583
584
/** \defgroup ldlm_handles LDLM HANDLES
 * Ways to get hold of locks without any addresses.
 * @{
585
 */
586

Ned Bass's avatar
Ned Bass committed
587
588
589
590
/**
 * Fills in handle for LDLM lock \a lock into supplied \a lockh
 * Does not take any references.
 */
tappro's avatar
tappro committed
591
void ldlm_lock2handle(const struct ldlm_lock *lock, struct lustre_handle *lockh)
592
{
Ned Bass's avatar
Ned Bass committed
593
	lockh->cookie = lock->l_handle.h_cookie;
594
}
595
EXPORT_SYMBOL(ldlm_lock2handle);
596

Ned Bass's avatar
Ned Bass committed
597
598
599
600
601
/**
 * Obtain a lock reference by handle.
 *
 * if \a flags: atomically get the lock and set the flags.
 *              Return NULL if flag already set
602
 */
tappro's avatar
tappro committed
603
struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle,
604
				     __u64 flags)
605
{
606
607
	struct ldlm_lock *lock;
	ENTRY;
608

609
	LASSERT(handle);
adilger's avatar
adilger committed
610

611
	lock = class_handle2object(handle->cookie, NULL);
612
613
	if (lock == NULL)
		RETURN(NULL);
614

615
616
617
618
619
620
621
	if (lock->l_export != NULL && lock->l_export->exp_failed) {
		CDEBUG(D_INFO, "lock export failed: lock %p, exp %p\n",
		       lock, lock->l_export);
		LDLM_LOCK_PUT(lock);
		RETURN(NULL);
	}

622
623
	/* It's unlikely but possible that someone marked the lock as
	 * destroyed after we did handle2object on it */
624
	if ((flags == 0) && !ldlm_is_destroyed(lock)) {
625
626
627
		lu_ref_add(&lock->l_reference, "handle", current);
		RETURN(lock);
	}
628

629
	lock_res_and_lock(lock);
630

631
	LASSERT(lock->l_resource != NULL);
632

633
	lu_ref_add_atomic(&lock->l_reference, "handle", current);
634
	if (unlikely(ldlm_is_destroyed(lock))) {
635
636
637
638
639
		unlock_res_and_lock(lock);
		CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock);
		LDLM_LOCK_PUT(lock);
		RETURN(NULL);
	}
640

641
642
643
644
645
646
647
	/* If we're setting flags, make sure none of them are already set. */
	if (flags != 0) {
		if ((lock->l_flags & flags) != 0) {
			unlock_res_and_lock(lock);
			LDLM_LOCK_PUT(lock);
			RETURN(NULL);
		}
648

649
		lock->l_flags |= flags;
650
	}
651

652
653
	unlock_res_and_lock(lock);
	RETURN(lock);
654
}
655
EXPORT_SYMBOL(__ldlm_handle2lock);
Ned Bass's avatar
Ned Bass committed
656
/** @} ldlm_handles */
657

Ned Bass's avatar
Ned Bass committed
658
659
660
661
/**
 * Fill in "on the wire" representation for given LDLM lock into supplied
 * lock descriptor \a desc structure.
 */
662
663
void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc)
{
664
665
666
667
668
669
	ldlm_res2desc(lock->l_resource, &desc->l_resource);
	desc->l_req_mode = lock->l_req_mode;
	desc->l_granted_mode = lock->l_granted_mode;
	ldlm_convert_policy_to_wire(lock->l_resource->lr_type,
				    &lock->l_policy_data,
				    &desc->l_policy_data);
670
671
}

Ned Bass's avatar
Ned Bass committed
672
673
674
675
676
/**
 * Add a lock to list of conflicting locks to send AST to.
 *
 * Only add if we have not sent a blocking AST to the lock yet.
 */
677
678
static void ldlm_add_bl_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
				  struct list_head *work_list)
679
{
680
681
682
683
684
685
686
	if (!ldlm_is_ast_sent(lock)) {
		LDLM_DEBUG(lock, "lock incompatible; sending blocking AST.");
		ldlm_set_ast_sent(lock);
		/* If the enqueuing client said so, tell the AST recipient to
		 * discard dirty data, rather than writing back. */
		if (ldlm_is_ast_discard_data(new))
			ldlm_set_discard_data(lock);
687
688
689
690
691
692
693
694
695
696
697
698
699

		/* Lock can be converted from a blocking state back to granted
		 * after lock convert or COS downgrade but still be in an
		 * older bl_list because it is controlled only by
		 * ldlm_work_bl_ast_lock(), let it be processed there.
		 */
		if (list_empty(&lock->l_bl_ast)) {
			list_add(&lock->l_bl_ast, work_list);
			LDLM_LOCK_GET(lock);
		}
		LASSERT(lock->l_blocking_lock == NULL);
		lock->l_blocking_lock = LDLM_LOCK_GET(new);
	}
alex's avatar
b=3984    
alex committed
700
701
}

Ned Bass's avatar
Ned Bass committed
702
703
704
/**
 * Add a lock to list of just granted locks to send completion AST to.
 */
705
706
static void ldlm_add_cp_work_item(struct ldlm_lock *lock,
				  struct list_head *work_list)
alex's avatar
b=3984    
alex committed
707
{
708
709
	if (!ldlm_is_cp_reqd(lock)) {
		ldlm_set_cp_reqd(lock);
nathan's avatar
nathan committed
710
                LDLM_DEBUG(lock, "lock granted; sending completion AST.");
711
712
		LASSERT(list_empty(&lock->l_cp_ast));
		list_add(&lock->l_cp_ast, work_list);
alex's avatar
b=3984    
alex committed
713
714
715
                LDLM_LOCK_GET(lock);
        }
}
716

Ned Bass's avatar
Ned Bass committed
717
718
719
720
721
722
/**
 * Aggregator function to add AST work items into a list. Determines
 * what sort of an AST work needs to be done and calls the proper
 * adding function.
 * Must be called with lr_lock held.
 */
alex's avatar
b=3984    
alex committed
723
void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
724
			    struct list_head *work_list)
alex's avatar
b=3984    
alex committed
725
726
727
728
729
{
        ENTRY;
        check_res_locked(lock->l_resource);
        if (new)
                ldlm_add_bl_work_item(lock, new, work_list);
tappro's avatar
tappro committed
730
        else
alex's avatar
b=3984    
alex committed
731
                ldlm_add_cp_work_item(lock, work_list);
pschwan's avatar
pschwan committed
732
        EXIT;
733
}
734

Ned Bass's avatar
Ned Bass committed
735
736
737
738
739
/**
 * Add specified reader/writer reference to LDLM lock with handle \a lockh.
 * r/w reference type is determined by \a mode
 * Calls ldlm_lock_addref_internal.
 */
740
void ldlm_lock_addref(const struct lustre_handle *lockh, enum ldlm_mode mode)
741
{
742
	struct ldlm_lock *lock;
743

744
	lock = ldlm_handle2lock(lockh);
745
	LASSERTF(lock != NULL, "Non-existing lock: %#llx\n", lockh->cookie);
746
747
	ldlm_lock_addref_internal(lock, mode);
	LDLM_LOCK_PUT(lock);
748
}
749
EXPORT_SYMBOL(ldlm_lock_addref);
750

Ned Bass's avatar
Ned Bass committed
751
752
753
754
755
756
757
/**
 * Helper function.
 * Add specified reader/writer reference to LDLM lock \a lock.
 * r/w reference type is determined by \a mode
 * Removes lock from LRU if it is there.
 * Assumes the LDLM lock is already locked.
 */
758
759
void ldlm_lock_addref_internal_nolock(struct ldlm_lock *lock,
				      enum ldlm_mode mode)
760
{
pschwan's avatar
pschwan committed
761
        ldlm_lock_remove_from_lru(lock);
762
        if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
763
                lock->l_readers++;
764
765
                lu_ref_add_atomic(&lock->l_reference, "reader", lock);
        }
zam's avatar
zam committed
766
        if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
767
                lock->l_writers++;
768
769
                lu_ref_add_atomic(&lock->l_reference, "writer", lock);
        }
770
        LDLM_LOCK_GET(lock);
771
        lu_ref_add_atomic(&lock->l_reference, "user", lock);
772
        LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]);
alex's avatar
b=3984    
alex committed
773
774
}

775
/**
Ned Bass's avatar
Ned Bass committed
776
777
 * Attempts to add reader/writer reference to a lock with handle \a lockh, and
 * fails if lock is already LDLM_FL_CBPENDING or destroyed.
778
779
780
781
782
 *
 * \retval 0 success, lock was addref-ed
 *
 * \retval -EAGAIN lock is being canceled.
 */
783
int ldlm_lock_addref_try(const struct lustre_handle *lockh, enum ldlm_mode mode)
784
785
786
787
788
789
790
791
{
        struct ldlm_lock *lock;
        int               result;

        result = -EAGAIN;
        lock = ldlm_handle2lock(lockh);
        if (lock != NULL) {
                lock_res_and_lock(lock);
nikita's avatar
nikita committed
792
                if (lock->l_readers != 0 || lock->l_writers != 0 ||
793
		    !ldlm_is_cbpending(lock)) {
794
795
796
797
798
799
800
801
                        ldlm_lock_addref_internal_nolock(lock, mode);
                        result = 0;
                }
                unlock_res_and_lock(lock);
                LDLM_LOCK_PUT(lock);
        }
        return result;
}
802
EXPORT_SYMBOL(ldlm_lock_addref_try);
803

Ned Bass's avatar
Ned Bass committed
804
805
806
807
808
/**
 * Add specified reader/writer reference to LDLM lock \a lock.
 * Locks LDLM lock and calls ldlm_lock_addref_internal_nolock to do the work.
 * Only called for local locks.
 */
809
void ldlm_lock_addref_internal(struct ldlm_lock *lock, enum ldlm_mode mode)
alex's avatar
b=3984    
alex committed
810
{
811
812
813
	lock_res_and_lock(lock);
	ldlm_lock_addref_internal_nolock(lock, mode);
	unlock_res_and_lock(lock);
814
815
}

Ned Bass's avatar
Ned Bass committed
816
817
818
819
820
821
822
/**
 * Removes reader/writer reference for LDLM lock \a lock.
 * Assumes LDLM lock is already locked.
 * only called in ldlm_flock_destroy and for local locks.
 * Does NOT add lock to LRU if no r/w references left to accomodate flock locks
 * that cannot be placed in LRU.
 */
823
824
void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock,
				      enum ldlm_mode mode)
825
{
yury's avatar
yury committed
826
        LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
827
        if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
828
                LASSERT(lock->l_readers > 0);
829
                lu_ref_del(&lock->l_reference, "reader", lock);
830
                lock->l_readers--;
831
        }
zam's avatar
zam committed
832
        if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
833
                LASSERT(lock->l_writers > 0);
834
                lu_ref_del(&lock->l_reference, "writer", lock);
835
                lock->l_writers--;
836
        }
837

838
839
        lu_ref_del(&lock->l_reference, "user", lock);
        LDLM_LOCK_RELEASE(lock);    /* matches the LDLM_LOCK_GET() in addref */
yury's avatar
b=15260    
yury committed
840
841
}

Ned Bass's avatar
Ned Bass committed
842
843
844
845
846
847
848
849
/**
 * Removes reader/writer reference for LDLM lock \a lock.
 * Locks LDLM lock first.
 * If the lock is determined to be client lock on a client and r/w refcount
 * drops to zero and the lock is not blocked, the lock is added to LRU lock
 * on the namespace.
 * For blocked LDLM locks if r/w count drops to zero, blocking_ast is called.
 */
850
void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode)
yury's avatar
b=15260    
yury committed
851
852
853
854
855
856
{
        struct ldlm_namespace *ns;
        ENTRY;

        lock_res_and_lock(lock);

857
        ns = ldlm_lock_to_ns(lock);
yury's avatar
b=15260    
yury committed
858
859
860

        ldlm_lock_decref_internal_nolock(lock, mode);

861
862
863
864
865
	if ((ldlm_is_local(lock) || lock->l_req_mode == LCK_GROUP) &&
	    !lock->l_readers && !lock->l_writers) {
		/* If this is a local lock on a server namespace and this was
		 * the last reference, cancel the lock.
		 *
866
867
868
869
870
871
		 * Group locks are special:
		 * They must not go in LRU, but they are not called back
		 * like non-group locks, instead they are manually released.
		 * They have an l_writers reference which they keep until
		 * they are manually released, so we remove them when they have
		 * no more reader or writer references. - LU-6368 */
872
873
874
875
876
877
		ldlm_set_cbpending(lock);
	}

	if (!lock->l_readers && !lock->l_writers && ldlm_is_cbpending(lock)) {
		/* If we received a blocked AST and this was the last reference,
		 * run the callback. */
878
		if (ldlm_is_ns_srv(lock) && lock->l_export)
879
880
                        CERROR("FL_CBPENDING set on non-local lock--just a "
                               "warning\n");
881

882
                LDLM_DEBUG(lock, "final decref done on cbpending lock");
883

884
885
                LDLM_LOCK_GET(lock); /* dropped by bl thread */
                ldlm_lock_remove_from_lru(lock);
alex's avatar
b=7200    
alex committed
886
                unlock_res_and_lock(lock);
yury's avatar
b=18028    
yury committed
887

888
		if (ldlm_is_fail_loc(lock))
yury's avatar
b=18028    
yury committed
889
890
                        OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);

891
		if (ldlm_is_atomic_cb(lock) ||
vitaly's avatar
vitaly committed
892
                    ldlm_bl_to_thread_lock(ns, NULL, lock) != 0)
893
                        ldlm_handle_bl_callback(ns, NULL, lock);
yury's avatar
b=13872    
yury committed
894
        } else if (ns_is_client(ns) &&
nathan's avatar
nathan committed
895
                   !lock->l_readers && !lock->l_writers &&
896
		   !ldlm_is_no_lru(lock) &&
897
898
		   !ldlm_is_bl_ast(lock) &&
		   !ldlm_is_converting(lock)) {
899
900
901

                LDLM_DEBUG(lock, "add lock into lru list");

pschwan's avatar
pschwan committed
902
903
                /* If this is a client-side namespace and this was the last
                 * reference, put it on the LRU. */
yury's avatar
b=2262    
yury committed
904
                ldlm_lock_add_to_lru(lock);
alex's avatar
b=7200    
alex committed
905
                unlock_res_and_lock(lock);
yury's avatar
b=18080    
yury committed
906

907
		if (ldlm_is_fail_loc(lock))
yury's avatar
b=18080    
yury committed
908
909
                        OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);

adilger's avatar
adilger committed
910
911
                /* Call ldlm_cancel_lru() only if EARLY_CANCEL and LRU RESIZE
                 * are not supported by the server, otherwise, it is done on
yury's avatar
b=2262    
yury committed
912
                 * enqueue. */