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