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