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