Whamcloud - gitweb
Branch HEAD
[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_body_capa[] = {
77         &RMF_PTLRPC_BODY,
78         &RMF_MDT_BODY,
79         &RMF_CAPA1
80 };
81
82 static const struct req_msg_field *mdt_close_client[] = {
83         &RMF_PTLRPC_BODY,
84         &RMF_MDT_EPOCH,
85         &RMF_REC_SETATTR,
86         &RMF_CAPA1
87 };
88
89 static const struct req_msg_field *mds_statfs_server[] = {
90         &RMF_PTLRPC_BODY,
91         &RMF_OBD_STATFS
92 };
93
94 static const struct req_msg_field *seq_query_client[] = {
95         &RMF_PTLRPC_BODY,
96         &RMF_SEQ_OPC,
97         &RMF_SEQ_RANGE
98 };
99
100 static const struct req_msg_field *seq_query_server[] = {
101         &RMF_PTLRPC_BODY,
102         &RMF_SEQ_RANGE
103 };
104
105 static const struct req_msg_field *fld_query_client[] = {
106         &RMF_PTLRPC_BODY,
107         &RMF_FLD_OPC,
108         &RMF_FLD_MDFLD
109 };
110
111 static const struct req_msg_field *fld_query_server[] = {
112         &RMF_PTLRPC_BODY,
113         &RMF_FLD_MDFLD
114 };
115
116 static const struct req_msg_field *mds_getattr_name_client[] = {
117         &RMF_PTLRPC_BODY,
118         &RMF_MDT_BODY,
119         &RMF_CAPA1,
120         &RMF_NAME
121 };
122
123 static const struct req_msg_field *mds_reint_client[] = {
124         &RMF_PTLRPC_BODY,
125         &RMF_REINT_OPC
126 };
127
128 static const struct req_msg_field *mds_reint_create_client[] = {
129         &RMF_PTLRPC_BODY,
130         &RMF_REC_CREATE,
131         &RMF_CAPA1,
132         &RMF_NAME,
133 };
134
135 static const struct req_msg_field *mds_reint_create_rmt_acl_client[] = {
136         &RMF_PTLRPC_BODY,
137         &RMF_REC_CREATE,
138         &RMF_CAPA1,
139         &RMF_NAME,
140         &RMF_EADATA,
141         &RMF_DLM_REQ
142 };
143
144 static const struct req_msg_field *mds_reint_create_sym_client[] = {
145         &RMF_PTLRPC_BODY,
146         &RMF_REC_CREATE,
147         &RMF_CAPA1,
148         &RMF_NAME,
149         &RMF_SYMTGT,
150         &RMF_DLM_REQ
151 };
152
153 static const struct req_msg_field *mds_reint_create_slave_client[] = {
154         &RMF_PTLRPC_BODY,
155         &RMF_REC_CREATE,
156         &RMF_CAPA1,
157         &RMF_NAME,
158         &RMF_EADATA
159 };
160
161 static const struct req_msg_field *mds_reint_open_client[] = {
162         &RMF_PTLRPC_BODY,
163         &RMF_REC_CREATE,
164         &RMF_CAPA1,
165         &RMF_CAPA2,
166         &RMF_NAME,
167         &RMF_EADATA
168 };
169
170 static const struct req_msg_field *mds_reint_open_server[] = {
171         &RMF_PTLRPC_BODY,
172         &RMF_MDT_BODY,
173         &RMF_MDT_MD,
174         &RMF_ACL,
175         &RMF_CAPA1,
176         &RMF_CAPA2
177 };
178
179 static const struct req_msg_field *mds_reint_unlink_client[] = {
180         &RMF_PTLRPC_BODY,
181         &RMF_REC_UNLINK,
182         &RMF_CAPA1,
183         &RMF_NAME,
184         &RMF_DLM_REQ
185 };
186
187 static const struct req_msg_field *mds_reint_link_client[] = {
188         &RMF_PTLRPC_BODY,
189         &RMF_REC_LINK,
190         &RMF_CAPA1,
191         &RMF_CAPA2,
192         &RMF_NAME,
193         &RMF_DLM_REQ
194 };
195
196 static const struct req_msg_field *mds_reint_rename_client[] = {
197         &RMF_PTLRPC_BODY,
198         &RMF_REC_RENAME,
199         &RMF_CAPA1,
200         &RMF_CAPA2,
201         &RMF_NAME,
202         &RMF_SYMTGT,
203         &RMF_DLM_REQ
204 };
205
206 static const struct req_msg_field *mds_last_unlink_server[] = {
207         &RMF_PTLRPC_BODY,
208         &RMF_MDT_BODY,
209         &RMF_MDT_MD,
210         &RMF_LOGCOOKIES
211 };
212
213 static const struct req_msg_field *mds_reint_setattr_client[] = {
214         &RMF_PTLRPC_BODY,
215         &RMF_REC_SETATTR,
216         &RMF_CAPA1,
217         &RMF_MDT_EPOCH,
218         &RMF_EADATA,
219         &RMF_LOGCOOKIES,
220         &RMF_DLM_REQ
221 };
222
223 static const struct req_msg_field *mds_connect_client[] = {
224         &RMF_PTLRPC_BODY,
225         &RMF_TGTUUID,
226         &RMF_CLUUID,
227         &RMF_CONN,
228         &RMF_CONNECT_DATA
229 };
230
231 static const struct req_msg_field *mds_connect_server[] = {
232         &RMF_PTLRPC_BODY,
233         &RMF_CONNECT_DATA
234 };
235
236 static const struct req_msg_field *mds_set_info_client[] = {
237         &RMF_PTLRPC_BODY,
238         &RMF_SETINFO_KEY,
239         &RMF_SETINFO_VAL
240 };
241
242 static const struct req_msg_field *ldlm_enqueue_client[] = {
243         &RMF_PTLRPC_BODY,
244         &RMF_DLM_REQ
245 };
246
247 static const struct req_msg_field *ldlm_enqueue_server[] = {
248         &RMF_PTLRPC_BODY,
249         &RMF_DLM_REP
250 };
251
252 static const struct req_msg_field *ldlm_intent_client[] = {
253         &RMF_PTLRPC_BODY,
254         &RMF_DLM_REQ,
255         &RMF_LDLM_INTENT,
256         &RMF_REINT_OPC
257 };
258
259 static const struct req_msg_field *ldlm_intent_server[] = {
260         &RMF_PTLRPC_BODY,
261         &RMF_DLM_REP,
262         &RMF_MDT_BODY,
263         &RMF_MDT_MD,
264         &RMF_ACL,
265         &RMF_CAPA1
266 };
267
268 static const struct req_msg_field *ldlm_intent_open_server[] = {
269         &RMF_PTLRPC_BODY,
270         &RMF_DLM_REP,
271         &RMF_MDT_BODY,
272         &RMF_MDT_MD,
273         &RMF_ACL,
274         &RMF_CAPA1,
275         &RMF_CAPA2
276 };
277
278 static const struct req_msg_field *ldlm_intent_getattr_client[] = {
279         &RMF_PTLRPC_BODY,
280         &RMF_DLM_REQ,
281         &RMF_LDLM_INTENT,
282         &RMF_MDT_BODY,     /* coincides with mds_getattr_name_client[] */
283         &RMF_CAPA1,
284         &RMF_NAME
285 };
286
287 static const struct req_msg_field *ldlm_intent_create_client[] = {
288         &RMF_PTLRPC_BODY,
289         &RMF_DLM_REQ,
290         &RMF_LDLM_INTENT,
291         &RMF_REC_CREATE,    /* coincides with mds_reint_create_client[] */
292         &RMF_CAPA1,
293         &RMF_NAME,
294         &RMF_EADATA
295 };
296
297 static const struct req_msg_field *ldlm_intent_open_client[] = {
298         &RMF_PTLRPC_BODY,
299         &RMF_DLM_REQ,
300         &RMF_LDLM_INTENT,
301         &RMF_REC_CREATE,    /* coincides with mds_reint_open_client[] */
302         &RMF_CAPA1,
303         &RMF_CAPA2,
304         &RMF_NAME,
305         &RMF_EADATA
306 };
307
308 static const struct req_msg_field *ldlm_intent_unlink_client[] = {
309         &RMF_PTLRPC_BODY,
310         &RMF_DLM_REQ,
311         &RMF_LDLM_INTENT,
312         &RMF_REC_UNLINK,    /* coincides with mds_reint_unlink_client[] */
313         &RMF_CAPA1,
314         &RMF_NAME
315 };
316
317 static const struct req_msg_field *mds_getxattr_client[] = {
318         &RMF_PTLRPC_BODY,
319         &RMF_MDT_BODY,
320         &RMF_CAPA1,
321         &RMF_NAME,
322         &RMF_EADATA
323 };
324
325 static const struct req_msg_field *mds_getxattr_server[] = {
326         &RMF_PTLRPC_BODY,
327         &RMF_MDT_BODY,
328         &RMF_EADATA
329 };
330
331 static const struct req_msg_field *mds_setxattr_client[] = {
332         &RMF_PTLRPC_BODY,
333         &RMF_MDT_BODY,
334         &RMF_CAPA1,
335         &RMF_NAME,
336         &RMF_EADATA
337 };
338
339 static const struct req_msg_field *mds_setxattr_server[] = {
340         &RMF_PTLRPC_BODY,
341         &RMF_EADATA
342 };
343
344 static const struct req_msg_field *mds_getattr_server[] = {
345         &RMF_PTLRPC_BODY,
346         &RMF_MDT_BODY,
347         &RMF_MDT_MD,
348         &RMF_ACL,
349         &RMF_CAPA1
350 };
351
352 static const struct req_format *req_formats[] = {
353         &RQF_MDS_CONNECT,
354         &RQF_MDS_DISCONNECT,
355         &RQF_MDS_SET_INFO,
356         &RQF_MDS_GETSTATUS,
357         &RQF_MDS_STATFS,
358         &RQF_MDS_GETATTR,
359         &RQF_MDS_GETATTR_NAME,
360         &RQF_MDS_REINT,
361         &RQF_MDS_REINT_CREATE,
362         &RQF_MDS_REINT_CREATE_RMT_ACL,
363         &RQF_MDS_REINT_CREATE_SYM,
364         &RQF_MDS_REINT_CREATE_SLAVE,
365         &RQF_MDS_REINT_OPEN,
366         &RQF_MDS_REINT_UNLINK,
367         &RQF_MDS_REINT_LINK,
368         &RQF_MDS_REINT_RENAME,
369         &RQF_MDS_REINT_SETATTR,
370         &RQF_LDLM_ENQUEUE,
371         &RQF_LDLM_INTENT,
372         &RQF_LDLM_INTENT_GETATTR,
373         &RQF_LDLM_INTENT_OPEN,
374         &RQF_LDLM_INTENT_CREATE,
375         &RQF_LDLM_INTENT_UNLINK,
376         &RQF_SEQ_QUERY,
377         &RQF_FLD_QUERY,
378         &RQF_MDS_GETXATTR,
379         &RQF_MDS_SETXATTR,
380         &RQF_MDS_SYNC,
381         &RQF_MDS_CLOSE,
382         &RQF_MDS_PIN,
383         &RQF_MDS_READPAGE,
384         &RQF_MDS_WRITEPAGE,
385         &RQF_MDS_IS_SUBDIR,
386         &RQF_MDS_DONE_WRITING
387 };
388
389 struct req_msg_field {
390         __u32       rmf_flags;
391         const char *rmf_name;
392         /*
393          * Field length. (-1) means "variable length".
394          */
395         int         rmf_size;
396         void      (*rmf_swabber)(void *);
397         int         rmf_offset[ARRAY_SIZE(req_formats)][RCL_NR];
398 };
399
400 enum rmf_flags {
401         RMF_F_STRING = 1 << 0
402 };
403
404 struct req_capsule;
405
406 /*
407  * Request fields.
408  */
409 #define DEFINE_MSGF(name, flags, size, swabber) {       \
410         .rmf_name    = (name),                          \
411         .rmf_flags   = (flags),                         \
412         .rmf_size    = (size),                          \
413         .rmf_swabber = (void (*)(void*))(swabber)       \
414 }
415
416 const struct req_msg_field RMF_SETINFO_VAL =
417         DEFINE_MSGF("setinfo_val", 0,
418                     sizeof(__u32), lustre_swab_generic_32s);
419 EXPORT_SYMBOL(RMF_SETINFO_VAL);
420
421 const struct req_msg_field RMF_SEQ_OPC =
422         DEFINE_MSGF("seq_query_opc", 0,
423                     sizeof(__u32), lustre_swab_generic_32s);
424 EXPORT_SYMBOL(RMF_SEQ_OPC);
425
426 const struct req_msg_field RMF_SEQ_RANGE =
427         DEFINE_MSGF("seq_query_range", 0,
428                     sizeof(struct lu_range), lustre_swab_lu_range);
429 EXPORT_SYMBOL(RMF_SEQ_RANGE);
430
431 const struct req_msg_field RMF_FLD_OPC =
432         DEFINE_MSGF("fld_query_opc", 0,
433                     sizeof(__u32), lustre_swab_generic_32s);
434 EXPORT_SYMBOL(RMF_FLD_OPC);
435
436 const struct req_msg_field RMF_FLD_MDFLD =
437         DEFINE_MSGF("fld_query_mdfld", 0,
438                     sizeof(struct md_fld), lustre_swab_md_fld);
439 EXPORT_SYMBOL(RMF_FLD_MDFLD);
440
441 const struct req_msg_field RMF_MDT_BODY =
442         DEFINE_MSGF("mdt_body", 0,
443                     sizeof(struct mdt_body), lustre_swab_mdt_body);
444 EXPORT_SYMBOL(RMF_MDT_BODY);
445
446 const struct req_msg_field RMF_MDT_EPOCH =
447         DEFINE_MSGF("mdt_epoch", 0,
448                     sizeof(struct mdt_epoch), lustre_swab_mdt_epoch);
449 EXPORT_SYMBOL(RMF_MDT_EPOCH);
450
451 const struct req_msg_field RMF_PTLRPC_BODY =
452         DEFINE_MSGF("ptlrpc_body", 0,
453                     sizeof(struct ptlrpc_body), lustre_swab_ptlrpc_body);
454 EXPORT_SYMBOL(RMF_PTLRPC_BODY);
455
456 const struct req_msg_field RMF_OBD_STATFS =
457         DEFINE_MSGF("obd_statfs", 0,
458                     sizeof(struct obd_statfs), lustre_swab_obd_statfs);
459 EXPORT_SYMBOL(RMF_OBD_STATFS);
460
461 const struct req_msg_field RMF_SETINFO_KEY =
462         DEFINE_MSGF("setinfo_key", 0, -1, NULL);
463 EXPORT_SYMBOL(RMF_SETINFO_KEY);
464
465 const struct req_msg_field RMF_NAME =
466         DEFINE_MSGF("name", RMF_F_STRING, -1, NULL);
467 EXPORT_SYMBOL(RMF_NAME);
468
469 const struct req_msg_field RMF_SYMTGT =
470         DEFINE_MSGF("symtgt", RMF_F_STRING, -1, NULL);
471 EXPORT_SYMBOL(RMF_SYMTGT);
472
473 const struct req_msg_field RMF_TGTUUID =
474         DEFINE_MSGF("tgtuuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
475 EXPORT_SYMBOL(RMF_TGTUUID);
476
477 const struct req_msg_field RMF_CLUUID =
478         DEFINE_MSGF("cluuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
479 EXPORT_SYMBOL(RMF_CLUUID);
480
481 /*
482  * connection handle received in MDS_CONNECT request.
483  *
484  * XXX no swabbing?
485  */
486 const struct req_msg_field RMF_CONN =
487         DEFINE_MSGF("conn", 0, sizeof(struct lustre_handle), NULL);
488 EXPORT_SYMBOL(RMF_CONN);
489
490 const struct req_msg_field RMF_CONNECT_DATA =
491         DEFINE_MSGF("cdata", 0,
492                     sizeof(struct obd_connect_data), lustre_swab_connect);
493 EXPORT_SYMBOL(RMF_CONNECT_DATA);
494
495 const struct req_msg_field RMF_DLM_REQ =
496         DEFINE_MSGF("dlm_req", 0,
497                     sizeof(struct ldlm_request), lustre_swab_ldlm_request);
498 EXPORT_SYMBOL(RMF_DLM_REQ);
499
500 const struct req_msg_field RMF_DLM_REP =
501         DEFINE_MSGF("dlm_rep", 0,
502                     sizeof(struct ldlm_reply), lustre_swab_ldlm_reply);
503 EXPORT_SYMBOL(RMF_DLM_REP);
504
505 const struct req_msg_field RMF_LDLM_INTENT =
506         DEFINE_MSGF("ldlm_intent", 0,
507                     sizeof(struct ldlm_intent), lustre_swab_ldlm_intent);
508 EXPORT_SYMBOL(RMF_LDLM_INTENT);
509
510 const struct req_msg_field RMF_MDT_MD =
511         DEFINE_MSGF("mdt_md", 0, MIN_MD_SIZE, lustre_swab_lov_mds_md);
512 EXPORT_SYMBOL(RMF_MDT_MD);
513
514 const struct req_msg_field RMF_REC_UNLINK =
515         DEFINE_MSGF("rec_unlink", 0, sizeof(struct mdt_rec_unlink),
516                     lustre_swab_mdt_rec_unlink);
517 EXPORT_SYMBOL(RMF_REC_UNLINK);
518
519 const struct req_msg_field RMF_REC_LINK =
520         DEFINE_MSGF("rec_link", 0, sizeof(struct mdt_rec_link),
521                     lustre_swab_mdt_rec_link);
522 EXPORT_SYMBOL(RMF_REC_LINK);
523
524 const struct req_msg_field RMF_REC_RENAME =
525         DEFINE_MSGF("rec_rename", 0, sizeof(struct mdt_rec_rename),
526                     lustre_swab_mdt_rec_rename);
527 EXPORT_SYMBOL(RMF_REC_RENAME);
528
529 const struct req_msg_field RMF_REC_CREATE =
530         DEFINE_MSGF("rec_create", 0,
531                     sizeof(struct mdt_rec_create), lustre_swab_mdt_rec_create);
532 EXPORT_SYMBOL(RMF_REC_CREATE);
533
534 const struct req_msg_field RMF_REC_SETATTR =
535         DEFINE_MSGF("rec_setattr", 0, sizeof(struct mdt_rec_setattr),
536                     lustre_swab_mdt_rec_setattr);
537 EXPORT_SYMBOL(RMF_REC_SETATTR);
538
539 /* FIXME: this length should be defined as a macro */
540 const struct req_msg_field RMF_EADATA = DEFINE_MSGF("eadata", 0, -1, NULL);
541 EXPORT_SYMBOL(RMF_EADATA);
542
543 const struct req_msg_field RMF_ACL = DEFINE_MSGF("acl", 0,
544                                      __POSIX_ACL_MAX_SIZE, NULL);
545 EXPORT_SYMBOL(RMF_ACL);
546
547 const struct req_msg_field RMF_LOGCOOKIES =
548         DEFINE_MSGF("logcookies", 0, sizeof(struct llog_cookie), NULL);
549 EXPORT_SYMBOL(RMF_LOGCOOKIES);
550
551 const struct req_msg_field RMF_REINT_OPC =
552         DEFINE_MSGF("reint_opc", 0, sizeof(__u32), lustre_swab_generic_32s);
553 EXPORT_SYMBOL(RMF_REINT_OPC);
554
555 const struct req_msg_field RMF_CAPA1 =
556         DEFINE_MSGF("capa", 0, sizeof(struct lustre_capa),
557                     lustre_swab_lustre_capa);
558 EXPORT_SYMBOL(RMF_CAPA1);
559
560 const struct req_msg_field RMF_CAPA2 =
561         DEFINE_MSGF("capa", 0, sizeof(struct lustre_capa),
562                     lustre_swab_lustre_capa);
563 EXPORT_SYMBOL(RMF_CAPA2);
564
565 /*
566  * Request formats.
567  */
568
569 struct req_format {
570         const char *rf_name;
571         int         rf_idx;
572         struct {
573                 int                          nr;
574                 const struct req_msg_field **d;
575         } rf_fields[RCL_NR];
576 };
577
578 #define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) {    \
579         .rf_name   = name,                                              \
580         .rf_fields = {                                                  \
581                 [RCL_CLIENT] = {                                        \
582                         .nr = client_nr,                                \
583                         .d  = client                                    \
584                 },                                                      \
585                 [RCL_SERVER] = {                                        \
586                         .nr = server_nr,                                \
587                         .d  = server                                    \
588                 }                                                       \
589         }                                                               \
590 }
591
592 #define DEFINE_REQ_FMT0(name, client, server)                           \
593 DEFINE_REQ_FMT(name, client, ARRAY_SIZE(client), server, ARRAY_SIZE(server))
594
595 const struct req_format RQF_SEQ_QUERY =
596         DEFINE_REQ_FMT0("SEQ_QUERY", seq_query_client, seq_query_server);
597 EXPORT_SYMBOL(RQF_SEQ_QUERY);
598
599 const struct req_format RQF_FLD_QUERY =
600         DEFINE_REQ_FMT0("FLD_QUERY", fld_query_client, fld_query_server);
601 EXPORT_SYMBOL(RQF_FLD_QUERY);
602
603 const struct req_format RQF_MDS_GETSTATUS =
604         DEFINE_REQ_FMT0("MDS_GETSTATUS", empty, mdt_body_capa);
605 EXPORT_SYMBOL(RQF_MDS_GETSTATUS);
606
607 const struct req_format RQF_MDS_STATFS =
608         DEFINE_REQ_FMT0("MDS_STATFS", empty, mds_statfs_server);
609 EXPORT_SYMBOL(RQF_MDS_STATFS);
610
611 const struct req_format RQF_MDS_SYNC =
612         DEFINE_REQ_FMT0("MDS_SYNC", mdt_body_capa, mdt_body_only);
613 EXPORT_SYMBOL(RQF_MDS_SYNC);
614
615 const struct req_format RQF_MDS_GETATTR =
616         DEFINE_REQ_FMT0("MDS_GETATTR", mdt_body_capa, mds_getattr_server);
617 EXPORT_SYMBOL(RQF_MDS_GETATTR);
618
619 const struct req_format RQF_MDS_GETXATTR =
620         DEFINE_REQ_FMT0("MDS_GETXATTR",
621                         mds_getxattr_client, mds_getxattr_server);
622 EXPORT_SYMBOL(RQF_MDS_GETXATTR);
623
624 const struct req_format RQF_MDS_SETXATTR =
625         DEFINE_REQ_FMT0("MDS_SETXATTR",
626                         mds_setxattr_client, mds_setxattr_server);
627 EXPORT_SYMBOL(RQF_MDS_SETXATTR);
628
629 const struct req_format RQF_MDS_GETATTR_NAME =
630         DEFINE_REQ_FMT0("MDS_GETATTR_NAME",
631                         mds_getattr_name_client, mds_getattr_server);
632 EXPORT_SYMBOL(RQF_MDS_GETATTR_NAME);
633
634 const struct req_format RQF_MDS_REINT =
635         DEFINE_REQ_FMT0("MDS_REINT", mds_reint_client, mdt_body_only);
636 EXPORT_SYMBOL(RQF_MDS_REINT);
637
638 const struct req_format RQF_MDS_REINT_CREATE =
639         DEFINE_REQ_FMT0("MDS_REINT_CREATE",
640                         mds_reint_create_client, mdt_body_capa);
641 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE);
642
643 const struct req_format RQF_MDS_REINT_CREATE_RMT_ACL =
644         DEFINE_REQ_FMT0("MDS_REINT_CREATE_RMT_ACL",
645                         mds_reint_create_rmt_acl_client, mdt_body_capa);
646 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_RMT_ACL);
647
648 const struct req_format RQF_MDS_REINT_CREATE_SLAVE =
649         DEFINE_REQ_FMT0("MDS_REINT_CREATE_SLAVE",
650                         mds_reint_create_slave_client, mdt_body_capa);
651 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SLAVE);
652
653 const struct req_format RQF_MDS_REINT_CREATE_SYM =
654         DEFINE_REQ_FMT0("MDS_REINT_CREATE_SYM",
655                         mds_reint_create_sym_client, mdt_body_capa);
656 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SYM);
657
658 const struct req_format RQF_MDS_REINT_OPEN =
659         DEFINE_REQ_FMT0("MDS_REINT_OPEN",
660                         mds_reint_open_client, mds_reint_open_server);
661 EXPORT_SYMBOL(RQF_MDS_REINT_OPEN);
662
663 const struct req_format RQF_MDS_REINT_UNLINK =
664         DEFINE_REQ_FMT0("MDS_REINT_UNLINK", mds_reint_unlink_client,
665                         mds_last_unlink_server);
666 EXPORT_SYMBOL(RQF_MDS_REINT_UNLINK);
667
668 const struct req_format RQF_MDS_REINT_LINK =
669         DEFINE_REQ_FMT0("MDS_REINT_LINK",
670                         mds_reint_link_client, mdt_body_only);
671 EXPORT_SYMBOL(RQF_MDS_REINT_LINK);
672
673 const struct req_format RQF_MDS_REINT_RENAME =
674         DEFINE_REQ_FMT0("MDS_REINT_RENAME", mds_reint_rename_client,
675                         mds_last_unlink_server);
676 EXPORT_SYMBOL(RQF_MDS_REINT_RENAME);
677
678 const struct req_format RQF_MDS_REINT_SETATTR =
679         DEFINE_REQ_FMT0("MDS_REINT_SETATTR",
680                         mds_reint_setattr_client, mdt_body_capa);
681 EXPORT_SYMBOL(RQF_MDS_REINT_SETATTR);
682
683 const struct req_format RQF_MDS_CONNECT =
684         DEFINE_REQ_FMT0("MDS_CONNECT",
685                         mds_connect_client, mds_connect_server);
686 EXPORT_SYMBOL(RQF_MDS_CONNECT);
687
688 const struct req_format RQF_MDS_DISCONNECT =
689         DEFINE_REQ_FMT0("MDS_DISCONNECT", empty, empty);
690 EXPORT_SYMBOL(RQF_MDS_DISCONNECT);
691
692 const struct req_format RQF_MDS_SET_INFO =
693         DEFINE_REQ_FMT0("MDS_SET_INFO", mds_set_info_client, empty);
694 EXPORT_SYMBOL(RQF_MDS_SET_INFO);
695  
696 const struct req_format RQF_LDLM_ENQUEUE =
697         DEFINE_REQ_FMT0("LDLM_ENQUEUE",
698                         ldlm_enqueue_client, ldlm_enqueue_server);
699 EXPORT_SYMBOL(RQF_LDLM_ENQUEUE);
700
701 const struct req_format RQF_LDLM_INTENT =
702         DEFINE_REQ_FMT0("LDLM_INTENT",
703                         ldlm_intent_client, ldlm_intent_server);
704 EXPORT_SYMBOL(RQF_LDLM_INTENT);
705
706 const struct req_format RQF_LDLM_INTENT_GETATTR =
707         DEFINE_REQ_FMT0("LDLM_INTENT_GETATTR",
708                         ldlm_intent_getattr_client, ldlm_intent_server);
709 EXPORT_SYMBOL(RQF_LDLM_INTENT_GETATTR);
710
711 const struct req_format RQF_LDLM_INTENT_OPEN =
712         DEFINE_REQ_FMT0("LDLM_INTENT_OPEN",
713                         ldlm_intent_open_client, ldlm_intent_open_server);
714 EXPORT_SYMBOL(RQF_LDLM_INTENT_OPEN);
715
716 const struct req_format RQF_LDLM_INTENT_CREATE =
717         DEFINE_REQ_FMT0("LDLM_INTENT_CREATE",
718                         ldlm_intent_create_client, ldlm_intent_server);
719 EXPORT_SYMBOL(RQF_LDLM_INTENT_CREATE);
720
721 const struct req_format RQF_LDLM_INTENT_UNLINK =
722         DEFINE_REQ_FMT0("LDLM_INTENT_UNLINK",
723                         ldlm_intent_unlink_client, ldlm_intent_server);
724 EXPORT_SYMBOL(RQF_LDLM_INTENT_UNLINK);
725
726 const struct req_format RQF_MDS_CLOSE =
727         DEFINE_REQ_FMT0("MDS_CLOSE",
728                         mdt_close_client, mds_last_unlink_server);
729 EXPORT_SYMBOL(RQF_MDS_CLOSE);
730
731 const struct req_format RQF_MDS_PIN =
732         DEFINE_REQ_FMT0("MDS_PIN",
733                         mdt_body_capa, mdt_body_only);
734 EXPORT_SYMBOL(RQF_MDS_PIN);
735
736 const struct req_format RQF_MDS_DONE_WRITING =
737         DEFINE_REQ_FMT0("MDS_DONE_WRITING",
738                         mdt_close_client, mdt_body_only);
739 EXPORT_SYMBOL(RQF_MDS_DONE_WRITING);
740
741 const struct req_format RQF_MDS_READPAGE =
742         DEFINE_REQ_FMT0("MDS_READPAGE",
743                         mdt_body_capa, mdt_body_only);
744 EXPORT_SYMBOL(RQF_MDS_READPAGE);
745
746 /* This is for split */
747 const struct req_format RQF_MDS_WRITEPAGE =
748         DEFINE_REQ_FMT0("MDS_WRITEPAGE",
749                         mdt_body_capa, mdt_body_only);
750 EXPORT_SYMBOL(RQF_MDS_WRITEPAGE);
751
752 const struct req_format RQF_MDS_IS_SUBDIR =
753         DEFINE_REQ_FMT0("MDS_IS_SUBDIR",
754                         mdt_body_only, mdt_body_only);
755 EXPORT_SYMBOL(RQF_MDS_IS_SUBDIR);
756
757 #if !defined(__REQ_LAYOUT_USER__)
758
759 int req_layout_init(void)
760 {
761         int i;
762         int j;
763         int k;
764
765         for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
766                 struct req_format *rf;
767
768                 rf = (struct req_format *)req_formats[i];
769                 rf->rf_idx = i;
770                 for (j = 0; j < RCL_NR; ++j) {
771                         LASSERT(rf->rf_fields[j].nr <= REQ_MAX_FIELD_NR);
772                         for (k = 0; k < rf->rf_fields[j].nr; ++k) {
773                                 struct req_msg_field *field;
774
775                                 field = (typeof(field))rf->rf_fields[j].d[k];
776                                 LASSERT(field->rmf_offset[i][j] == 0);
777                                 /*
778                                  * k + 1 to detect unused format/field
779                                  * combinations.
780                                  */
781                                 field->rmf_offset[i][j] = k + 1;
782                         }
783                 }
784         }
785         return 0;
786 }
787 EXPORT_SYMBOL(req_layout_init);
788
789 void req_layout_fini(void)
790 {
791 }
792 EXPORT_SYMBOL(req_layout_fini);
793
794 /*
795  * Initialize capsule.
796  *
797  * @area is an array of REQ_MAX_FIELD_NR elements, used to store sizes of
798  * variable-sized fields.
799  */
800 void req_capsule_init(struct req_capsule *pill,
801                       struct ptlrpc_request *req, enum req_location location,
802                       int *area)
803 {
804         LASSERT(location == RCL_SERVER || location == RCL_CLIENT);
805
806         memset(pill, 0, sizeof *pill);
807         pill->rc_req = req;
808         pill->rc_loc = location;
809         pill->rc_area = area;
810 }
811 EXPORT_SYMBOL(req_capsule_init);
812
813 void req_capsule_fini(struct req_capsule *pill)
814 {
815 }
816 EXPORT_SYMBOL(req_capsule_fini);
817
818 static int __req_format_is_sane(const struct req_format *fmt)
819 {
820         return
821                 0 <= fmt->rf_idx && fmt->rf_idx < ARRAY_SIZE(req_formats) &&
822                 req_formats[fmt->rf_idx] == fmt;
823 }
824
825 static struct lustre_msg *__req_msg(const struct req_capsule *pill,
826                                     enum req_location loc)
827 {
828         struct ptlrpc_request *req;
829
830         req = pill->rc_req;
831         return loc == RCL_CLIENT ? req->rq_reqmsg : req->rq_repmsg;
832 }
833
834 void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt)
835 {
836         LASSERT(pill->rc_fmt == NULL);
837         LASSERT(__req_format_is_sane(fmt));
838
839         pill->rc_fmt = fmt;
840 }
841 EXPORT_SYMBOL(req_capsule_set);
842
843 int req_capsule_pack(struct req_capsule *pill)
844 {
845         int i;
846         int nr;
847         int result;
848         int total;
849
850         const struct req_format *fmt;
851
852         LASSERT(pill->rc_loc == RCL_SERVER);
853         fmt = pill->rc_fmt;
854         LASSERT(fmt != NULL);
855
856         nr = fmt->rf_fields[RCL_SERVER].nr;
857         for (total = 0, i = 0; i < nr; ++i) {
858                 int *size;
859
860                 size = &pill->rc_area[i];
861                 if (*size == -1) {
862                         *size = fmt->rf_fields[RCL_SERVER].d[i]->rmf_size;
863                         LASSERT(*size != -1);
864                 }
865                 total += *size;
866         }
867         result = lustre_pack_reply(pill->rc_req, nr, pill->rc_area, NULL);
868         if (result != 0) {
869                 DEBUG_REQ(D_ERROR, pill->rc_req,
870                           "Cannot pack %d fields (%d bytes) in format `%s': ",
871                           nr, total, fmt->rf_name);
872         }
873         return result;
874 }
875 EXPORT_SYMBOL(req_capsule_pack);
876
877 static int __req_capsule_offset(const struct req_capsule *pill,
878                                 const struct req_msg_field *field,
879                                 enum req_location loc)
880 {
881         int offset;
882
883         offset = field->rmf_offset[pill->rc_fmt->rf_idx][loc];
884         LASSERT(offset > 0);
885         offset --;
886         LASSERT(0 <= offset && offset < (sizeof(pill->rc_swabbed) << 3));
887         return offset;
888 }
889
890 static void *__req_capsule_get(struct req_capsule *pill,
891                                const struct req_msg_field *field,
892                                enum req_location loc)
893 {
894         const struct req_format *fmt;
895         struct lustre_msg       *msg;
896         void                    *value;
897         int                      len;
898         int                      offset;
899
900         void *(*getter)(struct lustre_msg *m, int n, int minlen);
901
902         static const char *rcl_names[RCL_NR] = {
903                 [RCL_CLIENT] = "client",
904                 [RCL_SERVER] = "server"
905         };
906
907         fmt = pill->rc_fmt;
908         LASSERT(fmt != NULL);
909         LASSERT(__req_format_is_sane(fmt));
910
911         offset = __req_capsule_offset(pill, field, loc);
912
913         msg = __req_msg(pill, loc);
914
915         getter = (field->rmf_flags & RMF_F_STRING) ?
916                 (typeof(getter))lustre_msg_string : lustre_msg_buf;
917
918         len = max(field->rmf_size, 0);
919         value = getter(msg, offset, len);
920
921         if (!(pill->rc_swabbed & (1 << offset)) && loc != pill->rc_loc &&
922             field->rmf_swabber != NULL && value != NULL &&
923             lustre_msg_swabbed(msg)) {
924                 field->rmf_swabber(value);
925                 pill->rc_swabbed |= (1 << offset);
926         }
927         if (value == NULL)
928                 DEBUG_REQ(D_ERROR, pill->rc_req,
929                           "Wrong buffer for field `%s' (%d of %d) "
930                           "in format `%s': %d vs. %d (%s)\n",
931                           field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name,
932                           lustre_msg_buflen(msg, offset), field->rmf_size,
933                           rcl_names[loc]);
934
935         return value;
936 }
937
938 void *req_capsule_client_get(struct req_capsule *pill,
939                              const struct req_msg_field *field)
940 {
941         return __req_capsule_get(pill, field, RCL_CLIENT);
942 }
943 EXPORT_SYMBOL(req_capsule_client_get);
944
945 void *req_capsule_server_get(struct req_capsule *pill,
946                              const struct req_msg_field *field)
947 {
948         return __req_capsule_get(pill, field, RCL_SERVER);
949 }
950 EXPORT_SYMBOL(req_capsule_server_get);
951
952 const void *req_capsule_other_get(struct req_capsule *pill,
953                                   const struct req_msg_field *field)
954 {
955         return __req_capsule_get(pill, field, pill->rc_loc ^ 1);
956 }
957 EXPORT_SYMBOL(req_capsule_other_get);
958
959 void req_capsule_set_size(const struct req_capsule *pill,
960                           const struct req_msg_field *field,
961                           enum req_location loc, int size)
962 {
963         pill->rc_area[__req_capsule_offset(pill, field, loc)] = size;
964 }
965 EXPORT_SYMBOL(req_capsule_set_size);
966
967 int req_capsule_get_size(const struct req_capsule *pill,
968                          const struct req_msg_field *field,
969                          enum req_location loc)
970 {
971         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
972
973         return lustre_msg_buflen(__req_msg(pill, loc),
974                                  __req_capsule_offset(pill, field, loc));
975 }
976 EXPORT_SYMBOL(req_capsule_get_size);
977
978 #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)]
979
980 void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt)
981 {
982         int i;
983         int j;
984
985         const struct req_format *old;
986
987         LASSERT(pill->rc_fmt != NULL);
988         LASSERT(__req_format_is_sane(fmt));
989
990         old = pill->rc_fmt;
991         /*
992          * Sanity checking...
993          */
994         for (i = 0; i < RCL_NR; ++i) {
995                 LASSERT(fmt->rf_fields[i].nr >= old->rf_fields[i].nr);
996                 for (j = 0; j < old->rf_fields[i].nr - 1; ++j) {
997                         LASSERT(FMT_FIELD(fmt, i, j) == FMT_FIELD(old, i, j));
998                 }
999                 /*
1000                  * Last field in old format can be shorter than in new.
1001                  */
1002                 LASSERT(FMT_FIELD(fmt, i, j)->rmf_size >=
1003                         FMT_FIELD(old, i, j)->rmf_size);
1004         }
1005         /* last field should be returned to the unswabbed state */
1006         pill->rc_swabbed &= ~(__u32)(1 << j);
1007         pill->rc_fmt = fmt;
1008 }
1009 EXPORT_SYMBOL(req_capsule_extend);
1010
1011 int req_capsule_has_field(const struct req_capsule *pill,
1012                           const struct req_msg_field *field,
1013                           enum req_location loc)
1014 {
1015         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
1016
1017         return field->rmf_offset[pill->rc_fmt->rf_idx][loc];
1018 }
1019 EXPORT_SYMBOL(req_capsule_has_field);
1020
1021 int req_capsule_field_present(const struct req_capsule *pill,
1022                               const struct req_msg_field *field,
1023                               enum req_location loc)
1024 {
1025         int offset;
1026
1027         LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
1028         LASSERT(req_capsule_has_field(pill, field, loc));
1029
1030         offset = __req_capsule_offset(pill, field, loc);
1031         return lustre_msg_bufcount(__req_msg(pill, loc)) > offset;
1032 }
1033 EXPORT_SYMBOL(req_capsule_field_present);
1034
1035
1036 /*
1037  * Shrink the specified reply message buffer @field to a specified @newlen.
1038  * If @move_data is non-zero, then move following buffer backward 
1039  *    if @newlen is zero;
1040  * The internal offset should be adjusted by @adjust because buffer maybe has
1041  *    been moved by previous call. (@adjust >= 0) is a must.
1042  * Return value: 1 if buffer has been moved, otherwise 0 is returned.
1043  */
1044 int req_capsule_shrink(const struct req_capsule *pill,
1045                        const struct req_msg_field *field,
1046                        const unsigned int newlen,
1047                        const int adjust,
1048                        const int move_data)
1049 {
1050         int offset;
1051
1052         LASSERT(adjust >= 0);
1053         LASSERT(req_capsule_has_field(pill, field, RCL_SERVER));
1054
1055         offset = __req_capsule_offset(pill, field, RCL_SERVER);
1056         offset -= adjust;
1057         LASSERT(offset >= 1);
1058
1059         lustre_shrink_reply(pill->rc_req, offset, newlen, move_data);
1060         return (newlen == 0) ? 1 : 0;
1061 }
1062 EXPORT_SYMBOL(req_capsule_shrink);
1063
1064 /* __REQ_LAYOUT_USER__ */
1065 #endif