Whamcloud - gitweb
9f59b3661a1a87fe933f90d05517a428f01ca81b
[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         set_mrc_cr_flags(rec, cr_flags);
341 }
342
343 static inline enum mds_attr_flags mdc_attr_pack(unsigned int ia_valid,
344                                                 enum op_xvalid ia_xvalid)
345 {
346         enum mds_attr_flags sa_valid = 0;
347
348         if (ia_valid & ATTR_MODE)
349                 sa_valid |= MDS_ATTR_MODE;
350         if (ia_valid & ATTR_UID)
351                 sa_valid |= MDS_ATTR_UID;
352         if (ia_valid & ATTR_GID)
353                 sa_valid |= MDS_ATTR_GID;
354         if (ia_valid & ATTR_SIZE)
355                 sa_valid |= MDS_ATTR_SIZE;
356         if (ia_valid & ATTR_ATIME)
357                 sa_valid |= MDS_ATTR_ATIME;
358         if (ia_valid & ATTR_MTIME)
359                 sa_valid |= MDS_ATTR_MTIME;
360         if (ia_valid & ATTR_CTIME)
361                 sa_valid |= MDS_ATTR_CTIME;
362         if (ia_valid & ATTR_ATIME_SET)
363                 sa_valid |= MDS_ATTR_ATIME_SET;
364         if (ia_valid & ATTR_MTIME_SET)
365                 sa_valid |= MDS_ATTR_MTIME_SET;
366         if (ia_valid & ATTR_FORCE)
367                 sa_valid |= MDS_ATTR_FORCE;
368         if (ia_xvalid & OP_XVALID_FLAGS)
369                 sa_valid |= MDS_ATTR_ATTR_FLAG;
370         if (ia_valid & ATTR_KILL_SUID)
371                 sa_valid |=  MDS_ATTR_KILL_SUID;
372         if (ia_valid & ATTR_KILL_SGID)
373                 sa_valid |= MDS_ATTR_KILL_SGID;
374         if (ia_xvalid & OP_XVALID_CTIME_SET)
375                 sa_valid |= MDS_ATTR_CTIME_SET;
376         if (ia_valid & ATTR_OPEN)
377                 sa_valid |= MDS_ATTR_FROM_OPEN;
378         if (ia_xvalid & OP_XVALID_BLOCKS)
379                 sa_valid |= MDS_ATTR_BLOCKS;
380         if (ia_xvalid & OP_XVALID_OWNEROVERRIDE)
381                 /* NFSD hack (see bug 5781) */
382                 sa_valid |= MDS_OPEN_OWNEROVERRIDE;
383         if (ia_xvalid & OP_XVALID_PROJID)
384                 sa_valid |= MDS_ATTR_PROJID;
385         if (ia_xvalid & OP_XVALID_LAZYSIZE)
386                 sa_valid |= MDS_ATTR_LSIZE;
387         if (ia_xvalid & OP_XVALID_LAZYBLOCKS)
388                 sa_valid |= MDS_ATTR_LBLOCKS;
389
390         return sa_valid;
391 }
392
393 static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec,
394                                  struct md_op_data *op_data)
395 {
396         rec->sa_opcode  = REINT_SETATTR;
397         rec->sa_fsuid   = from_kuid(&init_user_ns, current_fsuid());
398         rec->sa_fsgid   = from_kgid(&init_user_ns, current_fsgid());
399         rec->sa_cap = current_cap().cap[0];
400         rec->sa_suppgid = -1;
401
402         rec->sa_fid    = op_data->op_fid1;
403         rec->sa_valid  = mdc_attr_pack(op_data->op_attr.ia_valid,
404                                        op_data->op_xvalid);
405         rec->sa_mode   = op_data->op_attr.ia_mode;
406         rec->sa_uid    = from_kuid(&init_user_ns, op_data->op_attr.ia_uid);
407         rec->sa_gid    = from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
408         rec->sa_projid = op_data->op_projid;
409         rec->sa_size   = op_data->op_attr.ia_size;
410         rec->sa_blocks = op_data->op_attr_blocks;
411         rec->sa_atime = op_data->op_attr.ia_atime.tv_sec;
412         rec->sa_mtime = op_data->op_attr.ia_mtime.tv_sec;
413         rec->sa_ctime = op_data->op_attr.ia_ctime.tv_sec;
414         rec->sa_attr_flags = op_data->op_attr_flags;
415         if ((op_data->op_attr.ia_valid & ATTR_GID) &&
416             in_group_p(op_data->op_attr.ia_gid))
417                 rec->sa_suppgid =
418                         from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
419         else
420                 rec->sa_suppgid = op_data->op_suppgids[0];
421
422         rec->sa_bias = op_data->op_bias;
423 }
424
425 static void mdc_ioepoch_pack(struct mdt_ioepoch *epoch,
426                              struct md_op_data *op_data)
427 {
428         epoch->mio_open_handle = op_data->op_open_handle;
429         epoch->mio_unused1 = 0;
430         epoch->mio_unused2 = 0;
431         epoch->mio_padding = 0;
432 }
433
434 void mdc_setattr_pack(struct req_capsule *pill, struct md_op_data *op_data,
435                       void *ea, size_t ealen)
436 {
437         struct mdt_rec_setattr *rec;
438         struct lov_user_md *lum = NULL;
439
440         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
441                      sizeof(struct mdt_rec_setattr));
442         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
443         mdc_setattr_pack_rec(rec, op_data);
444
445         if (ealen == 0)
446                 return;
447
448         lum = req_capsule_client_get(pill, &RMF_EADATA);
449         if (ea == NULL) { /* Remove LOV EA */
450                 lum->lmm_magic = cpu_to_le32(LOV_USER_MAGIC_V1);
451                 lum->lmm_stripe_size = 0;
452                 lum->lmm_stripe_count = 0;
453                 lum->lmm_stripe_offset =
454                   (typeof(lum->lmm_stripe_offset))LOV_OFFSET_DEFAULT;
455         } else {
456                 memcpy(lum, ea, ealen);
457         }
458 }
459
460 void mdc_unlink_pack(struct req_capsule *pill, struct md_op_data *op_data)
461 {
462         struct mdt_rec_unlink *rec;
463
464         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
465                      sizeof(struct mdt_rec_unlink));
466         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
467         LASSERT(rec != NULL);
468
469         rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ?
470                                         REINT_RMENTRY : REINT_UNLINK;
471         rec->ul_fsuid = op_data->op_fsuid;
472         rec->ul_fsgid = op_data->op_fsgid;
473         rec->ul_cap = op_data->op_cap.cap[0];
474         rec->ul_mode = op_data->op_mode;
475         rec->ul_suppgid1 = op_data->op_suppgids[0];
476         rec->ul_suppgid2 = -1;
477         rec->ul_fid1 = op_data->op_fid1;
478         rec->ul_fid2 = op_data->op_fid2;
479         rec->ul_time = op_data->op_mod_time;
480         rec->ul_bias = op_data->op_bias;
481
482         mdc_pack_name(pill, &RMF_NAME, op_data->op_name, op_data->op_namelen);
483
484         /* pack SELinux policy info if any */
485         mdc_file_sepol_pack(pill);
486 }
487
488 void mdc_link_pack(struct req_capsule *pill, struct md_op_data *op_data)
489 {
490         struct mdt_rec_link *rec;
491
492         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
493                      sizeof(struct mdt_rec_link));
494         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
495         LASSERT(rec != NULL);
496
497         rec->lk_opcode   = REINT_LINK;
498         rec->lk_fsuid    = op_data->op_fsuid; /* current->fsuid; */
499         rec->lk_fsgid    = op_data->op_fsgid; /* current->fsgid; */
500         rec->lk_cap      = op_data->op_cap.cap[0]; /* current->cap_effective; */
501         rec->lk_suppgid1 = op_data->op_suppgids[0];
502         rec->lk_suppgid2 = op_data->op_suppgids[1];
503         rec->lk_fid1     = op_data->op_fid1;
504         rec->lk_fid2     = op_data->op_fid2;
505         rec->lk_time     = op_data->op_mod_time;
506         rec->lk_bias     = op_data->op_bias;
507
508         mdc_pack_name(pill, &RMF_NAME, op_data->op_name, op_data->op_namelen);
509
510         /* pack SELinux policy info if any */
511         mdc_file_sepol_pack(pill);
512 }
513
514 static void mdc_close_intent_pack(struct req_capsule *pill,
515                                   struct md_op_data *op_data)
516 {
517         struct close_data       *data;
518         struct ldlm_lock        *lock;
519         enum mds_op_bias         bias = op_data->op_bias;
520
521         if (!(bias & (MDS_CLOSE_INTENT | MDS_CLOSE_MIGRATE)))
522                 return;
523
524         data = req_capsule_client_get(pill, &RMF_CLOSE_DATA);
525         LASSERT(data != NULL);
526
527         lock = ldlm_handle2lock(&op_data->op_lease_handle);
528         if (lock != NULL) {
529                 data->cd_handle = lock->l_remote_handle;
530                 LDLM_LOCK_PUT(lock);
531         }
532         ldlm_cli_cancel(&op_data->op_lease_handle, LCF_LOCAL);
533
534         data->cd_data_version = op_data->op_data_version;
535         data->cd_fid = op_data->op_fid2;
536
537         if (bias & MDS_CLOSE_LAYOUT_SPLIT) {
538                 data->cd_mirror_id = op_data->op_mirror_id;
539         } else if (bias & MDS_CLOSE_RESYNC_DONE) {
540                 struct close_data_resync_done *sync = &data->cd_resync;
541
542                 BUILD_BUG_ON(sizeof(data->cd_resync) >
543                              sizeof(data->cd_reserved));
544                 sync->resync_count = op_data->op_data_size / sizeof(__u32);
545                 if (sync->resync_count <= INLINE_RESYNC_ARRAY_SIZE) {
546                         memcpy(sync->resync_ids_inline, op_data->op_data,
547                                op_data->op_data_size);
548                 } else {
549                         size_t count = sync->resync_count;
550
551                         memcpy(req_capsule_client_get(pill, &RMF_U32),
552                                op_data->op_data, count * sizeof(__u32));
553                 }
554         } else if (bias & MDS_PCC_ATTACH) {
555                 data->cd_archive_id = op_data->op_archive_id;
556         }
557 }
558
559 void mdc_rename_pack(struct req_capsule *pill, struct md_op_data *op_data,
560                      const char *old, size_t oldlen,
561                      const char *new, size_t newlen)
562 {
563         struct mdt_rec_rename *rec;
564
565         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
566                      sizeof(struct mdt_rec_rename));
567         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
568
569         /* XXX do something about time, uid, gid */
570         rec->rn_opcode   = REINT_RENAME;
571         rec->rn_fsuid    = op_data->op_fsuid;
572         rec->rn_fsgid    = op_data->op_fsgid;
573         rec->rn_cap      = op_data->op_cap.cap[0];
574         rec->rn_suppgid1 = op_data->op_suppgids[0];
575         rec->rn_suppgid2 = op_data->op_suppgids[1];
576         rec->rn_fid1     = op_data->op_fid1;
577         rec->rn_fid2     = op_data->op_fid2;
578         rec->rn_time     = op_data->op_mod_time;
579         rec->rn_mode     = op_data->op_mode;
580         rec->rn_bias     = op_data->op_bias;
581
582         mdc_pack_name(pill, &RMF_NAME, old, oldlen);
583
584         if (new != NULL)
585                 mdc_pack_name(pill, &RMF_SYMTGT, new, newlen);
586
587         /* pack SELinux policy info if any */
588         mdc_file_sepol_pack(pill);
589 }
590
591 void mdc_migrate_pack(struct req_capsule *pill, struct md_op_data *op_data,
592                       const char *name, size_t namelen)
593 {
594         struct mdt_rec_rename *rec;
595         char *ea;
596
597         BUILD_BUG_ON(sizeof(struct mdt_rec_reint) !=
598                      sizeof(struct mdt_rec_rename));
599         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
600
601         rec->rn_opcode   = REINT_MIGRATE;
602         rec->rn_fsuid    = op_data->op_fsuid;
603         rec->rn_fsgid    = op_data->op_fsgid;
604         rec->rn_cap      = op_data->op_cap.cap[0];
605         rec->rn_suppgid1 = op_data->op_suppgids[0];
606         rec->rn_suppgid2 = op_data->op_suppgids[1];
607         rec->rn_fid1     = op_data->op_fid1;
608         rec->rn_fid2     = op_data->op_fid4;
609         rec->rn_time     = op_data->op_mod_time;
610         rec->rn_mode     = op_data->op_mode;
611         rec->rn_bias     = op_data->op_bias;
612
613         mdc_pack_name(pill, &RMF_NAME, name, namelen);
614
615         if (op_data->op_bias & MDS_CLOSE_MIGRATE) {
616                 struct mdt_ioepoch *epoch;
617
618                 mdc_close_intent_pack(pill, op_data);
619                 epoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
620                 mdc_ioepoch_pack(epoch, op_data);
621         }
622
623         ea = req_capsule_client_get(pill, &RMF_EADATA);
624         memcpy(ea, op_data->op_data, op_data->op_data_size);
625 }
626
627 void mdc_getattr_pack(struct req_capsule *pill, __u64 valid, __u32 flags,
628                       struct md_op_data *op_data, size_t ea_size)
629 {
630         struct mdt_body *b = req_capsule_client_get(pill, &RMF_MDT_BODY);
631
632         b->mbo_valid = valid;
633         if (op_data->op_bias & MDS_CROSS_REF)
634                 b->mbo_valid |= OBD_MD_FLCROSSREF;
635         b->mbo_eadatasize = ea_size;
636         b->mbo_flags = flags;
637         __mdc_pack_body(b, op_data->op_suppgids[0]);
638
639         b->mbo_fid1 = op_data->op_fid1;
640         b->mbo_fid2 = op_data->op_fid2;
641         b->mbo_valid |= OBD_MD_FLID;
642
643         if (op_data->op_name != NULL)
644                 mdc_pack_name(pill, &RMF_NAME, op_data->op_name,
645                               op_data->op_namelen);
646 }
647
648 void mdc_close_pack(struct req_capsule *pill, struct md_op_data *op_data)
649 {
650         struct mdt_ioepoch *epoch;
651         struct mdt_rec_setattr *rec;
652
653         epoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
654         rec = req_capsule_client_get(pill, &RMF_REC_REINT);
655
656         mdc_setattr_pack_rec(rec, op_data);
657         /*
658          * The client will zero out local timestamps when losing the IBITS lock
659          * so any new RPC timestamps will update the client inode's timestamps.
660          * There was a defect on the server side which allowed the atime to be
661          * overwritten by a zeroed-out atime packed into the close RPC.
662          *
663          * Proactively clear the MDS_ATTR_ATIME flag in the RPC in this case
664          * to avoid zeroing the atime on old unpatched servers.  See LU-8041.
665          */
666         if (rec->sa_atime == 0)
667                 rec->sa_valid &= ~MDS_ATTR_ATIME;
668
669         mdc_ioepoch_pack(epoch, op_data);
670         mdc_close_intent_pack(pill, op_data);
671 }