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