ldlm_lock.c 81.1 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
#ifdef HAVE_SERVER_SUPPORT
140
static ldlm_processing_policy ldlm_processing_policy_table[] = {
141
142
143
144
	[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
145
146
};

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

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];
}

165
#endif /* HAVE_SERVER_SUPPORT */
166

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

173
174
/*
 * REFCOUNTED LOCK OBJECTS
175
 */
176
177


Ned Bass's avatar
Ned Bass committed
178
179
180
/**
 * Get a reference on a lock.
 *
181
 * Lock refcounts, during creation:
182
183
184
185
 *   - 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
 */
186
187
struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock)
{
188
	refcount_inc(&lock->l_handle.h_ref);
189
190
        return lock;
}
191
EXPORT_SYMBOL(ldlm_lock_get);
192

193
194
195
196
197
198
199
200
201
static void lock_handle_free(struct rcu_head *rcu)
{
	struct ldlm_lock *lock = container_of(rcu, struct ldlm_lock,
					      l_handle.h_rcu);

	OBD_FREE_PRE(lock, sizeof(*lock), "slab-freed");
	kmem_cache_free(ldlm_lock_slab, lock);
}

Ned Bass's avatar
Ned Bass committed
202
203
204
205
206
/**
 * Release lock reference.
 *
 * Also frees the lock if it was last reference.
 */
207
208
209
210
void ldlm_lock_put(struct ldlm_lock *lock)
{
        ENTRY;

alex's avatar
b=3984    
alex committed
211
        LASSERT(lock->l_resource != LP_POISON);
212
213
	LASSERT(refcount_read(&lock->l_handle.h_ref) > 0);
	if (refcount_dec_and_test(&lock->l_handle.h_ref)) {
alex's avatar
b=7200    
alex committed
214
                struct ldlm_resource *res;
215

tappro's avatar
tappro committed
216
217
                LDLM_DEBUG(lock,
                           "final lock_put on destroyed lock, freeing it.");
alex's avatar
b=3984    
alex committed
218

alex's avatar
b=7200    
alex committed
219
                res = lock->l_resource;
220
		LASSERT(ldlm_is_destroyed(lock));
221
		LASSERT(list_empty(&lock->l_exp_list));
222
223
		LASSERT(list_empty(&lock->l_res_link));
		LASSERT(list_empty(&lock->l_pending_chain));
pschwan's avatar
pschwan committed
224

225
226
                lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
                                     LDLM_NSS_LOCKS);
227
                lu_ref_del(&res->lr_reference, "lock", lock);
tappro's avatar
tappro committed
228
                if (lock->l_export) {
zam's avatar
zam committed
229
                        class_export_lock_put(lock->l_export, lock);
tappro's avatar
tappro committed
230
231
                        lock->l_export = NULL;
                }
pschwan's avatar
   
pschwan committed
232

phil's avatar
phil committed
233
                if (lock->l_lvb_data != NULL)
234
                        OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len);
phil's avatar
phil committed
235

236
237
238
239
240
241
242
243
244
		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;
245
                lu_ref_fini(&lock->l_reference);
246
		call_rcu(&lock->l_handle.h_rcu, lock_handle_free);
pschwan's avatar
   
pschwan committed
247
        }
pschwan's avatar
pschwan committed
248

249
250
        EXIT;
}
251
EXPORT_SYMBOL(ldlm_lock_put);
252

Ned Bass's avatar
Ned Bass committed
253
254
255
/**
 * Removes LDLM lock \a lock from LRU. Assumes LRU is already locked.
 */
nathan's avatar
nathan committed
256
int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
pschwan's avatar
pschwan committed
257
{
258
	int rc = 0;
259
	if (!list_empty(&lock->l_lru)) {
260
261
262
		struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);

		LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
263
264
		if (ns->ns_last_pos == &lock->l_lru)
			ns->ns_last_pos = lock->l_lru.prev;
265
		list_del_init(&lock->l_lru);
266
267
268
269
270
		LASSERT(ns->ns_nr_unused > 0);
		ns->ns_nr_unused--;
		rc = 1;
	}
	return rc;
nathan's avatar
nathan committed
271
272
}

Ned Bass's avatar
Ned Bass committed
273
274
/**
 * Removes LDLM lock \a lock from LRU. Obtains the LRU lock first.
275
276
277
278
279
280
281
282
 *
 * 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
283
 */
284
int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, ktime_t last_use)
nathan's avatar
nathan committed
285
{
286
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
287
	int rc = 0;
288

289
	ENTRY;
290
	if (ldlm_is_ns_srv(lock)) {
291
		LASSERT(list_empty(&lock->l_lru));
292
293
		RETURN(0);
	}
294

295
	spin_lock(&ns->ns_lock);
296
297
	if (!ktime_compare(last_use, ktime_set(0, 0)) ||
	    !ktime_compare(last_use, lock->l_last_used))
298
		rc = ldlm_lock_remove_from_lru_nolock(lock);
299
	spin_unlock(&ns->ns_lock);
300
301

	RETURN(rc);
pschwan's avatar
pschwan committed
302
303
}

Ned Bass's avatar
Ned Bass committed
304
305
306
/**
 * Adds LDLM lock \a lock to namespace LRU. Assumes LRU is already locked.
 */
yury's avatar
b=2262    
yury committed
307
308
void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock)
{
309
310
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);

311
	lock->l_last_used = ktime_get();
312
	LASSERT(list_empty(&lock->l_lru));
313
	LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
314
	list_add_tail(&lock->l_lru, &ns->ns_unused_list);
315
316
	LASSERT(ns->ns_nr_unused >= 0);
	ns->ns_nr_unused++;
yury's avatar
b=2262    
yury committed
317
318
}

Ned Bass's avatar
Ned Bass committed
319
320
321
322
/**
 * Adds LDLM lock \a lock to namespace LRU. Obtains necessary LRU locks
 * first.
 */
yury's avatar
b=2262    
yury committed
323
324
void ldlm_lock_add_to_lru(struct ldlm_lock *lock)
{
325
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
326

327
328
329
330
331
	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
332
333
}

Ned Bass's avatar
Ned Bass committed
334
335
336
337
/**
 * 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
338
339
void ldlm_lock_touch_in_lru(struct ldlm_lock *lock)
{
340
	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
341

342
	ENTRY;
343
	if (ldlm_is_ns_srv(lock)) {
344
		LASSERT(list_empty(&lock->l_lru));
345
346
347
		EXIT;
		return;
	}
348

349
	spin_lock(&ns->ns_lock);
350
	if (!list_empty(&lock->l_lru)) {
351
352
353
354
355
		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
356
357
}

Ned Bass's avatar
Ned Bass committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/**
 * 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
372
373
374
 * 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
375
376
 * Because it's not in the hash table anymore.  -phil
 */
377
static int ldlm_lock_destroy_internal(struct ldlm_lock *lock)
378
379
{
        ENTRY;
alex's avatar
b=3984    
alex committed
380

381
        if (lock->l_readers || lock->l_writers) {
pschwan's avatar
pschwan committed
382
383
                LDLM_ERROR(lock, "lock still has references");
                LBUG();
384
385
        }

386
	if (!list_empty(&lock->l_res_link)) {
phil's avatar
phil committed
387
                LDLM_ERROR(lock, "lock still on resource");
388
                LBUG();
389
        }
390

391
	if (ldlm_is_destroyed(lock)) {
392
		LASSERT(list_empty(&lock->l_lru));
393
394
395
		EXIT;
		return 0;
	}
396
	ldlm_set_destroyed(lock);
397

398
399
400
	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. */
401
402
403
		/* In the function below, .hs_keycmp resolves to
		 * ldlm_export_lock_keycmp() */
		/* coverity[overrun-buffer-val] */
404
405
406
		cfs_hash_del(lock->l_export->exp_lock_hash,
			     &lock->l_remote_handle, &lock->l_exp_hash);
	}
alex's avatar
b=3984    
alex committed
407

pschwan's avatar
pschwan committed
408
        ldlm_lock_remove_from_lru(lock);
409
        class_handle_unhash(&lock->l_handle);
shaver's avatar
shaver committed
410

nathan's avatar
nathan committed
411
412
413
        EXIT;
        return 1;
}
414

Ned Bass's avatar
Ned Bass committed
415
416
417
/**
 * Destroys a LDLM lock \a lock. Performs necessary locking first.
 */
nathan's avatar
nathan committed
418
419
420
421
422
423
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
424
        unlock_res_and_lock(lock);
nathan's avatar
nathan committed
425
426

        /* drop reference from hashtable only for first destroy */
427
428
429
430
        if (first) {
                lu_ref_del(&lock->l_reference, "hash", lock);
                LDLM_LOCK_RELEASE(lock);
        }
nathan's avatar
nathan committed
431
432
433
        EXIT;
}

Ned Bass's avatar
Ned Bass committed
434
435
436
/**
 * Destroys a LDLM lock \a lock that is already locked.
 */
nathan's avatar
nathan committed
437
438
439
440
441
442
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 */
443
444
445
446
        if (first) {
                lu_ref_del(&lock->l_reference, "hash", lock);
                LDLM_LOCK_RELEASE(lock);
        }
447
448
        EXIT;
}
449

450
static const char lock_handle_owner[] = "ldlm";
451

Ned Bass's avatar
Ned Bass committed
452
453
454
455
/**
 *
 * Allocate and initialize new lock structure.
 *
pschwan's avatar
   
pschwan committed
456
 * usage: pass in a resource on which you have done ldlm_resource_get
457
 *        new lock will take over the refcount.
458
 * returns: lock with refcount 2 - one for current caller and one for remote
pschwan's avatar
   
pschwan committed
459
 */
vitaly's avatar
vitaly committed
460
static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource)
461
{
462
463
	struct ldlm_lock *lock;
	ENTRY;
464

465
466
	if (resource == NULL)
		LBUG();
467

468
469
470
	OBD_SLAB_ALLOC_PTR_GFP(lock, ldlm_lock_slab, GFP_NOFS);
	if (lock == NULL)
		RETURN(NULL);
471

472
473
	spin_lock_init(&lock->l_lock);
	lock->l_resource = resource;
474
	lu_ref_add(&resource->lr_reference, "lock", lock);
475

476
	refcount_set(&lock->l_handle.h_ref, 2);
477
478
479
480
481
482
	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);
483
484
	init_waitqueue_head(&lock->l_waitq);
	lock->l_blocking_lock = NULL;
485
486
487
488
	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);
489

490
491
        lprocfs_counter_incr(ldlm_res_to_ns(resource)->ns_stats,
                             LDLM_NSS_LOCKS);
492
	INIT_HLIST_NODE(&lock->l_handle.h_link);
493
	class_handle_hash(&lock->l_handle, lock_handle_owner);
494

495
496
        lu_ref_init(&lock->l_reference);
        lu_ref_add(&lock->l_reference, "hash", lock);
497
	lock->l_callback_timestamp = 0;
498
	lock->l_activity = 0;
499

zam's avatar
zam committed
500
#if LUSTRE_TRACKS_LOCK_EXP_REFS
501
	INIT_LIST_HEAD(&lock->l_exp_refs_link);
502
503
        lock->l_exp_refs_nr = 0;
        lock->l_exp_refs_target = NULL;
zam's avatar
zam committed
504
#endif
505
	INIT_LIST_HEAD(&lock->l_exp_list);
zam's avatar
zam committed
506

507
        RETURN(lock);
508
509
}

Ned Bass's avatar
Ned Bass committed
510
511
512
513
514
/**
 * 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)
 */
515
int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
tappro's avatar
tappro committed
516
                              const struct ldlm_res_id *new_resid)
517
{
518
	struct ldlm_resource *oldres;
alex's avatar
b=7200    
alex committed
519
520
        struct ldlm_resource *newres;
        int type;
521
522
        ENTRY;

yury's avatar
b=13872    
yury committed
523
        LASSERT(ns_is_client(ns));
alex's avatar
b=7200    
alex committed
524

525
526
527
	oldres = lock_res_and_lock(lock);
	if (memcmp(new_resid, &oldres->lr_name,
		   sizeof(oldres->lr_name)) == 0) {
528
                /* Nothing to do */
alex's avatar
b=7200    
alex committed
529
                unlock_res_and_lock(lock);
530
531
                RETURN(0);
        }
532

tappro's avatar
tappro committed
533
        LASSERT(new_resid->name[0] != 0);
pschwan's avatar
pschwan committed
534
535

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

alex's avatar
b=7200    
alex committed
538
        type = oldres->lr_type;
nathan's avatar
nathan committed
539
540
        unlock_res_and_lock(lock);

541
542
543
	newres = ldlm_resource_get(ns, NULL, new_resid, type, 1);
	if (IS_ERR(newres))
		RETURN(PTR_ERR(newres));
544
545

        lu_ref_add(&newres->lr_reference, "lock", lock);
546
        /*
547
548
549
550
         * 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.
551
         */
552
	spin_lock(&lock->l_lock);
553
554
555
556
557
        oldres = lock->l_resource;
        if (oldres < newres) {
                lock_res(oldres);
                lock_res_nested(newres, LRT_NEW);
        } else {
nikita's avatar
nikita committed
558
                lock_res(newres);
559
560
561
562
                lock_res_nested(oldres, LRT_NEW);
        }
        LASSERT(memcmp(new_resid, &oldres->lr_name,
                       sizeof oldres->lr_name) != 0);
563
        lock->l_resource = newres;
alex's avatar
b=3984    
alex committed
564
        unlock_res(oldres);
565
        unlock_res_and_lock(lock);
alex's avatar
b=3984    
alex committed
566

pschwan's avatar
   
pschwan committed
567
        /* ...and the flowers are still standing! */
568
        lu_ref_del(&oldres->lr_reference, "lock", lock);
pschwan's avatar
   
pschwan committed
569
        ldlm_resource_putref(oldres);
570
571
572
573

        RETURN(0);
}

Ned Bass's avatar
Ned Bass committed
574
575
576
/** \defgroup ldlm_handles LDLM HANDLES
 * Ways to get hold of locks without any addresses.
 * @{
577
 */
578

Ned Bass's avatar
Ned Bass committed
579
580
581
582
/**
 * Fills in handle for LDLM lock \a lock into supplied \a lockh
 * Does not take any references.
 */
tappro's avatar
tappro committed
583
void ldlm_lock2handle(const struct ldlm_lock *lock, struct lustre_handle *lockh)
584
{
Ned Bass's avatar
Ned Bass committed
585
	lockh->cookie = lock->l_handle.h_cookie;
586
}
587
EXPORT_SYMBOL(ldlm_lock2handle);
588

Ned Bass's avatar
Ned Bass committed
589
590
591
592
593
/**
 * Obtain a lock reference by handle.
 *
 * if \a flags: atomically get the lock and set the flags.
 *              Return NULL if flag already set
594
 */
tappro's avatar
tappro committed
595
struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle,
596
				     __u64 flags)
597
{
598
599
	struct ldlm_lock *lock;
	ENTRY;
600

601
	LASSERT(handle);
adilger's avatar
adilger committed
602

603
604
605
	if (!lustre_handle_is_used(handle))
		RETURN(NULL);

606
	lock = class_handle2object(handle->cookie, lock_handle_owner);
607
608
	if (lock == NULL)
		RETURN(NULL);
609

610
611
612
613
614
615
616
	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);
	}

617
618
	/* It's unlikely but possible that someone marked the lock as
	 * destroyed after we did handle2object on it */
619
	if ((flags == 0) && !ldlm_is_destroyed(lock)) {
620
		lu_ref_add_atomic(&lock->l_reference, "handle", lock);
621
622
		RETURN(lock);
	}
623

624
	lock_res_and_lock(lock);
625

626
	LASSERT(lock->l_resource != NULL);
627

628
	lu_ref_add_atomic(&lock->l_reference, "handle", lock);
629
	if (unlikely(ldlm_is_destroyed(lock))) {
630
631
632
633
634
		unlock_res_and_lock(lock);
		CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock);
		LDLM_LOCK_PUT(lock);
		RETURN(NULL);
	}
635

636
637
638
639
640
641
642
	/* 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);
		}
643

644
		lock->l_flags |= flags;
645
	}
646

647
648
	unlock_res_and_lock(lock);
	RETURN(lock);
649
}
650
EXPORT_SYMBOL(__ldlm_handle2lock);
Ned Bass's avatar
Ned Bass committed
651
/** @} ldlm_handles */
652

Ned Bass's avatar
Ned Bass committed
653
654
655
656
/**
 * Fill in "on the wire" representation for given LDLM lock into supplied
 * lock descriptor \a desc structure.
 */
657
658
void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc)
{
659
660
661
662
663
664
	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);
665
666
}

Ned Bass's avatar
Ned Bass committed
667
668
669
670
671
/**
 * 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.
 */
672
673
static void ldlm_add_bl_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
				  struct list_head *work_list)
674
{
675
676
677
678
679
680
681
	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);
682
683
684
685
686
687
688
689
690
691
692
693
694

		/* 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
695
696
}

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

Ned Bass's avatar
Ned Bass committed
712
713
714
715
716
717
/**
 * 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
718
void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
719
			    struct list_head *work_list)
alex's avatar
b=3984    
alex committed
720
721
722
723
724
{
        ENTRY;
        check_res_locked(lock->l_resource);
        if (new)
                ldlm_add_bl_work_item(lock, new, work_list);
tappro's avatar
tappro committed
725
        else
alex's avatar
b=3984    
alex committed
726
                ldlm_add_cp_work_item(lock, work_list);
pschwan's avatar
pschwan committed
727
        EXIT;
728
}
729

Ned Bass's avatar
Ned Bass committed
730
731
732
733
734
/**
 * 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.
 */
735
void ldlm_lock_addref(const struct lustre_handle *lockh, enum ldlm_mode mode)
736
{
737
	struct ldlm_lock *lock;
738

739
	lock = ldlm_handle2lock(lockh);
740
	LASSERTF(lock != NULL, "Non-existing lock: %#llx\n", lockh->cookie);
741
742
	ldlm_lock_addref_internal(lock, mode);
	LDLM_LOCK_PUT(lock);
743
}
744
EXPORT_SYMBOL(ldlm_lock_addref);
745

Ned Bass's avatar
Ned Bass committed
746
747
748
749
750
751
752
/**
 * 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.
 */
753
754
void ldlm_lock_addref_internal_nolock(struct ldlm_lock *lock,
				      enum ldlm_mode mode)
755
{
pschwan's avatar
pschwan committed
756
        ldlm_lock_remove_from_lru(lock);
757
        if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
758
                lock->l_readers++;
759
760
                lu_ref_add_atomic(&lock->l_reference, "reader", lock);
        }
zam's avatar
zam committed
761
        if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
762
                lock->l_writers++;
763
764
                lu_ref_add_atomic(&lock->l_reference, "writer", lock);
        }
765
        LDLM_LOCK_GET(lock);
766
        lu_ref_add_atomic(&lock->l_reference, "user", lock);
767
        LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]);
alex's avatar
b=3984    
alex committed
768
769
}

770
/**
Ned Bass's avatar
Ned Bass committed
771
772
 * Attempts to add reader/writer reference to a lock with handle \a lockh, and
 * fails if lock is already LDLM_FL_CBPENDING or destroyed.
773
774
775
776
777
 *
 * \retval 0 success, lock was addref-ed
 *
 * \retval -EAGAIN lock is being canceled.
 */
778
int ldlm_lock_addref_try(const struct lustre_handle *lockh, enum ldlm_mode mode)
779
780
781
782
783
784
785
786
{
        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
787
                if (lock->l_readers != 0 || lock->l_writers != 0 ||
788
		    !ldlm_is_cbpending(lock)) {
789
790
791
792
793
794
795
796
                        ldlm_lock_addref_internal_nolock(lock, mode);
                        result = 0;
                }
                unlock_res_and_lock(lock);
                LDLM_LOCK_PUT(lock);
        }
        return result;
}
797
EXPORT_SYMBOL(ldlm_lock_addref_try);
798

Ned Bass's avatar
Ned Bass committed
799
800
801
802
803
/**
 * 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.
 */
804
void ldlm_lock_addref_internal(struct ldlm_lock *lock, enum ldlm_mode mode)
alex's avatar
b=3984    
alex committed
805
{
806
807
808
	lock_res_and_lock(lock);
	ldlm_lock_addref_internal_nolock(lock, mode);
	unlock_res_and_lock(lock);
809
810
}

Ned Bass's avatar
Ned Bass committed
811
812
813
814
815
816
817
/**
 * 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.
 */
818
819
void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock,
				      enum ldlm_mode mode)
820
{
yury's avatar
yury committed
821
        LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
822
        if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
823
                LASSERT(lock->l_readers > 0);
824
                lu_ref_del(&lock->l_reference, "reader", lock);
825
                lock->l_readers--;
826
        }
zam's avatar
zam committed
827
        if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
828
                LASSERT(lock->l_writers > 0);
829
                lu_ref_del(&lock->l_reference, "writer", lock);
830
                lock->l_writers--;
831
        }
832

833
834
        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
835
836
}

Ned Bass's avatar
Ned Bass committed
837
838
839
840
841
842
843
844
/**
 * 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.
 */
845
void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode)
yury's avatar
b=15260    
yury committed
846
{
847
	struct ldlm_namespace *ns;
yury's avatar
b=15260    
yury committed
848

849
	ENTRY;
yury's avatar
b=15260    
yury committed
850

851
852
853
	lock_res_and_lock(lock);

	ns = ldlm_lock_to_ns(lock);
yury's avatar
b=15260    
yury committed
854

855
	ldlm_lock_decref_internal_nolock(lock, mode);
yury's avatar
b=15260    
yury committed
856

857
858
859
860
861
	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.
		 *
862
863
864
865
866
867
		 * 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 */
868
869
870
871
		ldlm_set_cbpending(lock);
	}

	if (!lock->l_readers && !lock->l_writers && ldlm_is_cbpending(lock)) {
872
873
		unsigned int mask = D_DLMTRACE;

874
875
		/* If we received a blocked AST and this was the last reference,
		 * run the callback. */
876
		if (ldlm_is_ns_srv(lock) && lock->l_export)
877
878
879
880
			mask |= D_WARNING;
		LDLM_DEBUG_LIMIT(mask, lock,
				 "final decref done on %sCBPENDING lock",
				 mask & D_WARNING ? "non-local " : "");
881

882
883
884
		LDLM_LOCK_GET(lock); /* dropped by bl thread */
		ldlm_lock_remove_from_lru(lock);
		unlock_res_and_lock(lock);
yury's avatar
b=18028    
yury committed
885

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

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

898
899
900
901