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