4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2014, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
38 * Author: Nikita Danilov <nikita.danilov@sun.com>
39 * Author: Jinshan Xiong <jinshan.xiong@intel.com>
42 #define DEBUG_SUBSYSTEM S_CLASS
44 #include <linux/list.h>
45 #include <libcfs/libcfs.h>
46 #include <obd_class.h>
47 #include <obd_support.h>
48 #include <lustre_fid.h>
49 #include <cl_object.h>
50 #include "cl_internal.h"
52 static void cl_lock_trace0(int level, const struct lu_env *env,
53 const char *prefix, const struct cl_lock *lock,
54 const char *func, const int line)
56 struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj);
57 CDEBUG(level, "%s: %p (%p/%d) at %s():%d\n",
58 prefix, lock, env, h->coh_nesting, func, line);
60 #define cl_lock_trace(level, env, prefix, lock) \
61 cl_lock_trace0(level, env, prefix, lock, __FUNCTION__, __LINE__)
64 * Adds lock slice to the compound lock.
66 * This is called by cl_object_operations::coo_lock_init() methods to add a
67 * per-layer state to the lock. New state is added at the end of
68 * cl_lock::cll_layers list, that is, it is at the bottom of the stack.
70 * \see cl_req_slice_add(), cl_page_slice_add(), cl_io_slice_add()
72 void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice,
73 struct cl_object *obj,
74 const struct cl_lock_operations *ops)
77 slice->cls_lock = lock;
78 list_add_tail(&slice->cls_linkage, &lock->cll_layers);
83 EXPORT_SYMBOL(cl_lock_slice_add);
85 void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock)
89 cl_lock_trace(D_DLMTRACE, env, "destroy lock", lock);
91 while (!list_empty(&lock->cll_layers)) {
92 struct cl_lock_slice *slice;
94 slice = list_entry(lock->cll_layers.next,
95 struct cl_lock_slice, cls_linkage);
96 list_del_init(lock->cll_layers.next);
97 slice->cls_ops->clo_fini(env, slice);
99 POISON(lock, 0x5a, sizeof(*lock));
102 EXPORT_SYMBOL(cl_lock_fini);
104 int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
105 const struct cl_io *io)
107 struct cl_object *obj = lock->cll_descr.cld_obj;
108 struct cl_object *scan;
112 /* Make sure cl_lock::cll_descr is initialized. */
113 LASSERT(obj != NULL);
115 INIT_LIST_HEAD(&lock->cll_layers);
116 list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
118 result = scan->co_ops->coo_lock_init(env, scan, lock, io);
120 cl_lock_fini(env, lock);
126 EXPORT_SYMBOL(cl_lock_init);
129 * Returns a slice with a lock, corresponding to the given layer in the
134 const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock,
135 const struct lu_device_type *dtype)
137 const struct cl_lock_slice *slice;
141 list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
142 if (slice->cls_obj->co_lu.lo_dev->ld_type == dtype)
147 EXPORT_SYMBOL(cl_lock_at);
149 void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock)
151 const struct cl_lock_slice *slice;
154 cl_lock_trace(D_DLMTRACE, env, "cancel lock", lock);
155 list_for_each_entry_reverse(slice, &lock->cll_layers, cls_linkage) {
156 if (slice->cls_ops->clo_cancel != NULL)
157 slice->cls_ops->clo_cancel(env, slice);
162 EXPORT_SYMBOL(cl_lock_cancel);
166 * \param anchor: if we need to wait for resources before getting the lock,
167 * use @anchor for the purpose.
168 * \retval 0 enqueue successfully
169 * \retval <0 error code
171 int cl_lock_enqueue(const struct lu_env *env, struct cl_io *io,
172 struct cl_lock *lock, struct cl_sync_io *anchor)
174 const struct cl_lock_slice *slice;
179 list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
180 if (slice->cls_ops->clo_enqueue == NULL)
183 rc = slice->cls_ops->clo_enqueue(env, slice, io, anchor);
189 EXPORT_SYMBOL(cl_lock_enqueue);
192 * Main high-level entry point of cl_lock interface that finds existing or
193 * enqueues new lock matching given description.
195 int cl_lock_request(const struct lu_env *env, struct cl_io *io,
196 struct cl_lock *lock)
198 struct cl_sync_io *anchor = NULL;
199 __u32 enq_flags = lock->cll_descr.cld_enq_flags;
203 rc = cl_lock_init(env, lock, io);
207 if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) {
208 anchor = &cl_env_info(env)->clt_anchor;
209 cl_sync_io_init(anchor, 1, cl_sync_io_end);
212 rc = cl_lock_enqueue(env, io, lock, anchor);
214 if (anchor != NULL) {
217 /* drop the reference count held at initialization time */
218 cl_sync_io_note(env, anchor, 0);
219 rc2 = cl_sync_io_wait(env, anchor, 0);
220 if (rc2 < 0 && rc == 0)
225 cl_lock_release(env, lock);
228 EXPORT_SYMBOL(cl_lock_request);
231 * Releases a hold and a reference on a lock, obtained by cl_lock_hold().
233 void cl_lock_release(const struct lu_env *env, struct cl_lock *lock)
237 cl_lock_trace(D_DLMTRACE, env, "release lock", lock);
238 cl_lock_cancel(env, lock);
239 cl_lock_fini(env, lock);
242 EXPORT_SYMBOL(cl_lock_release);
244 const char *cl_lock_mode_name(const enum cl_lock_mode mode)
246 static const char * const names[] = {
251 CLASSERT(CLM_MAX == ARRAY_SIZE(names));
254 EXPORT_SYMBOL(cl_lock_mode_name);
257 * Prints human readable representation of a lock description.
259 void cl_lock_descr_print(const struct lu_env *env, void *cookie,
260 lu_printer_t printer,
261 const struct cl_lock_descr *descr)
263 const struct lu_fid *fid;
265 fid = lu_object_fid(&descr->cld_obj->co_lu);
266 (*printer)(env, cookie, DDESCR"@"DFID, PDESCR(descr), PFID(fid));
268 EXPORT_SYMBOL(cl_lock_descr_print);
271 * Prints human readable representation of \a lock to the \a f.
273 void cl_lock_print(const struct lu_env *env, void *cookie,
274 lu_printer_t printer, const struct cl_lock *lock)
276 const struct cl_lock_slice *slice;
278 (*printer)(env, cookie, "lock@%p", lock);
279 cl_lock_descr_print(env, cookie, printer, &lock->cll_descr);
280 (*printer)(env, cookie, " {\n");
282 list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
283 (*printer)(env, cookie, " %s@%p: ",
284 slice->cls_obj->co_lu.lo_dev->ld_type->ldt_name,
286 if (slice->cls_ops->clo_print != NULL)
287 slice->cls_ops->clo_print(env, cookie, printer, slice);
288 (*printer)(env, cookie, "\n");
290 (*printer)(env, cookie, "} lock@%p\n", lock);
292 EXPORT_SYMBOL(cl_lock_print);