4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/ptlrpc/sec_null.c
38 * Author: Eric Mei <ericm@clusterfs.com>
41 #define DEBUG_SUBSYSTEM S_SEC
44 #include "../include/obd_support.h"
45 #include "../include/obd_cksum.h"
46 #include "../include/obd_class.h"
47 #include "../include/lustre_net.h"
48 #include "../include/lustre_sec.h"
50 static struct ptlrpc_sec_policy null_policy
;
51 static struct ptlrpc_sec null_sec
;
52 static struct ptlrpc_cli_ctx null_cli_ctx
;
53 static struct ptlrpc_svc_ctx null_svc_ctx
;
56 * we can temporarily use the topmost 8-bits of lm_secflvr to identify
57 * the source sec part.
60 void null_encode_sec_part(struct lustre_msg
*msg
, enum lustre_sec_part sp
)
62 msg
->lm_secflvr
|= (((__u32
) sp
) & 0xFF) << 24;
66 enum lustre_sec_part
null_decode_sec_part(struct lustre_msg
*msg
)
68 return (msg
->lm_secflvr
>> 24) & 0xFF;
71 static int null_ctx_refresh(struct ptlrpc_cli_ctx
*ctx
)
73 /* should never reach here */
79 int null_ctx_sign(struct ptlrpc_cli_ctx
*ctx
, struct ptlrpc_request
*req
)
81 req
->rq_reqbuf
->lm_secflvr
= SPTLRPC_FLVR_NULL
;
83 if (!req
->rq_import
->imp_dlm_fake
) {
84 struct obd_device
*obd
= req
->rq_import
->imp_obd
;
85 null_encode_sec_part(req
->rq_reqbuf
,
88 req
->rq_reqdata_len
= req
->rq_reqlen
;
93 int null_ctx_verify(struct ptlrpc_cli_ctx
*ctx
, struct ptlrpc_request
*req
)
97 LASSERT(req
->rq_repdata
);
99 req
->rq_repmsg
= req
->rq_repdata
;
100 req
->rq_replen
= req
->rq_repdata_len
;
103 cksums
= lustre_msg_get_cksum(req
->rq_repdata
);
104 cksumc
= lustre_msg_calc_cksum(req
->rq_repmsg
);
105 if (cksumc
!= cksums
) {
107 "early reply checksum mismatch: %08x != %08x\n",
117 struct ptlrpc_sec
*null_create_sec(struct obd_import
*imp
,
118 struct ptlrpc_svc_ctx
*svc_ctx
,
119 struct sptlrpc_flavor
*sf
)
121 LASSERT(SPTLRPC_FLVR_POLICY(sf
->sf_rpc
) == SPTLRPC_POLICY_NULL
);
123 /* general layer has take a module reference for us, because we never
124 * really destroy the sec, simply release the reference here.
126 sptlrpc_policy_put(&null_policy
);
131 void null_destroy_sec(struct ptlrpc_sec
*sec
)
133 LASSERT(sec
== &null_sec
);
137 struct ptlrpc_cli_ctx
*null_lookup_ctx(struct ptlrpc_sec
*sec
,
138 struct vfs_cred
*vcred
,
139 int create
, int remove_dead
)
141 atomic_inc(&null_cli_ctx
.cc_refcount
);
142 return &null_cli_ctx
;
146 int null_flush_ctx_cache(struct ptlrpc_sec
*sec
,
148 int grace
, int force
)
154 int null_alloc_reqbuf(struct ptlrpc_sec
*sec
,
155 struct ptlrpc_request
*req
,
158 if (!req
->rq_reqbuf
) {
159 int alloc_size
= size_roundup_power2(msgsize
);
161 LASSERT(!req
->rq_pool
);
162 req
->rq_reqbuf
= libcfs_kvzalloc(alloc_size
, GFP_NOFS
);
166 req
->rq_reqbuf_len
= alloc_size
;
168 LASSERT(req
->rq_pool
);
169 LASSERT(req
->rq_reqbuf_len
>= msgsize
);
170 memset(req
->rq_reqbuf
, 0, msgsize
);
173 req
->rq_reqmsg
= req
->rq_reqbuf
;
178 void null_free_reqbuf(struct ptlrpc_sec
*sec
,
179 struct ptlrpc_request
*req
)
182 LASSERTF(req
->rq_reqmsg
== req
->rq_reqbuf
,
183 "req %p: reqmsg %p is not reqbuf %p in null sec\n",
184 req
, req
->rq_reqmsg
, req
->rq_reqbuf
);
185 LASSERTF(req
->rq_reqbuf_len
>= req
->rq_reqlen
,
186 "req %p: reqlen %d should smaller than buflen %d\n",
187 req
, req
->rq_reqlen
, req
->rq_reqbuf_len
);
189 kvfree(req
->rq_reqbuf
);
190 req
->rq_reqbuf
= NULL
;
191 req
->rq_reqbuf_len
= 0;
196 int null_alloc_repbuf(struct ptlrpc_sec
*sec
,
197 struct ptlrpc_request
*req
,
200 /* add space for early replied */
201 msgsize
+= lustre_msg_early_size();
203 msgsize
= size_roundup_power2(msgsize
);
205 req
->rq_repbuf
= libcfs_kvzalloc(msgsize
, GFP_NOFS
);
209 req
->rq_repbuf_len
= msgsize
;
214 void null_free_repbuf(struct ptlrpc_sec
*sec
,
215 struct ptlrpc_request
*req
)
217 LASSERT(req
->rq_repbuf
);
219 kvfree(req
->rq_repbuf
);
220 req
->rq_repbuf
= NULL
;
221 req
->rq_repbuf_len
= 0;
225 int null_enlarge_reqbuf(struct ptlrpc_sec
*sec
,
226 struct ptlrpc_request
*req
,
227 int segment
, int newsize
)
229 struct lustre_msg
*newbuf
;
230 struct lustre_msg
*oldbuf
= req
->rq_reqmsg
;
231 int oldsize
, newmsg_size
, alloc_size
;
233 LASSERT(req
->rq_reqbuf
);
234 LASSERT(req
->rq_reqbuf
== req
->rq_reqmsg
);
235 LASSERT(req
->rq_reqbuf_len
>= req
->rq_reqlen
);
236 LASSERT(req
->rq_reqlen
== lustre_packed_msg_size(oldbuf
));
238 /* compute new message size */
239 oldsize
= req
->rq_reqbuf
->lm_buflens
[segment
];
240 req
->rq_reqbuf
->lm_buflens
[segment
] = newsize
;
241 newmsg_size
= lustre_packed_msg_size(oldbuf
);
242 req
->rq_reqbuf
->lm_buflens
[segment
] = oldsize
;
244 /* request from pool should always have enough buffer */
245 LASSERT(!req
->rq_pool
|| req
->rq_reqbuf_len
>= newmsg_size
);
247 if (req
->rq_reqbuf_len
< newmsg_size
) {
248 alloc_size
= size_roundup_power2(newmsg_size
);
250 newbuf
= libcfs_kvzalloc(alloc_size
, GFP_NOFS
);
254 /* Must lock this, so that otherwise unprotected change of
255 * rq_reqmsg is not racing with parallel processing of
256 * imp_replay_list traversing threads. See LU-3333
257 * This is a bandaid at best, we really need to deal with this
258 * in request enlarging code before unpacking that's already
261 spin_lock(&req
->rq_import
->imp_lock
);
262 memcpy(newbuf
, req
->rq_reqbuf
, req
->rq_reqlen
);
264 kvfree(req
->rq_reqbuf
);
265 req
->rq_reqbuf
= req
->rq_reqmsg
= newbuf
;
266 req
->rq_reqbuf_len
= alloc_size
;
269 spin_unlock(&req
->rq_import
->imp_lock
);
272 _sptlrpc_enlarge_msg_inplace(req
->rq_reqmsg
, segment
, newsize
);
273 req
->rq_reqlen
= newmsg_size
;
278 static struct ptlrpc_svc_ctx null_svc_ctx
= {
279 .sc_refcount
= ATOMIC_INIT(1),
280 .sc_policy
= &null_policy
,
284 int null_accept(struct ptlrpc_request
*req
)
286 LASSERT(SPTLRPC_FLVR_POLICY(req
->rq_flvr
.sf_rpc
) ==
287 SPTLRPC_POLICY_NULL
);
289 if (req
->rq_flvr
.sf_rpc
!= SPTLRPC_FLVR_NULL
) {
290 CERROR("Invalid rpc flavor 0x%x\n", req
->rq_flvr
.sf_rpc
);
294 req
->rq_sp_from
= null_decode_sec_part(req
->rq_reqbuf
);
296 req
->rq_reqmsg
= req
->rq_reqbuf
;
297 req
->rq_reqlen
= req
->rq_reqdata_len
;
299 req
->rq_svc_ctx
= &null_svc_ctx
;
300 atomic_inc(&req
->rq_svc_ctx
->sc_refcount
);
306 int null_alloc_rs(struct ptlrpc_request
*req
, int msgsize
)
308 struct ptlrpc_reply_state
*rs
;
309 int rs_size
= sizeof(*rs
) + msgsize
;
311 LASSERT(msgsize
% 8 == 0);
313 rs
= req
->rq_reply_state
;
317 LASSERT(rs
->rs_size
>= rs_size
);
319 rs
= libcfs_kvzalloc(rs_size
, GFP_NOFS
);
323 rs
->rs_size
= rs_size
;
326 rs
->rs_svc_ctx
= req
->rq_svc_ctx
;
327 atomic_inc(&req
->rq_svc_ctx
->sc_refcount
);
329 rs
->rs_repbuf
= (struct lustre_msg
*) (rs
+ 1);
330 rs
->rs_repbuf_len
= rs_size
- sizeof(*rs
);
331 rs
->rs_msg
= rs
->rs_repbuf
;
333 req
->rq_reply_state
= rs
;
338 void null_free_rs(struct ptlrpc_reply_state
*rs
)
340 LASSERT_ATOMIC_GT(&rs
->rs_svc_ctx
->sc_refcount
, 1);
341 atomic_dec(&rs
->rs_svc_ctx
->sc_refcount
);
343 if (!rs
->rs_prealloc
)
348 int null_authorize(struct ptlrpc_request
*req
)
350 struct ptlrpc_reply_state
*rs
= req
->rq_reply_state
;
354 rs
->rs_repbuf
->lm_secflvr
= SPTLRPC_FLVR_NULL
;
355 rs
->rs_repdata_len
= req
->rq_replen
;
357 if (likely(req
->rq_packed_final
)) {
358 if (lustre_msghdr_get_flags(req
->rq_reqmsg
) & MSGHDR_AT_SUPPORT
)
359 req
->rq_reply_off
= lustre_msg_early_size();
361 req
->rq_reply_off
= 0;
365 cksum
= lustre_msg_calc_cksum(rs
->rs_repbuf
);
366 lustre_msg_set_cksum(rs
->rs_repbuf
, cksum
);
367 req
->rq_reply_off
= 0;
373 static struct ptlrpc_ctx_ops null_ctx_ops
= {
374 .refresh
= null_ctx_refresh
,
375 .sign
= null_ctx_sign
,
376 .verify
= null_ctx_verify
,
379 static struct ptlrpc_sec_cops null_sec_cops
= {
380 .create_sec
= null_create_sec
,
381 .destroy_sec
= null_destroy_sec
,
382 .lookup_ctx
= null_lookup_ctx
,
383 .flush_ctx_cache
= null_flush_ctx_cache
,
384 .alloc_reqbuf
= null_alloc_reqbuf
,
385 .alloc_repbuf
= null_alloc_repbuf
,
386 .free_reqbuf
= null_free_reqbuf
,
387 .free_repbuf
= null_free_repbuf
,
388 .enlarge_reqbuf
= null_enlarge_reqbuf
,
391 static struct ptlrpc_sec_sops null_sec_sops
= {
392 .accept
= null_accept
,
393 .alloc_rs
= null_alloc_rs
,
394 .authorize
= null_authorize
,
395 .free_rs
= null_free_rs
,
398 static struct ptlrpc_sec_policy null_policy
= {
399 .sp_owner
= THIS_MODULE
,
400 .sp_name
= "sec.null",
401 .sp_policy
= SPTLRPC_POLICY_NULL
,
402 .sp_cops
= &null_sec_cops
,
403 .sp_sops
= &null_sec_sops
,
406 static void null_init_internal(void)
408 static HLIST_HEAD(__list
);
410 null_sec
.ps_policy
= &null_policy
;
411 atomic_set(&null_sec
.ps_refcount
, 1); /* always busy */
413 null_sec
.ps_import
= NULL
;
414 null_sec
.ps_flvr
.sf_rpc
= SPTLRPC_FLVR_NULL
;
415 null_sec
.ps_flvr
.sf_flags
= 0;
416 null_sec
.ps_part
= LUSTRE_SP_ANY
;
417 null_sec
.ps_dying
= 0;
418 spin_lock_init(&null_sec
.ps_lock
);
419 atomic_set(&null_sec
.ps_nctx
, 1); /* for "null_cli_ctx" */
420 INIT_LIST_HEAD(&null_sec
.ps_gc_list
);
421 null_sec
.ps_gc_interval
= 0;
422 null_sec
.ps_gc_next
= 0;
424 hlist_add_head(&null_cli_ctx
.cc_cache
, &__list
);
425 atomic_set(&null_cli_ctx
.cc_refcount
, 1); /* for hash */
426 null_cli_ctx
.cc_sec
= &null_sec
;
427 null_cli_ctx
.cc_ops
= &null_ctx_ops
;
428 null_cli_ctx
.cc_expire
= 0;
429 null_cli_ctx
.cc_flags
= PTLRPC_CTX_CACHED
| PTLRPC_CTX_ETERNAL
|
431 null_cli_ctx
.cc_vcred
.vc_uid
= 0;
432 spin_lock_init(&null_cli_ctx
.cc_lock
);
433 INIT_LIST_HEAD(&null_cli_ctx
.cc_req_list
);
434 INIT_LIST_HEAD(&null_cli_ctx
.cc_gc_chain
);
437 int sptlrpc_null_init(void)
441 null_init_internal();
443 rc
= sptlrpc_register_policy(&null_policy
);
445 CERROR("failed to register %s: %d\n", null_policy
.sp_name
, rc
);
450 void sptlrpc_null_fini(void)
454 rc
= sptlrpc_unregister_policy(&null_policy
);
456 CERROR("failed to unregister %s: %d\n",
457 null_policy
.sp_name
, rc
);