Commit | Line | Data |
---|---|---|
d7e09d03 PT |
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 | |
6a5b99a4 | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
d7e09d03 | 19 | * |
d7e09d03 PT |
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 | * | |
1dc563a6 | 26 | * Copyright (c) 2011, 2015, Intel Corporation. |
d7e09d03 PT |
27 | */ |
28 | /* | |
29 | * This file is part of Lustre, http://www.lustre.org/ | |
30 | * Lustre is a trademark of Sun Microsystems, Inc. | |
31 | */ | |
32 | ||
33 | #define DEBUG_SUBSYSTEM S_MDC | |
05932307 GKH |
34 | #include "../include/lustre_net.h" |
35 | #include "../include/lustre/lustre_idl.h" | |
d7e09d03 PT |
36 | #include "mdc_internal.h" |
37 | ||
d7e09d03 PT |
38 | static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid) |
39 | { | |
2e1b5b8b JH |
40 | b->mbo_suppgid = suppgid; |
41 | b->mbo_uid = from_kuid(&init_user_ns, current_uid()); | |
42 | b->mbo_gid = from_kgid(&init_user_ns, current_gid()); | |
43 | b->mbo_fsuid = from_kuid(&init_user_ns, current_fsuid()); | |
44 | b->mbo_fsgid = from_kgid(&init_user_ns, current_fsgid()); | |
45 | b->mbo_capability = cfs_curproc_cap_pack(); | |
d7e09d03 PT |
46 | } |
47 | ||
d7e09d03 PT |
48 | void mdc_swap_layouts_pack(struct ptlrpc_request *req, |
49 | struct md_op_data *op_data) | |
50 | { | |
51 | struct mdt_body *b = req_capsule_client_get(&req->rq_pill, | |
52 | &RMF_MDT_BODY); | |
53 | ||
54 | __mdc_pack_body(b, op_data->op_suppgids[0]); | |
2e1b5b8b JH |
55 | b->mbo_fid1 = op_data->op_fid1; |
56 | b->mbo_fid2 = op_data->op_fid2; | |
57 | b->mbo_valid |= OBD_MD_FLID; | |
d7e09d03 PT |
58 | } |
59 | ||
ef2e0f55 | 60 | void mdc_pack_body(struct ptlrpc_request *req, const struct lu_fid *fid, |
d7e09d03 PT |
61 | __u64 valid, int ea_size, __u32 suppgid, int flags) |
62 | { | |
63 | struct mdt_body *b = req_capsule_client_get(&req->rq_pill, | |
64 | &RMF_MDT_BODY); | |
2e1b5b8b JH |
65 | b->mbo_valid = valid; |
66 | b->mbo_eadatasize = ea_size; | |
67 | b->mbo_flags = flags; | |
d7e09d03 PT |
68 | __mdc_pack_body(b, suppgid); |
69 | if (fid) { | |
2e1b5b8b JH |
70 | b->mbo_fid1 = *fid; |
71 | b->mbo_valid |= OBD_MD_FLID; | |
d7e09d03 PT |
72 | } |
73 | } | |
74 | ||
d097d67b JH |
75 | /** |
76 | * Pack a name (path component) into a request | |
77 | * | |
78 | * \param[in] req request | |
79 | * \param[in] field request field (usually RMF_NAME) | |
80 | * \param[in] name path component | |
81 | * \param[in] name_len length of path component | |
82 | * | |
83 | * \a field must be present in \a req and of size \a name_len + 1. | |
84 | * | |
85 | * \a name must be '\0' terminated of length \a name_len and represent | |
86 | * a single path component (not contain '/'). | |
87 | */ | |
88 | static void mdc_pack_name(struct ptlrpc_request *req, | |
89 | const struct req_msg_field *field, | |
90 | const char *name, size_t name_len) | |
91 | { | |
92 | size_t buf_size; | |
93 | size_t cpy_len; | |
94 | char *buf; | |
95 | ||
96 | buf = req_capsule_client_get(&req->rq_pill, field); | |
97 | buf_size = req_capsule_get_size(&req->rq_pill, field, RCL_CLIENT); | |
98 | ||
99 | LASSERT(name && name_len && buf && buf_size == name_len + 1); | |
100 | ||
101 | cpy_len = strlcpy(buf, name, buf_size); | |
102 | ||
103 | LASSERT(cpy_len == name_len && lu_name_is_valid_2(buf, cpy_len)); | |
104 | } | |
105 | ||
d7e09d03 | 106 | void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff, |
ef2e0f55 | 107 | __u32 size, const struct lu_fid *fid) |
d7e09d03 PT |
108 | { |
109 | struct mdt_body *b = req_capsule_client_get(&req->rq_pill, | |
110 | &RMF_MDT_BODY); | |
2e1b5b8b JH |
111 | b->mbo_fid1 = *fid; |
112 | b->mbo_valid |= OBD_MD_FLID; | |
113 | b->mbo_size = pgoff; /* !! */ | |
114 | b->mbo_nlink = size; /* !! */ | |
d7e09d03 | 115 | __mdc_pack_body(b, -1); |
2e1b5b8b | 116 | b->mbo_mode = LUDA_FID | LUDA_TYPE; |
d7e09d03 PT |
117 | } |
118 | ||
119 | /* packing of MDS records */ | |
120 | void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, | |
121 | const void *data, int datalen, __u32 mode, | |
122 | __u32 uid, __u32 gid, cfs_cap_t cap_effective, __u64 rdev) | |
123 | { | |
124 | struct mdt_rec_create *rec; | |
125 | char *tmp; | |
126 | __u64 flags; | |
127 | ||
128 | CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create)); | |
129 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
130 | ||
d7e09d03 PT |
131 | rec->cr_opcode = REINT_CREATE; |
132 | rec->cr_fsuid = uid; | |
133 | rec->cr_fsgid = gid; | |
134 | rec->cr_cap = cap_effective; | |
135 | rec->cr_fid1 = op_data->op_fid1; | |
136 | rec->cr_fid2 = op_data->op_fid2; | |
137 | rec->cr_mode = mode; | |
138 | rec->cr_rdev = rdev; | |
139 | rec->cr_time = op_data->op_mod_time; | |
140 | rec->cr_suppgid1 = op_data->op_suppgids[0]; | |
141 | rec->cr_suppgid2 = op_data->op_suppgids[1]; | |
142 | flags = op_data->op_flags & MF_SOM_LOCAL_FLAGS; | |
143 | if (op_data->op_bias & MDS_CREATE_VOLATILE) | |
144 | flags |= MDS_OPEN_VOLATILE; | |
145 | set_mrc_cr_flags(rec, flags); | |
146 | rec->cr_bias = op_data->op_bias; | |
147 | rec->cr_umask = current_umask(); | |
148 | ||
d097d67b | 149 | mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen); |
d7e09d03 PT |
150 | if (data) { |
151 | tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA); | |
152 | memcpy(tmp, data, datalen); | |
153 | } | |
154 | } | |
155 | ||
d3a8a4e2 | 156 | static __u64 mds_pack_open_flags(__u64 flags, __u32 mode) |
d7e09d03 PT |
157 | { |
158 | __u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE | | |
c1b66fcc | 159 | MDS_OPEN_FL_INTERNAL)); |
d7e09d03 PT |
160 | if (flags & O_CREAT) |
161 | cr_flags |= MDS_OPEN_CREAT; | |
162 | if (flags & O_EXCL) | |
163 | cr_flags |= MDS_OPEN_EXCL; | |
164 | if (flags & O_TRUNC) | |
165 | cr_flags |= MDS_OPEN_TRUNC; | |
166 | if (flags & O_APPEND) | |
167 | cr_flags |= MDS_OPEN_APPEND; | |
168 | if (flags & O_SYNC) | |
169 | cr_flags |= MDS_OPEN_SYNC; | |
170 | if (flags & O_DIRECTORY) | |
171 | cr_flags |= MDS_OPEN_DIRECTORY; | |
962dbfd6 | 172 | if (flags & __FMODE_EXEC) |
d7e09d03 | 173 | cr_flags |= MDS_FMODE_EXEC; |
38585ccc | 174 | if (cl_is_lov_delay_create(flags)) |
d7e09d03 PT |
175 | cr_flags |= MDS_OPEN_DELAY_CREATE; |
176 | ||
7d5ed06b | 177 | if (flags & O_NONBLOCK) |
d7e09d03 PT |
178 | cr_flags |= MDS_OPEN_NORESTORE; |
179 | ||
180 | return cr_flags; | |
181 | } | |
182 | ||
183 | /* packing of MDS records */ | |
184 | void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, | |
d3a8a4e2 | 185 | __u32 mode, __u64 rdev, __u64 flags, const void *lmm, |
d7e09d03 PT |
186 | int lmmlen) |
187 | { | |
188 | struct mdt_rec_create *rec; | |
189 | char *tmp; | |
190 | __u64 cr_flags; | |
191 | ||
192 | CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create)); | |
193 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
194 | ||
195 | /* XXX do something about time, uid, gid */ | |
196 | rec->cr_opcode = REINT_OPEN; | |
4b1a25f0 PT |
197 | rec->cr_fsuid = from_kuid(&init_user_ns, current_fsuid()); |
198 | rec->cr_fsgid = from_kgid(&init_user_ns, current_fsgid()); | |
d7e09d03 | 199 | rec->cr_cap = cfs_curproc_cap_pack(); |
cc1cf0e0 RS |
200 | rec->cr_fid1 = op_data->op_fid1; |
201 | rec->cr_fid2 = op_data->op_fid2; | |
202 | ||
d7e09d03 PT |
203 | rec->cr_mode = mode; |
204 | cr_flags = mds_pack_open_flags(flags, mode); | |
205 | rec->cr_rdev = rdev; | |
206 | rec->cr_time = op_data->op_mod_time; | |
207 | rec->cr_suppgid1 = op_data->op_suppgids[0]; | |
208 | rec->cr_suppgid2 = op_data->op_suppgids[1]; | |
209 | rec->cr_bias = op_data->op_bias; | |
210 | rec->cr_umask = current_umask(); | |
d3a8a4e2 | 211 | rec->cr_old_handle = op_data->op_handle; |
d7e09d03 | 212 | |
d7e09d03 | 213 | if (op_data->op_name) { |
d097d67b JH |
214 | mdc_pack_name(req, &RMF_NAME, op_data->op_name, |
215 | op_data->op_namelen); | |
216 | ||
d7e09d03 PT |
217 | if (op_data->op_bias & MDS_CREATE_VOLATILE) |
218 | cr_flags |= MDS_OPEN_VOLATILE; | |
219 | } | |
220 | ||
221 | if (lmm) { | |
222 | cr_flags |= MDS_OPEN_HAS_EA; | |
223 | tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA); | |
224 | memcpy(tmp, lmm, lmmlen); | |
225 | } | |
226 | set_mrc_cr_flags(rec, cr_flags); | |
227 | } | |
228 | ||
982ec91f SM |
229 | static inline __u64 attr_pack(unsigned int ia_valid) |
230 | { | |
d7e09d03 PT |
231 | __u64 sa_valid = 0; |
232 | ||
233 | if (ia_valid & ATTR_MODE) | |
234 | sa_valid |= MDS_ATTR_MODE; | |
235 | if (ia_valid & ATTR_UID) | |
236 | sa_valid |= MDS_ATTR_UID; | |
237 | if (ia_valid & ATTR_GID) | |
238 | sa_valid |= MDS_ATTR_GID; | |
239 | if (ia_valid & ATTR_SIZE) | |
240 | sa_valid |= MDS_ATTR_SIZE; | |
241 | if (ia_valid & ATTR_ATIME) | |
242 | sa_valid |= MDS_ATTR_ATIME; | |
243 | if (ia_valid & ATTR_MTIME) | |
244 | sa_valid |= MDS_ATTR_MTIME; | |
245 | if (ia_valid & ATTR_CTIME) | |
246 | sa_valid |= MDS_ATTR_CTIME; | |
247 | if (ia_valid & ATTR_ATIME_SET) | |
248 | sa_valid |= MDS_ATTR_ATIME_SET; | |
249 | if (ia_valid & ATTR_MTIME_SET) | |
250 | sa_valid |= MDS_ATTR_MTIME_SET; | |
251 | if (ia_valid & ATTR_FORCE) | |
252 | sa_valid |= MDS_ATTR_FORCE; | |
253 | if (ia_valid & ATTR_ATTR_FLAG) | |
254 | sa_valid |= MDS_ATTR_ATTR_FLAG; | |
255 | if (ia_valid & ATTR_KILL_SUID) | |
256 | sa_valid |= MDS_ATTR_KILL_SUID; | |
257 | if (ia_valid & ATTR_KILL_SGID) | |
258 | sa_valid |= MDS_ATTR_KILL_SGID; | |
259 | if (ia_valid & ATTR_CTIME_SET) | |
260 | sa_valid |= MDS_ATTR_CTIME_SET; | |
e56e17ea | 261 | if (ia_valid & ATTR_OPEN) |
d7e09d03 PT |
262 | sa_valid |= MDS_ATTR_FROM_OPEN; |
263 | if (ia_valid & ATTR_BLOCKS) | |
264 | sa_valid |= MDS_ATTR_BLOCKS; | |
265 | if (ia_valid & MDS_OPEN_OWNEROVERRIDE) | |
266 | /* NFSD hack (see bug 5781) */ | |
267 | sa_valid |= MDS_OPEN_OWNEROVERRIDE; | |
268 | return sa_valid; | |
269 | } | |
270 | ||
271 | static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec, | |
272 | struct md_op_data *op_data) | |
273 | { | |
274 | rec->sa_opcode = REINT_SETATTR; | |
4b1a25f0 PT |
275 | rec->sa_fsuid = from_kuid(&init_user_ns, current_fsuid()); |
276 | rec->sa_fsgid = from_kgid(&init_user_ns, current_fsgid()); | |
d7e09d03 PT |
277 | rec->sa_cap = cfs_curproc_cap_pack(); |
278 | rec->sa_suppgid = -1; | |
279 | ||
280 | rec->sa_fid = op_data->op_fid1; | |
281 | rec->sa_valid = attr_pack(op_data->op_attr.ia_valid); | |
282 | rec->sa_mode = op_data->op_attr.ia_mode; | |
4b1a25f0 PT |
283 | rec->sa_uid = from_kuid(&init_user_ns, op_data->op_attr.ia_uid); |
284 | rec->sa_gid = from_kgid(&init_user_ns, op_data->op_attr.ia_gid); | |
d7e09d03 PT |
285 | rec->sa_size = op_data->op_attr.ia_size; |
286 | rec->sa_blocks = op_data->op_attr_blocks; | |
287 | rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime); | |
288 | rec->sa_mtime = LTIME_S(op_data->op_attr.ia_mtime); | |
289 | rec->sa_ctime = LTIME_S(op_data->op_attr.ia_ctime); | |
bb41292b | 290 | rec->sa_attr_flags = op_data->op_attr_flags; |
d7e09d03 | 291 | if ((op_data->op_attr.ia_valid & ATTR_GID) && |
4b1a25f0 PT |
292 | in_group_p(op_data->op_attr.ia_gid)) |
293 | rec->sa_suppgid = | |
294 | from_kgid(&init_user_ns, op_data->op_attr.ia_gid); | |
d7e09d03 PT |
295 | else |
296 | rec->sa_suppgid = op_data->op_suppgids[0]; | |
297 | ||
298 | rec->sa_bias = op_data->op_bias; | |
299 | } | |
300 | ||
301 | static void mdc_ioepoch_pack(struct mdt_ioepoch *epoch, | |
302 | struct md_op_data *op_data) | |
303 | { | |
304 | memcpy(&epoch->handle, &op_data->op_handle, sizeof(epoch->handle)); | |
305 | epoch->ioepoch = op_data->op_ioepoch; | |
306 | epoch->flags = op_data->op_flags & MF_SOM_LOCAL_FLAGS; | |
307 | } | |
308 | ||
309 | void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, | |
310 | void *ea, int ealen, void *ea2, int ea2len) | |
311 | { | |
312 | struct mdt_rec_setattr *rec; | |
313 | struct mdt_ioepoch *epoch; | |
314 | struct lov_user_md *lum = NULL; | |
315 | ||
301af906 SM |
316 | CLASSERT(sizeof(struct mdt_rec_reint) == |
317 | sizeof(struct mdt_rec_setattr)); | |
d7e09d03 PT |
318 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); |
319 | mdc_setattr_pack_rec(rec, op_data); | |
320 | ||
d7e09d03 PT |
321 | if (op_data->op_flags & (MF_SOM_CHANGE | MF_EPOCH_OPEN)) { |
322 | epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH); | |
323 | mdc_ioepoch_pack(epoch, op_data); | |
324 | } | |
325 | ||
326 | if (ealen == 0) | |
327 | return; | |
328 | ||
329 | lum = req_capsule_client_get(&req->rq_pill, &RMF_EADATA); | |
34e3ff96 | 330 | if (!ea) { /* Remove LOV EA */ |
d7e09d03 PT |
331 | lum->lmm_magic = LOV_USER_MAGIC_V1; |
332 | lum->lmm_stripe_size = 0; | |
333 | lum->lmm_stripe_count = 0; | |
334 | lum->lmm_stripe_offset = (typeof(lum->lmm_stripe_offset))(-1); | |
335 | } else { | |
336 | memcpy(lum, ea, ealen); | |
337 | } | |
338 | ||
339 | if (ea2len == 0) | |
340 | return; | |
341 | ||
342 | memcpy(req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES), ea2, | |
343 | ea2len); | |
344 | } | |
345 | ||
346 | void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data) | |
347 | { | |
348 | struct mdt_rec_unlink *rec; | |
d7e09d03 PT |
349 | |
350 | CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink)); | |
351 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
d7e09d03 | 352 | |
301af906 | 353 | rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? |
d7e09d03 | 354 | REINT_RMENTRY : REINT_UNLINK; |
301af906 SM |
355 | rec->ul_fsuid = op_data->op_fsuid; |
356 | rec->ul_fsgid = op_data->op_fsgid; | |
357 | rec->ul_cap = op_data->op_cap; | |
358 | rec->ul_mode = op_data->op_mode; | |
359 | rec->ul_suppgid1 = op_data->op_suppgids[0]; | |
360 | rec->ul_suppgid2 = -1; | |
361 | rec->ul_fid1 = op_data->op_fid1; | |
362 | rec->ul_fid2 = op_data->op_fid2; | |
363 | rec->ul_time = op_data->op_mod_time; | |
364 | rec->ul_bias = op_data->op_bias; | |
d7e09d03 | 365 | |
d097d67b | 366 | mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen); |
d7e09d03 PT |
367 | } |
368 | ||
369 | void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data) | |
370 | { | |
371 | struct mdt_rec_link *rec; | |
d7e09d03 PT |
372 | |
373 | CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_link)); | |
374 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
d7e09d03 PT |
375 | |
376 | rec->lk_opcode = REINT_LINK; | |
125ffec0 SM |
377 | rec->lk_fsuid = op_data->op_fsuid; /* current->fsuid; */ |
378 | rec->lk_fsgid = op_data->op_fsgid; /* current->fsgid; */ | |
379 | rec->lk_cap = op_data->op_cap; /* current->cap_effective; */ | |
d7e09d03 PT |
380 | rec->lk_suppgid1 = op_data->op_suppgids[0]; |
381 | rec->lk_suppgid2 = op_data->op_suppgids[1]; | |
382 | rec->lk_fid1 = op_data->op_fid1; | |
383 | rec->lk_fid2 = op_data->op_fid2; | |
384 | rec->lk_time = op_data->op_mod_time; | |
385 | rec->lk_bias = op_data->op_bias; | |
386 | ||
d097d67b | 387 | mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen); |
d7e09d03 PT |
388 | } |
389 | ||
390 | void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data, | |
391 | const char *old, int oldlen, const char *new, int newlen) | |
392 | { | |
393 | struct mdt_rec_rename *rec; | |
d7e09d03 PT |
394 | |
395 | CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_rename)); | |
396 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
397 | ||
398 | /* XXX do something about time, uid, gid */ | |
79496845 | 399 | rec->rn_opcode = op_data->op_cli_flags & CLI_MIGRATE ? |
400 | REINT_MIGRATE : REINT_RENAME; | |
d7e09d03 PT |
401 | rec->rn_opcode = REINT_RENAME; |
402 | rec->rn_fsuid = op_data->op_fsuid; | |
403 | rec->rn_fsgid = op_data->op_fsgid; | |
404 | rec->rn_cap = op_data->op_cap; | |
405 | rec->rn_suppgid1 = op_data->op_suppgids[0]; | |
406 | rec->rn_suppgid2 = op_data->op_suppgids[1]; | |
407 | rec->rn_fid1 = op_data->op_fid1; | |
408 | rec->rn_fid2 = op_data->op_fid2; | |
409 | rec->rn_time = op_data->op_mod_time; | |
410 | rec->rn_mode = op_data->op_mode; | |
411 | rec->rn_bias = op_data->op_bias; | |
412 | ||
d097d67b | 413 | mdc_pack_name(req, &RMF_NAME, old, oldlen); |
d7e09d03 | 414 | |
d097d67b JH |
415 | if (new) |
416 | mdc_pack_name(req, &RMF_SYMTGT, new, newlen); | |
d7e09d03 PT |
417 | } |
418 | ||
419 | void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags, | |
420 | struct md_op_data *op_data, int ea_size) | |
421 | { | |
422 | struct mdt_body *b = req_capsule_client_get(&req->rq_pill, | |
423 | &RMF_MDT_BODY); | |
424 | ||
2e1b5b8b | 425 | b->mbo_valid = valid; |
d7e09d03 | 426 | if (op_data->op_bias & MDS_CHECK_SPLIT) |
2e1b5b8b | 427 | b->mbo_valid |= OBD_MD_FLCKSPLIT; |
d7e09d03 | 428 | if (op_data->op_bias & MDS_CROSS_REF) |
2e1b5b8b JH |
429 | b->mbo_valid |= OBD_MD_FLCROSSREF; |
430 | b->mbo_eadatasize = ea_size; | |
431 | b->mbo_flags = flags; | |
d7e09d03 PT |
432 | __mdc_pack_body(b, op_data->op_suppgids[0]); |
433 | ||
2e1b5b8b JH |
434 | b->mbo_fid1 = op_data->op_fid1; |
435 | b->mbo_fid2 = op_data->op_fid2; | |
436 | b->mbo_valid |= OBD_MD_FLID; | |
d7e09d03 | 437 | |
d097d67b JH |
438 | if (op_data->op_name) |
439 | mdc_pack_name(req, &RMF_NAME, op_data->op_name, | |
440 | op_data->op_namelen); | |
d7e09d03 PT |
441 | } |
442 | ||
48d23e61 JX |
443 | static void mdc_hsm_release_pack(struct ptlrpc_request *req, |
444 | struct md_op_data *op_data) | |
445 | { | |
446 | if (op_data->op_bias & MDS_HSM_RELEASE) { | |
447 | struct close_data *data; | |
448 | struct ldlm_lock *lock; | |
449 | ||
450 | data = req_capsule_client_get(&req->rq_pill, &RMF_CLOSE_DATA); | |
48d23e61 JX |
451 | |
452 | lock = ldlm_handle2lock(&op_data->op_lease_handle); | |
34e3ff96 | 453 | if (lock) { |
48d23e61 | 454 | data->cd_handle = lock->l_remote_handle; |
ead02808 | 455 | LDLM_LOCK_PUT(lock); |
48d23e61 JX |
456 | } |
457 | ldlm_cli_cancel(&op_data->op_lease_handle, LCF_LOCAL); | |
458 | ||
459 | data->cd_data_version = op_data->op_data_version; | |
460 | data->cd_fid = op_data->op_fid2; | |
461 | } | |
462 | } | |
463 | ||
d7e09d03 PT |
464 | void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data) |
465 | { | |
466 | struct mdt_ioepoch *epoch; | |
467 | struct mdt_rec_setattr *rec; | |
468 | ||
469 | epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH); | |
470 | rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); | |
471 | ||
472 | mdc_setattr_pack_rec(rec, op_data); | |
aea7ccd9 NY |
473 | /* |
474 | * The client will zero out local timestamps when losing the IBITS lock | |
475 | * so any new RPC timestamps will update the client inode's timestamps. | |
476 | * There was a defect on the server side which allowed the atime to be | |
477 | * overwritten by a zeroed-out atime packed into the close RPC. | |
478 | * | |
479 | * Proactively clear the MDS_ATTR_ATIME flag in the RPC in this case | |
480 | * to avoid zeroing the atime on old unpatched servers. See LU-8041. | |
481 | */ | |
482 | if (rec->sa_atime == 0) | |
483 | rec->sa_valid &= ~MDS_ATTR_ATIME; | |
484 | ||
d7e09d03 | 485 | mdc_ioepoch_pack(epoch, op_data); |
48d23e61 | 486 | mdc_hsm_release_pack(req, op_data); |
d7e09d03 | 487 | } |