Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / lustre / mdt / mdt_lib.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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  *
31  * lustre/mdt/mdt_lib.c
32  *
33  * Lustre Metadata Target (mdt) request unpacking helper.
34  *
35  * Author: Peter Braam <braam@clusterfs.com>
36  * Author: Andreas Dilger <adilger@clusterfs.com>
37  * Author: Phil Schwan <phil@clusterfs.com>
38  * Author: Mike Shaver <shaver@clusterfs.com>
39  * Author: Nikita Danilov <nikita@clusterfs.com>
40  * Author: Huang Hua <huanghua@clusterfs.com>
41  * Author: Fan Yong <fanyong@clusterfs.com>
42  */
43
44 #define DEBUG_SUBSYSTEM S_MDS
45
46 #include <linux/user_namespace.h>
47 #include <linux/uidgid.h>
48
49 #include "mdt_internal.h"
50 #include <uapi/linux/lnet/nidstr.h>
51 #include <lustre_nodemap.h>
52
53 typedef enum ucred_init_type {
54         NONE_INIT       = 0,
55         BODY_INIT       = 1,
56         REC_INIT        = 2
57 } ucred_init_type_t;
58
59 static __u64 get_mrc_cr_flags(struct mdt_rec_create *mrc)
60 {
61         return (__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32);
62 }
63
64 void mdt_exit_ucred(struct mdt_thread_info *info)
65 {
66         struct lu_ucred   *uc  = mdt_ucred(info);
67         struct mdt_device *mdt = info->mti_mdt;
68
69         LASSERT(uc != NULL);
70         if (uc->uc_valid != UCRED_INIT) {
71                 uc->uc_suppgids[0] = uc->uc_suppgids[1] = -1;
72                 if (uc->uc_ginfo) {
73                         put_group_info(uc->uc_ginfo);
74                         uc->uc_ginfo = NULL;
75                 }
76                 if (uc->uc_identity) {
77                         mdt_identity_put(mdt->mdt_identity_cache,
78                                          uc->uc_identity);
79                         uc->uc_identity = NULL;
80                 }
81                 uc->uc_valid = UCRED_INIT;
82         }
83 }
84
85 static int match_nosquash_list(struct spinlock *rsi_lock,
86                                struct list_head *nidlist,
87                                struct lnet_nid *peernid)
88 {
89         int rc;
90         ENTRY;
91         spin_lock(rsi_lock);
92         rc = cfs_match_nid(peernid, nidlist);
93         spin_unlock(rsi_lock);
94         RETURN(rc);
95 }
96
97 /* root_squash for inter-MDS operations */
98 static int mdt_root_squash(struct mdt_thread_info *info,
99                            struct lnet_nid *peernid)
100 {
101         struct lu_ucred *ucred = mdt_ucred(info);
102         struct root_squash_info *squash = &info->mti_mdt->mdt_squash;
103         ENTRY;
104
105         LASSERT(ucred != NULL);
106         if (!squash->rsi_uid || ucred->uc_fsuid)
107                 RETURN(0);
108
109         if (match_nosquash_list(&squash->rsi_lock,
110                                 &squash->rsi_nosquash_nids,
111                                 peernid)) {
112                 CDEBUG(D_OTHER, "%s is in nosquash_nids list\n",
113                        libcfs_nidstr(peernid));
114                 RETURN(0);
115         }
116
117         CDEBUG(D_OTHER, "squash req from %s, (%d:%d/%x)=>(%d:%d/%x)\n",
118                libcfs_nidstr(peernid), ucred->uc_fsuid, ucred->uc_fsgid,
119                (u32)ll_capability_u32(ucred->uc_cap),
120                squash->rsi_uid, squash->rsi_gid, 0);
121
122         ucred->uc_fsuid = squash->rsi_uid;
123         ucred->uc_fsgid = squash->rsi_gid;
124         ucred->uc_cap = CAP_EMPTY_SET;
125         ucred->uc_suppgids[0] = -1;
126         ucred->uc_suppgids[1] = -1;
127         if (ucred->uc_ginfo) {
128                 put_group_info(ucred->uc_ginfo);
129                 ucred->uc_ginfo = NULL;
130         }
131
132         RETURN(0);
133 }
134
135 static void ucred_set_jobid(struct mdt_thread_info *info, struct lu_ucred *uc)
136 {
137         struct ptlrpc_request   *req = mdt_info_req(info);
138         const char              *jobid = mdt_req_get_jobid(req);
139
140         /* set jobid if specified. */
141         if (jobid)
142                 strscpy(uc->uc_jobid, jobid, sizeof(uc->uc_jobid));
143         else
144                 uc->uc_jobid[0] = '\0';
145 }
146
147 static void ucred_set_nid(struct mdt_thread_info *info, struct lu_ucred *uc)
148 {
149         if (info && info->mti_exp && info->mti_exp->exp_connection)
150                 uc->uc_nid = lnet_nid_to_nid4(
151                         &info->mti_exp->exp_connection->c_peer.nid);
152         else
153                 uc->uc_nid = LNET_NID_ANY;
154 }
155
156 static void ucred_set_audit_enabled(struct mdt_thread_info *info,
157                                     struct lu_ucred *uc)
158 {
159         struct lu_nodemap *nodemap = NULL;
160         bool audit = true;
161
162         if (info && info->mti_exp) {
163                 nodemap = nodemap_get_from_exp(info->mti_exp);
164                 if (nodemap && !IS_ERR(nodemap)) {
165                         audit = nodemap->nmf_enable_audit;
166                         nodemap_putref(nodemap);
167                 }
168         }
169
170         uc->uc_enable_audit = audit;
171 }
172
173 static void ucred_set_rbac_roles(struct mdt_thread_info *info,
174                                  struct lu_ucred *uc)
175 {
176         struct lu_nodemap *nodemap = NULL;
177         enum nodemap_rbac_roles rbac = NODEMAP_RBAC_ALL;
178
179         if (info && info->mti_exp) {
180                 nodemap = nodemap_get_from_exp(info->mti_exp);
181                 if (!IS_ERR_OR_NULL(nodemap)) {
182                         rbac = nodemap->nmf_rbac;
183                         nodemap_putref(nodemap);
184                 }
185         }
186
187         uc->uc_rbac_file_perms = !!(rbac & NODEMAP_RBAC_FILE_PERMS);
188         uc->uc_rbac_dne_ops = !!(rbac & NODEMAP_RBAC_DNE_OPS);
189         uc->uc_rbac_quota_ops = !!(rbac & NODEMAP_RBAC_QUOTA_OPS);
190         uc->uc_rbac_byfid_ops = !!(rbac & NODEMAP_RBAC_BYFID_OPS);
191         uc->uc_rbac_chlg_ops = !!(rbac & NODEMAP_RBAC_CHLG_OPS);
192         uc->uc_rbac_fscrypt_admin = !!(rbac & NODEMAP_RBAC_FSCRYPT_ADMIN);
193 }
194
195 static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
196                           void *buf)
197 {
198         struct ptlrpc_request *req = mdt_info_req(info);
199         struct mdt_device *mdt = info->mti_mdt;
200         struct ptlrpc_user_desc *pud = req->rq_user_desc;
201         struct lu_ucred *ucred = mdt_ucred(info);
202         struct lu_nodemap *nodemap;
203         struct lnet_nid peernid = req->rq_peer.nid;
204         __u32 perm = 0;
205         int setuid;
206         int setgid;
207         int rc = 0;
208
209         ENTRY;
210
211         LASSERT(req->rq_auth_gss);
212         LASSERT(!req->rq_auth_usr_mdt);
213         LASSERT(req->rq_user_desc);
214         LASSERT(ucred != NULL);
215
216         ucred->uc_valid = UCRED_INVALID;
217
218         nodemap = nodemap_get_from_exp(info->mti_exp);
219         if (IS_ERR(nodemap))
220                 RETURN(PTR_ERR(nodemap));
221
222         pud->pud_uid = nodemap_map_id(nodemap, NODEMAP_UID,
223                                        NODEMAP_CLIENT_TO_FS, pud->pud_uid);
224         pud->pud_gid = nodemap_map_id(nodemap, NODEMAP_GID,
225                                        NODEMAP_CLIENT_TO_FS, pud->pud_gid);
226         pud->pud_fsuid = nodemap_map_id(nodemap, NODEMAP_UID,
227                                        NODEMAP_CLIENT_TO_FS, pud->pud_fsuid);
228         pud->pud_fsgid = nodemap_map_id(nodemap, NODEMAP_GID,
229                                        NODEMAP_CLIENT_TO_FS, pud->pud_fsgid);
230
231         ucred->uc_o_uid = pud->pud_uid;
232         ucred->uc_o_gid = pud->pud_gid;
233         ucred->uc_o_fsuid = pud->pud_fsuid;
234         ucred->uc_o_fsgid = pud->pud_fsgid;
235
236         if (type == BODY_INIT) {
237                 struct mdt_body *body = (struct mdt_body *)buf;
238
239                 ucred->uc_suppgids[0] = body->mbo_suppgid;
240                 ucred->uc_suppgids[1] = -1;
241         }
242
243         if (!flvr_is_rootonly(req->rq_flvr.sf_rpc) &&
244             req->rq_auth_uid != pud->pud_uid) {
245                 CDEBUG(D_SEC, "local client %s: auth uid %u "
246                        "while client claims %u:%u/%u:%u\n",
247                        libcfs_nidstr(&peernid), req->rq_auth_uid,
248                        pud->pud_uid, pud->pud_gid,
249                        pud->pud_fsuid, pud->pud_fsgid);
250                 GOTO(out_nodemap, rc = -EACCES);
251         }
252
253         if (nodemap && ucred->uc_o_uid == nodemap->nm_squash_uid &&
254             nodemap->nmf_deny_unknown)
255                 /* deny access before we get identity ref */
256                 GOTO(out, rc = -EACCES);
257
258         if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
259                 ucred->uc_identity = NULL;
260                 perm = CFS_SETUID_PERM | CFS_SETGID_PERM | CFS_SETGRP_PERM;
261         } else {
262                 struct md_identity *identity;
263
264                 identity = mdt_identity_get(mdt->mdt_identity_cache,
265                                             pud->pud_uid);
266                 if (IS_ERR(identity)) {
267                         if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
268                                 ucred->uc_identity = NULL;
269                                 perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
270                                        CFS_SETGRP_PERM;
271                         } else {
272                                 CDEBUG(D_SEC,
273                                        "Deny access without identity: uid %u\n",
274                                        pud->pud_uid);
275                                 GOTO(out_nodemap, rc = -EACCES);
276                         }
277                 } else {
278                         ucred->uc_identity = identity;
279                         perm = mdt_identity_get_perm(ucred->uc_identity,
280                                                      &peernid);
281                 }
282         }
283
284         /* find out the setuid/setgid attempt */
285         setuid = (pud->pud_uid != pud->pud_fsuid);
286         setgid = ((pud->pud_gid != pud->pud_fsgid) ||
287                   (ucred->uc_identity &&
288                    (pud->pud_gid != ucred->uc_identity->mi_gid)));
289
290         /* check permission of setuid */
291         if (setuid && !(perm & CFS_SETUID_PERM)) {
292                 CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
293                        pud->pud_uid, pud->pud_fsuid, libcfs_nidstr(&peernid));
294                 GOTO(out, rc = -EACCES);
295         }
296
297         /* check permission of setgid */
298         if (setgid && !(perm & CFS_SETGID_PERM)) {
299                 CDEBUG(D_SEC,
300                        "mdt blocked setgid attempt (%u:%u/%u:%u -> %d) from %s\n",
301                        pud->pud_uid, pud->pud_gid,
302                        pud->pud_fsuid, pud->pud_fsgid,
303                        ucred->uc_identity ? ucred->uc_identity->mi_gid : -1,
304                        libcfs_nidstr(&peernid));
305                 GOTO(out, rc = -EACCES);
306         }
307
308         if (perm & CFS_SETGRP_PERM && pud->pud_ngroups) {
309                 /* setgroups for local client */
310                 ucred->uc_ginfo = groups_alloc(pud->pud_ngroups);
311                 if (!ucred->uc_ginfo) {
312                         CERROR("failed to alloc %d groups\n",
313                                pud->pud_ngroups);
314                         GOTO(out, rc = -ENOMEM);
315                 }
316
317                 lustre_groups_from_list(ucred->uc_ginfo, pud->pud_groups);
318                 lustre_groups_sort(ucred->uc_ginfo);
319         } else {
320                 ucred->uc_suppgids[0] = -1;
321                 ucred->uc_suppgids[1] = -1;
322                 ucred->uc_ginfo = NULL;
323         }
324
325         ll_set_capability_u32(&ucred->uc_cap, pud->pud_cap);
326
327         ucred->uc_uid = pud->pud_uid;
328         ucred->uc_gid = pud->pud_gid;
329
330         ucred->uc_fsuid = pud->pud_fsuid;
331         ucred->uc_fsgid = pud->pud_fsgid;
332
333         /* clear suppgids if uid or gid was squashed. */
334         if (nodemap &&
335             (ucred->uc_o_uid == nodemap->nm_squash_uid ||
336              ucred->uc_o_gid == nodemap->nm_squash_gid)) {
337
338                 ucred->uc_cap = CAP_EMPTY_SET;
339                 ucred->uc_suppgids[0] = -1;
340                 ucred->uc_suppgids[1] = -1;
341                 if (ucred->uc_ginfo) {
342                         put_group_info(ucred->uc_ginfo);
343                         ucred->uc_ginfo = NULL;
344                 }
345         }
346
347         mdt_root_squash(info, &peernid);
348
349         if (ucred->uc_fsuid) {
350                 if (!cap_issubset(ucred->uc_cap, mdt->mdt_enable_cap_mask))
351                         CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
352                                mdt_obd_name(mdt),
353 #ifdef CAP_FOR_EACH_U32
354                                ucred->uc_cap.cap[0] |
355                                ((u64)ucred->uc_cap.cap[1] << 32),
356 #else
357                                ucred->uc_cap.val,
358 #endif
359                                libcfs_nidstr(&mdt_info_req(info)->rq_peer.nid));
360                 ucred->uc_cap = cap_intersect(ucred->uc_cap,
361                                               mdt->mdt_enable_cap_mask);
362         }
363
364         /* Thanks to Kerberos, Lustre does not have to trust clients anymore,
365          * but relies on keytabs and tickets, cryptographically validated, to
366          * recognize clients and users.
367          * RPC provided primary group should match the one got from the
368          * identity upcall.
369          * And RPC provided supplementary groups should not be trusted,
370          * but checked thanks to identity upcall and the trusted UID
371          * from the ticket.
372          */
373         if (SPTLRPC_FLVR_MECH(req->rq_flvr.sf_rpc) == SPTLRPC_MECH_GSS_KRB5) {
374                 if (!has_proper_groups(ucred))
375                         GOTO(out, rc = -EACCES);
376                 ucred->uc_suppgids[0] = -1;
377                 ucred->uc_suppgids[1] = -1;
378                 if (ucred->uc_ginfo) {
379                         put_group_info(ucred->uc_ginfo);
380                         ucred->uc_ginfo = NULL;
381                 }
382         }
383
384         ucred->uc_valid = UCRED_NEW;
385         ucred_set_jobid(info, ucred);
386         ucred_set_nid(info, ucred);
387         ucred_set_audit_enabled(info, ucred);
388         ucred_set_rbac_roles(info, ucred);
389
390         EXIT;
391
392 out:
393         if (rc) {
394                 if (ucred->uc_ginfo) {
395                         put_group_info(ucred->uc_ginfo);
396                         ucred->uc_ginfo = NULL;
397                 }
398                 if (ucred->uc_identity) {
399                         mdt_identity_put(mdt->mdt_identity_cache,
400                                          ucred->uc_identity);
401                         ucred->uc_identity = NULL;
402                 }
403         }
404
405 out_nodemap:
406         nodemap_putref(nodemap);
407         return rc;
408 }
409
410 /**
411  * Check whether allow the client to set supplementary group IDs or not.
412  *
413  * \param[in] info      pointer to the thread context
414  * \param[in] uc        pointer to the RPC user descriptor
415  *
416  * \retval              true if allow to set supplementary group IDs
417  * \retval              false for other cases
418  */
419 bool allow_client_chgrp(struct mdt_thread_info *info, struct lu_ucred *uc)
420 {
421         __u32 perm;
422
423         /* 1. If identity_upcall is disabled,
424          *    permit local client to do anything. */
425         if (is_identity_get_disabled(info->mti_mdt->mdt_identity_cache))
426                 return true;
427
428         /* 2. If fail to get related identities, then forbid any client to
429          *    set supplementary group IDs. */
430         if (uc->uc_identity == NULL)
431                 return false;
432
433         /* 3. Check the permission in the identities. */
434         perm = mdt_identity_get_perm(
435                 uc->uc_identity,
436                 &mdt_info_req(info)->rq_peer.nid);
437         if (perm & CFS_SETGRP_PERM)
438                 return true;
439
440         return false;
441 }
442
443 int mdt_check_ucred(struct mdt_thread_info *info)
444 {
445         struct ptlrpc_request   *req = mdt_info_req(info);
446         struct mdt_device       *mdt = info->mti_mdt;
447         struct ptlrpc_user_desc *pud = req->rq_user_desc;
448         struct lu_ucred         *ucred = mdt_ucred(info);
449         struct md_identity      *identity = NULL;
450         struct lnet_nid          peernid = req->rq_peer.nid;
451         __u32                    perm = 0;
452         int                      setuid;
453         int                      setgid;
454         int                      rc = 0;
455
456         ENTRY;
457
458         LASSERT(ucred != NULL);
459         if ((ucred->uc_valid == UCRED_OLD) || (ucred->uc_valid == UCRED_NEW))
460                 RETURN(0);
461
462         if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
463                 RETURN(0);
464
465         /* sanity check: if we use strong authentication, we expect the
466          * uid which client claimed is true */
467         if (!flvr_is_rootonly(req->rq_flvr.sf_rpc) &&
468             req->rq_auth_uid != pud->pud_uid) {
469                 CDEBUG(D_SEC, "local client %s: auth uid %u "
470                        "while client claims %u:%u/%u:%u\n",
471                        libcfs_nidstr(&peernid), req->rq_auth_uid,
472                        pud->pud_uid, pud->pud_gid,
473                        pud->pud_fsuid, pud->pud_fsgid);
474                 RETURN(-EACCES);
475         }
476
477         if (is_identity_get_disabled(mdt->mdt_identity_cache))
478                 RETURN(0);
479
480         identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
481         if (IS_ERR(identity)) {
482                 if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
483                         RETURN(0);
484                 } else {
485                         CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
486                                pud->pud_uid);
487                         RETURN(-EACCES);
488                 }
489         }
490
491         perm = mdt_identity_get_perm(identity, &peernid);
492         /* find out the setuid/setgid attempt */
493         setuid = (pud->pud_uid != pud->pud_fsuid);
494         setgid = (pud->pud_gid != pud->pud_fsgid ||
495                   pud->pud_gid != identity->mi_gid);
496
497         /* check permission of setuid */
498         if (setuid && !(perm & CFS_SETUID_PERM)) {
499                 CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
500                        pud->pud_uid, pud->pud_fsuid, libcfs_nidstr(&peernid));
501                 GOTO(out, rc = -EACCES);
502         }
503
504         /* check permission of setgid */
505         if (setgid && !(perm & CFS_SETGID_PERM)) {
506                 CDEBUG(D_SEC,
507                        "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) from %s\n",
508                        pud->pud_uid, pud->pud_gid,
509                        pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
510                        libcfs_nidstr(&peernid));
511                 GOTO(out, rc = -EACCES);
512         }
513
514         EXIT;
515
516 out:
517         mdt_identity_put(mdt->mdt_identity_cache, identity);
518         return rc;
519 }
520
521 static int old_init_ucred_common(struct mdt_thread_info *info,
522                                  struct lu_nodemap *nodemap)
523 {
524         struct ptlrpc_request *req = mdt_info_req(info);
525         struct lu_ucred *uc = mdt_ucred(info);
526         struct mdt_device *mdt = info->mti_mdt;
527         struct md_identity *identity = NULL;
528
529         if (nodemap && uc->uc_o_uid == nodemap->nm_squash_uid
530             && nodemap->nmf_deny_unknown)
531                 /* deny access before we get identity ref */
532                 RETURN(-EACCES);
533
534         if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
535                 identity = mdt_identity_get(mdt->mdt_identity_cache,
536                                             uc->uc_fsuid);
537                 if (IS_ERR(identity)) {
538                         if (unlikely(PTR_ERR(identity) == -EREMCHG ||
539                                      cap_raised(uc->uc_cap,
540                                                 CAP_DAC_READ_SEARCH))) {
541                                 identity = NULL;
542                         } else {
543                                 CDEBUG(D_SEC, "Deny access without identity: "
544                                        "uid %u\n", uc->uc_fsuid);
545                                 RETURN(-EACCES);
546                         }
547                 }
548         }
549         uc->uc_identity = identity;
550
551         if (nodemap &&
552             (uc->uc_o_uid == nodemap->nm_squash_uid ||
553              uc->uc_o_gid == nodemap->nm_squash_gid)) {
554
555                 uc->uc_cap = CAP_EMPTY_SET;
556                 uc->uc_suppgids[0] = -1;
557                 uc->uc_suppgids[1] = -1;
558         }
559
560         /* process root_squash here. */
561         mdt_root_squash(info,
562                         &mdt_info_req(info)->rq_peer.nid);
563
564         if (uc->uc_fsuid) {
565                 if (!cap_issubset(uc->uc_cap, mdt->mdt_enable_cap_mask))
566                         CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
567                                mdt_obd_name(mdt),
568 #ifdef CAP_FOR_EACH_U32
569                                uc->uc_cap.cap[0] | ((u64)uc->uc_cap.cap[1]<<32),
570 #else
571                                uc->uc_cap.val,
572 #endif
573                                libcfs_nidstr(&mdt_info_req(info)->rq_peer.nid));
574                 uc->uc_cap = cap_intersect(uc->uc_cap,mdt->mdt_enable_cap_mask);
575         }
576
577         /* Thanks to Kerberos, Lustre does not have to trust clients anymore,
578          * but relies on keytabs and tickets, cryptographically validated, to
579          * recognize clients and users.
580          * RPC provided primary group should match the one got from the
581          * identity upcall.
582          * And RPC provided supplementary groups should not be trusted,
583          * but checked thanks to identity upcall and the trusted UID
584          * from the ticket.
585          */
586         if (SPTLRPC_FLVR_MECH(req->rq_flvr.sf_rpc) == SPTLRPC_MECH_GSS_KRB5) {
587                 if (!has_proper_groups(uc)) {
588                         mdt_identity_put(mdt->mdt_identity_cache,
589                                          uc->uc_identity);
590                         uc->uc_identity = NULL;
591                         RETURN(-EACCES);
592                 }
593                 uc->uc_suppgids[0] = -1;
594                 uc->uc_suppgids[1] = -1;
595         }
596
597         uc->uc_valid = UCRED_OLD;
598         ucred_set_jobid(info, uc);
599         ucred_set_nid(info, uc);
600         ucred_set_audit_enabled(info, uc);
601         ucred_set_rbac_roles(info, uc);
602
603         EXIT;
604         return 0;
605 }
606
607 static int old_init_ucred(struct mdt_thread_info *info,
608                           struct mdt_body *body)
609 {
610         struct lu_ucred *uc = mdt_ucred(info);
611         struct lu_nodemap *nodemap;
612         int rc;
613         ENTRY;
614
615         nodemap = nodemap_get_from_exp(info->mti_exp);
616         if (IS_ERR(nodemap))
617                 RETURN(PTR_ERR(nodemap));
618
619         body->mbo_uid = nodemap_map_id(nodemap, NODEMAP_UID,
620                                        NODEMAP_CLIENT_TO_FS, body->mbo_uid);
621         body->mbo_gid = nodemap_map_id(nodemap, NODEMAP_GID,
622                                        NODEMAP_CLIENT_TO_FS, body->mbo_gid);
623         body->mbo_fsuid = nodemap_map_id(nodemap, NODEMAP_UID,
624                                        NODEMAP_CLIENT_TO_FS, body->mbo_fsuid);
625         body->mbo_fsgid = nodemap_map_id(nodemap, NODEMAP_GID,
626                                        NODEMAP_CLIENT_TO_FS, body->mbo_fsgid);
627
628         LASSERT(uc != NULL);
629         uc->uc_valid = UCRED_INVALID;
630         uc->uc_o_uid = uc->uc_uid = body->mbo_uid;
631         uc->uc_o_gid = uc->uc_gid = body->mbo_gid;
632         uc->uc_o_fsuid = uc->uc_fsuid = body->mbo_fsuid;
633         uc->uc_o_fsgid = uc->uc_fsgid = body->mbo_fsgid;
634         uc->uc_suppgids[0] = body->mbo_suppgid;
635         uc->uc_suppgids[1] = -1;
636         uc->uc_ginfo = NULL;
637         uc->uc_cap = CAP_EMPTY_SET;
638         ll_set_capability_u32(&uc->uc_cap, body->mbo_capability);
639
640         rc = old_init_ucred_common(info, nodemap);
641         nodemap_putref(nodemap);
642
643         RETURN(rc);
644 }
645
646 static int old_init_ucred_reint(struct mdt_thread_info *info)
647 {
648         struct lu_ucred *uc = mdt_ucred(info);
649         struct lu_nodemap *nodemap;
650         int rc;
651         ENTRY;
652
653         nodemap = nodemap_get_from_exp(info->mti_exp);
654         if (IS_ERR(nodemap))
655                 RETURN(PTR_ERR(nodemap));
656
657         LASSERT(uc != NULL);
658
659         uc->uc_fsuid = nodemap_map_id(nodemap, NODEMAP_UID,
660                                       NODEMAP_CLIENT_TO_FS, uc->uc_fsuid);
661         uc->uc_fsgid = nodemap_map_id(nodemap, NODEMAP_GID,
662                                       NODEMAP_CLIENT_TO_FS, uc->uc_fsgid);
663
664         uc->uc_valid = UCRED_INVALID;
665         uc->uc_o_uid = uc->uc_o_fsuid = uc->uc_uid = uc->uc_fsuid;
666         uc->uc_o_gid = uc->uc_o_fsgid = uc->uc_gid = uc->uc_fsgid;
667         uc->uc_ginfo = NULL;
668
669         rc = old_init_ucred_common(info, nodemap);
670         nodemap_putref(nodemap);
671
672         RETURN(rc);
673 }
674
675 int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body)
676 {
677         struct ptlrpc_request   *req = mdt_info_req(info);
678         struct lu_ucred         *uc  = mdt_ucred(info);
679
680         LASSERT(uc != NULL);
681         if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW))
682                 return 0;
683
684         mdt_exit_ucred(info);
685
686         if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
687                 return old_init_ucred(info, body);
688         else
689                 return new_init_ucred(info, BODY_INIT, body);
690 }
691
692 int mdt_init_ucred_reint(struct mdt_thread_info *info)
693 {
694         struct ptlrpc_request *req = mdt_info_req(info);
695         struct lu_ucred       *uc  = mdt_ucred(info);
696         struct md_attr        *ma  = &info->mti_attr;
697
698         LASSERT(uc != NULL);
699         if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW))
700                 return 0;
701
702         /* LU-5564: for normal close request, skip permission check */
703         if (lustre_msg_get_opc(req->rq_reqmsg) == MDS_CLOSE &&
704             !(ma->ma_attr_flags & (MDS_HSM_RELEASE | MDS_CLOSE_LAYOUT_SWAP))) {
705                 cap_raise_nfsd_set(uc->uc_cap, CAP_FULL_SET);
706                 cap_raise_fs_set(uc->uc_cap, CAP_FULL_SET);
707         }
708
709         mdt_exit_ucred(info);
710
711         if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
712                 return old_init_ucred_reint(info);
713         else
714                 return new_init_ucred(info, REC_INIT, NULL);
715 }
716
717 /* copied from lov/lov_ea.c, just for debugging, will be removed later */
718 void mdt_dump_lmm(int level, const struct lov_mds_md *lmm, __u64 valid)
719 {
720         const struct lov_ost_data_v1 *lod;
721         __u32 lmm_magic = le32_to_cpu(lmm->lmm_magic);
722         __u16 count;
723         int i;
724
725         if (likely(!cfs_cdebug_show(level, DEBUG_SUBSYSTEM)))
726                 return;
727
728         CDEBUG_LIMIT(level, "objid="DOSTID" magic=0x%08X pattern=%#X\n",
729                      POSTID(&lmm->lmm_oi), lmm_magic,
730                      le32_to_cpu(lmm->lmm_pattern));
731
732         /* No support for compound layouts yet */
733         if (lmm_magic != LOV_MAGIC_V1 && lmm_magic != LOV_MAGIC_V3)
734                 return;
735
736         count = le16_to_cpu(((struct lov_user_md *)lmm)->lmm_stripe_count);
737         CDEBUG_LIMIT(level, "stripe_size=0x%x, %sstripe_count=0x%x\n",
738                      le32_to_cpu(lmm->lmm_stripe_size),
739                      count > LOV_MAX_STRIPE_COUNT ? "bad " : "", count);
740
741         /* If it's a directory or a released file, then there are
742          * no actual objects to print, so bail out. */
743         if (valid & OBD_MD_FLDIREA ||
744             le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED)
745                 return;
746
747         if (unlikely(count > LOV_MAX_STRIPE_COUNT))
748                 return;
749
750         for (i = 0, lod = lmm->lmm_objects; i < count; i++, lod++) {
751                 struct ost_id oi;
752
753                 ostid_le_to_cpu(&lod->l_ost_oi, &oi);
754                 CDEBUG_LIMIT(level, "stripe %u idx %u subobj "DOSTID"\n",
755                              i, le32_to_cpu(lod->l_ost_idx), POSTID(&oi));
756         }
757 }
758
759 void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv)
760 {
761         const struct lmv_mds_md_v1 *lmm1;
762         const struct lmv_foreign_md *lfm;
763         int                        i;
764
765         if (likely(!cfs_cdebug_show(level, DEBUG_SUBSYSTEM)))
766                 return;
767
768         /* foreign LMV case */
769         lfm = &lmv->lmv_foreign_md;
770         if (le32_to_cpu(lfm->lfm_magic) == LMV_MAGIC_FOREIGN) {
771                 CDEBUG_LIMIT(level,
772                              "foreign magic 0x%08X, length %u, type %u, flags %u, value '%.*s'\n",
773                              le32_to_cpu(lfm->lfm_magic),
774                              le32_to_cpu(lfm->lfm_length),
775                              le32_to_cpu(lfm->lfm_type),
776                              le32_to_cpu(lfm->lfm_flags),
777                              le32_to_cpu(lfm->lfm_length), lfm->lfm_value);
778                 return;
779         }
780
781         lmm1 = &lmv->lmv_md_v1;
782         CDEBUG(level,
783                "magic 0x%08X, master %#X stripe_count %d hash_type %#x\n",
784                le32_to_cpu(lmm1->lmv_magic),
785                le32_to_cpu(lmm1->lmv_master_mdt_index),
786                le32_to_cpu(lmm1->lmv_stripe_count),
787                le32_to_cpu(lmm1->lmv_hash_type));
788
789         if (le32_to_cpu(lmm1->lmv_magic) == LMV_MAGIC_STRIPE)
790                 return;
791
792         if (le32_to_cpu(lmm1->lmv_stripe_count) > LMV_MAX_STRIPE_COUNT)
793                 return;
794
795         for (i = 0; i < le32_to_cpu(lmm1->lmv_stripe_count); i++) {
796                 struct lu_fid fid;
797
798                 fid_le_to_cpu(&fid, &lmm1->lmv_stripe_fids[i]);
799                 CDEBUG(level, "idx %u subobj "DFID"\n", i, PFID(&fid));
800         }
801 }
802
803 /* Shrink and/or grow reply buffers */
804 int mdt_fix_reply(struct mdt_thread_info *info)
805 {
806         struct req_capsule *pill = info->mti_pill;
807         struct mdt_body    *body;
808         int                md_size, md_packed = 0;
809         int                acl_size;
810         int                rc = 0;
811         ENTRY;
812
813         body = req_capsule_server_get(pill, &RMF_MDT_BODY);
814         LASSERT(body != NULL);
815
816         if (body->mbo_valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE |
817                                OBD_MD_LINKNAME))
818                 md_size = body->mbo_eadatasize;
819         else
820                 md_size = 0;
821
822         acl_size = body->mbo_aclsize;
823
824         /* this replay - not send info to client */
825         if (info->mti_spec.no_create) {
826                 md_size = 0;
827                 acl_size = 0;
828         }
829
830         CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d\n",
831                md_size, acl_size);
832 /*
833             &RMF_MDT_BODY,
834             &RMF_MDT_MD,
835             &RMF_ACL, or &RMF_LOGCOOKIES
836 (optional)  &RMF_CAPA1,
837 (optional)  &RMF_CAPA2,
838 (optional)  something else
839 */
840
841         /* MDT_MD buffer may be bigger than packed value, let's shrink all
842          * buffers before growing it */
843         if (info->mti_big_lmm_used) {
844                 /* big_lmm buffer may be used even without packing the result
845                  * into reply, just for internal server needs */
846                 if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER))
847                         md_packed = req_capsule_get_size(pill, &RMF_MDT_MD,
848                                                          RCL_SERVER);
849
850                 /* free big lmm if md_size is not needed */
851                 if (md_size == 0 || md_packed == 0) {
852                         info->mti_big_lmm_used = 0;
853                 } else {
854                         /* buffer must be allocated separately */
855                         LASSERT(info->mti_attr.ma_lmm !=
856                                 req_capsule_server_get(pill, &RMF_MDT_MD));
857                         req_capsule_shrink(pill, &RMF_MDT_MD, 0, RCL_SERVER);
858                 }
859         } else if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)) {
860                 req_capsule_shrink(pill, &RMF_MDT_MD, md_size, RCL_SERVER);
861         }
862
863         if (info->mti_big_acl_used) {
864                 if (acl_size == 0)
865                         info->mti_big_acl_used = 0;
866                 else
867                         req_capsule_shrink(pill, &RMF_ACL, 0, RCL_SERVER);
868         } else if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER)) {
869                 req_capsule_shrink(pill, &RMF_ACL, acl_size, RCL_SERVER);
870         } else if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER)) {
871                 req_capsule_shrink(pill, &RMF_LOGCOOKIES, acl_size, RCL_SERVER);
872         }
873
874         /* Shrink optional SECCTX buffer if it is not used */
875         if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
876             req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0 &&
877             !(body->mbo_valid & OBD_MD_SECCTX))
878                 req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0, RCL_SERVER);
879
880         /* Shrink optional ENCCTX buffer if it is not used */
881         if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX, RCL_SERVER) &&
882             req_capsule_get_size(pill, &RMF_FILE_ENCCTX, RCL_SERVER) != 0 &&
883             !(body->mbo_valid & OBD_MD_ENCCTX))
884                 req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0, RCL_SERVER);
885
886         /* Shrink optional default LMV buffer if it is not used */
887         if (req_capsule_has_field(pill, &RMF_DEFAULT_MDT_MD, RCL_SERVER) &&
888             req_capsule_get_size(pill, &RMF_DEFAULT_MDT_MD, RCL_SERVER) != 0 &&
889             !(body->mbo_valid & OBD_MD_DEFAULT_MEA))
890                 req_capsule_shrink(pill, &RMF_DEFAULT_MDT_MD, 0, RCL_SERVER);
891
892         /*
893          * Some more field should be shrinked if needed.
894          * This should be done by those who added fields to reply message.
895          */
896
897         /* Grow MD buffer if needed finally */
898         if (info->mti_big_lmm_used) {
899                 void *lmm;
900
901                 LASSERT(md_size > md_packed);
902                 CDEBUG(D_INFO, "Enlarge reply buffer, need extra %d bytes\n",
903                        md_size - md_packed);
904
905                 rc = req_capsule_server_grow(pill, &RMF_MDT_MD, md_size);
906                 if (rc) {
907                         /* we can't answer with proper LOV EA, drop flags,
908                          * the rc is also returned so this request is
909                          * considered as failed */
910                         body->mbo_valid &= ~(OBD_MD_FLDIREA | OBD_MD_FLEASIZE);
911                         /* don't return transno along with error */
912                         lustre_msg_set_transno(pill->rc_req->rq_repmsg, 0);
913                 } else {
914                         /* now we need to pack right LOV/LMV EA */
915                         lmm = req_capsule_server_get(pill, &RMF_MDT_MD);
916                         if (info->mti_attr.ma_valid & MA_LOV) {
917                                 LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD,
918                                                              RCL_SERVER) ==
919                                                 info->mti_attr.ma_lmm_size);
920                                 memcpy(lmm, info->mti_attr.ma_lmm,
921                                        info->mti_attr.ma_lmm_size);
922                         } else if (info->mti_attr.ma_valid & MA_LMV) {
923                                 LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD,
924                                                              RCL_SERVER) ==
925                                                 info->mti_attr.ma_lmv_size);
926                                 memcpy(lmm, info->mti_attr.ma_lmv,
927                                        info->mti_attr.ma_lmv_size);
928                         }
929                 }
930
931                 /* update mdt_max_mdsize so clients will be aware about that */
932                 if (info->mti_mdt->mdt_max_mdsize < info->mti_attr.ma_lmm_size)
933                         info->mti_mdt->mdt_max_mdsize =
934                                                 info->mti_attr.ma_lmm_size;
935                 info->mti_big_lmm_used = 0;
936         }
937
938         if (info->mti_big_acl_used) {
939                 CDEBUG(D_INFO, "Enlarge reply ACL buffer to %d bytes\n",
940                        acl_size);
941
942                 rc = req_capsule_server_grow(pill, &RMF_ACL, acl_size);
943                 if (rc) {
944                         body->mbo_valid &= ~OBD_MD_FLACL;
945                 } else {
946                         void *acl = req_capsule_server_get(pill, &RMF_ACL);
947
948                         memcpy(acl, info->mti_big_acl, acl_size);
949                 }
950
951                 info->mti_big_acl_used = 0;
952         }
953
954         RETURN(rc);
955 }
956
957
958 /* if object is dying, pack the lov/llog data,
959  * parameter info->mti_attr should be valid at this point!
960  * Also implements RAoLU policy */
961 int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo,
962                            struct md_attr *ma)
963 {
964         struct mdt_body *repbody = NULL;
965         const struct lu_attr *la = &ma->ma_attr;
966         struct coordinator *cdt = &info->mti_mdt->mdt_coordinator;
967         int rc;
968         __u64 need = 0;
969         struct hsm_action_item hai = {
970                 .hai_len = sizeof(hai),
971                 .hai_action = HSMA_REMOVE,
972                 .hai_extent.length = -1,
973                 .hai_cookie = 0,
974                 .hai_gid = 0,
975         };
976         int archive_id;
977
978         ENTRY;
979
980         if (mdt_info_req(info) != NULL) {
981                 repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
982                 LASSERT(repbody != NULL);
983         } else {
984                 CDEBUG(D_INFO, "not running in a request/reply context\n");
985         }
986
987         if ((ma->ma_valid & MA_INODE) && repbody != NULL)
988                 mdt_pack_attr2body(info, repbody, la, mdt_object_fid(mo));
989
990         if (ma->ma_valid & MA_LOV) {
991                 CERROR("No need in LOV EA upon unlink\n");
992                 dump_stack();
993         }
994         if (repbody != NULL)
995                 repbody->mbo_eadatasize = 0;
996
997         /* Only check unlinked and archived if RAoLU and upon last close */
998         if (!cdt->cdt_remove_archive_on_last_unlink ||
999             atomic_read(&mo->mot_open_count) != 0)
1000                 RETURN(0);
1001
1002         /* mdt_attr_get_complex will clear ma_valid, so check here first */
1003         if ((ma->ma_valid & MA_INODE) && (ma->ma_attr.la_nlink != 0))
1004                 RETURN(0);
1005
1006         if ((ma->ma_valid & MA_HSM) && (!(ma->ma_hsm.mh_flags & HS_EXISTS)))
1007                 RETURN(0);
1008
1009         need |= (MA_INODE | MA_HSM) & ~ma->ma_valid;
1010         if (need != 0) {
1011                 /* ma->ma_valid is missing either MA_INODE, MA_HSM, or both,
1012                  * try setting them */
1013                 ma->ma_need |= need;
1014                 rc = mdt_attr_get_complex(info, mo, ma);
1015                 if (rc) {
1016                         CERROR("%s: unable to fetch missing attributes of"
1017                                DFID": rc=%d\n", mdt_obd_name(info->mti_mdt),
1018                                PFID(mdt_object_fid(mo)), rc);
1019                         RETURN(0);
1020                 }
1021
1022                 if (need & MA_INODE) {
1023                         if (ma->ma_valid & MA_INODE) {
1024                                 if (ma->ma_attr.la_nlink != 0)
1025                                         RETURN(0);
1026                         } else {
1027                                 RETURN(0);
1028                         }
1029                 }
1030
1031                 if (need & MA_HSM) {
1032                         if (ma->ma_valid & MA_HSM) {
1033                                 if (!(ma->ma_hsm.mh_flags & HS_EXISTS))
1034                                         RETURN(0);
1035                         } else {
1036                                 RETURN(0);
1037                         }
1038                 }
1039         }
1040
1041         /* RAoLU policy is active, last close on file has occured,
1042          * file is unlinked, file is archived, so create remove request
1043          * for copytool!
1044          * If CDT is not running, requests will be logged for later. */
1045         if (ma->ma_hsm.mh_arch_id != 0)
1046                 archive_id = ma->ma_hsm.mh_arch_id;
1047         else
1048                 archive_id = cdt->cdt_default_archive_id;
1049
1050         hai.hai_fid = *mdt_object_fid(mo);
1051
1052         rc = mdt_agent_record_add(info->mti_env, info->mti_mdt, archive_id, 0,
1053                                   &hai);
1054         if (rc)
1055                 CERROR("%s: unable to add HSM remove request for "DFID
1056                        ": rc=%d\n", mdt_obd_name(info->mti_mdt),
1057                        PFID(mdt_object_fid(mo)), rc);
1058
1059         RETURN(0);
1060 }
1061
1062 static __u64 mdt_attr_valid_xlate(enum mds_attr_flags in,
1063                                   struct mdt_reint_record *rr,
1064                                   struct md_attr *ma)
1065 {
1066         __u64 out;
1067
1068         out = 0;
1069         if (in & MDS_ATTR_MODE)
1070                 out |= LA_MODE;
1071         if (in & MDS_ATTR_UID)
1072                 out |= LA_UID;
1073         if (in & MDS_ATTR_GID)
1074                 out |= LA_GID;
1075         if (in & MDS_ATTR_SIZE)
1076                 out |= LA_SIZE;
1077         if (in & MDS_ATTR_BLOCKS)
1078                 out |= LA_BLOCKS;
1079         if (in & MDS_ATTR_ATIME_SET)
1080                 out |= LA_ATIME;
1081         if (in & MDS_ATTR_CTIME_SET)
1082                 out |= LA_CTIME;
1083         if (in & MDS_ATTR_MTIME_SET)
1084                 out |= LA_MTIME;
1085         if (in & MDS_ATTR_ATTR_FLAG)
1086                 out |= LA_FLAGS;
1087         if (in & MDS_ATTR_KILL_SUID)
1088                 out |= LA_KILL_SUID;
1089         if (in & MDS_ATTR_KILL_SGID)
1090                 out |= LA_KILL_SGID;
1091         if (in & MDS_ATTR_PROJID)
1092                 out |= LA_PROJID;
1093         if (in & MDS_ATTR_LSIZE)
1094                 out |= LA_LSIZE;
1095         if (in & MDS_ATTR_LBLOCKS)
1096                 out |= LA_LBLOCKS;
1097
1098         if (in & MDS_ATTR_FROM_OPEN)
1099                 rr->rr_flags |= MRF_OPEN_TRUNC;
1100         if (in & MDS_ATTR_OVERRIDE)
1101                 ma->ma_attr_flags |= MDS_OWNEROVERRIDE;
1102         if (in & MDS_ATTR_FORCE)
1103                 ma->ma_attr_flags |= MDS_PERM_BYPASS;
1104
1105         in &= ~(MDS_ATTR_MODE | MDS_ATTR_UID | MDS_ATTR_GID | MDS_ATTR_PROJID |
1106                 MDS_ATTR_ATIME | MDS_ATTR_MTIME | MDS_ATTR_CTIME |
1107                 MDS_ATTR_ATIME_SET | MDS_ATTR_CTIME_SET | MDS_ATTR_MTIME_SET |
1108                 MDS_ATTR_SIZE | MDS_ATTR_BLOCKS | MDS_ATTR_ATTR_FLAG |
1109                 MDS_ATTR_FORCE | MDS_ATTR_KILL_SUID | MDS_ATTR_KILL_SGID |
1110                 MDS_ATTR_FROM_OPEN | MDS_ATTR_LSIZE | MDS_ATTR_LBLOCKS |
1111                 MDS_ATTR_OVERRIDE);
1112         if (in != 0)
1113                 CDEBUG(D_INFO, "Unknown attr bits: %#llx\n", (u64)in);
1114
1115         return out;
1116 }
1117
1118 /* unpacking */
1119
1120 int mdt_name_unpack(struct req_capsule *pill,
1121                     const struct req_msg_field *field,
1122                     struct lu_name *ln,
1123                     enum mdt_name_flags flags)
1124 {
1125         ln->ln_name = req_capsule_client_get(pill, field);
1126         ln->ln_namelen = req_capsule_get_size(pill, field, RCL_CLIENT) - 1;
1127
1128         if (!lu_name_is_valid(ln)) {
1129                 ln->ln_name = NULL;
1130                 ln->ln_namelen = 0;
1131
1132                 return -EPROTO;
1133         }
1134
1135         if ((flags & MNF_FIX_ANON) &&
1136             ln->ln_namelen == 1 && ln->ln_name[0] == '/') {
1137                 /* Newer (3.x) kernels use a name of "/" for the
1138                  * "anonymous" disconnected dentries from NFS
1139                  * filehandle conversion. See d_obtain_alias(). */
1140                 ln->ln_name = NULL;
1141                 ln->ln_namelen = 0;
1142         }
1143
1144         return 0;
1145 }
1146
1147 static int mdt_file_secctx_unpack(struct req_capsule *pill,
1148                                   const char **secctx_name,
1149                                   void **secctx, size_t *secctx_size)
1150 {
1151         const char *name;
1152         size_t name_size;
1153
1154         *secctx_name = NULL;
1155         *secctx = NULL;
1156         *secctx_size = 0;
1157
1158         if (!req_capsule_has_field(pill, &RMF_FILE_SECCTX_NAME, RCL_CLIENT) ||
1159             !req_capsule_field_present(pill, &RMF_FILE_SECCTX_NAME, RCL_CLIENT))
1160                 return 0;
1161
1162         name_size = req_capsule_get_size(pill, &RMF_FILE_SECCTX_NAME,
1163                                          RCL_CLIENT);
1164         if (name_size == 0)
1165                 return 0;
1166
1167         if (name_size > XATTR_NAME_MAX + 1)
1168                 return -EPROTO;
1169
1170         name = req_capsule_client_get(pill, &RMF_FILE_SECCTX_NAME);
1171         if (strnlen(name, name_size) != name_size - 1)
1172                 return -EPROTO;
1173
1174         if (!req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_CLIENT) ||
1175             !req_capsule_field_present(pill, &RMF_FILE_SECCTX, RCL_CLIENT))
1176                 return -EPROTO;
1177
1178         *secctx_name = name;
1179         *secctx = req_capsule_client_get(pill, &RMF_FILE_SECCTX);
1180         *secctx_size = req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_CLIENT);
1181
1182         return 0;
1183 }
1184
1185 static int mdt_file_encctx_unpack(struct req_capsule *pill,
1186                                   void **encctx, size_t *encctx_size)
1187 {
1188         *encctx = NULL;
1189         *encctx_size = 0;
1190
1191         if (!exp_connect_encrypt(pill->rc_req->rq_export))
1192                 return 0;
1193
1194         if (!req_capsule_has_field(pill, &RMF_FILE_ENCCTX, RCL_CLIENT) ||
1195             !req_capsule_field_present(pill, &RMF_FILE_ENCCTX, RCL_CLIENT))
1196                 return -EPROTO;
1197
1198         *encctx_size = req_capsule_get_size(pill, &RMF_FILE_ENCCTX, RCL_CLIENT);
1199         if (*encctx_size == 0)
1200                 return 0;
1201
1202         *encctx = req_capsule_client_get(pill, &RMF_FILE_ENCCTX);
1203
1204         return 0;
1205 }
1206
1207 static int mdt_setattr_unpack_rec(struct mdt_thread_info *info)
1208 {
1209         struct lu_ucred *uc = mdt_ucred(info);
1210         struct md_attr *ma = &info->mti_attr;
1211         struct lu_attr *la = &ma->ma_attr;
1212         struct req_capsule *pill = info->mti_pill;
1213         struct mdt_reint_record *rr = &info->mti_rr;
1214         struct mdt_rec_setattr *rec;
1215         struct lu_nodemap *nodemap;
1216
1217         ENTRY;
1218
1219         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1220         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1221         if (rec == NULL)
1222                 RETURN(-EFAULT);
1223
1224         /* This prior initialization is needed for old_init_ucred_reint() */
1225         uc->uc_fsuid = rec->sa_fsuid;
1226         uc->uc_fsgid = rec->sa_fsgid;
1227         uc->uc_cap = CAP_EMPTY_SET;
1228         ll_set_capability_u32(&uc->uc_cap, rec->sa_cap);
1229         uc->uc_suppgids[0] = rec->sa_suppgid;
1230         uc->uc_suppgids[1] = -1;
1231
1232         rr->rr_fid1 = &rec->sa_fid;
1233         la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma);
1234         la->la_mode  = rec->sa_mode;
1235         la->la_flags = rec->sa_attr_flags;
1236
1237         nodemap = nodemap_get_from_exp(info->mti_exp);
1238         if (IS_ERR(nodemap))
1239                 RETURN(PTR_ERR(nodemap));
1240
1241         la->la_uid = nodemap_map_id(nodemap, NODEMAP_UID,
1242                                     NODEMAP_CLIENT_TO_FS, rec->sa_uid);
1243         la->la_gid = nodemap_map_id(nodemap, NODEMAP_GID,
1244                                     NODEMAP_CLIENT_TO_FS, rec->sa_gid);
1245         la->la_projid = nodemap_map_id(nodemap, NODEMAP_PROJID,
1246                                        NODEMAP_CLIENT_TO_FS, rec->sa_projid);
1247         nodemap_putref(nodemap);
1248
1249         la->la_size  = rec->sa_size;
1250         la->la_blocks = rec->sa_blocks;
1251         la->la_ctime = rec->sa_ctime;
1252         la->la_atime = rec->sa_atime;
1253         la->la_mtime = rec->sa_mtime;
1254         ma->ma_valid = MA_INODE;
1255
1256         ma->ma_attr_flags |= rec->sa_bias & (MDS_CLOSE_INTENT |
1257                                 MDS_DATA_MODIFIED | MDS_TRUNC_KEEP_LEASE |
1258                                 MDS_PCC_ATTACH | MDS_CLOSE_LAYOUT_SWAP_HSM);
1259         RETURN(0);
1260 }
1261
1262 static int mdt_close_handle_unpack(struct mdt_thread_info *info)
1263 {
1264         struct req_capsule *pill = info->mti_pill;
1265         struct mdt_ioepoch *ioepoch;
1266         ENTRY;
1267
1268         if (req_capsule_get_size(pill, &RMF_MDT_EPOCH, RCL_CLIENT))
1269                 ioepoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
1270         else
1271                 ioepoch = NULL;
1272
1273         if (ioepoch == NULL)
1274                 RETURN(-EPROTO);
1275
1276         info->mti_open_handle = ioepoch->mio_open_handle;
1277
1278         RETURN(0);
1279 }
1280
1281 static inline int mdt_dlmreq_unpack(struct mdt_thread_info *info) {
1282         struct req_capsule      *pill = info->mti_pill;
1283
1284         if (req_capsule_get_size(pill, &RMF_DLM_REQ, RCL_CLIENT)) {
1285                 info->mti_dlm_req = req_capsule_client_get(pill, &RMF_DLM_REQ);
1286                 if (info->mti_dlm_req == NULL)
1287                         RETURN(-EFAULT);
1288         }
1289
1290         RETURN(0);
1291 }
1292
1293 static int mdt_setattr_unpack(struct mdt_thread_info *info)
1294 {
1295         struct mdt_reint_record *rr = &info->mti_rr;
1296         struct md_attr          *ma = &info->mti_attr;
1297         struct req_capsule      *pill = info->mti_pill;
1298         int rc;
1299         ENTRY;
1300
1301         rc = mdt_setattr_unpack_rec(info);
1302         if (rc)
1303                 RETURN(rc);
1304
1305         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1306                 rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
1307                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
1308                                                         RCL_CLIENT);
1309
1310                 if (rr->rr_eadatalen > 0) {
1311                         const struct lmv_user_md        *lum;
1312
1313                         lum = rr->rr_eadata;
1314                         /* Sigh ma_valid(from req) does not indicate whether
1315                          * it will set LOV/LMV EA, so we have to check magic */
1316                         if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
1317                                 ma->ma_valid |= MA_LMV;
1318                                 ma->ma_lmv = (void *)rr->rr_eadata;
1319                                 ma->ma_lmv_size = rr->rr_eadatalen;
1320                         } else {
1321                                 ma->ma_valid |= MA_LOV;
1322                                 ma->ma_lmm = (void *)rr->rr_eadata;
1323                                 ma->ma_lmm_size = rr->rr_eadatalen;
1324                         }
1325                 }
1326         }
1327
1328         rc = mdt_dlmreq_unpack(info);
1329         RETURN(rc);
1330 }
1331
1332 static int mdt_close_intent_unpack(struct mdt_thread_info *info)
1333 {
1334         struct md_attr          *ma = &info->mti_attr;
1335         struct req_capsule      *pill = info->mti_pill;
1336         ENTRY;
1337
1338         if (!(ma->ma_attr_flags & MDS_CLOSE_INTENT))
1339                 RETURN(0);
1340
1341         req_capsule_extend(pill, &RQF_MDS_CLOSE_INTENT);
1342
1343         if (!(req_capsule_has_field(pill, &RMF_CLOSE_DATA, RCL_CLIENT) &&
1344             req_capsule_field_present(pill, &RMF_CLOSE_DATA, RCL_CLIENT)))
1345                 RETURN(-EFAULT);
1346
1347         RETURN(0);
1348 }
1349
1350 int mdt_close_unpack(struct mdt_thread_info *info)
1351 {
1352         int rc;
1353         ENTRY;
1354
1355         rc = mdt_close_handle_unpack(info);
1356         if (rc)
1357                 RETURN(rc);
1358
1359         rc = mdt_setattr_unpack_rec(info);
1360         if (rc)
1361                 RETURN(rc);
1362
1363         rc = mdt_close_intent_unpack(info);
1364         if (rc)
1365                 RETURN(rc);
1366
1367         RETURN(mdt_init_ucred_reint(info));
1368 }
1369
1370 static int mdt_create_unpack(struct mdt_thread_info *info)
1371 {
1372         struct lu_ucred *uc  = mdt_ucred(info);
1373         struct mdt_rec_create *rec;
1374         struct lu_attr *attr = &info->mti_attr.ma_attr;
1375         struct mdt_reint_record *rr = &info->mti_rr;
1376         struct req_capsule      *pill = info->mti_pill;
1377         struct md_op_spec       *sp = &info->mti_spec;
1378         int rc;
1379
1380         ENTRY;
1381
1382         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1383         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1384         if (rec == NULL)
1385                 RETURN(-EFAULT);
1386
1387         /* This prior initialization is needed for old_init_ucred_reint() */
1388         uc->uc_fsuid = rec->cr_fsuid;
1389         uc->uc_fsgid = rec->cr_fsgid;
1390         uc->uc_cap = CAP_EMPTY_SET;
1391         ll_set_capability_u32(&uc->uc_cap, rec->cr_cap);
1392         uc->uc_suppgids[0] = rec->cr_suppgid1;
1393         uc->uc_suppgids[1] = -1;
1394         uc->uc_umask = rec->cr_umask;
1395
1396         rr->rr_fid1 = &rec->cr_fid1;
1397         rr->rr_fid2 = &rec->cr_fid2;
1398         attr->la_mode = rec->cr_mode;
1399         attr->la_rdev  = rec->cr_rdev;
1400         attr->la_uid   = rec->cr_fsuid;
1401         attr->la_gid   = rec->cr_fsgid;
1402         attr->la_ctime = rec->cr_time;
1403         attr->la_mtime = rec->cr_time;
1404         attr->la_atime = rec->cr_time;
1405         attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | LA_TYPE |
1406                 LA_CTIME | LA_MTIME | LA_ATIME;
1407         memset(&sp->u, 0, sizeof(sp->u));
1408         sp->sp_cr_flags = get_mrc_cr_flags(rec);
1409
1410         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1411         if (rc < 0)
1412                 RETURN(rc);
1413
1414         if (S_ISLNK(attr->la_mode)) {
1415                 const char *tgt = NULL;
1416                 int sz;
1417
1418                 req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_SYM);
1419                 sz = req_capsule_get_size(pill, &RMF_SYMTGT, RCL_CLIENT);
1420                 if (sz) {
1421                         tgt = req_capsule_client_get(pill, &RMF_SYMTGT);
1422                         sp->u.sp_symname.ln_name = tgt;
1423                         sp->u.sp_symname.ln_namelen = sz - 1; /* skip NUL */
1424                 }
1425                 if (tgt == NULL)
1426                         RETURN(-EFAULT);
1427         } else {
1428                 req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_ACL);
1429                 if (S_ISDIR(attr->la_mode)) {
1430                         struct obd_export *exp = mdt_info_req(info)->rq_export;
1431
1432                         sp->sp_dmv_imp_inherit =
1433                                 info->mti_mdt->mdt_enable_dmv_implicit_inherit;
1434                         if (req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT)
1435                             > 0) {
1436                                 sp->u.sp_ea.eadata =
1437                                         req_capsule_client_get(pill,
1438                                                                &RMF_EADATA);
1439                                 sp->u.sp_ea.eadatalen =
1440                                         req_capsule_get_size(pill, &RMF_EADATA,
1441                                                              RCL_CLIENT);
1442                                 sp->sp_cr_flags |= MDS_OPEN_HAS_EA;
1443                         }
1444                         if (OCD_HAS_FLAG2(&exp->exp_connect_data,
1445                                           DMV_IMP_INHERIT)) {
1446                                 if ((sp->sp_cr_flags & MDS_OPEN_DEFAULT_LMV) &&
1447                                     !(sp->sp_cr_flags & MDS_OPEN_HAS_EA))
1448                                         RETURN(-EPROTO);
1449                         } else if (sp->sp_cr_flags & MDS_OPEN_DEFAULT_LMV) {
1450                                 RETURN(-EPROTO);
1451                         }
1452                 }
1453         }
1454
1455         rc = mdt_file_secctx_unpack(pill, &sp->sp_cr_file_secctx_name,
1456                                     &sp->sp_cr_file_secctx,
1457                                     &sp->sp_cr_file_secctx_size);
1458         if (rc < 0)
1459                 RETURN(rc);
1460
1461         rc = mdt_file_encctx_unpack(pill, &sp->sp_cr_file_encctx,
1462                                     &sp->sp_cr_file_encctx_size);
1463         if (rc < 0)
1464                 RETURN(rc);
1465
1466         rc = req_check_sepol(pill);
1467         if (rc)
1468                 RETURN(rc);
1469
1470         rc = mdt_dlmreq_unpack(info);
1471         RETURN(rc);
1472 }
1473
1474 static int mdt_link_unpack(struct mdt_thread_info *info)
1475 {
1476         struct lu_ucred *uc  = mdt_ucred(info);
1477         struct mdt_rec_link *rec;
1478         struct lu_attr *attr = &info->mti_attr.ma_attr;
1479         struct mdt_reint_record *rr = &info->mti_rr;
1480         struct req_capsule *pill = info->mti_pill;
1481         int rc;
1482
1483         ENTRY;
1484
1485         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1486         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1487         if (rec == NULL)
1488                 RETURN(-EFAULT);
1489
1490         /* This prior initialization is needed for old_init_ucred_reint() */
1491         uc->uc_fsuid = rec->lk_fsuid;
1492         uc->uc_fsgid = rec->lk_fsgid;
1493         uc->uc_cap = CAP_EMPTY_SET;
1494         ll_set_capability_u32(&uc->uc_cap, rec->lk_cap);
1495         uc->uc_suppgids[0] = rec->lk_suppgid1;
1496         uc->uc_suppgids[1] = rec->lk_suppgid2;
1497
1498         attr->la_uid = rec->lk_fsuid;
1499         attr->la_gid = rec->lk_fsgid;
1500         rr->rr_fid1 = &rec->lk_fid1;
1501         rr->rr_fid2 = &rec->lk_fid2;
1502         attr->la_ctime = rec->lk_time;
1503         attr->la_mtime = rec->lk_time;
1504         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
1505
1506         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1507         if (rc < 0)
1508                 RETURN(rc);
1509
1510         rc = req_check_sepol(pill);
1511         if (rc)
1512                 RETURN(rc);
1513
1514         rc = mdt_dlmreq_unpack(info);
1515
1516         RETURN(rc);
1517 }
1518
1519 static int mdt_unlink_unpack(struct mdt_thread_info *info)
1520 {
1521         struct lu_ucred *uc  = mdt_ucred(info);
1522         struct mdt_rec_unlink *rec;
1523         struct lu_attr *attr = &info->mti_attr.ma_attr;
1524         struct mdt_reint_record *rr = &info->mti_rr;
1525         struct req_capsule      *pill = info->mti_pill;
1526         int rc;
1527
1528         ENTRY;
1529
1530         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1531         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1532         if (rec == NULL)
1533                 RETURN(-EFAULT);
1534
1535         /* This prior initialization is needed for old_init_ucred_reint() */
1536         uc->uc_fsuid = rec->ul_fsuid;
1537         uc->uc_fsgid = rec->ul_fsgid;
1538         uc->uc_cap = CAP_EMPTY_SET;
1539         ll_set_capability_u32(&uc->uc_cap, rec->ul_cap);
1540         uc->uc_suppgids[0] = rec->ul_suppgid1;
1541         uc->uc_suppgids[1] = -1;
1542
1543         attr->la_uid = rec->ul_fsuid;
1544         attr->la_gid = rec->ul_fsgid;
1545         rr->rr_fid1 = &rec->ul_fid1;
1546         rr->rr_fid2 = &rec->ul_fid2;
1547         attr->la_ctime = rec->ul_time;
1548         attr->la_mtime = rec->ul_time;
1549         attr->la_mode  = rec->ul_mode;
1550         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1551         if (rec->ul_bias & MDS_FID_OP)
1552                 info->mti_spec.sp_cr_flags |= MDS_OP_WITH_FID;
1553         else
1554                 info->mti_spec.sp_cr_flags &= ~MDS_OP_WITH_FID;
1555
1556         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1557         if (rc < 0)
1558                 RETURN(rc);
1559
1560         info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info));
1561
1562         rc = req_check_sepol(pill);
1563         if (rc)
1564                 RETURN(rc);
1565
1566         rc = mdt_dlmreq_unpack(info);
1567         RETURN(rc);
1568 }
1569
1570 static int mdt_rmentry_unpack(struct mdt_thread_info *info)
1571 {
1572         info->mti_spec.sp_rm_entry = 1;
1573         return mdt_unlink_unpack(info);
1574 }
1575
1576 static int mdt_rename_unpack(struct mdt_thread_info *info)
1577 {
1578         struct lu_ucred *uc = mdt_ucred(info);
1579         struct mdt_rec_rename *rec;
1580         struct lu_attr *attr = &info->mti_attr.ma_attr;
1581         struct mdt_reint_record *rr = &info->mti_rr;
1582         struct req_capsule *pill = info->mti_pill;
1583         struct md_op_spec *spec = &info->mti_spec;
1584         int rc;
1585
1586         ENTRY;
1587
1588         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1589         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1590         if (rec == NULL)
1591                 RETURN(-EFAULT);
1592
1593         /* This prior initialization is needed for old_init_ucred_reint() */
1594         uc->uc_fsuid = rec->rn_fsuid;
1595         uc->uc_fsgid = rec->rn_fsgid;
1596         uc->uc_cap = CAP_EMPTY_SET;
1597         ll_set_capability_u32(&uc->uc_cap, rec->rn_cap);
1598         uc->uc_suppgids[0] = rec->rn_suppgid1;
1599         uc->uc_suppgids[1] = rec->rn_suppgid2;
1600
1601         attr->la_uid = rec->rn_fsuid;
1602         attr->la_gid = rec->rn_fsgid;
1603         rr->rr_fid1 = &rec->rn_fid1;
1604         rr->rr_fid2 = &rec->rn_fid2;
1605         attr->la_ctime = rec->rn_time;
1606         attr->la_mtime = rec->rn_time;
1607         /* rename_tgt contains the mode already */
1608         attr->la_mode = rec->rn_mode;
1609         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1610
1611         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1612         if (rc < 0)
1613                 RETURN(rc);
1614
1615         rc = mdt_name_unpack(pill, &RMF_SYMTGT, &rr->rr_tgt_name, 0);
1616         if (rc < 0)
1617                 RETURN(rc);
1618
1619         spec->no_create = !!req_is_replay(mdt_info_req(info));
1620
1621         rc = req_check_sepol(pill);
1622         if (rc)
1623                 RETURN(rc);
1624
1625         rc = mdt_dlmreq_unpack(info);
1626
1627         RETURN(rc);
1628 }
1629
1630 static int mdt_migrate_unpack(struct mdt_thread_info *info)
1631 {
1632         struct lu_ucred *uc = mdt_ucred(info);
1633         struct mdt_rec_rename *rec;
1634         struct lu_attr *attr = &info->mti_attr.ma_attr;
1635         struct mdt_reint_record *rr = &info->mti_rr;
1636         struct req_capsule *pill = info->mti_pill;
1637         struct md_op_spec *spec = &info->mti_spec;
1638         int rc;
1639
1640         ENTRY;
1641
1642         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1643         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1644         if (rec == NULL)
1645                 RETURN(-EFAULT);
1646
1647         /* This prior initialization is needed for old_init_ucred_reint() */
1648         uc->uc_fsuid = rec->rn_fsuid;
1649         uc->uc_fsgid = rec->rn_fsgid;
1650         uc->uc_cap = CAP_EMPTY_SET;
1651         ll_set_capability_u32(&uc->uc_cap, rec->rn_cap);
1652         uc->uc_suppgids[0] = rec->rn_suppgid1;
1653         uc->uc_suppgids[1] = rec->rn_suppgid2;
1654
1655         attr->la_uid = rec->rn_fsuid;
1656         attr->la_gid = rec->rn_fsgid;
1657         rr->rr_fid1 = &rec->rn_fid1;
1658         rr->rr_fid2 = &rec->rn_fid2;
1659         attr->la_ctime = rec->rn_time;
1660         attr->la_mtime = rec->rn_time;
1661         /* rename_tgt contains the mode already */
1662         attr->la_mode = rec->rn_mode;
1663         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1664         spec->sp_cr_flags = 0;
1665
1666         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1667         if (rc < 0)
1668                 RETURN(rc);
1669
1670         if (rec->rn_bias & MDS_CLOSE_MIGRATE) {
1671                 rc = mdt_close_handle_unpack(info);
1672                 if (rc)
1673                         RETURN(rc);
1674
1675                 spec->sp_migrate_close = 1;
1676         } else {
1677                 spec->sp_migrate_close = 0;
1678         }
1679
1680         spec->sp_migrate_nsonly = !!(rec->rn_bias & MDS_MIGRATE_NSONLY);
1681
1682         /* lustre version > 2.11 migration packs lum */
1683         if (req_capsule_has_field(pill, &RMF_EADATA, RCL_CLIENT)) {
1684                 if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1685                         rr->rr_eadatalen = req_capsule_get_size(pill,
1686                                                                 &RMF_EADATA,
1687                                                                 RCL_CLIENT);
1688
1689                         if (rr->rr_eadatalen > 0) {
1690                                 struct lmv_user_md_v1 *lmu;
1691
1692                                 lmu = req_capsule_client_get(pill, &RMF_EADATA);
1693                                 lmu->lum_hash_type |=
1694                                         cpu_to_le32(LMV_HASH_FLAG_FIXED);
1695                                 rr->rr_eadata = lmu;
1696                                 spec->u.sp_ea.eadatalen = rr->rr_eadatalen;
1697                                 spec->u.sp_ea.eadata = rr->rr_eadata;
1698                                 spec->sp_cr_flags |= MDS_OPEN_HAS_EA;
1699                         }
1700                 } else {
1701                         /* old client doesn't provide lum. */
1702                         RETURN(-EOPNOTSUPP);
1703                 }
1704         }
1705
1706         spec->no_create = !!req_is_replay(mdt_info_req(info));
1707
1708         rc = mdt_dlmreq_unpack(info);
1709
1710         RETURN(rc);
1711 }
1712
1713 /*
1714  * please see comment above LOV_MAGIC_V1_DEFINED
1715  */
1716 void mdt_fix_lov_magic(struct mdt_thread_info *info, void *eadata)
1717 {
1718         struct lov_user_md_v1   *v1 = eadata;
1719
1720         LASSERT(v1);
1721
1722         if (unlikely(req_is_replay(mdt_info_req(info)))) {
1723                 if ((v1->lmm_magic & LOV_MAGIC_MASK) == LOV_MAGIC_MAGIC)
1724                         v1->lmm_magic |= LOV_MAGIC_DEFINED;
1725                 else if ((v1->lmm_magic & __swab32(LOV_MAGIC_MAGIC)) ==
1726                          __swab32(LOV_MAGIC_MAGIC))
1727                         v1->lmm_magic |= __swab32(LOV_MAGIC_DEFINED);
1728         }
1729 }
1730
1731 static int mdt_open_unpack(struct mdt_thread_info *info)
1732 {
1733         struct lu_ucred *uc = mdt_ucred(info);
1734         struct mdt_rec_create *rec;
1735         struct lu_attr *attr = &info->mti_attr.ma_attr;
1736         struct req_capsule *pill = info->mti_pill;
1737         struct mdt_reint_record *rr = &info->mti_rr;
1738         struct ptlrpc_request *req = mdt_info_req(info);
1739         struct md_op_spec *sp = &info->mti_spec;
1740         int rc;
1741         ENTRY;
1742
1743         BUILD_BUG_ON(sizeof(struct mdt_rec_create) !=
1744                      sizeof(struct mdt_rec_reint));
1745         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1746         if (rec == NULL)
1747                 RETURN(-EFAULT);
1748
1749         /* This prior initialization is needed for old_init_ucred_reint() */
1750         uc->uc_fsuid = rec->cr_fsuid;
1751         uc->uc_fsgid = rec->cr_fsgid;
1752         uc->uc_cap = CAP_EMPTY_SET;
1753         ll_set_capability_u32(&uc->uc_cap, rec->cr_cap);
1754         uc->uc_suppgids[0] = rec->cr_suppgid1;
1755         uc->uc_suppgids[1] = rec->cr_suppgid2;
1756         uc->uc_umask = rec->cr_umask;
1757
1758         rr->rr_fid1   = &rec->cr_fid1;
1759         rr->rr_fid2   = &rec->cr_fid2;
1760         rr->rr_open_handle = &rec->cr_open_handle_old;
1761         attr->la_mode = rec->cr_mode;
1762         attr->la_rdev  = rec->cr_rdev;
1763         attr->la_uid   = rec->cr_fsuid;
1764         attr->la_gid   = rec->cr_fsgid;
1765         attr->la_ctime = rec->cr_time;
1766         attr->la_mtime = rec->cr_time;
1767         attr->la_atime = rec->cr_time;
1768         attr->la_valid = LA_MODE  | LA_RDEV  | LA_UID   | LA_GID |
1769                          LA_CTIME | LA_MTIME | LA_ATIME;
1770         memset(&info->mti_spec.u, 0, sizeof(info->mti_spec.u));
1771         info->mti_spec.sp_cr_flags = get_mrc_cr_flags(rec);
1772         /* Do not trigger ASSERTION if client miss to set such flags. */
1773         if (unlikely(info->mti_spec.sp_cr_flags == 0))
1774                 RETURN(-EPROTO);
1775
1776         info->mti_cross_ref = !!(rec->cr_bias & MDS_CROSS_REF);
1777
1778         mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, MNF_FIX_ANON);
1779
1780         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1781                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
1782                                                         RCL_CLIENT);
1783
1784                 if (rr->rr_eadatalen > 0) {
1785                         rr->rr_eadata = req_capsule_client_get(pill,
1786                                                                &RMF_EADATA);
1787                         sp->u.sp_ea.eadatalen = rr->rr_eadatalen;
1788                         sp->u.sp_ea.eadata = rr->rr_eadata;
1789                         sp->sp_archive_id = rec->cr_archive_id;
1790                         sp->no_create = !!req_is_replay(req);
1791                         mdt_fix_lov_magic(info, rr->rr_eadata);
1792                 }
1793
1794                 /*
1795                  * Client default md_size may be 0 right after client start,
1796                  * until all osc are connected, set here just some reasonable
1797                  * value to prevent misbehavior.
1798                  */
1799                 if (rr->rr_eadatalen == 0 &&
1800                     !(info->mti_spec.sp_cr_flags & MDS_OPEN_DELAY_CREATE))
1801                         rr->rr_eadatalen = MIN_MD_SIZE;
1802         }
1803
1804         rc = mdt_file_secctx_unpack(pill, &sp->sp_cr_file_secctx_name,
1805                                     &sp->sp_cr_file_secctx,
1806                                     &sp->sp_cr_file_secctx_size);
1807         if (rc < 0)
1808                 RETURN(rc);
1809
1810         rc = mdt_file_encctx_unpack(pill, &sp->sp_cr_file_encctx,
1811                                     &sp->sp_cr_file_encctx_size);
1812         if (rc < 0)
1813                 RETURN(rc);
1814
1815         rc = req_check_sepol(pill);
1816         if (rc)
1817                 RETURN(rc);
1818
1819         RETURN(rc);
1820 }
1821
1822 static int mdt_setxattr_unpack(struct mdt_thread_info *info)
1823 {
1824         struct mdt_reint_record *rr = &info->mti_rr;
1825         struct lu_ucred *uc = mdt_ucred(info);
1826         struct lu_attr *attr = &info->mti_attr.ma_attr;
1827         struct req_capsule *pill = info->mti_pill;
1828         struct mdt_rec_setxattr *rec;
1829         int rc;
1830         ENTRY;
1831
1832
1833         BUILD_BUG_ON(sizeof(struct mdt_rec_setxattr) !=
1834                      sizeof(struct mdt_rec_reint));
1835         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1836         if (rec == NULL)
1837                 RETURN(-EFAULT);
1838
1839         /* This prior initialization is needed for old_init_ucred_reint() */
1840         uc->uc_fsuid  = rec->sx_fsuid;
1841         uc->uc_fsgid  = rec->sx_fsgid;
1842         uc->uc_cap = CAP_EMPTY_SET;
1843         ll_set_capability_u32(&uc->uc_cap, rec->sx_cap);
1844         uc->uc_suppgids[0] = rec->sx_suppgid1;
1845         uc->uc_suppgids[1] = -1;
1846
1847         rr->rr_opcode = rec->sx_opcode;
1848         rr->rr_fid1   = &rec->sx_fid;
1849         attr->la_valid = rec->sx_valid;
1850         attr->la_ctime = rec->sx_time;
1851         attr->la_size = rec->sx_size;
1852         attr->la_flags = rec->sx_flags;
1853
1854         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1855         if (rc < 0)
1856                 RETURN(rc);
1857
1858         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1859                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
1860                                                         RCL_CLIENT);
1861
1862                 if (rr->rr_eadatalen > info->mti_mdt->mdt_max_ea_size)
1863                         RETURN(-E2BIG);
1864
1865                 if (rr->rr_eadatalen > 0) {
1866                         rr->rr_eadata = req_capsule_client_get(pill,
1867                                                                &RMF_EADATA);
1868                         if (rr->rr_eadata == NULL)
1869                                 RETURN(-EFAULT);
1870                 } else {
1871                         rr->rr_eadata = NULL;
1872                 }
1873         } else if (!(attr->la_valid & OBD_MD_FLXATTRRM)) {
1874                 CDEBUG(D_INFO, "no xattr data supplied\n");
1875                 RETURN(-EFAULT);
1876         }
1877
1878         rc = req_check_sepol(pill);
1879         if (rc)
1880                 RETURN(rc);
1881
1882         if (mdt_dlmreq_unpack(info) < 0)
1883                 RETURN(-EPROTO);
1884
1885         RETURN(0);
1886 }
1887
1888 static int mdt_resync_unpack(struct mdt_thread_info *info)
1889 {
1890         struct req_capsule      *pill = info->mti_pill;
1891         struct mdt_reint_record *rr   = &info->mti_rr;
1892         struct lu_ucred         *uc     = mdt_ucred(info);
1893         struct mdt_rec_resync   *rec;
1894         ENTRY;
1895
1896         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1897         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1898         if (rec == NULL)
1899                 RETURN(-EFAULT);
1900
1901         /* This prior initialization is needed for old_init_ucred_reint() */
1902         uc->uc_fsuid = rec->rs_fsuid;
1903         uc->uc_fsgid = rec->rs_fsgid;
1904         uc->uc_cap = CAP_EMPTY_SET;
1905         ll_set_capability_u32(&uc->uc_cap, rec->rs_cap);
1906
1907         rr->rr_fid1   = &rec->rs_fid;
1908         rr->rr_mirror_id = rec->rs_mirror_id;
1909
1910         /* cookie doesn't need to be swapped but it has been swapped
1911          * in lustre_swab_mdt_rec_reint() as rr_mtime, so here it needs
1912          * restoring. */
1913         if (req_capsule_req_need_swab(pill))
1914                 __swab64s(&rec->rs_lease_handle.cookie);
1915         rr->rr_lease_handle = &rec->rs_lease_handle;
1916
1917         RETURN(mdt_dlmreq_unpack(info));
1918 }
1919
1920 typedef int (*reint_unpacker)(struct mdt_thread_info *info);
1921
1922 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
1923         [REINT_SETATTR]  = mdt_setattr_unpack,
1924         [REINT_CREATE]   = mdt_create_unpack,
1925         [REINT_LINK]     = mdt_link_unpack,
1926         [REINT_UNLINK]   = mdt_unlink_unpack,
1927         [REINT_RENAME]   = mdt_rename_unpack,
1928         [REINT_OPEN]     = mdt_open_unpack,
1929         [REINT_SETXATTR] = mdt_setxattr_unpack,
1930         [REINT_RMENTRY]  = mdt_rmentry_unpack,
1931         [REINT_MIGRATE]  = mdt_migrate_unpack,
1932         [REINT_RESYNC]   = mdt_resync_unpack,
1933 };
1934
1935 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
1936 {
1937         int rc;
1938         ENTRY;
1939
1940         memset(&info->mti_rr, 0, sizeof(info->mti_rr));
1941         if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) {
1942                 info->mti_rr.rr_opcode = op;
1943                 rc = mdt_reint_unpackers[op](info);
1944         } else {
1945                 CERROR("Unexpected opcode %d\n", op);
1946                 rc = -EFAULT;
1947         }
1948         RETURN(rc);
1949 }
1950
1951 int mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
1952                              struct mdt_object *child)
1953 {
1954         char *secctx_name;
1955         struct lu_buf *buffer;
1956         struct mdt_body *repbody;
1957         struct req_capsule *pill = info->mti_pill;
1958         int rc = 0;
1959
1960         if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
1961             req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0) {
1962                 secctx_name =
1963                         req_capsule_client_get(pill, &RMF_FILE_SECCTX_NAME);
1964                 buffer = &info->mti_buf;
1965
1966                 /* fill reply buffer with security context now */
1967                 buffer->lb_len = req_capsule_get_size(pill, &RMF_FILE_SECCTX,
1968                                                       RCL_SERVER);
1969                 buffer->lb_buf = req_capsule_server_get(info->mti_pill,
1970                                                         &RMF_FILE_SECCTX);
1971                 rc = mo_xattr_get(info->mti_env, mdt_object_child(child),
1972                                   buffer, secctx_name);
1973                 if (rc >= 0) {
1974                         CDEBUG(D_SEC,
1975                                "found security context of size %d for "DFID"\n",
1976                                rc, PFID(mdt_object_fid(child)));
1977
1978                         repbody = req_capsule_server_get(pill, &RMF_MDT_BODY);
1979                         repbody->mbo_valid |= OBD_MD_SECCTX;
1980                         if (rc < buffer->lb_len)
1981                                 req_capsule_shrink(pill, &RMF_FILE_SECCTX, rc,
1982                                                    RCL_SERVER);
1983                         rc = 0;
1984                 } else {
1985                         CDEBUG(D_SEC,
1986                              "security context not found for "DFID": rc = %d\n",
1987                              PFID(mdt_object_fid(child)), rc);
1988                         req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0,
1989                                            RCL_SERVER);
1990                         /* handling -ENOENT is important because it may change
1991                          * object state in DNE env dropping LOHA_EXISTS flag,
1992                          * it is important to return that to the caller.
1993                          * Check LU-13115 for details.
1994                          */
1995                         if (rc != -ENOENT)
1996                                 rc = 0;
1997                 }
1998         }
1999         return rc;
2000 }
2001
2002 /* check whether two FIDs belong to different MDTs.
2003  * \retval      1 on different MDTs.
2004  *              0 on the same MDT.
2005  *              -ve on error
2006  */
2007 int mdt_fids_different_target(struct mdt_thread_info *info,
2008                               const struct lu_fid *fid1,
2009                               const struct lu_fid *fid2)
2010 {
2011         const struct lu_env *env = info->mti_env;
2012         struct mdt_device *mdt = info->mti_mdt;
2013         struct lu_seq_range *range = &info->mti_range;
2014         struct seq_server_site *ss;
2015         __u32 index1, index2;
2016         int rc;
2017
2018         if (fid_seq(fid1) == fid_seq(fid2))
2019                 return 0;
2020
2021         ss = mdt->mdt_lu_dev.ld_site->ld_seq_site;
2022
2023         range->lsr_flags = LU_SEQ_RANGE_MDT;
2024         rc = fld_server_lookup(env, ss->ss_server_fld, fid1->f_seq, range);
2025         if (rc)
2026                 return rc;
2027
2028         index1 = range->lsr_index;
2029
2030         rc = fld_server_lookup(env, ss->ss_server_fld, fid2->f_seq, range);
2031         if (rc)
2032                 return rc;
2033
2034         index2 = range->lsr_index;
2035
2036         return index1 != index2;
2037 }
2038
2039 /**
2040  * Check whether \a child is remote object on \a parent.
2041  *
2042  * \param[in]  info     thread environment
2043  * \param[in]  parent   parent object, it's the same as child object in
2044  *                      getattr_by_fid
2045  * \param[in]  child    child object
2046  *
2047  * \retval 1    is remote object.
2048  * \retval 0    isn't remote object.
2049  * \retval < 1  error code
2050  */
2051 int mdt_is_remote_object(struct mdt_thread_info *info,
2052                          struct mdt_object *parent,
2053                          struct mdt_object *child)
2054 {
2055         struct lu_buf *buf = &info->mti_big_buf;
2056         struct linkea_data ldata = { NULL };
2057         struct link_ea_header *leh;
2058         struct link_ea_entry *lee;
2059         struct lu_name name;
2060         struct lu_fid pfid;
2061         int reclen;
2062         int i;
2063         int rc;
2064
2065         ENTRY;
2066
2067         if (fid_is_root(mdt_object_fid(child)))
2068                 RETURN(0);
2069
2070         if (likely(parent != child)) {
2071                 if (mdt_object_remote(parent) ^ mdt_object_remote(child))
2072                         RETURN(1);
2073
2074                 if (!mdt_object_remote(parent) && !mdt_object_remote(child))
2075                         RETURN(0);
2076
2077                 rc = mdt_fids_different_target(info, mdt_object_fid(parent),
2078                                                mdt_object_fid(child));
2079                 RETURN(rc);
2080         }
2081
2082         /* client < 2.13.52 getattr_by_fid parent and child are the same */
2083         buf = lu_buf_check_and_alloc(buf, PATH_MAX);
2084         if (!buf->lb_buf)
2085                 RETURN(-ENOMEM);
2086
2087         ldata.ld_buf = buf;
2088         rc = mdt_links_read(info, child, &ldata);
2089         /* can't read linkea, just assume it's remote object */
2090         if (rc == -ENOENT || rc == -ENODATA)
2091                 RETURN(1);
2092         if (rc)
2093                 RETURN(rc);
2094
2095         leh = buf->lb_buf;
2096         lee = (struct link_ea_entry *)(leh + 1);
2097         for (i = 0; i < leh->leh_reccount; i++) {
2098                 linkea_entry_unpack(lee, &reclen, &name, &pfid);
2099                 lee = (struct link_ea_entry *) ((char *)lee + reclen);
2100                 rc = mdt_fids_different_target(info, &pfid,
2101                                                mdt_object_fid(child));
2102                 if (rc)
2103                         RETURN(rc);
2104         }
2105
2106         RETURN(0);
2107 }
2108
2109 int mdt_pack_encctx_in_reply(struct mdt_thread_info *info,
2110                              struct mdt_object *child)
2111 {
2112         struct lu_buf *buffer;
2113         struct mdt_body *repbody;
2114         struct req_capsule *pill = info->mti_pill;
2115         struct obd_export *exp = mdt_info_req(info)->rq_export;
2116         int rc = 0;
2117
2118         if (!exp_connect_encrypt(exp))
2119                 return rc;
2120
2121         if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX, RCL_SERVER) &&
2122             req_capsule_get_size(pill, &RMF_FILE_ENCCTX, RCL_SERVER) != 0) {
2123                 struct lu_attr la = { 0 };
2124                 struct dt_object *dt = mdt_obj2dt(child);
2125
2126                 if (dt && dt->do_ops && dt->do_ops->do_attr_get)
2127                         dt_attr_get(info->mti_env, mdt_obj2dt(child), &la);
2128
2129                 if (la.la_valid & LA_FLAGS && la.la_flags & LUSTRE_ENCRYPT_FL) {
2130                         buffer = &info->mti_buf;
2131
2132                         /* fill reply buffer with encryption context now */
2133                         buffer->lb_len =
2134                                 req_capsule_get_size(pill, &RMF_FILE_ENCCTX,
2135                                                      RCL_SERVER);
2136                         buffer->lb_buf =
2137                                 req_capsule_server_get(pill, &RMF_FILE_ENCCTX);
2138                         rc = mo_xattr_get(info->mti_env,
2139                                           mdt_object_child(child),
2140                                           buffer,
2141                                           LL_XATTR_NAME_ENCRYPTION_CONTEXT);
2142                         if (unlikely(rc == -ENODATA))
2143                                 /* For compatibility with 2.14 */
2144                                 rc = mo_xattr_get(info->mti_env,
2145                                           mdt_object_child(child),
2146                                           buffer,
2147                                           LL_XATTR_NAME_ENCRYPTION_CONTEXT_OLD);
2148                         if (rc >= 0) {
2149                                 CDEBUG(D_SEC,
2150                                        "found encryption ctx of size %d for "DFID"\n",
2151                                        rc, PFID(mdt_object_fid(child)));
2152
2153                                 repbody = req_capsule_server_get(pill,
2154                                                                  &RMF_MDT_BODY);
2155                                 repbody->mbo_valid |= OBD_MD_ENCCTX;
2156                                 if (rc < buffer->lb_len)
2157                                         req_capsule_shrink(pill,
2158                                                            &RMF_FILE_ENCCTX, rc,
2159                                                            RCL_SERVER);
2160                                 rc = 0;
2161                         } else {
2162                                 CDEBUG(D_SEC,
2163                                        "encryption ctx not found for "DFID": rc = %d\n",
2164                                        PFID(mdt_object_fid(child)), rc);
2165                                 req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
2166                                                    RCL_SERVER);
2167                                 /* handling -ENOENT is important because it may
2168                                  * change object state in DNE env dropping
2169                                  * LOHA_EXISTS flag, it is important to return
2170                                  * that to the caller.
2171                                  * Check LU-13115 for details.
2172                                  */
2173                                 if (rc != -ENOENT)
2174                                         rc = 0;
2175                         }
2176                 } else {
2177                         req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
2178                                            RCL_SERVER);
2179                 }
2180         }
2181         return rc;
2182 }