Whamcloud - gitweb
8c3fafeb5b210a4009ed1b02fbe0cd3328042b46
[fs/lustre-release.git] / lustre / mdc / mdc_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) 2003, 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
32 #define DEBUG_SUBSYSTEM S_MDC
33 #include <linux/user_namespace.h>
34 #include <linux/uidgid.h>
35
36 #include <lustre_net.h>
37 #include <obd_class.h>
38 #include <obd.h>
39 #include <cl_object.h>
40 #include "mdc_internal.h"
41
42 static void set_mrc_cr_flags(struct mdt_rec_create *mrc, __u64 flags)
43 {
44         mrc->cr_flags_l = (__u32)(flags & 0xFFFFFFFFUll);
45         mrc->cr_flags_h = (__u32)(flags >> 32);
46 }
47
48 static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid)
49 {
50         LASSERT(b);
51
52         b->mbo_suppgid = suppgid;
53         b->mbo_uid = from_kuid(&init_user_ns, current_uid());
54         b->mbo_gid = from_kgid(&init_user_ns, current_gid());
55         b->mbo_fsuid = from_kuid(&init_user_ns, current_fsuid());
56         b->mbo_fsgid = from_kgid(&init_user_ns, current_fsgid());
57         b->mbo_capability = cfs_curproc_cap_pack();
58 }
59
60 void mdc_swap_layouts_pack(struct req_capsule *pill,
61                            struct md_op_data *op_data)
62 {
63         struct mdt_body *b = req_capsule_client_get(pill, &RMF_MDT_BODY);
64
65         __mdc_pack_body(b, op_data->op_suppgids[0]);
66         b->mbo_fid1 = op_data->op_fid1;
67         b->mbo_fid2 = op_data->op_fid2;
68         b->mbo_valid |= OBD_MD_FLID;
69 }
70
71 void mdc_pack_body(struct req_capsule *pill, const struct lu_fid *fid,
72                    u64 valid, size_t ea_size, u32 suppgid, u32 flags)
73 {
74         struct mdt_body *b = req_capsule_client_get(pill, &RMF_MDT_BODY);
75         LASSERT(b);
76         b->mbo_valid = valid;
77         b->mbo_eadatasize = ea_size;
78         b->mbo_flags = flags;
79         __mdc_pack_body(b, suppgid);
80         if (fid) {
81                 b->mbo_fid1 = *fid;
82                 b->mbo_valid |= OBD_MD_FLID;
83         }
84 }
85
86 /**
87  * Pack a name (path component) into a request
88  *
89  * \param[in]   pill            request pill
90  * \param[in]   field           request field (usually RMF_NAME)
91  * \param[in]   name            path component
92  * \param[in]   name_len        length of path component
93  *
94  * \a field must be present in \a req and of size \a name_len + 1.
95  *
96  * \a name must be '\0' terminated of length \a name_len and represent
97  * a single path component (not contain '/').
98  */
99 static void mdc_pack_name(struct req_capsule *pill,
100                           const struct req_msg_field *field,
101                           const char *name, size_t name_len)
102 {
103         char *buf;
104         size_t buf_size;
105         size_t cpy_len;
106
107         buf = req_capsule_client_get(pill, field);
108         buf_size = req_capsule_get_size(pill, field, RCL_CLIENT);
109
110         LASSERT(name != NULL && name_len != 0 &&
111                 buf != NULL && buf_size == name_len + 1);
112
113         cpy_len = strlcpy(buf, name, buf_size);
114
115         LASSERT(lu_name_is_valid_2(buf, cpy_len));
116         if (cpy_len != name_len)
117                 CDEBUG(D_DENTRY, "%s len %zd != %zd, concurrent rename?\n",
118                        buf, name_len, cpy_len);
119 }
120
121 void mdc_file_secctx_pack(struct req_capsule *pill, const char *secctx_name,
122                           const void *secctx, size_t secctx_size)
123 {
124         void *buf;
125         size_t buf_size;
126
127         if (secctx_name == NULL)
128                 return;
129
130         buf = req_capsule_client_get(pill, &RMF_FILE_SECCTX_NAME);
131         buf_size = req_capsule_get_size(pill, &RMF_FILE_SECCTX_NAME,
132                                         RCL_CLIENT);
133
134         LASSERT(buf_size == strlen(secctx_name) + 1);
135         memcpy(buf, secctx_name, buf_size);
136
137         buf = req_capsule_client_get(pill, &RMF_FILE_SECCTX);
138         buf_size = req_capsule_get_size(pill, &RMF_FILE_SECCTX,
139                                         RCL_CLIENT);
140
141         LASSERT(buf_size == secctx_size);
142         memcpy(buf, secctx, buf_size);
143 }
144
145 void mdc_file_encctx_pack(struct req_capsule *pill,
146                           const void *encctx, size_t encctx_size)
147 {
148         void *buf;
149         size_t buf_size;
150
151         if (encctx == NULL)
152                 return;
153
154         buf = req_capsule_client_get(pill, &RMF_FILE_ENCCTX);
155         buf_size = req_capsule_get_size(pill, &RMF_FILE_ENCCTX,
156                                         RCL_CLIENT);
157
158         LASSERT(buf_size == encctx_size);
159         memcpy(buf, encctx, buf_size);
160 }
161
162 void mdc_file_sepol_pack(struct req_capsule *pill)
163 {
164         void *buf;
165         size_t buf_size;
166         struct ptlrpc_request *req = pill->rc_req;
167
168         if (strlen(req->rq_sepol) == 0)
169                 return;
170
171         buf = req_capsule_client_get(pill, &RMF_SELINUX_POL);
172         buf_size = req_capsule_get_size(pill, &RMF_SELINUX_POL,
173                                         RCL_CLIENT);
174
175         LASSERT(buf_size == strlen(req->rq_sepol) + 1);
176         snprintf(buf, strlen(req->rq_sepol) + 1, "%s", req->rq_sepol);
177 }
178
179 void mdc_readdir_pack(struct req_capsule *pill, __u64 pgoff, size_t size,
180                       const struct lu_fid *fid)
181 {
182         struct mdt_body *b = req_capsule_client_get(pill, &RMF_MDT_BODY);
183
184         b->mbo_fid1 = *fid;
185         b->mbo_valid |= OBD_MD_FLID;
186         b->mbo_size = pgoff;                    /* !! */
187         b->mbo_nlink = size;                    /* !! */
188         __mdc_pack_body(b, -1);
189         b->mbo_mode = LUDA_FID | LUDA_TYPE;
190 }
191
192 /* packing of MDS records */
193 void mdc_create_pack(struct req_capsule *pill, struct md_op_data *op_data,
194                      const void *data, size_t datalen, umode_t mode,
195                      uid_t uid, gid_t gid, cfs_cap_t cap_effective, __u64 rdev)
196 {
197         struct mdt_rec_create *rec;
198         char *tmp;
199         __u64 flags;
200
201         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
202                      sizeof(struct mdt_rec_create));
203         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
204
205         rec->cr_opcode   = REINT_CREATE;
206         rec->cr_fsuid    = uid;
207         rec->cr_fsgid    = gid;
208         rec->cr_cap      = cap_effective;
209         rec->cr_fid1     = op_data->op_fid1;
210         rec->cr_fid2     = op_data->op_fid2;
211         rec->cr_mode     = mode;
212         rec->cr_rdev     = rdev;
213         rec->cr_time     = op_data->op_mod_time;
214         rec->cr_suppgid1 = op_data->op_suppgids[0];
215         rec->cr_suppgid2 = op_data->op_suppgids[1];
216         flags = 0;
217         if (op_data->op_bias & MDS_CREATE_VOLATILE)
218                 flags |= MDS_OPEN_VOLATILE;
219         if (op_data->op_bias & MDS_SETSTRIPE_CREATE)
220                 /* borrow MDS_OPEN_CREATE flag to indicate current setstripe
221                  * create only, and don't restripe if object exists.
222                  */
223                 flags |= MDS_OPEN_CREAT;
224         set_mrc_cr_flags(rec, flags);
225         rec->cr_bias     = op_data->op_bias;
226         rec->cr_umask    = current_umask();
227
228         mdc_pack_name(pill, &RMF_NAME, op_data->op_name, op_data->op_namelen);
229         if (data) {
230                 tmp = req_capsule_client_get(pill, &RMF_EADATA);
231                 memcpy(tmp, data, datalen);
232         }
233
234         mdc_file_secctx_pack(pill, op_data->op_file_secctx_name,
235                              op_data->op_file_secctx,
236                              op_data->op_file_secctx_size);
237
238         mdc_file_encctx_pack(pill, op_data->op_file_encctx,
239                              op_data->op_file_encctx_size);
240
241         /* pack SELinux policy info if any */
242         mdc_file_sepol_pack(pill);
243 }
244
245 static inline __u64 mds_pack_open_flags(__u64 flags)
246 {
247         __u64 cr_flags = (flags & MDS_OPEN_FL_INTERNAL);
248
249         if (flags & FMODE_READ)
250                 cr_flags |= MDS_FMODE_READ;
251         if (flags & FMODE_WRITE)
252                 cr_flags |= MDS_FMODE_WRITE;
253         if (flags & O_CREAT)
254                 cr_flags |= MDS_OPEN_CREAT;
255         if (flags & O_EXCL)
256                 cr_flags |= MDS_OPEN_EXCL;
257         if (flags & O_TRUNC)
258                 cr_flags |= MDS_OPEN_TRUNC;
259         if (flags & O_APPEND)
260                 cr_flags |= MDS_OPEN_APPEND;
261         if (flags & O_SYNC)
262                 cr_flags |= MDS_OPEN_SYNC;
263         if (flags & O_DIRECTORY)
264                 cr_flags |= MDS_OPEN_DIRECTORY;
265 #ifdef FMODE_EXEC
266         if (flags & FMODE_EXEC)
267                 cr_flags |= MDS_FMODE_EXEC;
268 #endif
269         if (cl_is_lov_delay_create(flags))
270                 cr_flags |= MDS_OPEN_DELAY_CREATE;
271
272         if (flags & O_NONBLOCK)
273                 cr_flags |= MDS_OPEN_NORESTORE;
274
275         return cr_flags;
276 }
277
278 /* packing of MDS records */
279 void mdc_open_pack(struct req_capsule *pill, struct md_op_data *op_data,
280                    umode_t mode, __u64 rdev, __u64 flags, const void *lmm,
281                    size_t lmmlen)
282 {
283         struct mdt_rec_create *rec;
284         char *tmp;
285         __u64 cr_flags;
286
287         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
288                      sizeof(struct mdt_rec_create));
289         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
290
291         /* XXX do something about time, uid, gid */
292         rec->cr_opcode = REINT_OPEN;
293         rec->cr_fsuid   = from_kuid(&init_user_ns, current_fsuid());
294         rec->cr_fsgid   = from_kgid(&init_user_ns, current_fsgid());
295         rec->cr_cap    = cfs_curproc_cap_pack();
296         rec->cr_mode   = mode;
297         cr_flags        = mds_pack_open_flags(flags);
298         rec->cr_rdev   = rdev;
299         rec->cr_umask  = current_umask();
300         if (op_data != NULL) {
301                 rec->cr_fid1       = op_data->op_fid1;
302                 rec->cr_fid2       = op_data->op_fid2;
303                 rec->cr_time       = op_data->op_mod_time;
304                 rec->cr_suppgid1   = op_data->op_suppgids[0];
305                 rec->cr_suppgid2   = op_data->op_suppgids[1];
306                 rec->cr_bias       = op_data->op_bias;
307                 rec->cr_open_handle_old = op_data->op_open_handle;
308
309                 if (op_data->op_name) {
310                         mdc_pack_name(pill, &RMF_NAME, op_data->op_name,
311                                       op_data->op_namelen);
312
313                         if (op_data->op_bias & MDS_CREATE_VOLATILE)
314                                 cr_flags |= MDS_OPEN_VOLATILE;
315                 }
316
317                 mdc_file_secctx_pack(pill, op_data->op_file_secctx_name,
318                                      op_data->op_file_secctx,
319                                      op_data->op_file_secctx_size);
320
321                 mdc_file_encctx_pack(pill, op_data->op_file_encctx,
322                                      op_data->op_file_encctx_size);
323
324                 /* pack SELinux policy info if any */
325                 mdc_file_sepol_pack(pill);
326         }
327
328         if (lmm) {
329                 cr_flags |= MDS_OPEN_HAS_EA;
330                 tmp = req_capsule_client_get(pill, &RMF_EADATA);
331                 memcpy(tmp, lmm, lmmlen);
332                 if (cr_flags & MDS_OPEN_PCC) {
333                         LASSERT(op_data != NULL);
334                         rec->cr_archive_id = op_data->op_archive_id;
335                 }
336         }
337         set_mrc_cr_flags(rec, cr_flags);
338 }
339
340 static inline enum mds_attr_flags mdc_attr_pack(unsigned int ia_valid,
341                                                 enum op_xvalid ia_xvalid)
342 {
343         enum mds_attr_flags sa_valid = 0;
344
345         if (ia_valid & ATTR_MODE)
346                 sa_valid |= MDS_ATTR_MODE;
347         if (ia_valid & ATTR_UID)
348                 sa_valid |= MDS_ATTR_UID;
349         if (ia_valid & ATTR_GID)
350                 sa_valid |= MDS_ATTR_GID;
351         if (ia_valid & ATTR_SIZE)
352                 sa_valid |= MDS_ATTR_SIZE;
353         if (ia_valid & ATTR_ATIME)
354                 sa_valid |= MDS_ATTR_ATIME;
355         if (ia_valid & ATTR_MTIME)
356                 sa_valid |= MDS_ATTR_MTIME;
357         if (ia_valid & ATTR_CTIME)
358                 sa_valid |= MDS_ATTR_CTIME;
359         if (ia_valid & ATTR_ATIME_SET)
360                 sa_valid |= MDS_ATTR_ATIME_SET;
361         if (ia_valid & ATTR_MTIME_SET)
362                 sa_valid |= MDS_ATTR_MTIME_SET;
363         if (ia_valid & ATTR_FORCE)
364                 sa_valid |= MDS_ATTR_FORCE;
365         if (ia_xvalid & OP_XVALID_FLAGS)
366                 sa_valid |= MDS_ATTR_ATTR_FLAG;
367         if (ia_valid & ATTR_KILL_SUID)
368                 sa_valid |=  MDS_ATTR_KILL_SUID;
369         if (ia_valid & ATTR_KILL_SGID)
370                 sa_valid |= MDS_ATTR_KILL_SGID;
371         if (ia_xvalid & OP_XVALID_CTIME_SET)
372                 sa_valid |= MDS_ATTR_CTIME_SET;
373         if (ia_valid & ATTR_OPEN)
374                 sa_valid |= MDS_ATTR_FROM_OPEN;
375         if (ia_xvalid & OP_XVALID_BLOCKS)
376                 sa_valid |= MDS_ATTR_BLOCKS;
377         if (ia_xvalid & OP_XVALID_OWNEROVERRIDE)
378                 /* NFSD hack (see bug 5781) */
379                 sa_valid |= MDS_OPEN_OWNEROVERRIDE;
380         if (ia_xvalid & OP_XVALID_PROJID)
381                 sa_valid |= MDS_ATTR_PROJID;
382         if (ia_xvalid & OP_XVALID_LAZYSIZE)
383                 sa_valid |= MDS_ATTR_LSIZE;
384         if (ia_xvalid & OP_XVALID_LAZYBLOCKS)
385                 sa_valid |= MDS_ATTR_LBLOCKS;
386
387         return sa_valid;
388 }
389
390 static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec,
391                                  struct md_op_data *op_data)
392 {
393         rec->sa_opcode  = REINT_SETATTR;
394         rec->sa_fsuid   = from_kuid(&init_user_ns, current_fsuid());
395         rec->sa_fsgid   = from_kgid(&init_user_ns, current_fsgid());
396         rec->sa_cap     = cfs_curproc_cap_pack();
397         rec->sa_suppgid = -1;
398
399         rec->sa_fid    = op_data->op_fid1;
400         rec->sa_valid  = mdc_attr_pack(op_data->op_attr.ia_valid,
401                                        op_data->op_xvalid);
402         rec->sa_mode   = op_data->op_attr.ia_mode;
403         rec->sa_uid    = from_kuid(&init_user_ns, op_data->op_attr.ia_uid);
404         rec->sa_gid    = from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
405         rec->sa_projid = op_data->op_projid;
406         rec->sa_size   = op_data->op_attr.ia_size;
407         rec->sa_blocks = op_data->op_attr_blocks;
408         rec->sa_atime = op_data->op_attr.ia_atime.tv_sec;
409         rec->sa_mtime = op_data->op_attr.ia_mtime.tv_sec;
410         rec->sa_ctime = op_data->op_attr.ia_ctime.tv_sec;
411         rec->sa_attr_flags = op_data->op_attr_flags;
412         if ((op_data->op_attr.ia_valid & ATTR_GID) &&
413             in_group_p(op_data->op_attr.ia_gid))
414                 rec->sa_suppgid =
415                         from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
416         else
417                 rec->sa_suppgid = op_data->op_suppgids[0];
418
419         rec->sa_bias = op_data->op_bias;
420 }
421
422 static void mdc_ioepoch_pack(struct mdt_ioepoch *epoch,
423                              struct md_op_data *op_data)
424 {
425         epoch->mio_open_handle = op_data->op_open_handle;
426         epoch->mio_unused1 = 0;
427         epoch->mio_unused2 = 0;
428         epoch->mio_padding = 0;
429 }
430
431 void mdc_setattr_pack(struct req_capsule *pill, struct md_op_data *op_data,
432                       void *ea, size_t ealen)
433 {
434         struct mdt_rec_setattr *rec;
435         struct lov_user_md *lum = NULL;
436
437         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
438                      sizeof(struct mdt_rec_setattr));
439         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
440         mdc_setattr_pack_rec(rec, op_data);
441
442         if (ealen == 0)
443                 return;
444
445         lum = req_capsule_client_get(pill, &RMF_EADATA);
446         if (ea == NULL) { /* Remove LOV EA */
447                 lum->lmm_magic = cpu_to_le32(LOV_USER_MAGIC_V1);
448                 lum->lmm_stripe_size = 0;
449                 lum->lmm_stripe_count = 0;
450                 lum->lmm_stripe_offset =
451                   (typeof(lum->lmm_stripe_offset))LOV_OFFSET_DEFAULT;
452         } else {
453                 memcpy(lum, ea, ealen);
454         }
455 }
456
457 void mdc_unlink_pack(struct req_capsule *pill, struct md_op_data *op_data)
458 {
459         struct mdt_rec_unlink *rec;
460
461         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
462                      sizeof(struct mdt_rec_unlink));
463         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
464         LASSERT(rec != NULL);
465
466         rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ?
467                                         REINT_RMENTRY : REINT_UNLINK;
468         rec->ul_fsuid = op_data->op_fsuid;
469         rec->ul_fsgid = op_data->op_fsgid;
470         rec->ul_cap = op_data->op_cap;
471         rec->ul_mode = op_data->op_mode;
472         rec->ul_suppgid1 = op_data->op_suppgids[0];
473         rec->ul_suppgid2 = -1;
474         rec->ul_fid1 = op_data->op_fid1;
475         rec->ul_fid2 = op_data->op_fid2;
476         rec->ul_time = op_data->op_mod_time;
477         rec->ul_bias = op_data->op_bias;
478
479         mdc_pack_name(pill, &RMF_NAME, op_data->op_name, op_data->op_namelen);
480
481         /* pack SELinux policy info if any */
482         mdc_file_sepol_pack(pill);
483 }
484
485 void mdc_link_pack(struct req_capsule *pill, struct md_op_data *op_data)
486 {
487         struct mdt_rec_link *rec;
488
489         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
490                      sizeof(struct mdt_rec_link));
491         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
492         LASSERT(rec != NULL);
493
494         rec->lk_opcode   = REINT_LINK;
495         rec->lk_fsuid    = op_data->op_fsuid; /* current->fsuid; */
496         rec->lk_fsgid    = op_data->op_fsgid; /* current->fsgid; */
497         rec->lk_cap      = op_data->op_cap; /* current->cap_effective; */
498         rec->lk_suppgid1 = op_data->op_suppgids[0];
499         rec->lk_suppgid2 = op_data->op_suppgids[1];
500         rec->lk_fid1     = op_data->op_fid1;
501         rec->lk_fid2     = op_data->op_fid2;
502         rec->lk_time     = op_data->op_mod_time;
503         rec->lk_bias     = op_data->op_bias;
504
505         mdc_pack_name(pill, &RMF_NAME, op_data->op_name, op_data->op_namelen);
506
507         /* pack SELinux policy info if any */
508         mdc_file_sepol_pack(pill);
509 }
510
511 static void mdc_close_intent_pack(struct req_capsule *pill,
512                                   struct md_op_data *op_data)
513 {
514         struct close_data       *data;
515         struct ldlm_lock        *lock;
516         enum mds_op_bias         bias = op_data->op_bias;
517
518         if (!(bias & (MDS_CLOSE_INTENT | MDS_CLOSE_MIGRATE)))
519                 return;
520
521         data = req_capsule_client_get(pill, &RMF_CLOSE_DATA);
522         LASSERT(data != NULL);
523
524         lock = ldlm_handle2lock(&op_data->op_lease_handle);
525         if (lock != NULL) {
526                 data->cd_handle = lock->l_remote_handle;
527                 LDLM_LOCK_PUT(lock);
528         }
529         ldlm_cli_cancel(&op_data->op_lease_handle, LCF_LOCAL);
530
531         data->cd_data_version = op_data->op_data_version;
532         data->cd_fid = op_data->op_fid2;
533
534         if (bias & MDS_CLOSE_LAYOUT_SPLIT) {
535                 data->cd_mirror_id = op_data->op_mirror_id;
536         } else if (bias & MDS_CLOSE_RESYNC_DONE) {
537                 struct close_data_resync_done *sync = &data->cd_resync;
538
539                 BUILD_BUG_ON(sizeof(data->cd_resync) >
540                              sizeof(data->cd_reserved));
541                 sync->resync_count = op_data->op_data_size / sizeof(__u32);
542                 if (sync->resync_count <= INLINE_RESYNC_ARRAY_SIZE) {
543                         memcpy(sync->resync_ids_inline, op_data->op_data,
544                                op_data->op_data_size);
545                 } else {
546                         size_t count = sync->resync_count;
547
548                         memcpy(req_capsule_client_get(pill, &RMF_U32),
549                                op_data->op_data, count * sizeof(__u32));
550                 }
551         } else if (bias & MDS_PCC_ATTACH) {
552                 data->cd_archive_id = op_data->op_archive_id;
553         }
554 }
555
556 void mdc_rename_pack(struct req_capsule *pill, struct md_op_data *op_data,
557                      const char *old, size_t oldlen,
558                      const char *new, size_t newlen)
559 {
560         struct mdt_rec_rename *rec;
561
562         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
563                      sizeof(struct mdt_rec_rename));
564         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
565
566         /* XXX do something about time, uid, gid */
567         rec->rn_opcode   = REINT_RENAME;
568         rec->rn_fsuid    = op_data->op_fsuid;
569         rec->rn_fsgid    = op_data->op_fsgid;
570         rec->rn_cap      = op_data->op_cap;
571         rec->rn_suppgid1 = op_data->op_suppgids[0];
572         rec->rn_suppgid2 = op_data->op_suppgids[1];
573         rec->rn_fid1     = op_data->op_fid1;
574         rec->rn_fid2     = op_data->op_fid2;
575         rec->rn_time     = op_data->op_mod_time;
576         rec->rn_mode     = op_data->op_mode;
577         rec->rn_bias     = op_data->op_bias;
578
579         mdc_pack_name(pill, &RMF_NAME, old, oldlen);
580
581         if (new != NULL)
582                 mdc_pack_name(pill, &RMF_SYMTGT, new, newlen);
583
584         /* pack SELinux policy info if any */
585         mdc_file_sepol_pack(pill);
586 }
587
588 void mdc_migrate_pack(struct req_capsule *pill, struct md_op_data *op_data,
589                       const char *name, size_t namelen)
590 {
591         struct mdt_rec_rename *rec;
592         char *ea;
593
594         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
595                      sizeof(struct mdt_rec_rename));
596         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
597
598         rec->rn_opcode   = REINT_MIGRATE;
599         rec->rn_fsuid    = op_data->op_fsuid;
600         rec->rn_fsgid    = op_data->op_fsgid;
601         rec->rn_cap      = op_data->op_cap;
602         rec->rn_suppgid1 = op_data->op_suppgids[0];
603         rec->rn_suppgid2 = op_data->op_suppgids[1];
604         rec->rn_fid1     = op_data->op_fid1;
605         rec->rn_fid2     = op_data->op_fid4;
606         rec->rn_time     = op_data->op_mod_time;
607         rec->rn_mode     = op_data->op_mode;
608         rec->rn_bias     = op_data->op_bias;
609
610         mdc_pack_name(pill, &RMF_NAME, name, namelen);
611
612         if (op_data->op_bias & MDS_CLOSE_MIGRATE) {
613                 struct mdt_ioepoch *epoch;
614
615                 mdc_close_intent_pack(pill, op_data);
616                 epoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
617                 mdc_ioepoch_pack(epoch, op_data);
618         }
619
620         ea = req_capsule_client_get(pill, &RMF_EADATA);
621         memcpy(ea, op_data->op_data, op_data->op_data_size);
622 }
623
624 void mdc_getattr_pack(struct req_capsule *pill, __u64 valid, __u32 flags,
625                       struct md_op_data *op_data, size_t ea_size)
626 {
627         struct mdt_body *b = req_capsule_client_get(pill, &RMF_MDT_BODY);
628
629         b->mbo_valid = valid;
630         if (op_data->op_bias & MDS_CROSS_REF)
631                 b->mbo_valid |= OBD_MD_FLCROSSREF;
632         b->mbo_eadatasize = ea_size;
633         b->mbo_flags = flags;
634         __mdc_pack_body(b, op_data->op_suppgids[0]);
635
636         b->mbo_fid1 = op_data->op_fid1;
637         b->mbo_fid2 = op_data->op_fid2;
638         b->mbo_valid |= OBD_MD_FLID;
639
640         if (op_data->op_name != NULL)
641                 mdc_pack_name(pill, &RMF_NAME, op_data->op_name,
642                               op_data->op_namelen);
643 }
644
645 void mdc_close_pack(struct req_capsule *pill, struct md_op_data *op_data)
646 {
647         struct mdt_ioepoch *epoch;
648         struct mdt_rec_setattr *rec;
649
650         epoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
651         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
652
653         mdc_setattr_pack_rec(rec, op_data);
654         /*
655          * The client will zero out local timestamps when losing the IBITS lock
656          * so any new RPC timestamps will update the client inode's timestamps.
657          * There was a defect on the server side which allowed the atime to be
658          * overwritten by a zeroed-out atime packed into the close RPC.
659          *
660          * Proactively clear the MDS_ATTR_ATIME flag in the RPC in this case
661          * to avoid zeroing the atime on old unpatched servers.  See LU-8041.
662          */
663         if (rec->sa_atime == 0)
664                 rec->sa_valid &= ~MDS_ATTR_ATIME;
665
666         mdc_ioepoch_pack(epoch, op_data);
667         mdc_close_intent_pack(pill, op_data);
668 }