Whamcloud - gitweb
LU-9859 libcfs: use round_up directly
[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                     req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT) > 0) {
1366                         sp->u.sp_ea.eadata =
1367                                 req_capsule_client_get(pill, &RMF_EADATA);
1368                         sp->u.sp_ea.eadatalen =
1369                                 req_capsule_get_size(pill, &RMF_EADATA,
1370                                                      RCL_CLIENT);
1371                         sp->sp_cr_flags |= MDS_OPEN_HAS_EA;
1372                 }
1373         }
1374
1375         rc = mdt_file_secctx_unpack(pill, &sp->sp_cr_file_secctx_name,
1376                                     &sp->sp_cr_file_secctx,
1377                                     &sp->sp_cr_file_secctx_size);
1378         if (rc < 0)
1379                 RETURN(rc);
1380
1381         rc = mdt_file_encctx_unpack(pill, &sp->sp_cr_file_encctx,
1382                                     &sp->sp_cr_file_encctx_size);
1383         if (rc < 0)
1384                 RETURN(rc);
1385
1386         rc = req_check_sepol(pill);
1387         if (rc)
1388                 RETURN(rc);
1389
1390         rc = mdt_dlmreq_unpack(info);
1391         RETURN(rc);
1392 }
1393
1394 static int mdt_link_unpack(struct mdt_thread_info *info)
1395 {
1396         struct lu_ucred *uc  = mdt_ucred(info);
1397         struct mdt_rec_link *rec;
1398         struct lu_attr *attr = &info->mti_attr.ma_attr;
1399         struct mdt_reint_record *rr = &info->mti_rr;
1400         struct req_capsule *pill = info->mti_pill;
1401         int rc;
1402
1403         ENTRY;
1404
1405         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1406         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1407         if (rec == NULL)
1408                 RETURN(-EFAULT);
1409
1410         /* This prior initialization is needed for old_init_ucred_reint() */
1411         uc->uc_fsuid = rec->lk_fsuid;
1412         uc->uc_fsgid = rec->lk_fsgid;
1413         uc->uc_cap = CAP_EMPTY_SET;
1414         uc->uc_cap.cap[0] = rec->lk_cap;
1415         uc->uc_suppgids[0] = rec->lk_suppgid1;
1416         uc->uc_suppgids[1] = rec->lk_suppgid2;
1417
1418         attr->la_uid = rec->lk_fsuid;
1419         attr->la_gid = rec->lk_fsgid;
1420         rr->rr_fid1 = &rec->lk_fid1;
1421         rr->rr_fid2 = &rec->lk_fid2;
1422         attr->la_ctime = rec->lk_time;
1423         attr->la_mtime = rec->lk_time;
1424         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
1425
1426         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1427         if (rc < 0)
1428                 RETURN(rc);
1429
1430         rc = req_check_sepol(pill);
1431         if (rc)
1432                 RETURN(rc);
1433
1434         rc = mdt_dlmreq_unpack(info);
1435
1436         RETURN(rc);
1437 }
1438
1439 static int mdt_unlink_unpack(struct mdt_thread_info *info)
1440 {
1441         struct lu_ucred *uc  = mdt_ucred(info);
1442         struct mdt_rec_unlink *rec;
1443         struct lu_attr *attr = &info->mti_attr.ma_attr;
1444         struct mdt_reint_record *rr = &info->mti_rr;
1445         struct req_capsule      *pill = info->mti_pill;
1446         int rc;
1447
1448         ENTRY;
1449
1450         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1451         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1452         if (rec == NULL)
1453                 RETURN(-EFAULT);
1454
1455         /* This prior initialization is needed for old_init_ucred_reint() */
1456         uc->uc_fsuid = rec->ul_fsuid;
1457         uc->uc_fsgid = rec->ul_fsgid;
1458         uc->uc_cap = CAP_EMPTY_SET;
1459         uc->uc_cap.cap[0] = rec->ul_cap;
1460         uc->uc_suppgids[0] = rec->ul_suppgid1;
1461         uc->uc_suppgids[1] = -1;
1462
1463         attr->la_uid = rec->ul_fsuid;
1464         attr->la_gid = rec->ul_fsgid;
1465         rr->rr_fid1 = &rec->ul_fid1;
1466         rr->rr_fid2 = &rec->ul_fid2;
1467         attr->la_ctime = rec->ul_time;
1468         attr->la_mtime = rec->ul_time;
1469         attr->la_mode  = rec->ul_mode;
1470         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1471         if (rec->ul_bias & MDS_FID_OP)
1472                 info->mti_spec.sp_cr_flags |= MDS_OP_WITH_FID;
1473         else
1474                 info->mti_spec.sp_cr_flags &= ~MDS_OP_WITH_FID;
1475
1476         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1477         if (rc < 0)
1478                 RETURN(rc);
1479
1480         info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info));
1481
1482         rc = req_check_sepol(pill);
1483         if (rc)
1484                 RETURN(rc);
1485
1486         rc = mdt_dlmreq_unpack(info);
1487         RETURN(rc);
1488 }
1489
1490 static int mdt_rmentry_unpack(struct mdt_thread_info *info)
1491 {
1492         info->mti_spec.sp_rm_entry = 1;
1493         return mdt_unlink_unpack(info);
1494 }
1495
1496 static int mdt_rename_unpack(struct mdt_thread_info *info)
1497 {
1498         struct lu_ucred *uc = mdt_ucred(info);
1499         struct mdt_rec_rename *rec;
1500         struct lu_attr *attr = &info->mti_attr.ma_attr;
1501         struct mdt_reint_record *rr = &info->mti_rr;
1502         struct req_capsule *pill = info->mti_pill;
1503         struct md_op_spec *spec = &info->mti_spec;
1504         int rc;
1505
1506         ENTRY;
1507
1508         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1509         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1510         if (rec == NULL)
1511                 RETURN(-EFAULT);
1512
1513         /* This prior initialization is needed for old_init_ucred_reint() */
1514         uc->uc_fsuid = rec->rn_fsuid;
1515         uc->uc_fsgid = rec->rn_fsgid;
1516         uc->uc_cap = CAP_EMPTY_SET;
1517         uc->uc_cap.cap[0] = rec->rn_cap;
1518         uc->uc_suppgids[0] = rec->rn_suppgid1;
1519         uc->uc_suppgids[1] = rec->rn_suppgid2;
1520
1521         attr->la_uid = rec->rn_fsuid;
1522         attr->la_gid = rec->rn_fsgid;
1523         rr->rr_fid1 = &rec->rn_fid1;
1524         rr->rr_fid2 = &rec->rn_fid2;
1525         attr->la_ctime = rec->rn_time;
1526         attr->la_mtime = rec->rn_time;
1527         /* rename_tgt contains the mode already */
1528         attr->la_mode = rec->rn_mode;
1529         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1530
1531         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1532         if (rc < 0)
1533                 RETURN(rc);
1534
1535         rc = mdt_name_unpack(pill, &RMF_SYMTGT, &rr->rr_tgt_name, 0);
1536         if (rc < 0)
1537                 RETURN(rc);
1538
1539         spec->no_create = !!req_is_replay(mdt_info_req(info));
1540
1541         rc = req_check_sepol(pill);
1542         if (rc)
1543                 RETURN(rc);
1544
1545         rc = mdt_dlmreq_unpack(info);
1546
1547         RETURN(rc);
1548 }
1549
1550 static int mdt_migrate_unpack(struct mdt_thread_info *info)
1551 {
1552         struct lu_ucred *uc = mdt_ucred(info);
1553         struct mdt_rec_rename *rec;
1554         struct lu_attr *attr = &info->mti_attr.ma_attr;
1555         struct mdt_reint_record *rr = &info->mti_rr;
1556         struct req_capsule *pill = info->mti_pill;
1557         struct md_op_spec *spec = &info->mti_spec;
1558         int rc;
1559
1560         ENTRY;
1561
1562         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1563         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1564         if (rec == NULL)
1565                 RETURN(-EFAULT);
1566
1567         /* This prior initialization is needed for old_init_ucred_reint() */
1568         uc->uc_fsuid = rec->rn_fsuid;
1569         uc->uc_fsgid = rec->rn_fsgid;
1570         uc->uc_cap = CAP_EMPTY_SET;
1571         uc->uc_cap.cap[0] = rec->rn_cap;
1572         uc->uc_suppgids[0] = rec->rn_suppgid1;
1573         uc->uc_suppgids[1] = rec->rn_suppgid2;
1574
1575         attr->la_uid = rec->rn_fsuid;
1576         attr->la_gid = rec->rn_fsgid;
1577         rr->rr_fid1 = &rec->rn_fid1;
1578         rr->rr_fid2 = &rec->rn_fid2;
1579         attr->la_ctime = rec->rn_time;
1580         attr->la_mtime = rec->rn_time;
1581         /* rename_tgt contains the mode already */
1582         attr->la_mode = rec->rn_mode;
1583         attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
1584         spec->sp_cr_flags = 0;
1585
1586         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1587         if (rc < 0)
1588                 RETURN(rc);
1589
1590         if (rec->rn_bias & MDS_CLOSE_MIGRATE) {
1591                 rc = mdt_close_handle_unpack(info);
1592                 if (rc)
1593                         RETURN(rc);
1594
1595                 spec->sp_migrate_close = 1;
1596         } else {
1597                 spec->sp_migrate_close = 0;
1598         }
1599
1600         spec->sp_migrate_nsonly = !!(rec->rn_bias & MDS_MIGRATE_NSONLY);
1601
1602         /* lustre version > 2.11 migration packs lum */
1603         if (req_capsule_has_field(pill, &RMF_EADATA, RCL_CLIENT)) {
1604                 if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1605                         rr->rr_eadatalen = req_capsule_get_size(pill,
1606                                                                 &RMF_EADATA,
1607                                                                 RCL_CLIENT);
1608
1609                         if (rr->rr_eadatalen > 0) {
1610                                 struct lmv_user_md_v1 *lmu;
1611
1612                                 lmu = req_capsule_client_get(pill, &RMF_EADATA);
1613                                 lmu->lum_hash_type |=
1614                                         cpu_to_le32(LMV_HASH_FLAG_FIXED);
1615                                 rr->rr_eadata = lmu;
1616                                 spec->u.sp_ea.eadatalen = rr->rr_eadatalen;
1617                                 spec->u.sp_ea.eadata = rr->rr_eadata;
1618                                 spec->sp_cr_flags |= MDS_OPEN_HAS_EA;
1619                         }
1620                 } else {
1621                         /* old client doesn't provide lum. */
1622                         RETURN(-EOPNOTSUPP);
1623                 }
1624         }
1625
1626         spec->no_create = !!req_is_replay(mdt_info_req(info));
1627
1628         rc = mdt_dlmreq_unpack(info);
1629
1630         RETURN(rc);
1631 }
1632
1633 /*
1634  * please see comment above LOV_MAGIC_V1_DEFINED
1635  */
1636 void mdt_fix_lov_magic(struct mdt_thread_info *info, void *eadata)
1637 {
1638         struct lov_user_md_v1   *v1 = eadata;
1639
1640         LASSERT(v1);
1641
1642         if (unlikely(req_is_replay(mdt_info_req(info)))) {
1643                 if ((v1->lmm_magic & LOV_MAGIC_MASK) == LOV_MAGIC_MAGIC)
1644                         v1->lmm_magic |= LOV_MAGIC_DEFINED;
1645                 else if ((v1->lmm_magic & __swab32(LOV_MAGIC_MAGIC)) ==
1646                          __swab32(LOV_MAGIC_MAGIC))
1647                         v1->lmm_magic |= __swab32(LOV_MAGIC_DEFINED);
1648         }
1649 }
1650
1651 static int mdt_open_unpack(struct mdt_thread_info *info)
1652 {
1653         struct lu_ucred *uc = mdt_ucred(info);
1654         struct mdt_rec_create *rec;
1655         struct lu_attr *attr = &info->mti_attr.ma_attr;
1656         struct req_capsule *pill = info->mti_pill;
1657         struct mdt_reint_record *rr = &info->mti_rr;
1658         struct ptlrpc_request *req = mdt_info_req(info);
1659         struct md_op_spec *sp = &info->mti_spec;
1660         int rc;
1661         ENTRY;
1662
1663         BUILD_BUG_ON(sizeof(struct mdt_rec_create) !=
1664                      sizeof(struct mdt_rec_reint));
1665         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1666         if (rec == NULL)
1667                 RETURN(-EFAULT);
1668
1669         /* This prior initialization is needed for old_init_ucred_reint() */
1670         uc->uc_fsuid = rec->cr_fsuid;
1671         uc->uc_fsgid = rec->cr_fsgid;
1672         uc->uc_cap = CAP_EMPTY_SET;
1673         uc->uc_cap.cap[0] = rec->cr_cap;
1674         uc->uc_suppgids[0] = rec->cr_suppgid1;
1675         uc->uc_suppgids[1] = rec->cr_suppgid2;
1676         uc->uc_umask = rec->cr_umask;
1677
1678         rr->rr_fid1   = &rec->cr_fid1;
1679         rr->rr_fid2   = &rec->cr_fid2;
1680         rr->rr_open_handle = &rec->cr_open_handle_old;
1681         attr->la_mode = rec->cr_mode;
1682         attr->la_rdev  = rec->cr_rdev;
1683         attr->la_uid   = rec->cr_fsuid;
1684         attr->la_gid   = rec->cr_fsgid;
1685         attr->la_ctime = rec->cr_time;
1686         attr->la_mtime = rec->cr_time;
1687         attr->la_atime = rec->cr_time;
1688         attr->la_valid = LA_MODE  | LA_RDEV  | LA_UID   | LA_GID |
1689                          LA_CTIME | LA_MTIME | LA_ATIME;
1690         memset(&info->mti_spec.u, 0, sizeof(info->mti_spec.u));
1691         info->mti_spec.sp_cr_flags = get_mrc_cr_flags(rec);
1692         /* Do not trigger ASSERTION if client miss to set such flags. */
1693         if (unlikely(info->mti_spec.sp_cr_flags == 0))
1694                 RETURN(-EPROTO);
1695
1696         info->mti_cross_ref = !!(rec->cr_bias & MDS_CROSS_REF);
1697
1698         mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, MNF_FIX_ANON);
1699
1700         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1701                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
1702                                                         RCL_CLIENT);
1703
1704                 if (rr->rr_eadatalen > 0) {
1705                         rr->rr_eadata = req_capsule_client_get(pill,
1706                                                                &RMF_EADATA);
1707                         sp->u.sp_ea.eadatalen = rr->rr_eadatalen;
1708                         sp->u.sp_ea.eadata = rr->rr_eadata;
1709                         sp->sp_archive_id = rec->cr_archive_id;
1710                         sp->no_create = !!req_is_replay(req);
1711                         mdt_fix_lov_magic(info, rr->rr_eadata);
1712                 }
1713
1714                 /*
1715                  * Client default md_size may be 0 right after client start,
1716                  * until all osc are connected, set here just some reasonable
1717                  * value to prevent misbehavior.
1718                  */
1719                 if (rr->rr_eadatalen == 0 &&
1720                     !(info->mti_spec.sp_cr_flags & MDS_OPEN_DELAY_CREATE))
1721                         rr->rr_eadatalen = MIN_MD_SIZE;
1722         }
1723
1724         rc = mdt_file_secctx_unpack(pill, &sp->sp_cr_file_secctx_name,
1725                                     &sp->sp_cr_file_secctx,
1726                                     &sp->sp_cr_file_secctx_size);
1727         if (rc < 0)
1728                 RETURN(rc);
1729
1730         rc = mdt_file_encctx_unpack(pill, &sp->sp_cr_file_encctx,
1731                                     &sp->sp_cr_file_encctx_size);
1732         if (rc < 0)
1733                 RETURN(rc);
1734
1735         rc = req_check_sepol(pill);
1736         if (rc)
1737                 RETURN(rc);
1738
1739         RETURN(rc);
1740 }
1741
1742 static int mdt_setxattr_unpack(struct mdt_thread_info *info)
1743 {
1744         struct mdt_reint_record *rr = &info->mti_rr;
1745         struct lu_ucred *uc = mdt_ucred(info);
1746         struct lu_attr *attr = &info->mti_attr.ma_attr;
1747         struct req_capsule *pill = info->mti_pill;
1748         struct mdt_rec_setxattr *rec;
1749         int rc;
1750         ENTRY;
1751
1752
1753         BUILD_BUG_ON(sizeof(struct mdt_rec_setxattr) !=
1754                      sizeof(struct mdt_rec_reint));
1755         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1756         if (rec == NULL)
1757                 RETURN(-EFAULT);
1758
1759         /* This prior initialization is needed for old_init_ucred_reint() */
1760         uc->uc_fsuid  = rec->sx_fsuid;
1761         uc->uc_fsgid  = rec->sx_fsgid;
1762         uc->uc_cap = CAP_EMPTY_SET;
1763         uc->uc_cap.cap[0] = rec->sx_cap;
1764         uc->uc_suppgids[0] = rec->sx_suppgid1;
1765         uc->uc_suppgids[1] = -1;
1766
1767         rr->rr_opcode = rec->sx_opcode;
1768         rr->rr_fid1   = &rec->sx_fid;
1769         attr->la_valid = rec->sx_valid;
1770         attr->la_ctime = rec->sx_time;
1771         attr->la_size = rec->sx_size;
1772         attr->la_flags = rec->sx_flags;
1773
1774         rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
1775         if (rc < 0)
1776                 RETURN(rc);
1777
1778         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
1779                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
1780                                                         RCL_CLIENT);
1781
1782                 if (rr->rr_eadatalen > info->mti_mdt->mdt_max_ea_size)
1783                         RETURN(-E2BIG);
1784
1785                 if (rr->rr_eadatalen > 0) {
1786                         rr->rr_eadata = req_capsule_client_get(pill,
1787                                                                &RMF_EADATA);
1788                         if (rr->rr_eadata == NULL)
1789                                 RETURN(-EFAULT);
1790                 } else {
1791                         rr->rr_eadata = NULL;
1792                 }
1793         } else if (!(attr->la_valid & OBD_MD_FLXATTRRM)) {
1794                 CDEBUG(D_INFO, "no xattr data supplied\n");
1795                 RETURN(-EFAULT);
1796         }
1797
1798         rc = req_check_sepol(pill);
1799         if (rc)
1800                 RETURN(rc);
1801
1802         if (mdt_dlmreq_unpack(info) < 0)
1803                 RETURN(-EPROTO);
1804
1805         RETURN(0);
1806 }
1807
1808 static int mdt_resync_unpack(struct mdt_thread_info *info)
1809 {
1810         struct req_capsule      *pill = info->mti_pill;
1811         struct mdt_reint_record *rr   = &info->mti_rr;
1812         struct lu_ucred         *uc     = mdt_ucred(info);
1813         struct mdt_rec_resync   *rec;
1814         ENTRY;
1815
1816         BUILD_BUG_ON(sizeof(*rec) != sizeof(struct mdt_rec_reint));
1817         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
1818         if (rec == NULL)
1819                 RETURN(-EFAULT);
1820
1821         /* This prior initialization is needed for old_init_ucred_reint() */
1822         uc->uc_fsuid = rec->rs_fsuid;
1823         uc->uc_fsgid = rec->rs_fsgid;
1824         uc->uc_cap = CAP_EMPTY_SET;
1825         uc->uc_cap.cap[0] = rec->rs_cap;
1826
1827         rr->rr_fid1   = &rec->rs_fid;
1828         rr->rr_mirror_id = rec->rs_mirror_id;
1829
1830         /* cookie doesn't need to be swapped but it has been swapped
1831          * in lustre_swab_mdt_rec_reint() as rr_mtime, so here it needs
1832          * restoring. */
1833         if (req_capsule_req_need_swab(pill))
1834                 __swab64s(&rec->rs_lease_handle.cookie);
1835         rr->rr_lease_handle = &rec->rs_lease_handle;
1836
1837         RETURN(mdt_dlmreq_unpack(info));
1838 }
1839
1840 typedef int (*reint_unpacker)(struct mdt_thread_info *info);
1841
1842 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
1843         [REINT_SETATTR]  = mdt_setattr_unpack,
1844         [REINT_CREATE]   = mdt_create_unpack,
1845         [REINT_LINK]     = mdt_link_unpack,
1846         [REINT_UNLINK]   = mdt_unlink_unpack,
1847         [REINT_RENAME]   = mdt_rename_unpack,
1848         [REINT_OPEN]     = mdt_open_unpack,
1849         [REINT_SETXATTR] = mdt_setxattr_unpack,
1850         [REINT_RMENTRY]  = mdt_rmentry_unpack,
1851         [REINT_MIGRATE]  = mdt_migrate_unpack,
1852         [REINT_RESYNC]   = mdt_resync_unpack,
1853 };
1854
1855 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
1856 {
1857         int rc;
1858         ENTRY;
1859
1860         memset(&info->mti_rr, 0, sizeof(info->mti_rr));
1861         if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) {
1862                 info->mti_rr.rr_opcode = op;
1863                 rc = mdt_reint_unpackers[op](info);
1864         } else {
1865                 CERROR("Unexpected opcode %d\n", op);
1866                 rc = -EFAULT;
1867         }
1868         RETURN(rc);
1869 }
1870
1871 int mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
1872                              struct mdt_object *child)
1873 {
1874         char *secctx_name;
1875         struct lu_buf *buffer;
1876         struct mdt_body *repbody;
1877         struct req_capsule *pill = info->mti_pill;
1878         int rc = 0;
1879
1880         if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
1881             req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0) {
1882                 secctx_name =
1883                         req_capsule_client_get(pill, &RMF_FILE_SECCTX_NAME);
1884                 buffer = &info->mti_buf;
1885
1886                 /* fill reply buffer with security context now */
1887                 buffer->lb_len = req_capsule_get_size(pill, &RMF_FILE_SECCTX,
1888                                                       RCL_SERVER);
1889                 buffer->lb_buf = req_capsule_server_get(info->mti_pill,
1890                                                         &RMF_FILE_SECCTX);
1891                 rc = mo_xattr_get(info->mti_env, mdt_object_child(child),
1892                                   buffer, secctx_name);
1893                 if (rc >= 0) {
1894                         CDEBUG(D_SEC,
1895                                "found security context of size %d for "DFID"\n",
1896                                rc, PFID(mdt_object_fid(child)));
1897
1898                         repbody = req_capsule_server_get(pill, &RMF_MDT_BODY);
1899                         repbody->mbo_valid |= OBD_MD_SECCTX;
1900                         if (rc < buffer->lb_len)
1901                                 req_capsule_shrink(pill, &RMF_FILE_SECCTX, rc,
1902                                                    RCL_SERVER);
1903                         rc = 0;
1904                 } else {
1905                         CDEBUG(D_SEC,
1906                              "security context not found for "DFID": rc = %d\n",
1907                              PFID(mdt_object_fid(child)), rc);
1908                         req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0,
1909                                            RCL_SERVER);
1910                         /* handling -ENOENT is important because it may change
1911                          * object state in DNE env dropping LOHA_EXISTS flag,
1912                          * it is important to return that to the caller.
1913                          * Check LU-13115 for details.
1914                          */
1915                         if (rc != -ENOENT)
1916                                 rc = 0;
1917                 }
1918         }
1919         return rc;
1920 }
1921
1922 /* check whether two FIDs belong to different MDTs.
1923  * \retval      1 on different MDTs.
1924  *              0 on the same MDT.
1925  *              -ve on error
1926  */
1927 int mdt_fids_different_target(struct mdt_thread_info *info,
1928                               const struct lu_fid *fid1,
1929                               const struct lu_fid *fid2)
1930 {
1931         const struct lu_env *env = info->mti_env;
1932         struct mdt_device *mdt = info->mti_mdt;
1933         struct lu_seq_range *range = &info->mti_range;
1934         struct seq_server_site *ss;
1935         __u32 index1, index2;
1936         int rc;
1937
1938         if (fid_seq(fid1) == fid_seq(fid2))
1939                 return 0;
1940
1941         ss = mdt->mdt_lu_dev.ld_site->ld_seq_site;
1942
1943         range->lsr_flags = LU_SEQ_RANGE_MDT;
1944         rc = fld_server_lookup(env, ss->ss_server_fld, fid1->f_seq, range);
1945         if (rc)
1946                 return rc;
1947
1948         index1 = range->lsr_index;
1949
1950         rc = fld_server_lookup(env, ss->ss_server_fld, fid2->f_seq, range);
1951         if (rc)
1952                 return rc;
1953
1954         index2 = range->lsr_index;
1955
1956         return index1 != index2;
1957 }
1958
1959 /**
1960  * Check whether \a child is remote object on \a parent.
1961  *
1962  * \param[in]  info     thread environment
1963  * \param[in]  parent   parent object, it's the same as child object in
1964  *                      getattr_by_fid
1965  * \param[in]  child    child object
1966  *
1967  * \retval 1    is remote object.
1968  * \retval 0    isn't remote object.
1969  * \retval < 1  error code
1970  */
1971 int mdt_is_remote_object(struct mdt_thread_info *info,
1972                          struct mdt_object *parent,
1973                          struct mdt_object *child)
1974 {
1975         struct lu_buf *buf = &info->mti_big_buf;
1976         struct linkea_data ldata = { NULL };
1977         struct link_ea_header *leh;
1978         struct link_ea_entry *lee;
1979         struct lu_name name;
1980         struct lu_fid pfid;
1981         int reclen;
1982         int i;
1983         int rc;
1984
1985         ENTRY;
1986
1987         if (fid_is_root(mdt_object_fid(child)))
1988                 RETURN(0);
1989
1990         if (likely(parent != child)) {
1991                 if (mdt_object_remote(parent) ^ mdt_object_remote(child))
1992                         RETURN(1);
1993
1994                 if (!mdt_object_remote(parent) && !mdt_object_remote(child))
1995                         RETURN(0);
1996
1997                 rc = mdt_fids_different_target(info, mdt_object_fid(parent),
1998                                                mdt_object_fid(child));
1999                 RETURN(rc);
2000         }
2001
2002         /* client < 2.13.52 getattr_by_fid parent and child are the same */
2003         buf = lu_buf_check_and_alloc(buf, PATH_MAX);
2004         if (!buf->lb_buf)
2005                 RETURN(-ENOMEM);
2006
2007         ldata.ld_buf = buf;
2008         rc = mdt_links_read(info, child, &ldata);
2009         /* can't read linkea, just assume it's remote object */
2010         if (rc == -ENOENT || rc == -ENODATA)
2011                 RETURN(1);
2012         if (rc)
2013                 RETURN(rc);
2014
2015         leh = buf->lb_buf;
2016         lee = (struct link_ea_entry *)(leh + 1);
2017         for (i = 0; i < leh->leh_reccount; i++) {
2018                 linkea_entry_unpack(lee, &reclen, &name, &pfid);
2019                 lee = (struct link_ea_entry *) ((char *)lee + reclen);
2020                 rc = mdt_fids_different_target(info, &pfid,
2021                                                mdt_object_fid(child));
2022                 if (rc)
2023                         RETURN(rc);
2024         }
2025
2026         RETURN(0);
2027 }
2028
2029 int mdt_pack_encctx_in_reply(struct mdt_thread_info *info,
2030                              struct mdt_object *child)
2031 {
2032         struct lu_buf *buffer;
2033         struct mdt_body *repbody;
2034         struct req_capsule *pill = info->mti_pill;
2035         struct obd_export *exp = mdt_info_req(info)->rq_export;
2036         int rc = 0;
2037
2038         if (!exp_connect_encrypt(exp))
2039                 return rc;
2040
2041         if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX, RCL_SERVER) &&
2042             req_capsule_get_size(pill, &RMF_FILE_ENCCTX, RCL_SERVER) != 0) {
2043                 struct lu_attr la = { 0 };
2044                 struct dt_object *dt = mdt_obj2dt(child);
2045
2046                 if (dt && dt->do_ops && dt->do_ops->do_attr_get)
2047                         dt_attr_get(info->mti_env, mdt_obj2dt(child), &la);
2048
2049                 if (la.la_valid & LA_FLAGS && la.la_flags & LUSTRE_ENCRYPT_FL) {
2050                         buffer = &info->mti_buf;
2051
2052                         /* fill reply buffer with encryption context now */
2053                         buffer->lb_len =
2054                                 req_capsule_get_size(pill, &RMF_FILE_ENCCTX,
2055                                                      RCL_SERVER);
2056                         buffer->lb_buf =
2057                                 req_capsule_server_get(pill, &RMF_FILE_ENCCTX);
2058                         rc = mo_xattr_get(info->mti_env,
2059                                           mdt_object_child(child),
2060                                           buffer,
2061                                           LL_XATTR_NAME_ENCRYPTION_CONTEXT);
2062                         if (unlikely(rc == -ENODATA))
2063                                 /* For compatibility with 2.14 */
2064                                 rc = mo_xattr_get(info->mti_env,
2065                                           mdt_object_child(child),
2066                                           buffer,
2067                                           LL_XATTR_NAME_ENCRYPTION_CONTEXT_OLD);
2068                         if (rc >= 0) {
2069                                 CDEBUG(D_SEC,
2070                                        "found encryption ctx of size %d for "DFID"\n",
2071                                        rc, PFID(mdt_object_fid(child)));
2072
2073                                 repbody = req_capsule_server_get(pill,
2074                                                                  &RMF_MDT_BODY);
2075                                 repbody->mbo_valid |= OBD_MD_ENCCTX;
2076                                 if (rc < buffer->lb_len)
2077                                         req_capsule_shrink(pill,
2078                                                            &RMF_FILE_ENCCTX, rc,
2079                                                            RCL_SERVER);
2080                                 rc = 0;
2081                         } else {
2082                                 CDEBUG(D_SEC,
2083                                        "encryption ctx not found for "DFID": rc = %d\n",
2084                                        PFID(mdt_object_fid(child)), rc);
2085                                 req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
2086                                                    RCL_SERVER);
2087                                 /* handling -ENOENT is important because it may
2088                                  * change object state in DNE env dropping
2089                                  * LOHA_EXISTS flag, it is important to return
2090                                  * that to the caller.
2091                                  * Check LU-13115 for details.
2092                                  */
2093                                 if (rc != -ENOENT)
2094                                         rc = 0;
2095                         }
2096                 } else {
2097                         req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
2098                                            RCL_SERVER);
2099                 }
2100         }
2101         return rc;
2102 }