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_body_capa[] = {
82 static const struct req_msg_field *mdt_close_client[] = {
89 static const struct req_msg_field *mds_statfs_server[] = {
94 static const struct req_msg_field *seq_query_client[] = {
100 static const struct req_msg_field *seq_query_server[] = {
105 static const struct req_msg_field *fld_query_client[] = {
111 static const struct req_msg_field *fld_query_server[] = {
116 static const struct req_msg_field *mds_getattr_name_client[] = {
123 static const struct req_msg_field *mds_reint_client[] = {
128 static const struct req_msg_field *mds_reint_create_client[] = {
135 static const struct req_msg_field *mds_reint_create_rmt_acl_client[] = {
143 static const struct req_msg_field *mds_reint_create_sym_client[] = {
151 static const struct req_msg_field *mds_reint_create_slave_client[] = {
159 static const struct req_msg_field *mds_reint_open_client[] = {
168 static const struct req_msg_field *mds_reint_open_server[] = {
177 static const struct req_msg_field *mds_reint_unlink_client[] = {
184 static const struct req_msg_field *mds_reint_link_client[] = {
192 static const struct req_msg_field *mds_reint_rename_client[] = {
201 static const struct req_msg_field *mds_last_unlink_server[] = {
208 static const struct req_msg_field *mds_reint_setattr_client[] = {
217 static const struct req_msg_field *mds_connect_client[] = {
225 static const struct req_msg_field *mds_connect_server[] = {
230 static const struct req_msg_field *mds_set_info_client[] = {
236 static const struct req_msg_field *ldlm_enqueue_client[] = {
241 static const struct req_msg_field *ldlm_enqueue_server[] = {
246 static const struct req_msg_field *ldlm_intent_client[] = {
253 static const struct req_msg_field *ldlm_intent_server[] = {
262 static const struct req_msg_field *ldlm_intent_open_server[] = {
272 static const struct req_msg_field *ldlm_intent_getattr_client[] = {
276 &RMF_MDT_BODY, /* coincides with mds_getattr_name_client[] */
281 static const struct req_msg_field *ldlm_intent_create_client[] = {
285 &RMF_REC_CREATE, /* coincides with mds_reint_create_client[] */
291 static const struct req_msg_field *ldlm_intent_open_client[] = {
295 &RMF_REC_CREATE, /* coincides with mds_reint_open_client[] */
302 static const struct req_msg_field *ldlm_intent_unlink_client[] = {
306 &RMF_REC_UNLINK, /* coincides with mds_reint_unlink_client[] */
311 static const struct req_msg_field *mds_getxattr_client[] = {
319 static const struct req_msg_field *mds_getxattr_server[] = {
325 static const struct req_msg_field *mds_setxattr_client[] = {
333 static const struct req_msg_field *mds_setxattr_server[] = {
338 static const struct req_msg_field *mds_getattr_server[] = {
346 static const struct req_format *req_formats[] = {
353 &RQF_MDS_GETATTR_NAME,
355 &RQF_MDS_REINT_CREATE,
356 &RQF_MDS_REINT_CREATE_RMT_ACL,
357 &RQF_MDS_REINT_CREATE_SYM,
358 &RQF_MDS_REINT_CREATE_SLAVE,
360 &RQF_MDS_REINT_UNLINK,
362 &RQF_MDS_REINT_RENAME,
363 &RQF_MDS_REINT_SETATTR,
366 &RQF_LDLM_INTENT_GETATTR,
367 &RQF_LDLM_INTENT_OPEN,
368 &RQF_LDLM_INTENT_CREATE,
369 &RQF_LDLM_INTENT_UNLINK,
380 &RQF_MDS_DONE_WRITING
383 struct req_msg_field {
385 const char *rmf_name;
387 * Field length. (-1) means "variable length".
390 void (*rmf_swabber)(void *);
391 int rmf_offset[ARRAY_SIZE(req_formats)][RCL_NR];
395 RMF_F_STRING = 1 << 0
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) \
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);
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);
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);
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);
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);
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);
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);
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);
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);
455 const struct req_msg_field RMF_SETINFO_KEY =
456 DEFINE_MSGF("setinfo_key", 0, -1, NULL);
457 EXPORT_SYMBOL(RMF_SETINFO_KEY);
459 const struct req_msg_field RMF_NAME =
460 DEFINE_MSGF("name", RMF_F_STRING, -1, NULL);
461 EXPORT_SYMBOL(RMF_NAME);
463 const struct req_msg_field RMF_SYMTGT =
464 DEFINE_MSGF("symtgt", RMF_F_STRING, -1, NULL);
465 EXPORT_SYMBOL(RMF_SYMTGT);
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);
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);
476 * connection handle received in MDS_CONNECT request.
480 const struct req_msg_field RMF_CONN =
481 DEFINE_MSGF("conn", 0, sizeof(struct lustre_handle), NULL);
482 EXPORT_SYMBOL(RMF_CONN);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
537 const struct req_msg_field RMF_ACL = DEFINE_MSGF("acl", 0,
538 __POSIX_ACL_MAX_SIZE, NULL);
539 EXPORT_SYMBOL(RMF_ACL);
541 const struct req_msg_field RMF_LOGCOOKIES =
542 DEFINE_MSGF("logcookies", 0, sizeof(struct llog_cookie), NULL);
543 EXPORT_SYMBOL(RMF_LOGCOOKIES);
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);
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);
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);
568 const struct req_msg_field **d;
572 #define DEFINE_REQ_FMT(name, client, client_nr, server, server_nr) { \
586 #define DEFINE_REQ_FMT0(name, client, server) \
587 DEFINE_REQ_FMT(name, client, ARRAY_SIZE(client), server, ARRAY_SIZE(server))
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);
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);
597 const struct req_format RQF_MDS_GETSTATUS =
598 DEFINE_REQ_FMT0("MDS_GETSTATUS", empty, mdt_body_capa);
599 EXPORT_SYMBOL(RQF_MDS_GETSTATUS);
601 const struct req_format RQF_MDS_STATFS =
602 DEFINE_REQ_FMT0("MDS_STATFS", empty, mds_statfs_server);
603 EXPORT_SYMBOL(RQF_MDS_STATFS);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
682 const struct req_format RQF_MDS_DISCONNECT =
683 DEFINE_REQ_FMT0("MDS_DISCONNECT", empty, empty);
684 EXPORT_SYMBOL(RQF_MDS_DISCONNECT);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
751 #if !defined(__REQ_LAYOUT_USER__)
753 int req_layout_init(void)
759 for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
760 struct req_format *rf;
762 rf = (struct req_format *)req_formats[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;
769 field = (typeof(field))rf->rf_fields[j].d[k];
770 LASSERT(field->rmf_offset[i][j] == 0);
772 * k + 1 to detect unused format/field
775 field->rmf_offset[i][j] = k + 1;
781 EXPORT_SYMBOL(req_layout_init);
783 void req_layout_fini(void)
786 EXPORT_SYMBOL(req_layout_fini);
789 * Initialize capsule.
791 * @area is an array of REQ_MAX_FIELD_NR elements, used to store sizes of
792 * variable-sized fields.
794 void req_capsule_init(struct req_capsule *pill,
795 struct ptlrpc_request *req, enum req_location location,
798 LASSERT(location == RCL_SERVER || location == RCL_CLIENT);
800 memset(pill, 0, sizeof *pill);
802 pill->rc_loc = location;
803 pill->rc_area = area;
805 EXPORT_SYMBOL(req_capsule_init);
807 void req_capsule_fini(struct req_capsule *pill)
810 EXPORT_SYMBOL(req_capsule_fini);
812 static int __req_format_is_sane(const struct req_format *fmt)
815 0 <= fmt->rf_idx && fmt->rf_idx < ARRAY_SIZE(req_formats) &&
816 req_formats[fmt->rf_idx] == fmt;
819 static struct lustre_msg *__req_msg(const struct req_capsule *pill,
820 enum req_location loc)
822 struct ptlrpc_request *req;
825 return loc == RCL_CLIENT ? req->rq_reqmsg : req->rq_repmsg;
828 void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt)
830 LASSERT(pill->rc_fmt == NULL);
831 LASSERT(__req_format_is_sane(fmt));
835 EXPORT_SYMBOL(req_capsule_set);
837 int req_capsule_pack(struct req_capsule *pill)
844 const struct req_format *fmt;
846 LASSERT(pill->rc_loc == RCL_SERVER);
848 LASSERT(fmt != NULL);
850 nr = fmt->rf_fields[RCL_SERVER].nr;
851 for (total = 0, i = 0; i < nr; ++i) {
854 size = &pill->rc_area[i];
856 *size = fmt->rf_fields[RCL_SERVER].d[i]->rmf_size;
857 LASSERT(*size != -1);
861 result = lustre_pack_reply(pill->rc_req, nr, pill->rc_area, NULL);
863 DEBUG_REQ(D_ERROR, pill->rc_req,
864 "Cannot pack %d fields (%d bytes) in format `%s': ",
865 nr, total, fmt->rf_name);
869 EXPORT_SYMBOL(req_capsule_pack);
871 static int __req_capsule_offset(const struct req_capsule *pill,
872 const struct req_msg_field *field,
873 enum req_location loc)
877 offset = field->rmf_offset[pill->rc_fmt->rf_idx][loc];
880 LASSERT(0 <= offset && offset < (sizeof(pill->rc_swabbed) << 3));
884 static void *__req_capsule_get(struct req_capsule *pill,
885 const struct req_msg_field *field,
886 enum req_location loc)
888 const struct req_format *fmt;
889 struct lustre_msg *msg;
894 void *(*getter)(struct lustre_msg *m, int n, int minlen);
896 static const char *rcl_names[RCL_NR] = {
897 [RCL_CLIENT] = "client",
898 [RCL_SERVER] = "server"
902 LASSERT(fmt != NULL);
903 LASSERT(__req_format_is_sane(fmt));
905 offset = __req_capsule_offset(pill, field, loc);
907 msg = __req_msg(pill, loc);
909 getter = (field->rmf_flags & RMF_F_STRING) ?
910 (typeof(getter))lustre_msg_string : lustre_msg_buf;
912 len = max(field->rmf_size, 0);
913 value = getter(msg, offset, len);
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);
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,
931 void *req_capsule_client_get(struct req_capsule *pill,
932 const struct req_msg_field *field)
934 return __req_capsule_get(pill, field, RCL_CLIENT);
936 EXPORT_SYMBOL(req_capsule_client_get);
938 void *req_capsule_server_get(struct req_capsule *pill,
939 const struct req_msg_field *field)
941 return __req_capsule_get(pill, field, RCL_SERVER);
943 EXPORT_SYMBOL(req_capsule_server_get);
945 const void *req_capsule_other_get(struct req_capsule *pill,
946 const struct req_msg_field *field)
948 return __req_capsule_get(pill, field, pill->rc_loc ^ 1);
950 EXPORT_SYMBOL(req_capsule_other_get);
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)
956 pill->rc_area[__req_capsule_offset(pill, field, loc)] = size;
958 EXPORT_SYMBOL(req_capsule_set_size);
960 int req_capsule_get_size(const struct req_capsule *pill,
961 const struct req_msg_field *field,
962 enum req_location loc)
964 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
966 return lustre_msg_buflen(__req_msg(pill, loc),
967 __req_capsule_offset(pill, field, loc));
969 EXPORT_SYMBOL(req_capsule_get_size);
971 #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)]
973 void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt)
978 const struct req_format *old;
980 LASSERT(pill->rc_fmt != NULL);
981 LASSERT(__req_format_is_sane(fmt));
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));
993 * Last field in old format can be shorter than in new.
995 LASSERT(FMT_FIELD(fmt, i, j)->rmf_size >=
996 FMT_FIELD(old, i, j)->rmf_size);
998 /* last field should be returned to the unswabbed state */
999 pill->rc_swabbed &= ~(__u32)(1 << j);
1002 EXPORT_SYMBOL(req_capsule_extend);
1004 int req_capsule_has_field(const struct req_capsule *pill,
1005 const struct req_msg_field *field,
1006 enum req_location loc)
1008 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
1010 return field->rmf_offset[pill->rc_fmt->rf_idx][loc];
1012 EXPORT_SYMBOL(req_capsule_has_field);
1014 int req_capsule_field_present(const struct req_capsule *pill,
1015 const struct req_msg_field *field,
1016 enum req_location loc)
1020 LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
1021 LASSERT(req_capsule_has_field(pill, field, loc));
1023 offset = __req_capsule_offset(pill, field, loc);
1024 return lustre_msg_bufcount(__req_msg(pill, loc)) > offset;
1026 EXPORT_SYMBOL(req_capsule_field_present);
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.
1037 int req_capsule_shrink(const struct req_capsule *pill,
1038 const struct req_msg_field *field,
1039 const unsigned int newlen,
1041 const int move_data)
1045 LASSERT(adjust >= 0);
1046 LASSERT(req_capsule_has_field(pill, field, RCL_SERVER));
1048 offset = __req_capsule_offset(pill, field, RCL_SERVER);
1050 LASSERT(offset >= 1);
1052 lustre_shrink_reply(pill->rc_req, offset, newlen, move_data);
1053 return (newlen == 0) ? 1 : 0;
1055 EXPORT_SYMBOL(req_capsule_shrink);
1057 /* __REQ_LAYOUT_USER__ */