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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 
37 #define DEBUG_SUBSYSTEM S_MDC
38 #include "../include/lustre_net.h"
39 #include "../include/lustre/lustre_idl.h"
40 #include "mdc_internal.h"
41 
42 
__mdc_pack_body(struct mdt_body * b,__u32 suppgid)43 static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid)
44 {
45 	LASSERT(b != NULL);
46 
47 	b->suppgid = suppgid;
48 	b->uid = from_kuid(&init_user_ns, current_uid());
49 	b->gid = from_kgid(&init_user_ns, current_gid());
50 	b->fsuid = from_kuid(&init_user_ns, current_fsuid());
51 	b->fsgid = from_kgid(&init_user_ns, current_fsgid());
52 	b->capability = cfs_curproc_cap_pack();
53 }
54 
mdc_pack_capa(struct ptlrpc_request * req,const struct req_msg_field * field,struct obd_capa * oc)55 void mdc_pack_capa(struct ptlrpc_request *req,
56 		   const struct req_msg_field *field,
57 		   struct obd_capa *oc)
58 {
59 	struct req_capsule *pill = &req->rq_pill;
60 	struct lustre_capa *c;
61 
62 	if (oc == NULL) {
63 		LASSERT(req_capsule_get_size(pill, field, RCL_CLIENT) == 0);
64 		return;
65 	}
66 
67 	c = req_capsule_client_get(pill, field);
68 	LASSERT(c != NULL);
69 	capa_cpy(c, oc);
70 	DEBUG_CAPA(D_SEC, c, "pack");
71 }
72 
mdc_is_subdir_pack(struct ptlrpc_request * req,const struct lu_fid * pfid,const struct lu_fid * cfid,int flags)73 void mdc_is_subdir_pack(struct ptlrpc_request *req, const struct lu_fid *pfid,
74 			const struct lu_fid *cfid, int flags)
75 {
76 	struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
77 						    &RMF_MDT_BODY);
78 
79 	if (pfid) {
80 		b->fid1 = *pfid;
81 		b->valid = OBD_MD_FLID;
82 	}
83 	if (cfid)
84 		b->fid2 = *cfid;
85 	b->flags = flags;
86 }
87 
mdc_swap_layouts_pack(struct ptlrpc_request * req,struct md_op_data * op_data)88 void mdc_swap_layouts_pack(struct ptlrpc_request *req,
89 			   struct md_op_data *op_data)
90 {
91 	struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
92 						    &RMF_MDT_BODY);
93 
94 	__mdc_pack_body(b, op_data->op_suppgids[0]);
95 	b->fid1 = op_data->op_fid1;
96 	b->fid2 = op_data->op_fid2;
97 	b->valid |= OBD_MD_FLID;
98 
99 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
100 	mdc_pack_capa(req, &RMF_CAPA2, op_data->op_capa2);
101 }
102 
mdc_pack_body(struct ptlrpc_request * req,const struct lu_fid * fid,struct obd_capa * oc,__u64 valid,int ea_size,__u32 suppgid,int flags)103 void mdc_pack_body(struct ptlrpc_request *req,
104 		   const struct lu_fid *fid, struct obd_capa *oc,
105 		   __u64 valid, int ea_size, __u32 suppgid, int flags)
106 {
107 	struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
108 						    &RMF_MDT_BODY);
109 	LASSERT(b != NULL);
110 	b->valid = valid;
111 	b->eadatasize = ea_size;
112 	b->flags = flags;
113 	__mdc_pack_body(b, suppgid);
114 	if (fid) {
115 		b->fid1 = *fid;
116 		b->valid |= OBD_MD_FLID;
117 		mdc_pack_capa(req, &RMF_CAPA1, oc);
118 	}
119 }
120 
mdc_readdir_pack(struct ptlrpc_request * req,__u64 pgoff,__u32 size,const struct lu_fid * fid,struct obd_capa * oc)121 void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff,
122 		      __u32 size, const struct lu_fid *fid, struct obd_capa *oc)
123 {
124 	struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
125 						    &RMF_MDT_BODY);
126 	b->fid1 = *fid;
127 	b->valid |= OBD_MD_FLID;
128 	b->size = pgoff;		       /* !! */
129 	b->nlink = size;			/* !! */
130 	__mdc_pack_body(b, -1);
131 	b->mode = LUDA_FID | LUDA_TYPE;
132 
133 	mdc_pack_capa(req, &RMF_CAPA1, oc);
134 }
135 
136 /* packing of MDS records */
mdc_create_pack(struct ptlrpc_request * req,struct md_op_data * op_data,const void * data,int datalen,__u32 mode,__u32 uid,__u32 gid,cfs_cap_t cap_effective,__u64 rdev)137 void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
138 		     const void *data, int datalen, __u32 mode,
139 		     __u32 uid, __u32 gid, cfs_cap_t cap_effective, __u64 rdev)
140 {
141 	struct mdt_rec_create	*rec;
142 	char			*tmp;
143 	__u64			 flags;
144 
145 	CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create));
146 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
147 
148 
149 	rec->cr_opcode   = REINT_CREATE;
150 	rec->cr_fsuid    = uid;
151 	rec->cr_fsgid    = gid;
152 	rec->cr_cap      = cap_effective;
153 	rec->cr_fid1     = op_data->op_fid1;
154 	rec->cr_fid2     = op_data->op_fid2;
155 	rec->cr_mode     = mode;
156 	rec->cr_rdev     = rdev;
157 	rec->cr_time     = op_data->op_mod_time;
158 	rec->cr_suppgid1 = op_data->op_suppgids[0];
159 	rec->cr_suppgid2 = op_data->op_suppgids[1];
160 	flags = op_data->op_flags & MF_SOM_LOCAL_FLAGS;
161 	if (op_data->op_bias & MDS_CREATE_VOLATILE)
162 		flags |= MDS_OPEN_VOLATILE;
163 	set_mrc_cr_flags(rec, flags);
164 	rec->cr_bias     = op_data->op_bias;
165 	rec->cr_umask    = current_umask();
166 
167 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
168 
169 	tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
170 	LOGL0(op_data->op_name, op_data->op_namelen, tmp);
171 
172 	if (data) {
173 		tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA);
174 		memcpy(tmp, data, datalen);
175 	}
176 }
177 
mds_pack_open_flags(__u64 flags,__u32 mode)178 static __u64 mds_pack_open_flags(__u64 flags, __u32 mode)
179 {
180 	__u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE |
181 				   MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS |
182 				   MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK |
183 				   MDS_OPEN_BY_FID | MDS_OPEN_LEASE |
184 				   MDS_OPEN_RELEASE));
185 	if (flags & O_CREAT)
186 		cr_flags |= MDS_OPEN_CREAT;
187 	if (flags & O_EXCL)
188 		cr_flags |= MDS_OPEN_EXCL;
189 	if (flags & O_TRUNC)
190 		cr_flags |= MDS_OPEN_TRUNC;
191 	if (flags & O_APPEND)
192 		cr_flags |= MDS_OPEN_APPEND;
193 	if (flags & O_SYNC)
194 		cr_flags |= MDS_OPEN_SYNC;
195 	if (flags & O_DIRECTORY)
196 		cr_flags |= MDS_OPEN_DIRECTORY;
197 	if (flags & __FMODE_EXEC)
198 		cr_flags |= MDS_FMODE_EXEC;
199 	if (cl_is_lov_delay_create(flags))
200 		cr_flags |= MDS_OPEN_DELAY_CREATE;
201 
202 	if (flags & O_NONBLOCK)
203 		cr_flags |= MDS_OPEN_NORESTORE;
204 
205 	return cr_flags;
206 }
207 
208 /* packing of MDS records */
mdc_open_pack(struct ptlrpc_request * req,struct md_op_data * op_data,__u32 mode,__u64 rdev,__u64 flags,const void * lmm,int lmmlen)209 void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
210 		   __u32 mode, __u64 rdev, __u64 flags, const void *lmm,
211 		   int lmmlen)
212 {
213 	struct mdt_rec_create *rec;
214 	char *tmp;
215 	__u64 cr_flags;
216 
217 	CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create));
218 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
219 
220 	/* XXX do something about time, uid, gid */
221 	rec->cr_opcode   = REINT_OPEN;
222 	rec->cr_fsuid    = from_kuid(&init_user_ns, current_fsuid());
223 	rec->cr_fsgid    = from_kgid(&init_user_ns, current_fsgid());
224 	rec->cr_cap      = cfs_curproc_cap_pack();
225 	rec->cr_fid1 = op_data->op_fid1;
226 	rec->cr_fid2 = op_data->op_fid2;
227 
228 	rec->cr_mode     = mode;
229 	cr_flags = mds_pack_open_flags(flags, mode);
230 	rec->cr_rdev     = rdev;
231 	rec->cr_time     = op_data->op_mod_time;
232 	rec->cr_suppgid1 = op_data->op_suppgids[0];
233 	rec->cr_suppgid2 = op_data->op_suppgids[1];
234 	rec->cr_bias     = op_data->op_bias;
235 	rec->cr_umask    = current_umask();
236 	rec->cr_old_handle = op_data->op_handle;
237 
238 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
239 	/* the next buffer is child capa, which is used for replay,
240 	 * will be packed from the data in reply message. */
241 
242 	if (op_data->op_name) {
243 		tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
244 		LOGL0(op_data->op_name, op_data->op_namelen, tmp);
245 		if (op_data->op_bias & MDS_CREATE_VOLATILE)
246 			cr_flags |= MDS_OPEN_VOLATILE;
247 	}
248 
249 	if (lmm) {
250 		cr_flags |= MDS_OPEN_HAS_EA;
251 		tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA);
252 		memcpy(tmp, lmm, lmmlen);
253 	}
254 	set_mrc_cr_flags(rec, cr_flags);
255 }
256 
attr_pack(unsigned int ia_valid)257 static inline __u64 attr_pack(unsigned int ia_valid)
258 {
259 	__u64 sa_valid = 0;
260 
261 	if (ia_valid & ATTR_MODE)
262 		sa_valid |= MDS_ATTR_MODE;
263 	if (ia_valid & ATTR_UID)
264 		sa_valid |= MDS_ATTR_UID;
265 	if (ia_valid & ATTR_GID)
266 		sa_valid |= MDS_ATTR_GID;
267 	if (ia_valid & ATTR_SIZE)
268 		sa_valid |= MDS_ATTR_SIZE;
269 	if (ia_valid & ATTR_ATIME)
270 		sa_valid |= MDS_ATTR_ATIME;
271 	if (ia_valid & ATTR_MTIME)
272 		sa_valid |= MDS_ATTR_MTIME;
273 	if (ia_valid & ATTR_CTIME)
274 		sa_valid |= MDS_ATTR_CTIME;
275 	if (ia_valid & ATTR_ATIME_SET)
276 		sa_valid |= MDS_ATTR_ATIME_SET;
277 	if (ia_valid & ATTR_MTIME_SET)
278 		sa_valid |= MDS_ATTR_MTIME_SET;
279 	if (ia_valid & ATTR_FORCE)
280 		sa_valid |= MDS_ATTR_FORCE;
281 	if (ia_valid & ATTR_ATTR_FLAG)
282 		sa_valid |= MDS_ATTR_ATTR_FLAG;
283 	if (ia_valid & ATTR_KILL_SUID)
284 		sa_valid |=  MDS_ATTR_KILL_SUID;
285 	if (ia_valid & ATTR_KILL_SGID)
286 		sa_valid |= MDS_ATTR_KILL_SGID;
287 	if (ia_valid & ATTR_CTIME_SET)
288 		sa_valid |= MDS_ATTR_CTIME_SET;
289 	if (ia_valid & ATTR_FROM_OPEN)
290 		sa_valid |= MDS_ATTR_FROM_OPEN;
291 	if (ia_valid & ATTR_BLOCKS)
292 		sa_valid |= MDS_ATTR_BLOCKS;
293 	if (ia_valid & MDS_OPEN_OWNEROVERRIDE)
294 		/* NFSD hack (see bug 5781) */
295 		sa_valid |= MDS_OPEN_OWNEROVERRIDE;
296 	return sa_valid;
297 }
298 
mdc_setattr_pack_rec(struct mdt_rec_setattr * rec,struct md_op_data * op_data)299 static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec,
300 				 struct md_op_data *op_data)
301 {
302 	rec->sa_opcode  = REINT_SETATTR;
303 	rec->sa_fsuid   = from_kuid(&init_user_ns, current_fsuid());
304 	rec->sa_fsgid   = from_kgid(&init_user_ns, current_fsgid());
305 	rec->sa_cap     = cfs_curproc_cap_pack();
306 	rec->sa_suppgid = -1;
307 
308 	rec->sa_fid    = op_data->op_fid1;
309 	rec->sa_valid  = attr_pack(op_data->op_attr.ia_valid);
310 	rec->sa_mode   = op_data->op_attr.ia_mode;
311 	rec->sa_uid    = from_kuid(&init_user_ns, op_data->op_attr.ia_uid);
312 	rec->sa_gid    = from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
313 	rec->sa_size   = op_data->op_attr.ia_size;
314 	rec->sa_blocks = op_data->op_attr_blocks;
315 	rec->sa_atime  = LTIME_S(op_data->op_attr.ia_atime);
316 	rec->sa_mtime  = LTIME_S(op_data->op_attr.ia_mtime);
317 	rec->sa_ctime  = LTIME_S(op_data->op_attr.ia_ctime);
318 	rec->sa_attr_flags =
319 			((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags;
320 	if ((op_data->op_attr.ia_valid & ATTR_GID) &&
321 	    in_group_p(op_data->op_attr.ia_gid))
322 		rec->sa_suppgid =
323 			from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
324 	else
325 		rec->sa_suppgid = op_data->op_suppgids[0];
326 
327 	rec->sa_bias = op_data->op_bias;
328 }
329 
mdc_ioepoch_pack(struct mdt_ioepoch * epoch,struct md_op_data * op_data)330 static void mdc_ioepoch_pack(struct mdt_ioepoch *epoch,
331 			     struct md_op_data *op_data)
332 {
333 	memcpy(&epoch->handle, &op_data->op_handle, sizeof(epoch->handle));
334 	epoch->ioepoch = op_data->op_ioepoch;
335 	epoch->flags = op_data->op_flags & MF_SOM_LOCAL_FLAGS;
336 }
337 
mdc_setattr_pack(struct ptlrpc_request * req,struct md_op_data * op_data,void * ea,int ealen,void * ea2,int ea2len)338 void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
339 		      void *ea, int ealen, void *ea2, int ea2len)
340 {
341 	struct mdt_rec_setattr *rec;
342 	struct mdt_ioepoch *epoch;
343 	struct lov_user_md *lum = NULL;
344 
345 	CLASSERT(sizeof(struct mdt_rec_reint) ==
346 					sizeof(struct mdt_rec_setattr));
347 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
348 	mdc_setattr_pack_rec(rec, op_data);
349 
350 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
351 
352 	if (op_data->op_flags & (MF_SOM_CHANGE | MF_EPOCH_OPEN)) {
353 		epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH);
354 		mdc_ioepoch_pack(epoch, op_data);
355 	}
356 
357 	if (ealen == 0)
358 		return;
359 
360 	lum = req_capsule_client_get(&req->rq_pill, &RMF_EADATA);
361 	if (ea == NULL) { /* Remove LOV EA */
362 		lum->lmm_magic = LOV_USER_MAGIC_V1;
363 		lum->lmm_stripe_size = 0;
364 		lum->lmm_stripe_count = 0;
365 		lum->lmm_stripe_offset = (typeof(lum->lmm_stripe_offset))(-1);
366 	} else {
367 		memcpy(lum, ea, ealen);
368 	}
369 
370 	if (ea2len == 0)
371 		return;
372 
373 	memcpy(req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES), ea2,
374 	       ea2len);
375 }
376 
mdc_unlink_pack(struct ptlrpc_request * req,struct md_op_data * op_data)377 void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
378 {
379 	struct mdt_rec_unlink *rec;
380 	char *tmp;
381 
382 	CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink));
383 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
384 	LASSERT(rec != NULL);
385 
386 	rec->ul_opcode   = op_data->op_cli_flags & CLI_RM_ENTRY ?
387 					REINT_RMENTRY : REINT_UNLINK;
388 	rec->ul_fsuid    = op_data->op_fsuid;
389 	rec->ul_fsgid    = op_data->op_fsgid;
390 	rec->ul_cap      = op_data->op_cap;
391 	rec->ul_mode     = op_data->op_mode;
392 	rec->ul_suppgid1 = op_data->op_suppgids[0];
393 	rec->ul_suppgid2 = -1;
394 	rec->ul_fid1     = op_data->op_fid1;
395 	rec->ul_fid2     = op_data->op_fid2;
396 	rec->ul_time     = op_data->op_mod_time;
397 	rec->ul_bias     = op_data->op_bias;
398 
399 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
400 
401 	tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
402 	LASSERT(tmp != NULL);
403 	LOGL0(op_data->op_name, op_data->op_namelen, tmp);
404 }
405 
mdc_link_pack(struct ptlrpc_request * req,struct md_op_data * op_data)406 void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
407 {
408 	struct mdt_rec_link *rec;
409 	char *tmp;
410 
411 	CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_link));
412 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
413 	LASSERT(rec != NULL);
414 
415 	rec->lk_opcode   = REINT_LINK;
416 	rec->lk_fsuid    = op_data->op_fsuid; /* current->fsuid; */
417 	rec->lk_fsgid    = op_data->op_fsgid; /* current->fsgid; */
418 	rec->lk_cap      = op_data->op_cap;   /* current->cap_effective; */
419 	rec->lk_suppgid1 = op_data->op_suppgids[0];
420 	rec->lk_suppgid2 = op_data->op_suppgids[1];
421 	rec->lk_fid1     = op_data->op_fid1;
422 	rec->lk_fid2     = op_data->op_fid2;
423 	rec->lk_time     = op_data->op_mod_time;
424 	rec->lk_bias     = op_data->op_bias;
425 
426 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
427 	mdc_pack_capa(req, &RMF_CAPA2, op_data->op_capa2);
428 
429 	tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
430 	LOGL0(op_data->op_name, op_data->op_namelen, tmp);
431 }
432 
mdc_rename_pack(struct ptlrpc_request * req,struct md_op_data * op_data,const char * old,int oldlen,const char * new,int newlen)433 void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
434 		     const char *old, int oldlen, const char *new, int newlen)
435 {
436 	struct mdt_rec_rename *rec;
437 	char *tmp;
438 
439 	CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_rename));
440 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
441 
442 	/* XXX do something about time, uid, gid */
443 	rec->rn_opcode   = REINT_RENAME;
444 	rec->rn_fsuid    = op_data->op_fsuid;
445 	rec->rn_fsgid    = op_data->op_fsgid;
446 	rec->rn_cap      = op_data->op_cap;
447 	rec->rn_suppgid1 = op_data->op_suppgids[0];
448 	rec->rn_suppgid2 = op_data->op_suppgids[1];
449 	rec->rn_fid1     = op_data->op_fid1;
450 	rec->rn_fid2     = op_data->op_fid2;
451 	rec->rn_time     = op_data->op_mod_time;
452 	rec->rn_mode     = op_data->op_mode;
453 	rec->rn_bias     = op_data->op_bias;
454 
455 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
456 	mdc_pack_capa(req, &RMF_CAPA2, op_data->op_capa2);
457 
458 	tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
459 	LOGL0(old, oldlen, tmp);
460 
461 	if (new) {
462 		tmp = req_capsule_client_get(&req->rq_pill, &RMF_SYMTGT);
463 		LOGL0(new, newlen, tmp);
464 	}
465 }
466 
mdc_getattr_pack(struct ptlrpc_request * req,__u64 valid,int flags,struct md_op_data * op_data,int ea_size)467 void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags,
468 		      struct md_op_data *op_data, int ea_size)
469 {
470 	struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
471 						    &RMF_MDT_BODY);
472 
473 	b->valid = valid;
474 	if (op_data->op_bias & MDS_CHECK_SPLIT)
475 		b->valid |= OBD_MD_FLCKSPLIT;
476 	if (op_data->op_bias & MDS_CROSS_REF)
477 		b->valid |= OBD_MD_FLCROSSREF;
478 	b->eadatasize = ea_size;
479 	b->flags = flags;
480 	__mdc_pack_body(b, op_data->op_suppgids[0]);
481 
482 	b->fid1 = op_data->op_fid1;
483 	b->fid2 = op_data->op_fid2;
484 	b->valid |= OBD_MD_FLID;
485 
486 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
487 
488 	if (op_data->op_name) {
489 		char *tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
490 
491 		LOGL0(op_data->op_name, op_data->op_namelen, tmp);
492 
493 	}
494 }
495 
mdc_hsm_release_pack(struct ptlrpc_request * req,struct md_op_data * op_data)496 static void mdc_hsm_release_pack(struct ptlrpc_request *req,
497 				 struct md_op_data *op_data)
498 {
499 	if (op_data->op_bias & MDS_HSM_RELEASE) {
500 		struct close_data *data;
501 		struct ldlm_lock *lock;
502 
503 		data = req_capsule_client_get(&req->rq_pill, &RMF_CLOSE_DATA);
504 		LASSERT(data != NULL);
505 
506 		lock = ldlm_handle2lock(&op_data->op_lease_handle);
507 		if (lock != NULL) {
508 			data->cd_handle = lock->l_remote_handle;
509 			ldlm_lock_put(lock);
510 		}
511 		ldlm_cli_cancel(&op_data->op_lease_handle, LCF_LOCAL);
512 
513 		data->cd_data_version = op_data->op_data_version;
514 		data->cd_fid = op_data->op_fid2;
515 	}
516 }
517 
mdc_close_pack(struct ptlrpc_request * req,struct md_op_data * op_data)518 void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
519 {
520 	struct mdt_ioepoch *epoch;
521 	struct mdt_rec_setattr *rec;
522 
523 	epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH);
524 	rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
525 
526 	mdc_setattr_pack_rec(rec, op_data);
527 	mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1);
528 	mdc_ioepoch_pack(epoch, op_data);
529 	mdc_hsm_release_pack(req, op_data);
530 }
531 
mdc_req_avail(struct client_obd * cli,struct mdc_cache_waiter * mcw)532 static int mdc_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
533 {
534 	int rc;
535 
536 	client_obd_list_lock(&cli->cl_loi_list_lock);
537 	rc = list_empty(&mcw->mcw_entry);
538 	client_obd_list_unlock(&cli->cl_loi_list_lock);
539 	return rc;
540 };
541 
542 /* We record requests in flight in cli->cl_r_in_flight here.
543  * There is only one write rpc possible in mdc anyway. If this to change
544  * in the future - the code may need to be revisited. */
mdc_enter_request(struct client_obd * cli)545 int mdc_enter_request(struct client_obd *cli)
546 {
547 	int rc = 0;
548 	struct mdc_cache_waiter mcw;
549 	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
550 
551 	client_obd_list_lock(&cli->cl_loi_list_lock);
552 	if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
553 		list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
554 		init_waitqueue_head(&mcw.mcw_waitq);
555 		client_obd_list_unlock(&cli->cl_loi_list_lock);
556 		rc = l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw),
557 				  &lwi);
558 		if (rc) {
559 			client_obd_list_lock(&cli->cl_loi_list_lock);
560 			if (list_empty(&mcw.mcw_entry))
561 				cli->cl_r_in_flight--;
562 			list_del_init(&mcw.mcw_entry);
563 			client_obd_list_unlock(&cli->cl_loi_list_lock);
564 		}
565 	} else {
566 		cli->cl_r_in_flight++;
567 		client_obd_list_unlock(&cli->cl_loi_list_lock);
568 	}
569 	return rc;
570 }
571 
mdc_exit_request(struct client_obd * cli)572 void mdc_exit_request(struct client_obd *cli)
573 {
574 	struct list_head *l, *tmp;
575 	struct mdc_cache_waiter *mcw;
576 
577 	client_obd_list_lock(&cli->cl_loi_list_lock);
578 	cli->cl_r_in_flight--;
579 	list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
580 		if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
581 			/* No free request slots anymore */
582 			break;
583 		}
584 
585 		mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry);
586 		list_del_init(&mcw->mcw_entry);
587 		cli->cl_r_in_flight++;
588 		wake_up(&mcw->mcw_waitq);
589 	}
590 	/* Empty waiting list? Decrease reqs in-flight number */
591 
592 	client_obd_list_unlock(&cli->cl_loi_list_lock);
593 }
594