Whamcloud - gitweb
LU-9452 ldlm: remove MSG_CONNECT_LIBCLIENT support
[fs/lustre-release.git] / lustre / ofd / ofd_dlm.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/ofd/ofd_dlm.c
33  *
34  * This file contains OBD Filter Device (OFD) LDLM-related code which is just
35  * intent handling for glimpse lock.
36  *
37  * Author: Andreas Dilger <andreas.dilger@intel.com>
38  * Author: Jinshan Xiong <jinshan.xiong@intel.com>
39  * Author: Alexey Zhuravlev <alexey.zhuravlev@intel.com>
40  * Author: Mikhail Pershin <mike.pershin@intel.com>
41  */
42
43 #define DEBUG_SUBSYSTEM S_FILTER
44
45 #include "ofd_internal.h"
46
47 struct ofd_intent_args {
48         struct list_head        gl_list;
49         __u64                    size;
50         bool                    no_glimpse_ast;
51         int                     error;
52 };
53
54 int ofd_dlm_init(void)
55 {
56         ldlm_glimpse_work_kmem = kmem_cache_create("ldlm_glimpse_work_kmem",
57                                              sizeof(struct ldlm_glimpse_work),
58                                              0, 0, NULL);
59         if (ldlm_glimpse_work_kmem == NULL)
60                 return -ENOMEM;
61         else
62                 return 0;
63 }
64
65 void ofd_dlm_exit(void)
66 {
67         if (ldlm_glimpse_work_kmem) {
68                 kmem_cache_destroy(ldlm_glimpse_work_kmem);
69                 ldlm_glimpse_work_kmem = NULL;
70         }
71 }
72
73 /**
74  * OFD interval callback.
75  *
76  * The interval_callback_t is part of interval_iterate_reverse() and is called
77  * for each interval in tree. The OFD interval callback searches for locks
78  * covering extents beyond the given args->size. This is used to decide if the
79  * size is too small and needs to be updated.  Note that we are only interested
80  * in growing the size, as truncate is the only operation which can shrink it,
81  * and it is handled differently.  This is why we only look at locks beyond the
82  * current size.
83  *
84  * It finds the highest lock (by starting point) in this interval, and adds it
85  * to the list of locks to glimpse.  We must glimpse a list of locks - rather
86  * than only the highest lock on the file - because lockahead creates extent
87  * locks in advance of IO, and so breaks the assumption that the holder of the
88  * highest lock knows the current file size.
89  *
90  * This assumption is normally true because locks which are created as part of
91  * IO - rather than in advance of it - are guaranteed to be 'active', i.e.,
92  * involved in IO, and the holder of the highest 'active' lock always knows the
93  * current file size, because the size is either not changing or the holder of
94  * that lock is responsible for updating it.
95  *
96  * So we need only glimpse until we find the first client with an 'active'
97  * lock.
98  *
99  * Unfortunately, there is no way to know if a manually requested/speculative
100  * lock is 'active' from the server side.  So when we see a potentially
101  * speculative lock, we must send a glimpse for that lock unless we have
102  * already sent a glimpse to the holder of that lock.
103  *
104  * However, *all* non-speculative locks are active.  So we can stop glimpsing
105  * as soon as we find a non-speculative lock.  Currently, all speculative PW
106  * locks have LDLM_FL_NO_EXPANSION set, and we use this to identify them.  This
107  * is enforced by an assertion in osc_lock_init, which references this comment.
108  *
109  * If that ever changes, we will either need to find a new way to identify
110  * active locks or we will need to consider all PW locks (we will still only
111  * glimpse one per client).
112  *
113  * Note that it is safe to glimpse only the 'top' lock from each interval
114  * because ofd_intent_cb is only called for PW extent locks, and for PW locks,
115  * there is only one lock per interval.
116  *
117  * \param[in] n         interval node
118  * \param[in,out] args  intent arguments, gl work list for identified locks
119  *
120  * \retval              INTERVAL_ITER_STOP if the interval is lower than
121  *                      file size, caller stops execution
122  * \retval              INTERVAL_ITER_CONT if callback finished successfully
123  *                      and caller may continue execution
124  */
125 static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
126 {
127         struct ldlm_interval     *node = (struct ldlm_interval *)n;
128         struct ofd_intent_args   *arg = args;
129         __u64                     size = arg->size;
130         struct ldlm_lock         *victim_lock = NULL;
131         struct ldlm_lock         *lck;
132         struct ldlm_glimpse_work *gl_work = NULL;
133         int rc = 0;
134
135         /* If the interval is lower than the current file size, just break. */
136         if (interval_high(n) <= size)
137                 GOTO(out, rc = INTERVAL_ITER_STOP);
138
139         /* Find the 'victim' lock from this interval */
140         list_for_each_entry(lck, &node->li_group, l_sl_policy) {
141                 victim_lock = LDLM_LOCK_GET(lck);
142
143                 /* the same policy group - every lock has the
144                  * same extent, so needn't do it any more */
145                 break;
146         }
147
148         /* l_export can be null in race with eviction - In that case, we will
149          * not find any locks in this interval */
150         if (!victim_lock)
151                 GOTO(out, rc = INTERVAL_ITER_CONT);
152
153         /*
154          * This check is for lock taken in ofd_destroy_by_fid() that does
155          * not have l_glimpse_ast set. So the logic is: if there is a lock
156          * with no l_glimpse_ast set, this object is being destroyed already.
157          * Hence, if you are grabbing DLM locks on the server, always set
158          * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()).
159          */
160         if (victim_lock->l_glimpse_ast == NULL) {
161                 LDLM_DEBUG(victim_lock, "no l_glimpse_ast");
162                 arg->no_glimpse_ast = true;
163                 GOTO(out_release, rc = INTERVAL_ITER_STOP);
164         }
165
166         /* If NO_EXPANSION is not set, this is an active lock, and we don't need
167          * to glimpse any further once we've glimpsed the client holding this
168          * lock.  So set us up to stop.  See comment above this function. */
169         if (!(victim_lock->l_flags & LDLM_FL_NO_EXPANSION))
170                 rc = INTERVAL_ITER_STOP;
171         else
172                 rc = INTERVAL_ITER_CONT;
173
174         /* Check to see if we're already set up to send a glimpse to this
175          * client; if so, don't add this lock to the glimpse list - We need
176          * only glimpse each client once. (And if we know that client holds
177          * an active lock, we can stop glimpsing.  So keep the rc set in the
178          * check above.) */
179         list_for_each_entry(gl_work, &arg->gl_list, gl_list) {
180                 if (gl_work->gl_lock->l_export == victim_lock->l_export)
181                         GOTO(out_release, rc);
182         }
183
184         if (!OBD_FAIL_CHECK(OBD_FAIL_OST_GL_WORK_ALLOC))
185                 OBD_SLAB_ALLOC_PTR_GFP(gl_work, ldlm_glimpse_work_kmem,
186                                        GFP_ATOMIC);
187
188         if (!gl_work) {
189                 arg->error = -ENOMEM;
190                 GOTO(out_release, rc = INTERVAL_ITER_STOP);
191         }
192
193         /* Populate the gl_work structure. */
194         gl_work->gl_lock = victim_lock;
195         list_add_tail(&gl_work->gl_list, &arg->gl_list);
196         /* There is actually no need for a glimpse descriptor when glimpsing
197          * extent locks */
198         gl_work->gl_desc = NULL;
199         /* This tells ldlm_work_gl_ast_lock this was allocated from a slab and
200          * must be freed in a slab-aware manner. */
201         gl_work->gl_flags = LDLM_GL_WORK_SLAB_ALLOCATED;
202
203         GOTO(out, rc);
204
205 out_release:
206         /* If the victim doesn't go on the glimpse list, we must release it */
207         LDLM_LOCK_RELEASE(victim_lock);
208
209 out:
210         return rc;
211 }
212 /**
213  * OFD lock intent policy
214  *
215  * This defines ldlm_namespace::ns_policy interface for OFD.
216  * Intent policy is called when lock has an intent, for OFD that
217  * means glimpse lock and policy fills Lock Value Block (LVB).
218  *
219  * If already granted lock is found it will be placed in \a lockp and
220  * returned back to caller function.
221  *
222  * \param[in] ns         namespace
223  * \param[in,out] lockp  pointer to the lock
224  * \param[in] req_cookie incoming request
225  * \param[in] mode       LDLM mode
226  * \param[in] flags      LDLM flags
227  * \param[in] data       opaque data, not used in OFD policy
228  *
229  * \retval              ELDLM_LOCK_REPLACED if already granted lock was found
230  *                      and placed in \a lockp
231  * \retval              ELDLM_LOCK_ABORTED in other cases except error
232  * \retval              negative errno on error
233  */
234 int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
235                       void *req_cookie, enum ldlm_mode mode, __u64 flags,
236                       void *data)
237 {
238         struct ptlrpc_request *req = req_cookie;
239         struct ldlm_lock *lock = *lockp;
240         struct ldlm_resource *res = lock->l_resource;
241         ldlm_processing_policy policy;
242         struct ost_lvb *res_lvb, *reply_lvb;
243         struct ldlm_reply *rep;
244         enum ldlm_error err;
245         int idx, rc;
246         struct ldlm_interval_tree *tree;
247         struct ofd_intent_args arg;
248         __u32 repsize[3] = {
249                 [MSG_PTLRPC_BODY_OFF] = sizeof(struct ptlrpc_body),
250                 [DLM_LOCKREPLY_OFF]   = sizeof(*rep),
251                 [DLM_REPLY_REC_OFF]   = sizeof(*reply_lvb)
252         };
253         struct ldlm_glimpse_work *pos, *tmp;
254         ENTRY;
255
256         INIT_LIST_HEAD(&arg.gl_list);
257         arg.no_glimpse_ast = false;
258         arg.error = 0;
259         lock->l_lvb_type = LVB_T_OST;
260         policy = ldlm_get_processing_policy(res);
261         LASSERT(policy != NULL);
262         LASSERT(req != NULL);
263
264         rc = lustre_pack_reply(req, 3, repsize, NULL);
265         if (rc)
266                 RETURN(req->rq_status = rc);
267
268         rep = lustre_msg_buf(req->rq_repmsg, DLM_LOCKREPLY_OFF, sizeof(*rep));
269         LASSERT(rep != NULL);
270
271         reply_lvb = lustre_msg_buf(req->rq_repmsg, DLM_REPLY_REC_OFF,
272                                    sizeof(*reply_lvb));
273         LASSERT(reply_lvb != NULL);
274
275         /* Call the extent policy function to see if our request can be
276          * granted, or is blocked.
277          * If the OST lock has LDLM_FL_HAS_INTENT set, it means a glimpse
278          * lock, and should not be granted if the lock will be blocked.
279          */
280
281         if (flags & LDLM_FL_BLOCK_NOWAIT) {
282                 OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_AGL_DELAY, 5);
283
284                 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_AGL_NOLOCK))
285                         RETURN(ELDLM_LOCK_ABORTED);
286         }
287
288         LASSERT(ns == ldlm_res_to_ns(res));
289         lock_res(res);
290
291         /* Check if this is a resend case (MSG_RESENT is set on RPC) and a
292          * lock was found by ldlm_handle_enqueue(); if so no need to grant
293          * it again. */
294         if (flags & LDLM_FL_RESENT) {
295                 rc = LDLM_ITER_CONTINUE;
296         } else {
297                 __u64 tmpflags = 0;
298                 rc = policy(lock, &tmpflags, LDLM_PROCESS_RESCAN, &err, NULL);
299                 check_res_locked(res);
300         }
301
302         /* The lock met with no resistance; we're finished. */
303         if (rc == LDLM_ITER_CONTINUE) {
304                 if (OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_GLIMPSE, 2)) {
305                         ldlm_resource_unlink_lock(lock);
306                         err = ELDLM_LOCK_ABORTED;
307                 } else {
308                         err = ELDLM_LOCK_REPLACED;
309                 }
310                 unlock_res(res);
311                 RETURN(err);
312         } else if (flags & LDLM_FL_BLOCK_NOWAIT) {
313                 /* LDLM_FL_BLOCK_NOWAIT means it is for AGL. Do not send glimpse
314                  * callback for glimpse size. The real size user will trigger
315                  * the glimpse callback when necessary. */
316                 unlock_res(res);
317                 RETURN(ELDLM_LOCK_ABORTED);
318         }
319
320         /* Do not grant any lock, but instead send GL callbacks.  The extent
321          * policy nicely created a list of all PW locks for us.  We will choose
322          * the highest of those which are larger than the size in the LVB, if
323          * any, and perform a glimpse callback. */
324         res_lvb = res->lr_lvb_data;
325         LASSERT(res_lvb != NULL);
326         *reply_lvb = *res_lvb;
327
328         /*
329          * ->ns_lock guarantees that no new locks are granted, and,
330          *  therefore, that res->lr_lvb_data cannot increase beyond the
331          *  end of already granted lock. As a result, it is safe to
332          *  check against "stale" reply_lvb->lvb_size value without
333          *  res->lr_lvb_sem.
334          */
335         arg.size = reply_lvb->lvb_size;
336
337         /* Check for PW locks beyond the size in the LVB, build the list
338          * of locks to glimpse (arg.gl_list) */
339         for (idx = 0; idx < LCK_MODE_NUM; idx++) {
340                 tree = &res->lr_itree[idx];
341                 if (tree->lit_mode == LCK_PR)
342                         continue;
343
344                 interval_iterate_reverse(tree->lit_root, ofd_intent_cb, &arg);
345                 if (arg.error) {
346                         unlock_res(res);
347                         GOTO(out, rc = arg.error);
348                 }
349         }
350         unlock_res(res);
351
352         /* There were no PW locks beyond the size in the LVB; finished. */
353         if (list_empty(&arg.gl_list))
354                 RETURN(ELDLM_LOCK_ABORTED);
355
356         if (arg.no_glimpse_ast) {
357                 /* We are racing with unlink(); just return -ENOENT */
358                 rep->lock_policy_res1 = ptlrpc_status_hton(-ENOENT);
359                 GOTO(out, ELDLM_LOCK_ABORTED);
360         }
361
362         /* this will update the LVB */
363         ldlm_glimpse_locks(res, &arg.gl_list);
364
365         lock_res(res);
366         *reply_lvb = *res_lvb;
367         unlock_res(res);
368
369 out:
370         /* If the list is not empty, we failed to glimpse some locks and
371          * must clean up.  Usually due to a race with unlink.*/
372         list_for_each_entry_safe(pos, tmp, &arg.gl_list, gl_list) {
373                 list_del(&pos->gl_list);
374                 LDLM_LOCK_RELEASE(pos->gl_lock);
375                 OBD_SLAB_FREE_PTR(pos, ldlm_glimpse_work_kmem);
376         }
377
378         RETURN(rc < 0 ? rc : ELDLM_LOCK_ABORTED);
379 }
380