1d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
2d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER START
3d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
4d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
6d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is free software; you can redistribute it and/or modify
7d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it under the terms of the GNU General Public License version 2 only,
8d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * as published by the Free Software Foundation.
9d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
10d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is distributed in the hope that it will be useful, but
11d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * WITHOUT ANY WARRANTY; without even the implied warranty of
12d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * General Public License version 2 for more details (a copy is included
14d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * in the LICENSE file that accompanied this code).
15d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
16d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * You should have received a copy of the GNU General Public License
17d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * version 2 along with this program; If not, see
18d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
20d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CA 95054 USA or visit www.sun.com if you need additional information or
22d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * have any questions.
23d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
24d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER END
25d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
26d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
27d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Use is subject to license terms.
29d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
30d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2011, 2012, Intel Corporation.
31d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
32d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
33d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This file is part of Lustre, http://www.lustre.org/
34d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre is a trademark of Sun Microsystems, Inc.
35d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
36d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * lustre/ptlrpc/sec_plain.c
37d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
38d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Author: Eric Mei <ericm@clusterfs.com>
39d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
40d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
41d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define DEBUG_SUBSYSTEM S_SEC
42d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
43d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
44e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd_support.h"
45e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd_cksum.h"
46e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd_class.h"
47e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/lustre_net.h"
48e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/lustre_sec.h"
49d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
50d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct plain_sec {
51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_sec       pls_base;
52d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rwlock_t	    pls_lock;
53d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_cli_ctx  *pls_ctx;
54d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
55d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
56d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic inline struct plain_sec *sec2plsec(struct ptlrpc_sec *sec)
57d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
58d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return container_of(sec, struct plain_sec, pls_base);
59d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
60d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
61d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_sec_policy plain_policy;
62d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_ctx_ops    plain_ctx_ops;
63d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_svc_ctx    plain_svc_ctx;
64d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
65d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic unsigned int plain_at_offset;
66d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
67d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
68d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * for simplicity, plain policy rpc use fixed layout.
69d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
70d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_PACK_SEGMENTS	     (4)
71d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
72d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_PACK_HDR_OFF	      (0)
73d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_PACK_MSG_OFF	      (1)
74d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_PACK_USER_OFF	     (2)
75d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_PACK_BULK_OFF	     (3)
76d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
77d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_FL_USER		   (0x01)
78d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_FL_BULK		   (0x02)
79d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
80d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct plain_header {
81d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    ph_ver;	    /* 0 */
82d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    ph_flags;
83d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    ph_sp;	     /* source */
84d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    ph_bulk_hash_alg;  /* complete flavor desc */
85d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    ph_pad[4];
86d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
87d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
88d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct plain_bulk_token {
89d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u8	    pbt_hash[8];
90d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
91d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
92d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PLAIN_BSD_SIZE \
93d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	(sizeof(struct ptlrpc_bulk_sec_desc) + sizeof(struct plain_bulk_token))
94d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
95d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/****************************************
96d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * bulk checksum helpers		*
97d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ****************************************/
98d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
99d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int plain_unpack_bsd(struct lustre_msg *msg, int swabbed)
100d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_bulk_sec_desc *bsd;
102d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
103d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bulk_sec_desc_unpack(msg, PLAIN_PACK_BULK_OFF, swabbed))
104d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EPROTO;
105d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
106d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd = lustre_msg_buf(msg, PLAIN_PACK_BULK_OFF, PLAIN_BSD_SIZE);
107d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bsd == NULL) {
108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("bulk sec desc has short size %d\n",
109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       lustre_msg_buflen(msg, PLAIN_PACK_BULK_OFF));
110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EPROTO;
111d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bsd->bsd_svc != SPTLRPC_BULK_SVC_NULL &&
114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    bsd->bsd_svc != SPTLRPC_BULK_SVC_INTG) {
115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("invalid bulk svc %u\n", bsd->bsd_svc);
116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EPROTO;
117d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
120d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
122d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int plain_generate_bulk_csum(struct ptlrpc_bulk_desc *desc,
123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    __u8 hash_alg,
124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct plain_bulk_token *token)
125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (hash_alg == BULK_HASH_ALG_NULL)
127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memset(token->pbt_hash, 0, sizeof(token->pbt_hash));
130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return sptlrpc_get_bulk_checksum(desc, hash_alg, token->pbt_hash,
131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					 sizeof(token->pbt_hash));
132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
133d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int plain_verify_bulk_csum(struct ptlrpc_bulk_desc *desc,
135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				  __u8 hash_alg,
136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				  struct plain_bulk_token *tokenr)
137d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_bulk_token tokenv;
139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		     rc;
140d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
141d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (hash_alg == BULK_HASH_ALG_NULL)
142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memset(&tokenv.pbt_hash, 0, sizeof(tokenv.pbt_hash));
145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = sptlrpc_get_bulk_checksum(desc, hash_alg, tokenv.pbt_hash,
146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				       sizeof(tokenv.pbt_hash));
147d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
148d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (memcmp(tokenr->pbt_hash, tokenv.pbt_hash, sizeof(tokenr->pbt_hash)))
151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EACCES;
152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
154d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
155d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void corrupt_bulk_data(struct ptlrpc_bulk_desc *desc)
156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
157d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char	   *ptr;
158d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int    off, i;
159d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
160d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (i = 0; i < desc->bd_iov_count; i++) {
161d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (desc->bd_iov[i].kiov_len == 0)
162d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			continue;
163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ptr = kmap(desc->bd_iov[i].kiov_page);
165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ptr[off] ^= 0x1;
167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		kunmap(desc->bd_iov[i].kiov_page);
168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
169d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/****************************************
173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * cli_ctx apis			 *
174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ****************************************/
175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_ctx_refresh(struct ptlrpc_cli_ctx *ctx)
178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* should never reach here */
180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LBUG();
181d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
183d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
184d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
185d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_ctx_validate(struct ptlrpc_cli_ctx *ctx)
186d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
187d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
191d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req)
192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lustre_msg   *msg = req->rq_reqbuf;
194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_header *phdr;
195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	msg->lm_secflvr = req->rq_flvr.sf_rpc;
197d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
198d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr = lustre_msg_buf(msg, PLAIN_PACK_HDR_OFF, 0);
199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_ver = 0;
200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_flags = 0;
201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_sp = ctx->cc_sec->ps_part;
202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_bulk_hash_alg = req->rq_flvr.u_bulk.hash.hash_alg;
203d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_udesc)
205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		phdr->ph_flags |= PLAIN_FL_USER;
206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_bulk)
207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		phdr->ph_flags |= PLAIN_FL_BULK;
208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
209d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqdata_len = lustre_msg_size_v2(msg->lm_bufcount,
210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						 msg->lm_buflens);
2110a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req)
216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lustre_msg   *msg = req->rq_repdata;
218d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_header *phdr;
219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32		cksum;
220d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		  swabbed;
221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (msg->lm_bufcount != PLAIN_PACK_SEGMENTS) {
223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("unexpected reply buf count %u\n", msg->lm_bufcount);
2240a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
225d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	swabbed = ptlrpc_rep_need_swab(req);
228d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
229d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr = lustre_msg_buf(msg, PLAIN_PACK_HDR_OFF, sizeof(*phdr));
230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr == NULL) {
231d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("missing plain header\n");
2320a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_ver != 0) {
236d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Invalid header version\n");
2370a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
238d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
239d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* expect no user desc in reply */
241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_flags & PLAIN_FL_USER) {
242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Unexpected udesc flag in reply\n");
2430a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_bulk_hash_alg != req->rq_flvr.u_bulk.hash.hash_alg) {
247d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("reply bulk flavor %u != %u\n", phdr->ph_bulk_hash_alg,
248d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       req->rq_flvr.u_bulk.hash.hash_alg);
2490a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
252d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (unlikely(req->rq_early)) {
253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		unsigned int hsize = 4;
254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
255d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
257d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
258d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				NULL, 0, (unsigned char *)&cksum, &hsize);
259d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (cksum != msg->lm_cksum) {
260d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CDEBUG(D_SEC,
261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "early reply checksum mismatch: %08x != %08x\n",
262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       cpu_to_le32(cksum), msg->lm_cksum);
2630a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -EINVAL;
264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
266d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* whether we sent with bulk or not, we expect the same
267d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * in reply, except for early reply */
268d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!req->rq_early &&
269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    !equi(req->rq_pack_bulk == 1,
270d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  phdr->ph_flags & PLAIN_FL_BULK)) {
271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CERROR("%s bulk checksum in reply\n",
272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       req->rq_pack_bulk ? "Missing" : "Unexpected");
2730a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -EPROTO;
274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
275d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
276d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (phdr->ph_flags & PLAIN_FL_BULK) {
277d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (plain_unpack_bsd(msg, swabbed))
2780a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman				return -EPROTO;
279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_repmsg = lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0);
283d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_replen = lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF);
2840a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
285d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
286d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
287d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
288d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_cli_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			struct ptlrpc_request *req,
290d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			struct ptlrpc_bulk_desc *desc)
291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_bulk_sec_desc *bsd;
293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_bulk_token     *token;
294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  rc;
295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_pack_bulk);
297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_reqbuf->lm_bufcount == PLAIN_PACK_SEGMENTS);
298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
299d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd = lustre_msg_buf(req->rq_reqbuf, PLAIN_PACK_BULK_OFF, 0);
300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	token = (struct plain_bulk_token *) bsd->bsd_data;
301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd->bsd_version = 0;
303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd->bsd_flags = 0;
304d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd->bsd_type = SPTLRPC_BULK_DEFAULT;
305d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsd->bsd_svc = SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc);
306d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
307d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bsd->bsd_svc == SPTLRPC_BULK_SVC_NULL)
3080a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_bulk_read)
3110a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
313d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = plain_generate_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg,
314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				      token);
315d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
316d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("bulk write: failed to compute checksum: %d\n", rc);
317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/*
319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * for sending we only compute the wrong checksum instead
320d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * of corrupting the data so it is still correct on a redo
321d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 */
322d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_SEND) &&
323d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    req->rq_flvr.u_bulk.hash.hash_alg != BULK_HASH_ALG_NULL)
324d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			token->pbt_hash[0] ^= 0x1;
325d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
327d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
329d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
331d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_cli_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
332d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  struct ptlrpc_request *req,
333d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  struct ptlrpc_bulk_desc *desc)
334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
335d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_bulk_sec_desc *bsdv;
336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_bulk_token     *tokenv;
337d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  rc;
338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  i, nob;
339d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
340d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_pack_bulk);
341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_reqbuf->lm_bufcount == PLAIN_PACK_SEGMENTS);
342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_repdata->lm_bufcount == PLAIN_PACK_SEGMENTS);
343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv = lustre_msg_buf(req->rq_repdata, PLAIN_PACK_BULK_OFF, 0);
345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	tokenv = (struct plain_bulk_token *) bsdv->bsd_data;
346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_bulk_write) {
348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (bsdv->bsd_flags & BSD_FL_ERR)
349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return -EIO;
350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fix the actual data size */
354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
355d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (desc->bd_iov[i].kiov_len + nob > desc->bd_nob_transferred) {
356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			desc->bd_iov[i].kiov_len =
357d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				desc->bd_nob_transferred - nob;
358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		nob += desc->bd_iov[i].kiov_len;
360d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
362d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = plain_verify_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg,
363d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    tokenv);
364d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
365d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("bulk read: client verify failed: %d\n", rc);
366d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
367d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
368d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
369d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
370d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/****************************************
371d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * sec apis			     *
372d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ****************************************/
373d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
374d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
375d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ptlrpc_cli_ctx *plain_sec_install_ctx(struct plain_sec *plsec)
376d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
377d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_cli_ctx  *ctx, *ctx_new;
378d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
379d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC_PTR(ctx_new);
380d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
381d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	write_lock(&plsec->pls_lock);
382d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
383d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ctx = plsec->pls_ctx;
384d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ctx) {
385d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_inc(&ctx->cc_refcount);
386d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
387d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (ctx_new)
388d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			OBD_FREE_PTR(ctx_new);
389d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (ctx_new) {
390d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx = ctx_new;
391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_set(&ctx->cc_refcount, 1); /* for cache */
393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx->cc_sec = &plsec->pls_base;
394d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx->cc_ops = &plain_ctx_ops;
395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx->cc_expire = 0;
396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx->cc_flags = PTLRPC_CTX_CACHED | PTLRPC_CTX_UPTODATE;
397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx->cc_vcred.vc_uid = 0;
398d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_lock_init(&ctx->cc_lock);
399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		INIT_LIST_HEAD(&ctx->cc_req_list);
400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		INIT_LIST_HEAD(&ctx->cc_gc_chain);
401d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
402d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		plsec->pls_ctx = ctx;
403d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_inc(&plsec->pls_base.ps_nctx);
404d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_inc(&plsec->pls_base.ps_refcount);
405d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_inc(&ctx->cc_refcount); /* for caller */
407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
409d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	write_unlock(&plsec->pls_lock);
410d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ctx;
412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
415d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_destroy_sec(struct ptlrpc_sec *sec)
416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
417d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_sec       *plsec = sec2plsec(sec);
418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
419d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(sec->ps_policy == &plain_policy);
420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(sec->ps_import);
421d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&sec->ps_refcount) == 0);
422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&sec->ps_nctx) == 0);
423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(plsec->pls_ctx == NULL);
424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	class_import_put(sec->ps_import);
426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE_PTR(plsec);
428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
431d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_kill_sec(struct ptlrpc_sec *sec)
432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_dying = 1;
434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ptlrpc_sec *plain_create_sec(struct obd_import *imp,
438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct ptlrpc_svc_ctx *svc_ctx,
439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct sptlrpc_flavor *sf)
440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_sec       *plsec;
442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_sec      *sec;
443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_cli_ctx  *ctx;
444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(SPTLRPC_FLVR_POLICY(sf->sf_rpc) == SPTLRPC_POLICY_PLAIN);
446d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
447d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC_PTR(plsec);
448d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (plsec == NULL)
4490a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return NULL;
450d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
451d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/*
452d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * initialize plain_sec
453d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
454d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rwlock_init(&plsec->pls_lock);
455d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	plsec->pls_ctx = NULL;
456d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
457d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec = &plsec->pls_base;
458d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_policy = &plain_policy;
459d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_set(&sec->ps_refcount, 0);
460d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_set(&sec->ps_nctx, 0);
461d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_id = sptlrpc_get_next_secid();
462d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_import = class_import_get(imp);
463d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_flvr = *sf;
464d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock_init(&sec->ps_lock);
465d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	INIT_LIST_HEAD(&sec->ps_gc_list);
466d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_gc_interval = 0;
467d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sec->ps_gc_next = 0;
468d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
469d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* install ctx immediately if this is a reverse sec */
470d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc_ctx) {
471d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx = plain_sec_install_ctx(plsec);
472d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (ctx == NULL) {
473d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			plain_destroy_sec(sec);
4740a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return NULL;
475d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
476d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		sptlrpc_cli_ctx_put(ctx, 1);
477d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
478d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
4790a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return sec;
480d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
481d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
482d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
483d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ptlrpc_cli_ctx *plain_lookup_ctx(struct ptlrpc_sec *sec,
484d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					struct vfs_cred *vcred,
485d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					int create, int remove_dead)
486d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
487d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_sec       *plsec = sec2plsec(sec);
488d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_cli_ctx  *ctx;
489d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
490d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	read_lock(&plsec->pls_lock);
491d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ctx = plsec->pls_ctx;
492d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ctx)
493d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		atomic_inc(&ctx->cc_refcount);
494d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	read_unlock(&plsec->pls_lock);
495d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
496d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (unlikely(ctx == NULL))
497d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ctx = plain_sec_install_ctx(plsec);
498d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
4990a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return ctx;
500d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
501d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
502d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
503d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_release_ctx(struct ptlrpc_sec *sec,
504d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       struct ptlrpc_cli_ctx *ctx, int sync)
505d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
506d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&sec->ps_refcount) > 0);
507d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&sec->ps_nctx) > 0);
508d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&ctx->cc_refcount) == 0);
509d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(ctx->cc_sec == sec);
510d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
511d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE_PTR(ctx);
512d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
513d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_dec(&sec->ps_nctx);
514d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	sptlrpc_sec_put(sec);
515d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
516d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
517d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
518d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_flush_ctx_cache(struct ptlrpc_sec *sec,
519d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  uid_t uid, int grace, int force)
520d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
521d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_sec       *plsec = sec2plsec(sec);
522d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_cli_ctx  *ctx;
523d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
524d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* do nothing unless caller want to flush for 'all' */
525d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (uid != -1)
5260a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
527d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
528d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	write_lock(&plsec->pls_lock);
529d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ctx = plsec->pls_ctx;
530d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	plsec->pls_ctx = NULL;
531d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	write_unlock(&plsec->pls_lock);
532d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
533d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ctx)
534d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		sptlrpc_cli_ctx_put(ctx, 1);
5350a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
536d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
537d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
538d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
539d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_alloc_reqbuf(struct ptlrpc_sec *sec,
540d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       struct ptlrpc_request *req,
541d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       int msgsize)
542d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
543d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, };
544d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int   alloc_len;
545d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
546d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_HDR_OFF] = sizeof(struct plain_header);
547d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_MSG_OFF] = msgsize;
548d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
549d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_udesc)
550d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		buflens[PLAIN_PACK_USER_OFF] = sptlrpc_current_user_desc_size();
551d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
552d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_bulk) {
553d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(req->rq_bulk_read || req->rq_bulk_write);
554d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		buflens[PLAIN_PACK_BULK_OFF] = PLAIN_BSD_SIZE;
555d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
556d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
557d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	alloc_len = lustre_msg_size_v2(PLAIN_PACK_SEGMENTS, buflens);
558d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
559d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!req->rq_reqbuf) {
560d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(!req->rq_pool);
561d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
562d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		alloc_len = size_roundup_power2(alloc_len);
563d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_ALLOC_LARGE(req->rq_reqbuf, alloc_len);
564d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!req->rq_reqbuf)
5650a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -ENOMEM;
566d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
567d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqbuf_len = alloc_len;
568d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
569d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(req->rq_pool);
570d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(req->rq_reqbuf_len >= alloc_len);
571d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memset(req->rq_reqbuf, 0, alloc_len);
572d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
573d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
574d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lustre_init_msg_v2(req->rq_reqbuf, PLAIN_PACK_SEGMENTS, buflens, NULL);
575d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, PLAIN_PACK_MSG_OFF, 0);
576d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
577d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_udesc)
578d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		sptlrpc_pack_user_desc(req->rq_reqbuf, PLAIN_PACK_USER_OFF);
579d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
5800a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
581d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
582d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
583d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
584d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_free_reqbuf(struct ptlrpc_sec *sec,
585d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       struct ptlrpc_request *req)
586d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
587d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!req->rq_pool) {
588d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
589d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqbuf = NULL;
590d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqbuf_len = 0;
591d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
592d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
593d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
594d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
595d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_alloc_repbuf(struct ptlrpc_sec *sec,
596d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       struct ptlrpc_request *req,
597d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       int msgsize)
598d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
599d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, };
600d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int alloc_len;
601d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
602d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_HDR_OFF] = sizeof(struct plain_header);
603d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_MSG_OFF] = msgsize;
604d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
605d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_bulk) {
606d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(req->rq_bulk_read || req->rq_bulk_write);
607d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		buflens[PLAIN_PACK_BULK_OFF] = PLAIN_BSD_SIZE;
608d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
609d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
610d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	alloc_len = lustre_msg_size_v2(PLAIN_PACK_SEGMENTS, buflens);
611d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
612d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* add space for early reply */
613d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	alloc_len += plain_at_offset;
614d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
615d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	alloc_len = size_roundup_power2(alloc_len);
616d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
617d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC_LARGE(req->rq_repbuf, alloc_len);
618d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!req->rq_repbuf)
6190a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -ENOMEM;
620d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
621d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_repbuf_len = alloc_len;
6220a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
623d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
624d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
625d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
626d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_free_repbuf(struct ptlrpc_sec *sec,
627d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       struct ptlrpc_request *req)
628d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
629d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE_LARGE(req->rq_repbuf, req->rq_repbuf_len);
630d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_repbuf = NULL;
631d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_repbuf_len = 0;
632d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
633d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
634d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
635d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_enlarge_reqbuf(struct ptlrpc_sec *sec,
636d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 struct ptlrpc_request *req,
637d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 int segment, int newsize)
638d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
639d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lustre_msg      *newbuf;
640d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		     oldsize;
641d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		     newmsg_size, newbuf_size;
642d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
643d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_reqbuf);
644d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_reqbuf_len >= req->rq_reqlen);
645d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(lustre_msg_buf(req->rq_reqbuf, PLAIN_PACK_MSG_OFF, 0) ==
646d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqmsg);
647d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
648d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* compute new embedded msg size.  */
649d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	oldsize = req->rq_reqmsg->lm_buflens[segment];
650d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqmsg->lm_buflens[segment] = newsize;
651d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	newmsg_size = lustre_msg_size_v2(req->rq_reqmsg->lm_bufcount,
652d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					 req->rq_reqmsg->lm_buflens);
653d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqmsg->lm_buflens[segment] = oldsize;
654d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
655d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* compute new wrapper msg size.  */
656d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	oldsize = req->rq_reqbuf->lm_buflens[PLAIN_PACK_MSG_OFF];
657d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqbuf->lm_buflens[PLAIN_PACK_MSG_OFF] = newmsg_size;
658d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	newbuf_size = lustre_msg_size_v2(req->rq_reqbuf->lm_bufcount,
659d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					 req->rq_reqbuf->lm_buflens);
660d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqbuf->lm_buflens[PLAIN_PACK_MSG_OFF] = oldsize;
661d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
662d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* request from pool should always have enough buffer */
663d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(!req->rq_pool || req->rq_reqbuf_len >= newbuf_size);
664d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
665d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_reqbuf_len < newbuf_size) {
666d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		newbuf_size = size_roundup_power2(newbuf_size);
667d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
668d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_ALLOC_LARGE(newbuf, newbuf_size);
669d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (newbuf == NULL)
6700a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -ENOMEM;
671d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
67261d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		/* Must lock this, so that otherwise unprotected change of
67361d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		 * rq_reqmsg is not racing with parallel processing of
67461d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		 * imp_replay_list traversing threads. See LU-3333
67561d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		 * This is a bandaid at best, we really need to deal with this
67661d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		 * in request enlarging code before unpacking that's already
67761d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		 * there */
67861d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		if (req->rq_import)
67961d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin			spin_lock(&req->rq_import->imp_lock);
68061d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin
681d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memcpy(newbuf, req->rq_reqbuf, req->rq_reqbuf_len);
682d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
683d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
684d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqbuf = newbuf;
685d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqbuf_len = newbuf_size;
686d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf,
687d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						PLAIN_PACK_MSG_OFF, 0);
68861d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin
68961d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin		if (req->rq_import)
69061d7258bf144ff388f51d0a3b295a7493fe10035Oleg Drokin			spin_unlock(&req->rq_import->imp_lock);
691d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
692d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
693d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	_sptlrpc_enlarge_msg_inplace(req->rq_reqbuf, PLAIN_PACK_MSG_OFF,
694d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     newmsg_size);
695d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	_sptlrpc_enlarge_msg_inplace(req->rq_reqmsg, segment, newsize);
696d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
697d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqlen = newmsg_size;
6980a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
699d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
700d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
701d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/****************************************
702d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * service apis			 *
703d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao ****************************************/
704d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
705d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_svc_ctx plain_svc_ctx = {
706d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sc_refcount    = ATOMIC_INIT(1),
707d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sc_policy      = &plain_policy,
708d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
709d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
710d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
711d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_accept(struct ptlrpc_request *req)
712d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
713d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lustre_msg   *msg = req->rq_reqbuf;
714d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_header *phdr;
715d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		  swabbed;
716d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
717d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc) ==
718d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		SPTLRPC_POLICY_PLAIN);
719d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
720d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (SPTLRPC_FLVR_BASE(req->rq_flvr.sf_rpc) !=
721d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_PLAIN) ||
722d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    SPTLRPC_FLVR_BULK_TYPE(req->rq_flvr.sf_rpc) !=
723d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    SPTLRPC_FLVR_BULK_TYPE(SPTLRPC_FLVR_PLAIN)) {
724d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Invalid rpc flavor %x\n", req->rq_flvr.sf_rpc);
7250a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return SECSVC_DROP;
726d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
727d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
728d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (msg->lm_bufcount < PLAIN_PACK_SEGMENTS) {
729d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("unexpected request buf count %u\n", msg->lm_bufcount);
7300a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return SECSVC_DROP;
731d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
732d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
733d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	swabbed = ptlrpc_req_need_swab(req);
734d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
735d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr = lustre_msg_buf(msg, PLAIN_PACK_HDR_OFF, sizeof(*phdr));
736d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr == NULL) {
737d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("missing plain header\n");
7380a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
739d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
740d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
741d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_ver != 0) {
742d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Invalid header version\n");
7430a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
744d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
745d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
746d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_bulk_hash_alg >= BULK_HASH_ALG_MAX) {
747d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("invalid hash algorithm: %u\n", phdr->ph_bulk_hash_alg);
7480a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPROTO;
749d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
750d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
751d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_sp_from = phdr->ph_sp;
752d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_flvr.u_bulk.hash.hash_alg = phdr->ph_bulk_hash_alg;
753d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
754d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_flags & PLAIN_FL_USER) {
755d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (sptlrpc_unpack_user_desc(msg, PLAIN_PACK_USER_OFF,
756d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					     swabbed)) {
757d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CERROR("Mal-formed user descriptor\n");
7580a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return SECSVC_DROP;
759d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
760d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
761d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_pack_udesc = 1;
762d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_user_desc = lustre_msg_buf(msg, PLAIN_PACK_USER_OFF, 0);
763d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
764d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
765d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (phdr->ph_flags & PLAIN_FL_BULK) {
766d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (plain_unpack_bsd(msg, swabbed))
7670a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return SECSVC_DROP;
768d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
769d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req->rq_pack_bulk = 1;
770d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
771d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
772d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqmsg = lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0);
773d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reqlen = msg->lm_buflens[PLAIN_PACK_MSG_OFF];
774d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
775d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_svc_ctx = &plain_svc_ctx;
776d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_inc(&req->rq_svc_ctx->sc_refcount);
777d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
7780a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return SECSVC_OK;
779d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
780d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
781d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
782d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_alloc_rs(struct ptlrpc_request *req, int msgsize)
783d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
784d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_reply_state   *rs;
785d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32			buflens[PLAIN_PACK_SEGMENTS] = { 0, };
786d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  rs_size = sizeof(*rs);
787d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
788d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(msgsize % 8 == 0);
789d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
790d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_HDR_OFF] = sizeof(struct plain_header);
791d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_MSG_OFF] = msgsize;
792d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
793d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_bulk && (req->rq_bulk_read || req->rq_bulk_write))
794d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		buflens[PLAIN_PACK_BULK_OFF] = PLAIN_BSD_SIZE;
795d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
796d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs_size += lustre_msg_size_v2(PLAIN_PACK_SEGMENTS, buflens);
797d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
798d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs = req->rq_reply_state;
799d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
800d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rs) {
801d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* pre-allocated */
802d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(rs->rs_size >= rs_size);
803d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
804d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_ALLOC_LARGE(rs, rs_size);
805d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rs == NULL)
8060a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -ENOMEM;
807d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
808d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rs->rs_size = rs_size;
809d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
810d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
811d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs->rs_svc_ctx = req->rq_svc_ctx;
812d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_inc(&req->rq_svc_ctx->sc_refcount);
813d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs->rs_repbuf = (struct lustre_msg *) (rs + 1);
814d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs->rs_repbuf_len = rs_size - sizeof(*rs);
815d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
816d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lustre_init_msg_v2(rs->rs_repbuf, PLAIN_PACK_SEGMENTS, buflens, NULL);
817d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs->rs_msg = lustre_msg_buf_v2(rs->rs_repbuf, PLAIN_PACK_MSG_OFF, 0);
818d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
819d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_reply_state = rs;
8200a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
821d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
822d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
823d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
824d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid plain_free_rs(struct ptlrpc_reply_state *rs)
825d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
826d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(atomic_read(&rs->rs_svc_ctx->sc_refcount) > 1);
827d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	atomic_dec(&rs->rs_svc_ctx->sc_refcount);
828d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
829d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!rs->rs_prealloc)
830d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE_LARGE(rs, rs->rs_size);
831d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
832d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
833d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
834d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_authorize(struct ptlrpc_request *req)
835d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
836d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_reply_state *rs = req->rq_reply_state;
837d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lustre_msg_v2      *msg = rs->rs_repbuf;
838d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_header       *phdr;
839d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			len;
840d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
841d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(rs);
842d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(msg);
843d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
844d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_replen != msg->lm_buflens[PLAIN_PACK_MSG_OFF])
845d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		len = lustre_shrink_msg(msg, PLAIN_PACK_MSG_OFF,
846d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					req->rq_replen, 1);
847d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
848d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		len = lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
849d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
850d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	msg->lm_secflvr = req->rq_flvr.sf_rpc;
851d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
852d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr = lustre_msg_buf(msg, PLAIN_PACK_HDR_OFF, 0);
853d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_ver = 0;
854d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_flags = 0;
855d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	phdr->ph_bulk_hash_alg = req->rq_flvr.u_bulk.hash.hash_alg;
856d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
857d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req->rq_pack_bulk)
858d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		phdr->ph_flags |= PLAIN_FL_BULK;
859d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
860d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rs->rs_repdata_len = len;
861d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
862d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (likely(req->rq_packed_final)) {
863d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)
864d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			req->rq_reply_off = plain_at_offset;
865d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		else
866d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			req->rq_reply_off = 0;
867d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
868d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		unsigned int hsize = 4;
869d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
870d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
871d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
872d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
873d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			NULL, 0, (unsigned char *)&msg->lm_cksum, &hsize);
874d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			req->rq_reply_off = 0;
875d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
876d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
8770a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
878d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
879d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
880d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
881d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_svc_unwrap_bulk(struct ptlrpc_request *req,
882d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  struct ptlrpc_bulk_desc *desc)
883d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
884d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_reply_state   *rs = req->rq_reply_state;
885d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
886d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_bulk_token     *tokenr;
887d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  rc;
888d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
889d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_bulk_write);
890d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_pack_bulk);
891d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
892d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdr = lustre_msg_buf(req->rq_reqbuf, PLAIN_PACK_BULK_OFF, 0);
893d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	tokenr = (struct plain_bulk_token *) bsdr->bsd_data;
894d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv = lustre_msg_buf(rs->rs_repbuf, PLAIN_PACK_BULK_OFF, 0);
895d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
896d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_version = 0;
897d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
898d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_svc = bsdr->bsd_svc;
899d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_flags = 0;
900d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
901d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bsdr->bsd_svc == SPTLRPC_BULK_SVC_NULL)
902d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
903d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
904d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = plain_verify_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg,
905d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    tokenr);
906d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
907d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		bsdv->bsd_flags |= BSD_FL_ERR;
908d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("bulk write: server verify failed: %d\n", rc);
909d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
910d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
911d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
912d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
913d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
914d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic
915d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint plain_svc_wrap_bulk(struct ptlrpc_request *req,
916d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			struct ptlrpc_bulk_desc *desc)
917d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
918d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_reply_state   *rs = req->rq_reply_state;
919d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
920d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct plain_bulk_token     *tokenv;
921d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			  rc;
922d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
923d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_bulk_read);
924d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(req->rq_pack_bulk);
925d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
926d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdr = lustre_msg_buf(req->rq_reqbuf, PLAIN_PACK_BULK_OFF, 0);
927d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv = lustre_msg_buf(rs->rs_repbuf, PLAIN_PACK_BULK_OFF, 0);
928d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	tokenv = (struct plain_bulk_token *) bsdv->bsd_data;
929d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
930d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_version = 0;
931d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
932d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_svc = bsdr->bsd_svc;
933d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bsdv->bsd_flags = 0;
934d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
935d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (bsdr->bsd_svc == SPTLRPC_BULK_SVC_NULL)
936d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
937d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
938d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = plain_generate_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg,
939d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				      tokenv);
940d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
941d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("bulk read: server failed to compute "
942d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       "checksum: %d\n", rc);
943d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
944d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE))
945d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			corrupt_bulk_data(desc);
946d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
947d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
948d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
949d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
950d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
951d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_ctx_ops plain_ctx_ops = {
952d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.refresh		= plain_ctx_refresh,
953d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.validate	       = plain_ctx_validate,
954d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sign		   = plain_ctx_sign,
955d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.verify		 = plain_ctx_verify,
956d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.wrap_bulk	      = plain_cli_wrap_bulk,
957d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.unwrap_bulk	    = plain_cli_unwrap_bulk,
958d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
959d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
960d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_sec_cops plain_sec_cops = {
961d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.create_sec	     = plain_create_sec,
962d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.destroy_sec	    = plain_destroy_sec,
963d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.kill_sec	       = plain_kill_sec,
964d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.lookup_ctx	     = plain_lookup_ctx,
965d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.release_ctx	    = plain_release_ctx,
966d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.flush_ctx_cache	= plain_flush_ctx_cache,
967d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.alloc_reqbuf	   = plain_alloc_reqbuf,
968d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.free_reqbuf	    = plain_free_reqbuf,
969d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.alloc_repbuf	   = plain_alloc_repbuf,
970d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.free_repbuf	    = plain_free_repbuf,
971d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.enlarge_reqbuf	 = plain_enlarge_reqbuf,
972d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
973d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
974d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_sec_sops plain_sec_sops = {
975d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.accept		 = plain_accept,
976d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.alloc_rs	       = plain_alloc_rs,
977d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.authorize	      = plain_authorize,
978d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.free_rs		= plain_free_rs,
979d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.unwrap_bulk	    = plain_svc_unwrap_bulk,
980d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.wrap_bulk	      = plain_svc_wrap_bulk,
981d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
982d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
983d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct ptlrpc_sec_policy plain_policy = {
984d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sp_owner	       = THIS_MODULE,
985d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sp_name		= "plain",
986d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sp_policy	      = SPTLRPC_POLICY_PLAIN,
987d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sp_cops		= &plain_sec_cops,
988d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.sp_sops		= &plain_sec_sops,
989d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
990d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
991d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint sptlrpc_plain_init(void)
992d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
993d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32 buflens[PLAIN_PACK_SEGMENTS] = { 0, };
994d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
995d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
996d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	buflens[PLAIN_PACK_MSG_OFF] = lustre_msg_early_size();
997d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	plain_at_offset = lustre_msg_size_v2(PLAIN_PACK_SEGMENTS, buflens);
998d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
999d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = sptlrpc_register_policy(&plain_policy);
1000d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
1001d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("failed to register: %d\n", rc);
1002d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1003d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1004d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1005d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1006d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid sptlrpc_plain_fini(void)
1007d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1008d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
1009d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1010d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = sptlrpc_unregister_policy(&plain_policy);
1011d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
1012d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("cannot unregister: %d\n", rc);
1013d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1014