GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / staging / lustre / lustre / lmv / lmv_intent.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) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 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
33 #define DEBUG_SUBSYSTEM S_LMV
34 #include <linux/slab.h>
35 #include <linux/module.h>
36 #include <linux/pagemap.h>
37 #include <asm/div64.h>
38 #include <linux/seq_file.h>
39 #include <linux/namei.h>
40 #include <lustre_intent.h>
41 #include <obd_support.h>
42 #include <lustre_lib.h>
43 #include <lustre_net.h>
44 #include <lustre_dlm.h>
45 #include <lustre_mdc.h>
46 #include <obd_class.h>
47 #include <lprocfs_status.h>
48 #include "lmv_internal.h"
49
50 static int lmv_intent_remote(struct obd_export *exp, struct lookup_intent *it,
51                              const struct lu_fid *parent_fid,
52                              struct ptlrpc_request **reqp,
53                              ldlm_blocking_callback cb_blocking,
54                              __u64 extra_lock_flags)
55 {
56         struct obd_device       *obd = exp->exp_obd;
57         struct lmv_obd          *lmv = &obd->u.lmv;
58         struct ptlrpc_request   *req = NULL;
59         struct lustre_handle    plock;
60         struct md_op_data       *op_data;
61         struct lmv_tgt_desc     *tgt;
62         struct mdt_body         *body;
63         int                     pmode;
64         int                     rc = 0;
65
66         body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
67         if (!body)
68                 return -EPROTO;
69
70         LASSERT((body->mbo_valid & OBD_MD_MDS));
71
72         /*
73          * Unfortunately, we have to lie to MDC/MDS to retrieve
74          * attributes llite needs and provideproper locking.
75          */
76         if (it->it_op & IT_LOOKUP)
77                 it->it_op = IT_GETATTR;
78
79         /*
80          * We got LOOKUP lock, but we really need attrs.
81          */
82         pmode = it->it_lock_mode;
83         if (pmode) {
84                 plock.cookie = it->it_lock_handle;
85                 it->it_lock_mode = 0;
86                 it->it_request = NULL;
87         }
88
89         LASSERT(fid_is_sane(&body->mbo_fid1));
90
91         tgt = lmv_find_target(lmv, &body->mbo_fid1);
92         if (IS_ERR(tgt)) {
93                 rc = PTR_ERR(tgt);
94                 goto out;
95         }
96
97         op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
98         if (!op_data) {
99                 rc = -ENOMEM;
100                 goto out;
101         }
102
103         op_data->op_fid1 = body->mbo_fid1;
104         /* Sent the parent FID to the remote MDT */
105         if (parent_fid) {
106                 /* The parent fid is only for remote open to
107                  * check whether the open is from OBF,
108                  * see mdt_cross_open
109                  */
110                 LASSERT(it->it_op & IT_OPEN);
111                 op_data->op_fid2 = *parent_fid;
112         }
113
114         op_data->op_bias = MDS_CROSS_REF;
115         CDEBUG(D_INODE, "REMOTE_INTENT with fid=" DFID " -> mds #%u\n",
116                PFID(&body->mbo_fid1), tgt->ltd_idx);
117
118         rc = md_intent_lock(tgt->ltd_exp, op_data, it, &req, cb_blocking,
119                             extra_lock_flags);
120         if (rc)
121                 goto out_free_op_data;
122
123         /*
124          * LLite needs LOOKUP lock to track dentry revocation in order to
125          * maintain dcache consistency. Thus drop UPDATE|PERM lock here
126          * and put LOOKUP in request.
127          */
128         if (it->it_lock_mode != 0) {
129                 it->it_remote_lock_handle =
130                                         it->it_lock_handle;
131                 it->it_remote_lock_mode = it->it_lock_mode;
132         }
133
134         if (pmode) {
135                 it->it_lock_handle = plock.cookie;
136                 it->it_lock_mode = pmode;
137         }
138
139 out_free_op_data:
140         kfree(op_data);
141 out:
142         if (rc && pmode)
143                 ldlm_lock_decref(&plock, pmode);
144
145         ptlrpc_req_finished(*reqp);
146         *reqp = req;
147         return rc;
148 }
149
150 int lmv_revalidate_slaves(struct obd_export *exp,
151                           const struct lmv_stripe_md *lsm,
152                           ldlm_blocking_callback cb_blocking,
153                           int extra_lock_flags)
154 {
155         struct obd_device *obd = exp->exp_obd;
156         struct lmv_obd *lmv = &obd->u.lmv;
157         struct ptlrpc_request *req = NULL;
158         struct mdt_body *body;
159         struct md_op_data *op_data;
160         int rc = 0, i;
161
162         /**
163          * revalidate slaves has some problems, temporarily return,
164          * we may not need that
165          */
166         op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
167         if (!op_data)
168                 return -ENOMEM;
169
170         /**
171          * Loop over the stripe information, check validity and update them
172          * from MDS if needed.
173          */
174         for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
175                 struct lookup_intent it = { .it_op = IT_GETATTR };
176                 struct lustre_handle *lockh = NULL;
177                 struct lmv_tgt_desc *tgt = NULL;
178                 struct inode *inode;
179                 struct lu_fid fid;
180
181                 fid = lsm->lsm_md_oinfo[i].lmo_fid;
182                 inode = lsm->lsm_md_oinfo[i].lmo_root;
183
184                 /*
185                  * Prepare op_data for revalidating. Note that @fid2 shluld be
186                  * defined otherwise it will go to server and take new lock
187                  * which is not needed here.
188                  */
189                 memset(op_data, 0, sizeof(*op_data));
190                 op_data->op_fid1 = fid;
191                 op_data->op_fid2 = fid;
192
193                 tgt = lmv_locate_mds(lmv, op_data, &fid);
194                 if (IS_ERR(tgt)) {
195                         rc = PTR_ERR(tgt);
196                         goto cleanup;
197                 }
198
199                 CDEBUG(D_INODE, "Revalidate slave " DFID " -> mds #%u\n",
200                        PFID(&fid), tgt->ltd_idx);
201
202                 if (req) {
203                         ptlrpc_req_finished(req);
204                         req = NULL;
205                 }
206
207                 rc = md_intent_lock(tgt->ltd_exp, op_data, &it, &req,
208                                     cb_blocking, extra_lock_flags);
209                 if (rc < 0)
210                         goto cleanup;
211
212                 lockh = (struct lustre_handle *)&it.it_lock_handle;
213                 if (rc > 0 && !req) {
214                         /* slave inode is still valid */
215                         CDEBUG(D_INODE, "slave " DFID " is still valid.\n",
216                                PFID(&fid));
217                         rc = 0;
218                 } else {
219                         /* refresh slave from server */
220                         body = req_capsule_server_get(&req->rq_pill,
221                                                       &RMF_MDT_BODY);
222                         if (!body) {
223                                 if (it.it_lock_mode && lockh) {
224                                         ldlm_lock_decref(lockh, it.it_lock_mode);
225                                         it.it_lock_mode = 0;
226                                 }
227
228                                 rc = -ENOENT;
229                                 goto cleanup;
230                         }
231
232                         i_size_write(inode, body->mbo_size);
233                         inode->i_blocks = body->mbo_blocks;
234                         set_nlink(inode, body->mbo_nlink);
235                         LTIME_S(inode->i_atime) = body->mbo_atime;
236                         LTIME_S(inode->i_ctime) = body->mbo_ctime;
237                         LTIME_S(inode->i_mtime) = body->mbo_mtime;
238                 }
239
240                 md_set_lock_data(tgt->ltd_exp, lockh, inode, NULL);
241
242                 if (it.it_lock_mode && lockh) {
243                         ldlm_lock_decref(lockh, it.it_lock_mode);
244                         it.it_lock_mode = 0;
245                 }
246         }
247
248 cleanup:
249         if (req)
250                 ptlrpc_req_finished(req);
251
252         kfree(op_data);
253         return rc;
254 }
255
256 /*
257  * IT_OPEN is intended to open (and create, possible) an object. Parent (pid)
258  * may be split dir.
259  */
260 static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
261                            struct lookup_intent *it,
262                            struct ptlrpc_request **reqp,
263                            ldlm_blocking_callback cb_blocking,
264                            __u64 extra_lock_flags)
265 {
266         struct obd_device       *obd = exp->exp_obd;
267         struct lmv_obd          *lmv = &obd->u.lmv;
268         struct lmv_tgt_desc     *tgt;
269         struct mdt_body         *body;
270         int                     rc;
271
272         if (it->it_flags & MDS_OPEN_BY_FID) {
273                 LASSERT(fid_is_sane(&op_data->op_fid2));
274
275                 /*
276                  * for striped directory, we can't know parent stripe fid
277                  * without name, but we can set it to child fid, and MDT
278                  * will obtain it from linkea in open in such case.
279                  */
280                 if (op_data->op_mea1)
281                         op_data->op_fid1 = op_data->op_fid2;
282
283                 tgt = lmv_find_target(lmv, &op_data->op_fid2);
284                 if (IS_ERR(tgt))
285                         return PTR_ERR(tgt);
286
287                 op_data->op_mds = tgt->ltd_idx;
288         } else {
289                 LASSERT(fid_is_sane(&op_data->op_fid1));
290                 LASSERT(fid_is_zero(&op_data->op_fid2));
291                 LASSERT(op_data->op_name);
292
293                 tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
294                 if (IS_ERR(tgt))
295                         return PTR_ERR(tgt);
296         }
297
298         /* If it is ready to open the file by FID, do not need
299          * allocate FID at all, otherwise it will confuse MDT
300          */
301         if ((it->it_op & IT_CREAT) && !(it->it_flags & MDS_OPEN_BY_FID)) {
302                 /*
303                  * For lookup(IT_CREATE) cases allocate new fid and setup FLD
304                  * for it.
305                  */
306                 rc = lmv_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
307                 if (rc != 0)
308                         return rc;
309         }
310
311         CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u\n",
312                PFID(&op_data->op_fid1),
313                PFID(&op_data->op_fid2), op_data->op_name, tgt->ltd_idx);
314
315         rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp, cb_blocking,
316                             extra_lock_flags);
317         if (rc != 0)
318                 return rc;
319         /*
320          * Nothing is found, do not access body->mbo_fid1 as it is zero and thus
321          * pointless.
322          */
323         if ((it->it_disposition & DISP_LOOKUP_NEG) &&
324             !(it->it_disposition & DISP_OPEN_CREATE) &&
325             !(it->it_disposition & DISP_OPEN_OPEN))
326                 return rc;
327
328         body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
329         if (!body)
330                 return -EPROTO;
331
332         /* Not cross-ref case, just get out of here. */
333         if (unlikely((body->mbo_valid & OBD_MD_MDS))) {
334                 rc = lmv_intent_remote(exp, it, &op_data->op_fid1, reqp,
335                                        cb_blocking, extra_lock_flags);
336                 if (rc != 0)
337                         return rc;
338
339                 body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
340                 if (!body)
341                         return -EPROTO;
342         }
343
344         return rc;
345 }
346
347 /*
348  * Handler for: getattr, lookup and revalidate cases.
349  */
350 static int lmv_intent_lookup(struct obd_export *exp,
351                              struct md_op_data *op_data,
352                              struct lookup_intent *it,
353                              struct ptlrpc_request **reqp,
354                              ldlm_blocking_callback cb_blocking,
355                              __u64 extra_lock_flags)
356 {
357         struct lmv_stripe_md *lsm = op_data->op_mea1;
358         struct obd_device      *obd = exp->exp_obd;
359         struct lmv_obd   *lmv = &obd->u.lmv;
360         struct lmv_tgt_desc    *tgt = NULL;
361         struct mdt_body *body;
362         int                  rc = 0;
363
364         /*
365          * If it returns ERR_PTR(-EBADFD) then it is an unknown hash type
366          * it will try all stripes to locate the object
367          */
368         tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
369         if (IS_ERR(tgt) && (PTR_ERR(tgt) != -EBADFD))
370                 return PTR_ERR(tgt);
371
372         /*
373          * Both migrating dir and unknown hash dir need to try
374          * all of sub-stripes
375          */
376         if (lsm && !lmv_is_known_hash_type(lsm->lsm_md_hash_type)) {
377                 struct lmv_oinfo *oinfo = &lsm->lsm_md_oinfo[0];
378
379                 op_data->op_fid1 = oinfo->lmo_fid;
380                 op_data->op_mds = oinfo->lmo_mds;
381                 tgt = lmv_get_target(lmv, oinfo->lmo_mds, NULL);
382                 if (IS_ERR(tgt))
383                         return PTR_ERR(tgt);
384         }
385
386         if (!fid_is_sane(&op_data->op_fid2))
387                 fid_zero(&op_data->op_fid2);
388
389         CDEBUG(D_INODE, "LOOKUP_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u lsm=%p lsm_magic=%x\n",
390                PFID(&op_data->op_fid1), PFID(&op_data->op_fid2),
391                op_data->op_name ? op_data->op_name : "<NULL>",
392                tgt->ltd_idx, lsm, !lsm ? -1 : lsm->lsm_md_magic);
393
394         op_data->op_bias &= ~MDS_CROSS_REF;
395
396         rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp, cb_blocking,
397                             extra_lock_flags);
398         if (rc < 0)
399                 return rc;
400
401         if (!*reqp) {
402                 /*
403                  * If RPC happens, lsm information will be revalidated
404                  * during update_inode process (see ll_update_lsm_md)
405                  */
406                 if (op_data->op_mea2) {
407                         rc = lmv_revalidate_slaves(exp, op_data->op_mea2,
408                                                    cb_blocking,
409                                                    extra_lock_flags);
410                         if (rc != 0)
411                                 return rc;
412                 }
413                 return rc;
414         } else if (it_disposition(it, DISP_LOOKUP_NEG) && lsm &&
415                    lmv_need_try_all_stripes(lsm)) {
416                 /*
417                  * For migrating and unknown hash type directory, it will
418                  * try to target the entry on other stripes
419                  */
420                 int stripe_index;
421
422                 for (stripe_index = 1;
423                      stripe_index < lsm->lsm_md_stripe_count &&
424                      it_disposition(it, DISP_LOOKUP_NEG); stripe_index++) {
425                         struct lmv_oinfo *oinfo;
426
427                         /* release the previous request */
428                         ptlrpc_req_finished(*reqp);
429                         it->it_request = NULL;
430                         *reqp = NULL;
431
432                         oinfo = &lsm->lsm_md_oinfo[stripe_index];
433                         tgt = lmv_find_target(lmv, &oinfo->lmo_fid);
434                         if (IS_ERR(tgt))
435                                 return PTR_ERR(tgt);
436
437                         CDEBUG(D_INODE, "Try other stripes " DFID "\n",
438                                PFID(&oinfo->lmo_fid));
439
440                         op_data->op_fid1 = oinfo->lmo_fid;
441                         it->it_disposition &= ~DISP_ENQ_COMPLETE;
442                         rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp,
443                                             cb_blocking, extra_lock_flags);
444                         if (rc)
445                                 return rc;
446                 }
447         }
448
449         /*
450          * MDS has returned success. Probably name has been resolved in
451          * remote inode. Let's check this.
452          */
453         body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
454         if (!body)
455                 return -EPROTO;
456
457         /* Not cross-ref case, just get out of here. */
458         if (unlikely((body->mbo_valid & OBD_MD_MDS))) {
459                 rc = lmv_intent_remote(exp, it, NULL, reqp, cb_blocking,
460                                        extra_lock_flags);
461                 if (rc != 0)
462                         return rc;
463                 body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
464                 if (!body)
465                         return -EPROTO;
466         }
467
468         return rc;
469 }
470
471 int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
472                     struct lookup_intent *it, struct ptlrpc_request **reqp,
473                     ldlm_blocking_callback cb_blocking,
474                     __u64 extra_lock_flags)
475 {
476         int             rc;
477
478         LASSERT(fid_is_sane(&op_data->op_fid1));
479
480         CDEBUG(D_INODE, "INTENT LOCK '%s' for " DFID " '%*s' on " DFID "\n",
481                LL_IT2STR(it), PFID(&op_data->op_fid2),
482                (int)op_data->op_namelen, op_data->op_name,
483                PFID(&op_data->op_fid1));
484
485         if (it->it_op & (IT_LOOKUP | IT_GETATTR | IT_LAYOUT))
486                 rc = lmv_intent_lookup(exp, op_data, it, reqp, cb_blocking,
487                                        extra_lock_flags);
488         else if (it->it_op & IT_OPEN)
489                 rc = lmv_intent_open(exp, op_data, it, reqp, cb_blocking,
490                                      extra_lock_flags);
491         else
492                 LBUG();
493
494         if (rc < 0) {
495                 struct lustre_handle lock_handle;
496
497                 if (it->it_lock_mode) {
498                         lock_handle.cookie = it->it_lock_handle;
499                         ldlm_lock_decref(&lock_handle, it->it_lock_mode);
500                 }
501
502                 it->it_lock_handle = 0;
503                 it->it_lock_mode = 0;
504
505                 if (it->it_remote_lock_mode) {
506                         lock_handle.cookie = it->it_remote_lock_handle;
507                         ldlm_lock_decref(&lock_handle,
508                                          it->it_remote_lock_mode);
509                 }
510
511                 it->it_remote_lock_handle = 0;
512                 it->it_remote_lock_mode = 0;
513         }
514
515         return rc;
516 }