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