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