Whamcloud - gitweb
1c918dd177efeb15a2fb27dd3b53578e86a2d4a1
[fs/lustre-release.git] / lustre / ptlrpc / layout.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/ptlrpc/layout.c
5  *  Lustre Metadata Target (mdt) request handler
6  *
7  *  Copyright (c) 2006 Cluster File Systems, Inc.
8  *   Author: Nikita Danilov <nikita@clusterfs.com>
9  *
10  *   This file is part of the Lustre file system, http://www.lustre.org
11  *   Lustre is a trademark of Cluster File Systems, Inc.
12  *
13  *   You may have signed or agreed to another license before downloading
14  *   this software.  If so, you are bound by the terms and conditions
15  *   of that agreement, and the following does not apply to you.  See the
16  *   LICENSE file included with this distribution for more information.
17  *
18  *   If you did not agree to a different license, then this copy of Lustre
19  *   is open source software; you can redistribute it and/or modify it
20  *   under the terms of version 2 of the GNU General Public License as
21  *   published by the Free Software Foundation.
22  *
23  *   In either case, Lustre is distributed in the hope that it will be
24  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *   license text for more details.
27  */
28
29 #if !defined(__REQ_LAYOUT_USER__)
30
31 #ifndef EXPORT_SYMTAB
32 # define EXPORT_SYMTAB
33 #endif
34 #define DEBUG_SUBSYSTEM S_RPC
35
36 #ifdef __KERNEL__
37 #include <linux/module.h>
38 #else
39 # include <liblustre.h>
40 #endif
41
42 /* LUSTRE_VERSION_CODE */
43 #include <lustre_ver.h>
44
45 #include <obd_support.h>
46 /* lustre_swab_mdt_body */
47 #include <lustre/lustre_idl.h>
48 /* obd2cli_tgt() (required by DEBUG_REQ()) */
49 #include <obd.h>
50
51 /* __REQ_LAYOUT_USER__ */
52 #endif
53 /* struct ptlrpc_request, lustre_msg* */
54 #include <lustre_req_layout.h>
55 #include <linux/lustre_acl.h>
56
57 #if __KERNEL__
58 #define __POSIX_ACL_MAX_SIZE \
59         (sizeof(xattr_acl_header) + 32 * sizeof(xattr_acl_entry))
60 #else
61 #define __POSIX_ACL_MAX_SIZE 0
62 #endif
63
64 /*
65  * empty set of fields... for suitable definition of emptiness.
66  */
67 static const struct req_msg_field *empty[] = {
68         &RMF_PTLRPC_BODY
69 };
70
71 static const struct req_msg_field *mdt_body_only[] = {
72         &RMF_PTLRPC_BODY,
73         &RMF_MDT_BODY
74 };
75
76 static const struct req_msg_field *mdt_close_msg[] = {
77         &RMF_PTLRPC_BODY,
78         &RMF_MDT_EPOCH,
79         &RMF_REC_SETATTR
80 };
81
82 static const struct req_msg_field *mds_statfs_server[] = {
83         &RMF_PTLRPC_BODY,
84         &RMF_OBD_STATFS
85 };
86
87 static const struct req_msg_field *seq_query_client[] = {
88         &RMF_PTLRPC_BODY,
89         &RMF_SEQ_OPC,
90         &RMF_SEQ_RANGE
91 };
92
93 static const struct req_msg_field *seq_query_server[] = {
94         &RMF_PTLRPC_BODY,
95         &RMF_SEQ_RANGE
96 };
97
98 static const struct req_msg_field *fld_query_client[] = {
99         &RMF_PTLRPC_BODY,
100         &RMF_FLD_OPC,
101         &RMF_FLD_MDFLD
102 };
103
104 static const struct req_msg_field *fld_query_server[] = {
105         &RMF_PTLRPC_BODY,
106         &RMF_FLD_MDFLD
107 };
108
109 static const struct req_msg_field *mds_getattr_name_client[] = {
110         &RMF_PTLRPC_BODY,
111         &RMF_MDT_BODY,
112         &RMF_NAME
113 };
114
115 static const struct req_msg_field *mds_reint_client[] = {
116         &RMF_PTLRPC_BODY,
117         &RMF_REINT_OPC
118 };
119
120 static const struct req_msg_field *mds_reint_create_client[] = {
121         &RMF_PTLRPC_BODY,
122         &RMF_REC_CREATE,
123         &RMF_NAME,
124 };
125
126 static const struct req_msg_field *mds_reint_create_sym_client[] = {
127         &RMF_PTLRPC_BODY,
128         &RMF_REC_CREATE,
129         &RMF_NAME,
130         &RMF_SYMTGT
131 };
132
133 static const struct req_msg_field *mds_reint_create_slave_client[] = {
134         &RMF_PTLRPC_BODY,
135         &RMF_REC_CREATE,
136         &RMF_NAME,
137         &RMF_EADATA
138 };
139
140 static const struct req_msg_field *mds_reint_open_client[] = {
141         &RMF_PTLRPC_BODY,
142         &RMF_REC_CREATE,
143         &RMF_NAME,
144         &RMF_EADATA
145 };
146
147 static const struct req_msg_field *mds_reint_open_server[] = {
148         &RMF_PTLRPC_BODY,
149         &RMF_MDT_BODY,
150         &RMF_MDT_MD,
151         &RMF_ACL
152 };
153
154 static const struct req_msg_field *mds_reint_unlink_client[] = {
155         &RMF_PTLRPC_BODY,
156         &RMF_REC_UNLINK,
157         &RMF_NAME
158 };
159
160 static const struct req_msg_field *mds_reint_link_client[] = {
161         &RMF_PTLRPC_BODY,
162         &RMF_REC_LINK,
163         &RMF_NAME
164 };
165
166 static const struct req_msg_field *mds_reint_rename_client[] = {
167         &RMF_PTLRPC_BODY,
168         &RMF_REC_RENAME,
169         &RMF_NAME,
170         &RMF_SYMTGT
171 };
172
173 static const struct req_msg_field *mds_last_unlink_server[] = {
174         &RMF_PTLRPC_BODY,
175         &RMF_MDT_BODY,
176         &RMF_MDT_MD,
177         &RMF_LOGCOOKIES
178 };
179
180 static const struct req_msg_field *mds_reint_setattr_client[] = {
181         &RMF_PTLRPC_BODY,
182         &RMF_REC_SETATTR,
183         &RMF_MDT_EPOCH,
184         &RMF_EADATA,
185         &RMF_LOGCOOKIES
186 };
187
188 static const struct req_msg_field *mds_connect_client[] = {
189         &RMF_PTLRPC_BODY,
190         &RMF_TGTUUID,
191         &RMF_CLUUID,
192         &RMF_CONN,
193         &RMF_CONNECT_DATA
194 };
195
196 static const struct req_msg_field *mds_connect_server[] = {
197         &RMF_PTLRPC_BODY,
198         &RMF_CONNECT_DATA
199 };
200
201 static const struct req_msg_field *ldlm_enqueue_client[] = {
202         &RMF_PTLRPC_BODY,
203         &RMF_DLM_REQ
204 };
205
206 static const struct req_msg_field *ldlm_enqueue_server[] = {
207         &RMF_PTLRPC_BODY,
208         &RMF_DLM_REP
209 };
210
211 static const struct req_msg_field *ldlm_intent_client[] = {
212         &RMF_PTLRPC_BODY,
213         &RMF_DLM_REQ,
214         &RMF_LDLM_INTENT,
215         &RMF_REINT_OPC
216 };
217
218 static const struct req_msg_field *ldlm_intent_server[] = {
219         &RMF_PTLRPC_BODY,
220         &RMF_DLM_REP,
221         &RMF_MDT_BODY,
222         &RMF_MDT_MD,
223         &RMF_ACL
224 };
225
226 static const struct req_msg_field *ldlm_intent_getattr_client[] = {
227         &RMF_PTLRPC_BODY,
228         &RMF_DLM_REQ,
229         &RMF_LDLM_INTENT,
230         &RMF_MDT_BODY,     /* coincides with mds_getattr_name_client[] */
231         &RMF_NAME
232 };
233
234 static const struct req_msg_field *ldlm_intent_create_client[] = {
235         &RMF_PTLRPC_BODY,
236         &RMF_DLM_REQ,
237         &RMF_LDLM_INTENT,
238         &RMF_REC_CREATE,    /* coincides with mds_reint_create_client[] */
239         &RMF_NAME,
240         &RMF_EADATA
241 };
242
243 static const struct req_msg_field *ldlm_intent_open_client[] = {
244         &RMF_PTLRPC_BODY,
245         &RMF_DLM_REQ,
246         &RMF_LDLM_INTENT,
247         &RMF_REC_CREATE,    /* coincides with mds_reint_open_client[] */
248         &RMF_NAME,
249         &RMF_EADATA
250 };
251
252 static const struct req_msg_field *ldlm_intent_unlink_client[] = {
253         &RMF_PTLRPC_BODY,
254         &RMF_DLM_REQ,
255         &RMF_LDLM_INTENT,
256         &RMF_REC_UNLINK,    /* coincides with mds_reint_unlink_client[] */
257         &RMF_NAME
258 };
259
260 static const struct req_msg_field *mds_getxattr_client[] = {
261         &RMF_PTLRPC_BODY,
262         &RMF_MDT_BODY,
263         &RMF_NAME
264 };
265
266 static const struct req_msg_field *mds_getxattr_server[] = {
267         &RMF_PTLRPC_BODY,
268         &RMF_MDT_BODY,
269         &RMF_EADATA
270 };
271
272 static const struct req_msg_field *mds_setxattr_client[] = {
273         &RMF_PTLRPC_BODY,
274         &RMF_MDT_BODY,
275         &RMF_NAME,
276         &RMF_EADATA
277 };
278
279 static const struct req_msg_field *mds_getattr_server[] = {
280         &RMF_PTLRPC_BODY,
281         &RMF_MDT_BODY,
282         &RMF_MDT_MD,
283         &RMF_ACL
284 };
285
286 static const struct req_format *req_formats[] = {
287         &RQF_MDS_CONNECT,
288         &RQF_MDS_DISCONNECT,
289         &RQF_MDS_GETSTATUS,
290         &RQF_MDS_STATFS,
291         &RQF_MDS_GETATTR,
292         &RQF_MDS_GETATTR_NAME,
293         &RQF_MDS_REINT,
294         &RQF_MDS_REINT_CREATE,
295         &RQF_MDS_REINT_CREATE_SYM,
296         &RQF_MDS_REINT_CREATE_SLAVE,
297         &RQF_MDS_REINT_OPEN,
298         &RQF_MDS_REINT_UNLINK,
299         &RQF_MDS_REINT_LINK,
300         &RQF_MDS_REINT_RENAME,
301         &RQF_MDS_REINT_SETATTR,
302         &RQF_LDLM_ENQUEUE,
303         &RQF_LDLM_INTENT,
304         &RQF_LDLM_INTENT_GETATTR,
305         &RQF_LDLM_INTENT_OPEN,
306         &RQF_LDLM_INTENT_CREATE,
307         &RQF_LDLM_INTENT_UNLINK,
308         &RQF_SEQ_QUERY,
309         &RQF_FLD_QUERY,
310         &RQF_MDS_GETXATTR,
311         &RQF_MDS_SETXATTR,
312         &RQF_MDS_SYNC,
313         &RQF_MDS_CLOSE,
314         &RQF_MDS_PIN,
315         &RQF_MDS_READPAGE,
316         &RQF_MDS_WRITEPAGE,
317         &RQF_MDS_IS_SUBDIR,
318         &RQF_MDS_DONE_WRITING
319 };
320
321 struct req_msg_field {
322         __u32       rmf_flags;
323         const char *rmf_name;
324         /*
325          * Field length. (-1) means "variable length".
326          */
327         int         rmf_size;
328         void      (*rmf_swabber)(void *);
329         int         rmf_offset[ARRAY_SIZE(req_formats)][RCL_NR];
330 };
331
332 enum rmf_flags {
333         RMF_F_STRING = 1 << 0
334 };
335
336 struct req_capsule;
337
338 /*
339  * Request fields.
340  */
341 #define DEFINE_MSGF(name, flags, size, swabber) {       \
342         .rmf_name    = (name),                          \
343         .rmf_flags   = (flags),                         \
344         .rmf_size    = (size),                          \
345         .rmf_swabber = (void (*)(void*))(swabber)       \
346 }
347
348 const struct req_msg_field RMF_SEQ_OPC =
349         DEFINE_MSGF("seq_query_opc", 0,
350                     sizeof(__u32), lustre_swab_generic_32s);
351 EXPORT_SYMBOL(RMF_SEQ_OPC);
352
353 const struct req_msg_field RMF_SEQ_RANGE =
354         DEFINE_MSGF("seq_query_range", 0,
355                     sizeof(struct lu_range), lustre_swab_lu_range);
356 EXPORT_SYMBOL(RMF_SEQ_RANGE);
357
358 const struct req_msg_field RMF_FLD_OPC =
359         DEFINE_MSGF("fld_query_opc", 0,
360                     sizeof(__u32), lustre_swab_generic_32s);
361 EXPORT_SYMBOL(RMF_FLD_OPC);
362
363 const struct req_msg_field RMF_FLD_MDFLD =
364         DEFINE_MSGF("fld_query_mdfld", 0,
365                     sizeof(struct md_fld), lustre_swab_md_fld);
366 EXPORT_SYMBOL(RMF_FLD_MDFLD);
367
368 const struct req_msg_field RMF_MDT_BODY =
369         DEFINE_MSGF("mdt_body", 0,
370                     sizeof(struct mdt_body), lustre_swab_mdt_body);
371 EXPORT_SYMBOL(RMF_MDT_BODY);
372
373 const struct req_msg_field RMF_MDT_EPOCH =
374         DEFINE_MSGF("mdt_epoch", 0,
375                     sizeof(struct mdt_epoch), lustre_swab_mdt_epoch);
376 EXPORT_SYMBOL(RMF_MDT_EPOCH);
377
378 const struct req_msg_field RMF_PTLRPC_BODY =
379         DEFINE_MSGF("ptlrpc_body", 0,
380                     sizeof(struct ptlrpc_body), lustre_swab_ptlrpc_body);
381 EXPORT_SYMBOL(RMF_PTLRPC_BODY);
382
383 const struct req_msg_field RMF_OBD_STATFS =
384         DEFINE_MSGF("obd_statfs", 0,
385                     sizeof(struct obd_statfs), lustre_swab_obd_statfs);
386 EXPORT_SYMBOL(RMF_OBD_STATFS);
387
388 const struct req_msg_field RMF_NAME =
389         DEFINE_MSGF("name", RMF_F_STRING, -1, NULL);
390 EXPORT_SYMBOL(RMF_NAME);
391
392 const struct req_msg_field RMF_SYMTGT =
393         DEFINE_MSGF("symtgt", RMF_F_STRING, -1, NULL);
394 EXPORT_SYMBOL(RMF_SYMTGT);
395
396 const struct req_msg_field RMF_TGTUUID =
397         DEFINE_MSGF("tgtuuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
398 EXPORT_SYMBOL(RMF_TGTUUID);
399
400 const struct req_msg_field RMF_CLUUID =
401         DEFINE_MSGF("cluuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
402 EXPORT_SYMBOL(RMF_CLUUID);
403
404 /*
405  * connection handle received in MDS_CONNECT request.
406  *
407  * XXX no swabbing?
408  */
409 const struct req_msg_field RMF_CONN =
410         DEFINE_MSGF("conn", 0, sizeof(struct lustre_handle), NULL);
411 EXPORT_SYMBOL(RMF_CONN);
412
413 const struct req_msg_field RMF_CONNECT_DATA =
414         DEFINE_MSGF("cdata", 0,
415                     sizeof(struct obd_connect_data), lustre_swab_connect);
416 EXPORT_SYMBOL(RMF_CONNECT_DATA);
417
418 const struct req_msg_field RMF_DLM_REQ =
419         DEFINE_MSGF("dlm_req", 0,
420                     sizeof(struct ldlm_request), lustre_swab_ldlm_request);
421 EXPORT_SYMBOL(RMF_DLM_REQ);
422
423 const struct req_msg_field RMF_DLM_REP =
424         DEFINE_MSGF("dlm_rep", 0,
425                     sizeof(struct ldlm_reply), lustre_swab_ldlm_reply);
426 EXPORT_SYMBOL(RMF_DLM_REP);
427
428 const struct req_msg_field RMF_LDLM_INTENT =
429         DEFINE_MSGF("ldlm_intent", 0,
430                     sizeof(struct ldlm_intent), lustre_swab_ldlm_intent);
431 EXPORT_SYMBOL(RMF_LDLM_INTENT);
432
433
434 /* FIXME XXX by Huang Hua
435  * to make sure about the size. Refer to MDS.
436  */
437
438 const struct req_msg_field RMF_MDT_MD =
439         DEFINE_MSGF("mdt_md", 0, MIN_MD_SIZE, lustre_swab_lov_mds_md);
440 EXPORT_SYMBOL(RMF_MDT_MD);
441
442 const struct req_msg_field RMF_REC_UNLINK =
443         DEFINE_MSGF("rec_unlink", 0, sizeof(struct mdt_rec_unlink),
444                     lustre_swab_mdt_rec_unlink);
445 EXPORT_SYMBOL(RMF_REC_UNLINK);
446
447 const struct req_msg_field RMF_REC_LINK =
448         DEFINE_MSGF("rec_link", 0, sizeof(struct mdt_rec_link),
449                     lustre_swab_mdt_rec_link);
450 EXPORT_SYMBOL(RMF_REC_LINK);
451
452 const struct req_msg_field RMF_REC_RENAME =
453         DEFINE_MSGF("rec_rename", 0, sizeof(struct mdt_rec_rename),
454                     lustre_swab_mdt_rec_rename);
455 EXPORT_SYMBOL(RMF_REC_RENAME);
456
457 const struct req_msg_field RMF_REC_CREATE =
458         DEFINE_MSGF("rec_create", 0,
459                     sizeof(struct mdt_rec_create), lustre_swab_mdt_rec_create);
460 EXPORT_SYMBOL(RMF_REC_CREATE);
461
462 const struct req_msg_field RMF_REC_SETATTR =
463         DEFINE_MSGF("rec_setattr", 0, sizeof(struct mdt_rec_setattr),
464                     lustre_swab_mdt_rec_setattr);
465 EXPORT_SYMBOL(RMF_REC_SETATTR);
466
467 /* FIXME: this length should be defined as a macro */
468 const struct req_msg_field RMF_EADATA = DEFINE_MSGF("eadata", 0, -1, NULL);
469 EXPORT_SYMBOL(RMF_EADATA);
470
471 const struct req_msg_field RMF_ACL = DEFINE_MSGF("acl", 0,
472                                      __POSIX_ACL_MAX_SIZE, NULL);
473 EXPORT_SYMBOL(RMF_ACL);
474
475 const struct req_msg_field RMF_LOGCOOKIES =
476         DEFINE_MSGF("logcookies", 0, sizeof(struct llog_cookie), NULL);
477 EXPORT_SYMBOL(RMF_LOGCOOKIES);
478
479 const struct req_msg_field RMF_REINT_OPC =
480         DEFINE_MSGF("reint_opc", 0, sizeof(__u32), lustre_swab_generic_32s);
481 EXPORT_SYMBOL(RMF_REINT_OPC);
482
483 /*
484  * Request formats.
485  */
486
487 struct req_format {
488         const char *rf_name;
489         int         rf_idx;
490         struct {
491                 int                          nr;
492                 const struct req_msg_field **d;
493         } rf_fields[RCL_NR];
494 };
495
496 #define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) {    \
497         .rf_name   = name,                                              \
498         .rf_fields = {                                                  \
499                 [RCL_CLIENT] = {                                        \
500                         .nr = client_nr,                                \
501                         .d  = client                                    \
502                 },                                                      \
503                 [RCL_SERVER] = {                                        \
504                         .nr = server_nr,                                \
505                         .d  = server                                    \
506                 }                                                       \
507         }                                                               \
508 }
509
510 #define DEFINE_REQ_FMT0(name, client, server)                           \
511 DEFINE_REQ_FMT(name, client, ARRAY_SIZE(client), server, ARRAY_SIZE(server))
512
513 const struct req_format RQF_SEQ_QUERY =
514         DEFINE_REQ_FMT0("SEQ_QUERY", seq_query_client, seq_query_server);
515 EXPORT_SYMBOL(RQF_SEQ_QUERY);
516
517 const struct req_format RQF_FLD_QUERY =
518         DEFINE_REQ_FMT0("FLD_QUERY", fld_query_client, fld_query_server);
519 EXPORT_SYMBOL(RQF_FLD_QUERY);
520
521 const struct req_format RQF_MDS_GETSTATUS =
522         DEFINE_REQ_FMT0("MDS_GETSTATUS", empty, mdt_body_only);
523 EXPORT_SYMBOL(RQF_MDS_GETSTATUS);
524
525 const struct req_format RQF_MDS_STATFS =
526         DEFINE_REQ_FMT0("MDS_STATFS", empty, mds_statfs_server);
527 EXPORT_SYMBOL(RQF_MDS_STATFS);
528
529 const struct req_format RQF_MDS_SYNC =
530         DEFINE_REQ_FMT0("MDS_SYNC", mdt_body_only, mdt_body_only);
531 EXPORT_SYMBOL(RQF_MDS_SYNC);
532
533 const struct req_format RQF_MDS_GETATTR =
534         DEFINE_REQ_FMT0("MDS_GETATTR", mdt_body_only, mds_getattr_server);
535 EXPORT_SYMBOL(RQF_MDS_GETATTR);
536
537 const struct req_format RQF_MDS_GETXATTR =
538         DEFINE_REQ_FMT0("MDS_GETXATTR",
539                         mds_getxattr_client, mds_getxattr_server);
540 EXPORT_SYMBOL(RQF_MDS_GETXATTR);
541
542 const struct req_format RQF_MDS_SETXATTR =
543         DEFINE_REQ_FMT0("MDS_SETXATTR", mds_setxattr_client, empty);
544 EXPORT_SYMBOL(RQF_MDS_SETXATTR);
545
546 const struct req_format RQF_MDS_GETATTR_NAME =
547         DEFINE_REQ_FMT0("MDS_GETATTR_NAME",
548                         mds_getattr_name_client, mds_getattr_server);
549 EXPORT_SYMBOL(RQF_MDS_GETATTR_NAME);
550
551 const struct req_format RQF_MDS_REINT =
552         DEFINE_REQ_FMT0("MDS_REINT", mds_reint_client, mdt_body_only);
553 EXPORT_SYMBOL(RQF_MDS_REINT);
554
555 const struct req_format RQF_MDS_REINT_CREATE =
556         DEFINE_REQ_FMT0("MDS_REINT_CREATE",
557                         mds_reint_create_client, mdt_body_only);
558 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE);
559
560 const struct req_format RQF_MDS_REINT_CREATE_SLAVE =
561         DEFINE_REQ_FMT0("MDS_REINT_CREATE_SLAVE",
562                         mds_reint_create_slave_client, mdt_body_only);
563 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SLAVE);
564
565 const struct req_format RQF_MDS_REINT_CREATE_SYM =
566         DEFINE_REQ_FMT0("MDS_REINT_CREATE_SYM",
567                         mds_reint_create_sym_client, mdt_body_only);
568 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SYM);
569
570 const struct req_format RQF_MDS_REINT_OPEN =
571         DEFINE_REQ_FMT0("MDS_REINT_OPEN",
572                         mds_reint_open_client, mds_reint_open_server);
573 EXPORT_SYMBOL(RQF_MDS_REINT_OPEN);
574
575 const struct req_format RQF_MDS_REINT_UNLINK =
576         DEFINE_REQ_FMT0("MDS_REINT_UNLINK", mds_reint_unlink_client,
577                         mds_last_unlink_server);
578 EXPORT_SYMBOL(RQF_MDS_REINT_UNLINK);
579
580 const struct req_format RQF_MDS_REINT_LINK =
581         DEFINE_REQ_FMT0("MDS_REINT_LINK",
582                         mds_reint_link_client, mdt_body_only);
583 EXPORT_SYMBOL(RQF_MDS_REINT_LINK);
584
585 const struct req_format RQF_MDS_REINT_RENAME =
586         DEFINE_REQ_FMT0("MDS_REINT_RENAME", mds_reint_rename_client,
587                         mds_last_unlink_server);
588 EXPORT_SYMBOL(RQF_MDS_REINT_RENAME);
589
590 const struct req_format RQF_MDS_REINT_SETATTR =
591         DEFINE_REQ_FMT0("MDS_REINT_SETATTR",
592                         mds_reint_setattr_client, mdt_body_only);
593 EXPORT_SYMBOL(RQF_MDS_REINT_SETATTR);
594
595 const struct req_format RQF_MDS_CONNECT =
596         DEFINE_REQ_FMT0("MDS_CONNECT",
597                         mds_connect_client, mds_connect_server);
598 EXPORT_SYMBOL(RQF_MDS_CONNECT);
599
600 const struct req_format RQF_MDS_DISCONNECT =
601         DEFINE_REQ_FMT0("MDS_DISCONNECT", empty, empty);
602 EXPORT_SYMBOL(RQF_MDS_DISCONNECT);
603
604 const struct req_format RQF_LDLM_ENQUEUE =
605         DEFINE_REQ_FMT0("LDLM_ENQUEUE",
606                         ldlm_enqueue_client, ldlm_enqueue_server);
607 EXPORT_SYMBOL(RQF_LDLM_ENQUEUE);
608
609 const struct req_format RQF_LDLM_INTENT =
610         DEFINE_REQ_FMT0("LDLM_INTENT",
611                         ldlm_intent_client, ldlm_intent_server);
612 EXPORT_SYMBOL(RQF_LDLM_INTENT);
613
614 const struct req_format RQF_LDLM_INTENT_GETATTR =
615         DEFINE_REQ_FMT0("LDLM_INTENT_GETATTR",
616                         ldlm_intent_getattr_client, ldlm_intent_server);
617 EXPORT_SYMBOL(RQF_LDLM_INTENT_GETATTR);
618
619 const struct req_format RQF_LDLM_INTENT_OPEN =
620         DEFINE_REQ_FMT0("LDLM_INTENT_OPEN",
621                         ldlm_intent_open_client, ldlm_intent_server);
622 EXPORT_SYMBOL(RQF_LDLM_INTENT_OPEN);
623
624 const struct req_format RQF_LDLM_INTENT_CREATE =
625         DEFINE_REQ_FMT0("LDLM_INTENT_CREATE",
626                         ldlm_intent_create_client, ldlm_intent_server);
627 EXPORT_SYMBOL(RQF_LDLM_INTENT_CREATE);
628
629 const struct req_format RQF_LDLM_INTENT_UNLINK =
630         DEFINE_REQ_FMT0("LDLM_INTENT_UNLINK",
631                         ldlm_intent_unlink_client, ldlm_intent_server);
632 EXPORT_SYMBOL(RQF_LDLM_INTENT_UNLINK);
633
634 const struct req_format RQF_MDS_CLOSE =
635         DEFINE_REQ_FMT0("MDS_CLOSE",
636                         mdt_close_msg, mds_last_unlink_server);
637 EXPORT_SYMBOL(RQF_MDS_CLOSE);
638
639 const struct req_format RQF_MDS_PIN =
640         DEFINE_REQ_FMT0("MDS_PIN",
641                         mdt_body_only, mdt_body_only);
642 EXPORT_SYMBOL(RQF_MDS_PIN);
643
644 const struct req_format RQF_MDS_DONE_WRITING =
645         DEFINE_REQ_FMT0("MDS_DONE_WRITING",
646                         mdt_close_msg, mdt_body_only);
647 EXPORT_SYMBOL(RQF_MDS_DONE_WRITING);
648
649 const struct req_format RQF_MDS_READPAGE =
650         DEFINE_REQ_FMT0("MDS_READPAGE",
651                         mdt_body_only, mdt_body_only);
652 EXPORT_SYMBOL(RQF_MDS_READPAGE);
653
654 const struct req_format RQF_MDS_WRITEPAGE =
655         DEFINE_REQ_FMT0("MDS_WRITEPAGE",
656                         mdt_body_only, mdt_body_only);
657 EXPORT_SYMBOL(RQF_MDS_WRITEPAGE);
658
659 const struct req_format RQF_MDS_IS_SUBDIR =
660         DEFINE_REQ_FMT0("MDS_IS_SUBDIR",
661                         mdt_body_only, mdt_body_only);
662 EXPORT_SYMBOL(RQF_MDS_IS_SUBDIR);
663
664 #if !defined(__REQ_LAYOUT_USER__)
665
666 int req_layout_init(void)
667 {
668         int i;
669         int j;
670         int k;
671
672         for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
673                 struct req_format *rf;
674
675                 rf = (struct req_format *)req_formats[i];
676                 rf->rf_idx = i;
677                 for (j = 0; j < RCL_NR; ++j) {
678                         LASSERT(rf->rf_fields[j].nr <= REQ_MAX_FIELD_NR);
679                         for (k = 0; k < rf->rf_fields[j].nr; ++k) {
680                                 struct req_msg_field *field;
681
682                                 field = (typeof(field))rf->rf_fields[j].d[k];
683                                 LASSERT(field->rmf_offset[i][j] == 0);
684                                 /*
685                                  * k + 1 to detect unused format/field
686                                  * combinations.
687                                  */
688                                 field->rmf_offset[i][j] = k + 1;
689                         }
690                 }
691         }
692         return 0;
693 }
694 EXPORT_SYMBOL(req_layout_init);
695
696 void req_layout_fini(void)
697 {
698 }
699 EXPORT_SYMBOL(req_layout_fini);
700
701 /*
702  * Initialize capsule.
703  *
704  * @area is an array of REQ_MAX_FIELD_NR elements, used to store sizes of
705  * variable-sized fields.
706  */
707 void req_capsule_init(struct req_capsule *pill,
708                       struct ptlrpc_request *req, enum req_location location,
709                       int *area)
710 {
711         LASSERT(location == RCL_SERVER || location == RCL_CLIENT);
712
713         memset(pill, 0, sizeof *pill);
714         pill->rc_req = req;
715         pill->rc_loc = location;
716         pill->rc_area = area;
717 }
718 EXPORT_SYMBOL(req_capsule_init);
719
720 void req_capsule_fini(struct req_capsule *pill)
721 {
722 }
723 EXPORT_SYMBOL(req_capsule_fini);
724
725 static int __req_format_is_sane(const struct req_format *fmt)
726 {
727         return
728                 0 <= fmt->rf_idx && fmt->rf_idx < ARRAY_SIZE(req_formats) &&
729                 req_formats[fmt->rf_idx] == fmt;
730 }
731
732 static struct lustre_msg *__req_msg(const struct req_capsule *pill,
733                                     enum req_location loc)
734 {
735         struct ptlrpc_request *req;
736
737         req = pill->rc_req;
738         return loc == RCL_CLIENT ? req->rq_reqmsg : req->rq_repmsg;
739 }
740
741 void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt)
742 {
743         LASSERT(pill->rc_fmt == NULL);
744         LASSERT(__req_format_is_sane(fmt));
745
746         pill->rc_fmt = fmt;
747 }
748 EXPORT_SYMBOL(req_capsule_set);
749
750 int req_capsule_pack(struct req_capsule *pill)
751 {
752         int i;
753         int nr;
754         int result;
755         int total;
756
757         const struct req_format *fmt;
758
759         LASSERT(pill->rc_loc == RCL_SERVER);
760         fmt = pill->rc_fmt;
761         LASSERT(fmt != NULL);
762
763         nr = fmt->rf_fields[RCL_SERVER].nr;
764         for (total = 0, i = 0; i < nr; ++i) {
765                 int *size;
766
767                 size = &pill->rc_area[i];
768                 if (*size == -1) {
769                         *size = fmt->rf_fields[RCL_SERVER].d[i]->rmf_size;
770                         LASSERT(*size != -1);
771                 }
772                 total += *size;
773         }
774         result = lustre_pack_reply(pill->rc_req, nr, pill->rc_area, NULL);
775         if (result != 0) {
776                 DEBUG_REQ(D_ERROR, pill->rc_req,
777                           "Cannot pack %d fields (%d bytes) in format `%s': ",
778                           nr, total, fmt->rf_name);
779         }
780         return result;
781 }
782 EXPORT_SYMBOL(req_capsule_pack);
783
784 static int __req_capsule_offset(const struct req_capsule *pill,
785                                 const struct req_msg_field *field,
786                                 enum req_location loc)
787 {
788         int offset;
789
790         offset = field->rmf_offset[pill->rc_fmt->rf_idx][loc];
791         LASSERT(offset > 0);
792         offset --;
793         LASSERT(0 <= offset && offset < (sizeof(pill->rc_swabbed) << 3));
794         return offset;
795 }
796
797 static void *__req_capsule_get(struct req_capsule *pill,
798                                const struct req_msg_field *field,
799                                enum req_location loc)
800 {
801         const struct req_format *fmt;
802         struct lustre_msg       *msg;
803         void                    *value;
804         int                      len;
805         int                      offset;
806
807         void *(*getter)(struct lustre_msg *m, int n, int minlen);
808
809         static const char *rcl_names[RCL_NR] = {
810                 [RCL_CLIENT] = "client",
811                 [RCL_SERVER] = "server"
812         };
813
814         fmt = pill->rc_fmt;
815         LASSERT(fmt != NULL);
816         LASSERT(__req_format_is_sane(fmt));
817
818         offset = __req_capsule_offset(pill, field, loc);
819
820         msg = __req_msg(pill, loc);
821
822         getter = (field->rmf_flags & RMF_F_STRING) ?
823                 (typeof(getter))lustre_msg_string : lustre_msg_buf;
824
825         len = max(field->rmf_size, 0);
826         value = getter(msg, offset, len);
827
828         if (!(pill->rc_swabbed & (1 << offset)) && loc != pill->rc_loc &&
829             field->rmf_swabber != NULL && value != NULL &&
830             lustre_msg_swabbed(msg)) {
831                 field->rmf_swabber(value);
832                 pill->rc_swabbed |= (1 << offset);
833         }
834         if (value == NULL)
835                 DEBUG_REQ(D_ERROR, pill->rc_req,
836                           "Wrong buffer for field `%s' (%d of %d) "
837                           "in format `%s': %d vs. %d (%s)\n",
838                           field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name,
839                           lustre_msg_buflen(msg, offset), field->rmf_size,
840                           rcl_names[loc]);
841         return value;
842 }
843
844 void *req_capsule_client_get(struct req_capsule *pill,
845                              const struct req_msg_field *field)
846 {
847         return __req_capsule_get(pill, field, RCL_CLIENT);
848 }
849 EXPORT_SYMBOL(req_capsule_client_get);
850
851 void *req_capsule_server_get(struct req_capsule *pill,
852                              const struct req_msg_field *field)
853 {
854         return __req_capsule_get(pill, field, RCL_SERVER);
855 }
856 EXPORT_SYMBOL(req_capsule_server_get);
857
858 const void *req_capsule_other_get(struct req_capsule *pill,
859                                   const struct req_msg_field *field)
860 {
861         return __req_capsule_get(pill, field, pill->rc_loc ^ 1);
862 }
863 EXPORT_SYMBOL(req_capsule_other_get);
864
865 void req_capsule_set_size(const struct req_capsule *pill,
866                           const struct req_msg_field *field,
867                           enum req_location loc, int size)
868 {
869         pill->rc_area[__req_capsule_offset(pill, field, loc)] = size;
870 }
871 EXPORT_SYMBOL(req_capsule_set_size);
872
873 int req_capsule_get_size(const struct req_capsule *pill,
874                          const struct req_msg_field *field,
875                          enum req_location loc)
876 {
877         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
878
879         return lustre_msg_buflen(__req_msg(pill, loc),
880                                  __req_capsule_offset(pill, field, loc));
881 }
882 EXPORT_SYMBOL(req_capsule_get_size);
883
884 #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)]
885
886 void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt)
887 {
888         int i;
889         int j;
890
891         const struct req_format *old;
892
893         LASSERT(pill->rc_fmt != NULL);
894         LASSERT(__req_format_is_sane(fmt));
895
896         old = pill->rc_fmt;
897         /*
898          * Sanity checking...
899          */
900         for (i = 0; i < RCL_NR; ++i) {
901                 LASSERT(fmt->rf_fields[i].nr >= old->rf_fields[i].nr);
902                 for (j = 0; j < old->rf_fields[i].nr - 1; ++j) {
903                         LASSERT(FMT_FIELD(fmt, i, j) == FMT_FIELD(old, i, j));
904                 }
905                 /*
906                  * Last field in old format can be shorter than in new.
907                  */
908                 LASSERT(FMT_FIELD(fmt, i, j)->rmf_size >=
909                         FMT_FIELD(old, i, j)->rmf_size);
910         }
911         /* last field should be returned to the unswabbed state */
912         pill->rc_swabbed &= ~(__u32)(1 << j);
913         pill->rc_fmt = fmt;
914 }
915 EXPORT_SYMBOL(req_capsule_extend);
916
917 int req_capsule_has_field(const struct req_capsule *pill,
918                           const struct req_msg_field *field,
919                           enum req_location loc)
920 {
921         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
922
923         return field->rmf_offset[pill->rc_fmt->rf_idx][loc];
924 }
925 EXPORT_SYMBOL(req_capsule_has_field);
926
927 int req_capsule_field_present(const struct req_capsule *pill,
928                               const struct req_msg_field *field,
929                               enum req_location loc)
930 {
931         int offset;
932
933         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
934         LASSERT(req_capsule_has_field(pill, field, loc));
935
936         offset = __req_capsule_offset(pill, field, loc);
937         return lustre_msg_bufcount(__req_msg(pill, loc)) > offset;
938 }
939 EXPORT_SYMBOL(req_capsule_field_present);
940
941 /* __REQ_LAYOUT_USER__ */
942 #endif