1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/ptlrpc/layout.c
5 * Lustre Metadata Target (mdt) request handler
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Nikita Danilov <nikita@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
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.
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.
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.
29 #if !defined(__REQ_LAYOUT_USER__)
32 # define EXPORT_SYMTAB
34 #define DEBUG_SUBSYSTEM S_RPC
37 #include <linux/module.h>
39 # include <liblustre.h>
42 /* LUSTRE_VERSION_CODE */
43 #include <lustre_ver.h>
45 #include <obd_support.h>
46 /* lustre_swab_mdt_body */
47 #include <lustre/lustre_idl.h>
48 /* obd2cli_tgt() (required by DEBUG_REQ()) */
51 /* __REQ_LAYOUT_USER__ */
53 /* struct ptlrpc_request, lustre_msg* */
54 #include <lustre_req_layout.h>
55 #include <linux/lustre_acl.h>
58 #define __POSIX_ACL_MAX_SIZE \
59 (sizeof(xattr_acl_header) + 32 * sizeof(xattr_acl_entry))
61 #define __POSIX_ACL_MAX_SIZE 0
65 * empty set of fields... for suitable definition of emptiness.
67 static const struct req_msg_field *empty[] = {
71 static const struct req_msg_field *mdt_body_only[] = {
76 static const struct req_msg_field *mdt_close_msg[] = {
82 static const struct req_msg_field *mds_statfs_server[] = {
87 static const struct req_msg_field *seq_query_client[] = {
93 static const struct req_msg_field *seq_query_server[] = {
98 static const struct req_msg_field *fld_query_client[] = {
104 static const struct req_msg_field *fld_query_server[] = {
109 static const struct req_msg_field *mds_getattr_name_client[] = {
115 static const struct req_msg_field *mds_reint_client[] = {
120 static const struct req_msg_field *mds_reint_create_client[] = {
126 static const struct req_msg_field *mds_reint_create_sym_client[] = {
133 static const struct req_msg_field *mds_reint_create_slave_client[] = {
140 static const struct req_msg_field *mds_reint_open_client[] = {
147 static const struct req_msg_field *mds_reint_open_server[] = {
154 static const struct req_msg_field *mds_reint_unlink_client[] = {
160 static const struct req_msg_field *mds_reint_link_client[] = {
166 static const struct req_msg_field *mds_reint_rename_client[] = {
173 static const struct req_msg_field *mds_last_unlink_server[] = {
180 static const struct req_msg_field *mds_reint_setattr_client[] = {
188 static const struct req_msg_field *mds_connect_client[] = {
196 static const struct req_msg_field *mds_connect_server[] = {
201 static const struct req_msg_field *ldlm_enqueue_client[] = {
206 static const struct req_msg_field *ldlm_enqueue_server[] = {
211 static const struct req_msg_field *ldlm_intent_client[] = {
218 static const struct req_msg_field *ldlm_intent_server[] = {
226 static const struct req_msg_field *ldlm_intent_getattr_client[] = {
230 &RMF_MDT_BODY, /* coincides with mds_getattr_name_client[] */
234 static const struct req_msg_field *ldlm_intent_create_client[] = {
238 &RMF_REC_CREATE, /* coincides with mds_reint_create_client[] */
243 static const struct req_msg_field *ldlm_intent_open_client[] = {
247 &RMF_REC_CREATE, /* coincides with mds_reint_open_client[] */
252 static const struct req_msg_field *ldlm_intent_unlink_client[] = {
256 &RMF_REC_UNLINK, /* coincides with mds_reint_unlink_client[] */
260 static const struct req_msg_field *mds_getxattr_client[] = {
266 static const struct req_msg_field *mds_getxattr_server[] = {
272 static const struct req_msg_field *mds_setxattr_client[] = {
279 static const struct req_msg_field *mds_getattr_server[] = {
286 static const struct req_format *req_formats[] = {
292 &RQF_MDS_GETATTR_NAME,
294 &RQF_MDS_REINT_CREATE,
295 &RQF_MDS_REINT_CREATE_SYM,
296 &RQF_MDS_REINT_CREATE_SLAVE,
298 &RQF_MDS_REINT_UNLINK,
300 &RQF_MDS_REINT_RENAME,
301 &RQF_MDS_REINT_SETATTR,
304 &RQF_LDLM_INTENT_GETATTR,
305 &RQF_LDLM_INTENT_OPEN,
306 &RQF_LDLM_INTENT_CREATE,
307 &RQF_LDLM_INTENT_UNLINK,
318 &RQF_MDS_DONE_WRITING
321 struct req_msg_field {
323 const char *rmf_name;
325 * Field length. (-1) means "variable length".
328 void (*rmf_swabber)(void *);
329 int rmf_offset[ARRAY_SIZE(req_formats)][RCL_NR];
333 RMF_F_STRING = 1 << 0
341 #define DEFINE_MSGF(name, flags, size, swabber) { \
342 .rmf_name = (name), \
343 .rmf_flags = (flags), \
344 .rmf_size = (size), \
345 .rmf_swabber = (void (*)(void*))(swabber) \
348 const struct req_msg_field RMF_SEQ_OPC =
349 DEFINE_MSGF("seq_query_opc", 0,
350 sizeof(__u32), lustre_swab_generic_32s);
351 EXPORT_SYMBOL(RMF_SEQ_OPC);
353 const struct req_msg_field RMF_SEQ_RANGE =
354 DEFINE_MSGF("seq_query_range", 0,
355 sizeof(struct lu_range), lustre_swab_lu_range);
356 EXPORT_SYMBOL(RMF_SEQ_RANGE);
358 const struct req_msg_field RMF_FLD_OPC =
359 DEFINE_MSGF("fld_query_opc", 0,
360 sizeof(__u32), lustre_swab_generic_32s);
361 EXPORT_SYMBOL(RMF_FLD_OPC);
363 const struct req_msg_field RMF_FLD_MDFLD =
364 DEFINE_MSGF("fld_query_mdfld", 0,
365 sizeof(struct md_fld), lustre_swab_md_fld);
366 EXPORT_SYMBOL(RMF_FLD_MDFLD);
368 const struct req_msg_field RMF_MDT_BODY =
369 DEFINE_MSGF("mdt_body", 0,
370 sizeof(struct mdt_body), lustre_swab_mdt_body);
371 EXPORT_SYMBOL(RMF_MDT_BODY);
373 const struct req_msg_field RMF_MDT_EPOCH =
374 DEFINE_MSGF("mdt_epoch", 0,
375 sizeof(struct mdt_epoch), lustre_swab_mdt_epoch);
376 EXPORT_SYMBOL(RMF_MDT_EPOCH);
378 const struct req_msg_field RMF_PTLRPC_BODY =
379 DEFINE_MSGF("ptlrpc_body", 0,
380 sizeof(struct ptlrpc_body), lustre_swab_ptlrpc_body);
381 EXPORT_SYMBOL(RMF_PTLRPC_BODY);
383 const struct req_msg_field RMF_OBD_STATFS =
384 DEFINE_MSGF("obd_statfs", 0,
385 sizeof(struct obd_statfs), lustre_swab_obd_statfs);
386 EXPORT_SYMBOL(RMF_OBD_STATFS);
388 const struct req_msg_field RMF_NAME =
389 DEFINE_MSGF("name", RMF_F_STRING, -1, NULL);
390 EXPORT_SYMBOL(RMF_NAME);
392 const struct req_msg_field RMF_SYMTGT =
393 DEFINE_MSGF("symtgt", RMF_F_STRING, -1, NULL);
394 EXPORT_SYMBOL(RMF_SYMTGT);
396 const struct req_msg_field RMF_TGTUUID =
397 DEFINE_MSGF("tgtuuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
398 EXPORT_SYMBOL(RMF_TGTUUID);
400 const struct req_msg_field RMF_CLUUID =
401 DEFINE_MSGF("cluuid", RMF_F_STRING, sizeof(struct obd_uuid) - 1, NULL);
402 EXPORT_SYMBOL(RMF_CLUUID);
405 * connection handle received in MDS_CONNECT request.
409 const struct req_msg_field RMF_CONN =
410 DEFINE_MSGF("conn", 0, sizeof(struct lustre_handle), NULL);
411 EXPORT_SYMBOL(RMF_CONN);
413 const struct req_msg_field RMF_CONNECT_DATA =
414 DEFINE_MSGF("cdata", 0,
415 sizeof(struct obd_connect_data), lustre_swab_connect);
416 EXPORT_SYMBOL(RMF_CONNECT_DATA);
418 const struct req_msg_field RMF_DLM_REQ =
419 DEFINE_MSGF("dlm_req", 0,
420 sizeof(struct ldlm_request), lustre_swab_ldlm_request);
421 EXPORT_SYMBOL(RMF_DLM_REQ);
423 const struct req_msg_field RMF_DLM_REP =
424 DEFINE_MSGF("dlm_rep", 0,
425 sizeof(struct ldlm_reply), lustre_swab_ldlm_reply);
426 EXPORT_SYMBOL(RMF_DLM_REP);
428 const struct req_msg_field RMF_LDLM_INTENT =
429 DEFINE_MSGF("ldlm_intent", 0,
430 sizeof(struct ldlm_intent), lustre_swab_ldlm_intent);
431 EXPORT_SYMBOL(RMF_LDLM_INTENT);
434 /* FIXME XXX by Huang Hua
435 * to make sure about the size. Refer to MDS.
438 const struct req_msg_field RMF_MDT_MD =
439 DEFINE_MSGF("mdt_md", 0, MIN_MD_SIZE, lustre_swab_lov_mds_md);
440 EXPORT_SYMBOL(RMF_MDT_MD);
442 const struct req_msg_field RMF_REC_UNLINK =
443 DEFINE_MSGF("rec_unlink", 0, sizeof(struct mdt_rec_unlink),
444 lustre_swab_mdt_rec_unlink);
445 EXPORT_SYMBOL(RMF_REC_UNLINK);
447 const struct req_msg_field RMF_REC_LINK =
448 DEFINE_MSGF("rec_link", 0, sizeof(struct mdt_rec_link),
449 lustre_swab_mdt_rec_link);
450 EXPORT_SYMBOL(RMF_REC_LINK);
452 const struct req_msg_field RMF_REC_RENAME =
453 DEFINE_MSGF("rec_rename", 0, sizeof(struct mdt_rec_rename),
454 lustre_swab_mdt_rec_rename);
455 EXPORT_SYMBOL(RMF_REC_RENAME);
457 const struct req_msg_field RMF_REC_CREATE =
458 DEFINE_MSGF("rec_create", 0,
459 sizeof(struct mdt_rec_create), lustre_swab_mdt_rec_create);
460 EXPORT_SYMBOL(RMF_REC_CREATE);
462 const struct req_msg_field RMF_REC_SETATTR =
463 DEFINE_MSGF("rec_setattr", 0, sizeof(struct mdt_rec_setattr),
464 lustre_swab_mdt_rec_setattr);
465 EXPORT_SYMBOL(RMF_REC_SETATTR);
467 /* FIXME: this length should be defined as a macro */
468 const struct req_msg_field RMF_EADATA = DEFINE_MSGF("eadata", 0, -1, NULL);
469 EXPORT_SYMBOL(RMF_EADATA);
471 const struct req_msg_field RMF_ACL = DEFINE_MSGF("acl", 0,
472 __POSIX_ACL_MAX_SIZE, NULL);
473 EXPORT_SYMBOL(RMF_ACL);
475 const struct req_msg_field RMF_LOGCOOKIES =
476 DEFINE_MSGF("logcookies", 0, sizeof(struct llog_cookie), NULL);
477 EXPORT_SYMBOL(RMF_LOGCOOKIES);
479 const struct req_msg_field RMF_REINT_OPC =
480 DEFINE_MSGF("reint_opc", 0, sizeof(__u32), lustre_swab_generic_32s);
481 EXPORT_SYMBOL(RMF_REINT_OPC);
492 const struct req_msg_field **d;
496 #define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) { \
510 #define DEFINE_REQ_FMT0(name, client, server) \
511 DEFINE_REQ_FMT(name, client, ARRAY_SIZE(client), server, ARRAY_SIZE(server))
513 const struct req_format RQF_SEQ_QUERY =
514 DEFINE_REQ_FMT0("SEQ_QUERY", seq_query_client, seq_query_server);
515 EXPORT_SYMBOL(RQF_SEQ_QUERY);
517 const struct req_format RQF_FLD_QUERY =
518 DEFINE_REQ_FMT0("FLD_QUERY", fld_query_client, fld_query_server);
519 EXPORT_SYMBOL(RQF_FLD_QUERY);
521 const struct req_format RQF_MDS_GETSTATUS =
522 DEFINE_REQ_FMT0("MDS_GETSTATUS", empty, mdt_body_only);
523 EXPORT_SYMBOL(RQF_MDS_GETSTATUS);
525 const struct req_format RQF_MDS_STATFS =
526 DEFINE_REQ_FMT0("MDS_STATFS", empty, mds_statfs_server);
527 EXPORT_SYMBOL(RQF_MDS_STATFS);
529 const struct req_format RQF_MDS_SYNC =
530 DEFINE_REQ_FMT0("MDS_SYNC", mdt_body_only, mdt_body_only);
531 EXPORT_SYMBOL(RQF_MDS_SYNC);
533 const struct req_format RQF_MDS_GETATTR =
534 DEFINE_REQ_FMT0("MDS_GETATTR", mdt_body_only, mds_getattr_server);
535 EXPORT_SYMBOL(RQF_MDS_GETATTR);
537 const struct req_format RQF_MDS_GETXATTR =
538 DEFINE_REQ_FMT0("MDS_GETXATTR",
539 mds_getxattr_client, mds_getxattr_server);
540 EXPORT_SYMBOL(RQF_MDS_GETXATTR);
542 const struct req_format RQF_MDS_SETXATTR =
543 DEFINE_REQ_FMT0("MDS_SETXATTR", mds_setxattr_client, empty);
544 EXPORT_SYMBOL(RQF_MDS_SETXATTR);
546 const struct req_format RQF_MDS_GETATTR_NAME =
547 DEFINE_REQ_FMT0("MDS_GETATTR_NAME",
548 mds_getattr_name_client, mds_getattr_server);
549 EXPORT_SYMBOL(RQF_MDS_GETATTR_NAME);
551 const struct req_format RQF_MDS_REINT =
552 DEFINE_REQ_FMT0("MDS_REINT", mds_reint_client, mdt_body_only);
553 EXPORT_SYMBOL(RQF_MDS_REINT);
555 const struct req_format RQF_MDS_REINT_CREATE =
556 DEFINE_REQ_FMT0("MDS_REINT_CREATE",
557 mds_reint_create_client, mdt_body_only);
558 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE);
560 const struct req_format RQF_MDS_REINT_CREATE_SLAVE =
561 DEFINE_REQ_FMT0("MDS_REINT_CREATE_SLAVE",
562 mds_reint_create_slave_client, mdt_body_only);
563 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SLAVE);
565 const struct req_format RQF_MDS_REINT_CREATE_SYM =
566 DEFINE_REQ_FMT0("MDS_REINT_CREATE_SYM",
567 mds_reint_create_sym_client, mdt_body_only);
568 EXPORT_SYMBOL(RQF_MDS_REINT_CREATE_SYM);
570 const struct req_format RQF_MDS_REINT_OPEN =
571 DEFINE_REQ_FMT0("MDS_REINT_OPEN",
572 mds_reint_open_client, mds_reint_open_server);
573 EXPORT_SYMBOL(RQF_MDS_REINT_OPEN);
575 const struct req_format RQF_MDS_REINT_UNLINK =
576 DEFINE_REQ_FMT0("MDS_REINT_UNLINK", mds_reint_unlink_client,
577 mds_last_unlink_server);
578 EXPORT_SYMBOL(RQF_MDS_REINT_UNLINK);
580 const struct req_format RQF_MDS_REINT_LINK =
581 DEFINE_REQ_FMT0("MDS_REINT_LINK",
582 mds_reint_link_client, mdt_body_only);
583 EXPORT_SYMBOL(RQF_MDS_REINT_LINK);
585 const struct req_format RQF_MDS_REINT_RENAME =
586 DEFINE_REQ_FMT0("MDS_REINT_RENAME", mds_reint_rename_client,
587 mds_last_unlink_server);
588 EXPORT_SYMBOL(RQF_MDS_REINT_RENAME);
590 const struct req_format RQF_MDS_REINT_SETATTR =
591 DEFINE_REQ_FMT0("MDS_REINT_SETATTR",
592 mds_reint_setattr_client, mdt_body_only);
593 EXPORT_SYMBOL(RQF_MDS_REINT_SETATTR);
595 const struct req_format RQF_MDS_CONNECT =
596 DEFINE_REQ_FMT0("MDS_CONNECT",
597 mds_connect_client, mds_connect_server);
598 EXPORT_SYMBOL(RQF_MDS_CONNECT);
600 const struct req_format RQF_MDS_DISCONNECT =
601 DEFINE_REQ_FMT0("MDS_DISCONNECT", empty, empty);
602 EXPORT_SYMBOL(RQF_MDS_DISCONNECT);
604 const struct req_format RQF_LDLM_ENQUEUE =
605 DEFINE_REQ_FMT0("LDLM_ENQUEUE",
606 ldlm_enqueue_client, ldlm_enqueue_server);
607 EXPORT_SYMBOL(RQF_LDLM_ENQUEUE);
609 const struct req_format RQF_LDLM_INTENT =
610 DEFINE_REQ_FMT0("LDLM_INTENT",
611 ldlm_intent_client, ldlm_intent_server);
612 EXPORT_SYMBOL(RQF_LDLM_INTENT);
614 const struct req_format RQF_LDLM_INTENT_GETATTR =
615 DEFINE_REQ_FMT0("LDLM_INTENT_GETATTR",
616 ldlm_intent_getattr_client, ldlm_intent_server);
617 EXPORT_SYMBOL(RQF_LDLM_INTENT_GETATTR);
619 const struct req_format RQF_LDLM_INTENT_OPEN =
620 DEFINE_REQ_FMT0("LDLM_INTENT_OPEN",
621 ldlm_intent_open_client, ldlm_intent_server);
622 EXPORT_SYMBOL(RQF_LDLM_INTENT_OPEN);
624 const struct req_format RQF_LDLM_INTENT_CREATE =
625 DEFINE_REQ_FMT0("LDLM_INTENT_CREATE",
626 ldlm_intent_create_client, ldlm_intent_server);
627 EXPORT_SYMBOL(RQF_LDLM_INTENT_CREATE);
629 const struct req_format RQF_LDLM_INTENT_UNLINK =
630 DEFINE_REQ_FMT0("LDLM_INTENT_UNLINK",
631 ldlm_intent_unlink_client, ldlm_intent_server);
632 EXPORT_SYMBOL(RQF_LDLM_INTENT_UNLINK);
634 const struct req_format RQF_MDS_CLOSE =
635 DEFINE_REQ_FMT0("MDS_CLOSE",
636 mdt_close_msg, mds_last_unlink_server);
637 EXPORT_SYMBOL(RQF_MDS_CLOSE);
639 const struct req_format RQF_MDS_PIN =
640 DEFINE_REQ_FMT0("MDS_PIN",
641 mdt_body_only, mdt_body_only);
642 EXPORT_SYMBOL(RQF_MDS_PIN);
644 const struct req_format RQF_MDS_DONE_WRITING =
645 DEFINE_REQ_FMT0("MDS_DONE_WRITING",
646 mdt_close_msg, mdt_body_only);
647 EXPORT_SYMBOL(RQF_MDS_DONE_WRITING);
649 const struct req_format RQF_MDS_READPAGE =
650 DEFINE_REQ_FMT0("MDS_READPAGE",
651 mdt_body_only, mdt_body_only);
652 EXPORT_SYMBOL(RQF_MDS_READPAGE);
654 const struct req_format RQF_MDS_WRITEPAGE =
655 DEFINE_REQ_FMT0("MDS_WRITEPAGE",
656 mdt_body_only, mdt_body_only);
657 EXPORT_SYMBOL(RQF_MDS_WRITEPAGE);
659 const struct req_format RQF_MDS_IS_SUBDIR =
660 DEFINE_REQ_FMT0("MDS_IS_SUBDIR",
661 mdt_body_only, mdt_body_only);
662 EXPORT_SYMBOL(RQF_MDS_IS_SUBDIR);
664 #if !defined(__REQ_LAYOUT_USER__)
666 int req_layout_init(void)
672 for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
673 struct req_format *rf;
675 rf = (struct req_format *)req_formats[i];
677 for (j = 0; j < RCL_NR; ++j) {
678 LASSERT(rf->rf_fields[j].nr <= REQ_MAX_FIELD_NR);
679 for (k = 0; k < rf->rf_fields[j].nr; ++k) {
680 struct req_msg_field *field;
682 field = (typeof(field))rf->rf_fields[j].d[k];
683 LASSERT(field->rmf_offset[i][j] == 0);
685 * k + 1 to detect unused format/field
688 field->rmf_offset[i][j] = k + 1;
694 EXPORT_SYMBOL(req_layout_init);
696 void req_layout_fini(void)
699 EXPORT_SYMBOL(req_layout_fini);
702 * Initialize capsule.
704 * @area is an array of REQ_MAX_FIELD_NR elements, used to store sizes of
705 * variable-sized fields.
707 void req_capsule_init(struct req_capsule *pill,
708 struct ptlrpc_request *req, enum req_location location,
711 LASSERT(location == RCL_SERVER || location == RCL_CLIENT);
713 memset(pill, 0, sizeof *pill);
715 pill->rc_loc = location;
716 pill->rc_area = area;
718 EXPORT_SYMBOL(req_capsule_init);
720 void req_capsule_fini(struct req_capsule *pill)
723 EXPORT_SYMBOL(req_capsule_fini);
725 static int __req_format_is_sane(const struct req_format *fmt)
728 0 <= fmt->rf_idx && fmt->rf_idx < ARRAY_SIZE(req_formats) &&
729 req_formats[fmt->rf_idx] == fmt;
732 static struct lustre_msg *__req_msg(const struct req_capsule *pill,
733 enum req_location loc)
735 struct ptlrpc_request *req;
738 return loc == RCL_CLIENT ? req->rq_reqmsg : req->rq_repmsg;
741 void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt)
743 LASSERT(pill->rc_fmt == NULL);
744 LASSERT(__req_format_is_sane(fmt));
748 EXPORT_SYMBOL(req_capsule_set);
750 int req_capsule_pack(struct req_capsule *pill)
757 const struct req_format *fmt;
759 LASSERT(pill->rc_loc == RCL_SERVER);
761 LASSERT(fmt != NULL);
763 nr = fmt->rf_fields[RCL_SERVER].nr;
764 for (total = 0, i = 0; i < nr; ++i) {
767 size = &pill->rc_area[i];
769 *size = fmt->rf_fields[RCL_SERVER].d[i]->rmf_size;
770 LASSERT(*size != -1);
774 result = lustre_pack_reply(pill->rc_req, nr, pill->rc_area, NULL);
776 DEBUG_REQ(D_ERROR, pill->rc_req,
777 "Cannot pack %d fields (%d bytes) in format `%s': ",
778 nr, total, fmt->rf_name);
782 EXPORT_SYMBOL(req_capsule_pack);
784 static int __req_capsule_offset(const struct req_capsule *pill,
785 const struct req_msg_field *field,
786 enum req_location loc)
790 offset = field->rmf_offset[pill->rc_fmt->rf_idx][loc];
793 LASSERT(0 <= offset && offset < (sizeof(pill->rc_swabbed) << 3));
797 static void *__req_capsule_get(struct req_capsule *pill,
798 const struct req_msg_field *field,
799 enum req_location loc)
801 const struct req_format *fmt;
802 struct lustre_msg *msg;
807 void *(*getter)(struct lustre_msg *m, int n, int minlen);
809 static const char *rcl_names[RCL_NR] = {
810 [RCL_CLIENT] = "client",
811 [RCL_SERVER] = "server"
815 LASSERT(fmt != NULL);
816 LASSERT(__req_format_is_sane(fmt));
818 offset = __req_capsule_offset(pill, field, loc);
820 msg = __req_msg(pill, loc);
822 getter = (field->rmf_flags & RMF_F_STRING) ?
823 (typeof(getter))lustre_msg_string : lustre_msg_buf;
825 len = max(field->rmf_size, 0);
826 value = getter(msg, offset, len);
828 if (!(pill->rc_swabbed & (1 << offset)) && loc != pill->rc_loc &&
829 field->rmf_swabber != NULL && value != NULL &&
830 lustre_msg_swabbed(msg)) {
831 field->rmf_swabber(value);
832 pill->rc_swabbed |= (1 << offset);
835 DEBUG_REQ(D_ERROR, pill->rc_req,
836 "Wrong buffer for field `%s' (%d of %d) "
837 "in format `%s': %d vs. %d (%s)\n",
838 field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name,
839 lustre_msg_buflen(msg, offset), field->rmf_size,
844 void *req_capsule_client_get(struct req_capsule *pill,
845 const struct req_msg_field *field)
847 return __req_capsule_get(pill, field, RCL_CLIENT);
849 EXPORT_SYMBOL(req_capsule_client_get);
851 void *req_capsule_server_get(struct req_capsule *pill,
852 const struct req_msg_field *field)
854 return __req_capsule_get(pill, field, RCL_SERVER);
856 EXPORT_SYMBOL(req_capsule_server_get);
858 const void *req_capsule_other_get(struct req_capsule *pill,
859 const struct req_msg_field *field)
861 return __req_capsule_get(pill, field, pill->rc_loc ^ 1);
863 EXPORT_SYMBOL(req_capsule_other_get);
865 void req_capsule_set_size(const struct req_capsule *pill,
866 const struct req_msg_field *field,
867 enum req_location loc, int size)
869 pill->rc_area[__req_capsule_offset(pill, field, loc)] = size;
871 EXPORT_SYMBOL(req_capsule_set_size);
873 int req_capsule_get_size(const struct req_capsule *pill,
874 const struct req_msg_field *field,
875 enum req_location loc)
877 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
879 return lustre_msg_buflen(__req_msg(pill, loc),
880 __req_capsule_offset(pill, field, loc));
882 EXPORT_SYMBOL(req_capsule_get_size);
884 #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)]
886 void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt)
891 const struct req_format *old;
893 LASSERT(pill->rc_fmt != NULL);
894 LASSERT(__req_format_is_sane(fmt));
900 for (i = 0; i < RCL_NR; ++i) {
901 LASSERT(fmt->rf_fields[i].nr >= old->rf_fields[i].nr);
902 for (j = 0; j < old->rf_fields[i].nr - 1; ++j) {
903 LASSERT(FMT_FIELD(fmt, i, j) == FMT_FIELD(old, i, j));
906 * Last field in old format can be shorter than in new.
908 LASSERT(FMT_FIELD(fmt, i, j)->rmf_size >=
909 FMT_FIELD(old, i, j)->rmf_size);
911 /* last field should be returned to the unswabbed state */
912 pill->rc_swabbed &= ~(__u32)(1 << j);
915 EXPORT_SYMBOL(req_capsule_extend);
917 int req_capsule_has_field(const struct req_capsule *pill,
918 const struct req_msg_field *field,
919 enum req_location loc)
921 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
923 return field->rmf_offset[pill->rc_fmt->rf_idx][loc];
925 EXPORT_SYMBOL(req_capsule_has_field);
927 int req_capsule_field_present(const struct req_capsule *pill,
928 const struct req_msg_field *field,
929 enum req_location loc)
933 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
934 LASSERT(req_capsule_has_field(pill, field, loc));
936 offset = __req_capsule_offset(pill, field, loc);
937 return lustre_msg_bufcount(__req_msg(pill, loc)) > offset;
939 EXPORT_SYMBOL(req_capsule_field_present);
941 /* __REQ_LAYOUT_USER__ */