diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2009-01-25 09:55:30 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-03-12 13:58:06 -0400 |
commit | 02941a530ef736210b4cf8b24dd34c238d5d5a40 (patch) | |
tree | f4ac1f663392cbc107e618dd28caa65f27d608ae /drivers/scsi/osd | |
parent | de258bf5e63863f42e0f9a7c5ffd29916a41e399 (diff) |
[SCSI] libosd: OSDv1 preliminary implementation
Implementation of the most basic OSD functionality and
infrastructure. Mainly Format, Create/Remove Partition,
Create/Remove Object, and read/write.
- Add Makefile and Kbuild to compile libosd.ko
- osd_initiator.c Implementation file for osd_initiator.h
and osd_sec.h APIs
- osd_debug.h - Some kprintf macro definitions
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Reviewed-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/osd')
-rw-r--r-- | drivers/scsi/osd/Kbuild | 32 | ||||
-rwxr-xr-x | drivers/scsi/osd/Makefile | 37 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_debug.h | 30 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 448 |
4 files changed, 547 insertions, 0 deletions
diff --git a/drivers/scsi/osd/Kbuild b/drivers/scsi/osd/Kbuild new file mode 100644 index 000000000000..a95e0251005c --- /dev/null +++ b/drivers/scsi/osd/Kbuild | |||
@@ -0,0 +1,32 @@ | |||
1 | # | ||
2 | # Kbuild for the OSD modules | ||
3 | # | ||
4 | # Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | # | ||
6 | # Authors: | ||
7 | # Boaz Harrosh <bharrosh@panasas.com> | ||
8 | # Benny Halevy <bhalevy@panasas.com> | ||
9 | # | ||
10 | # This program is free software; you can redistribute it and/or modify | ||
11 | # it under the terms of the GNU General Public License version 2 | ||
12 | # | ||
13 | |||
14 | ifneq ($(OSD_INC),) | ||
15 | # we are built out-of-tree Kconfigure everything as on | ||
16 | |||
17 | CONFIG_SCSI_OSD_INITIATOR=m | ||
18 | ccflags-y += -DCONFIG_SCSI_OSD_INITIATOR -DCONFIG_SCSI_OSD_INITIATOR_MODULE | ||
19 | |||
20 | # Uncomment to turn debug on | ||
21 | # ccflags-y += -DCONFIG_SCSI_OSD_DEBUG | ||
22 | |||
23 | # if we are built out-of-tree and the hosting kernel has OSD headers | ||
24 | # then "ccflags-y +=" will not pick the out-off-tree headers. Only by doing | ||
25 | # this it will work. This might break in future kernels | ||
26 | LINUXINCLUDE := -I$(OSD_INC) $(LINUXINCLUDE) | ||
27 | |||
28 | endif | ||
29 | |||
30 | # libosd.ko - osd-initiator library | ||
31 | libosd-y := osd_initiator.o | ||
32 | obj-$(CONFIG_SCSI_OSD_INITIATOR) += libosd.o | ||
diff --git a/drivers/scsi/osd/Makefile b/drivers/scsi/osd/Makefile new file mode 100755 index 000000000000..d905344f83ba --- /dev/null +++ b/drivers/scsi/osd/Makefile | |||
@@ -0,0 +1,37 @@ | |||
1 | # | ||
2 | # Makefile for the OSD modules (out of tree) | ||
3 | # | ||
4 | # Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | # | ||
6 | # Authors: | ||
7 | # Boaz Harrosh <bharrosh@panasas.com> | ||
8 | # Benny Halevy <bhalevy@panasas.com> | ||
9 | # | ||
10 | # This program is free software; you can redistribute it and/or modify | ||
11 | # it under the terms of the GNU General Public License version 2 | ||
12 | # | ||
13 | # This Makefile is used to call the kernel Makefile in case of an out-of-tree | ||
14 | # build. | ||
15 | # $KSRC should point to a Kernel source tree otherwise host's default is | ||
16 | # used. (eg. /lib/modules/`uname -r`/build) | ||
17 | |||
18 | # include path for out-of-tree Headers | ||
19 | OSD_INC ?= `pwd`/../../../include | ||
20 | |||
21 | # allow users to override these | ||
22 | # e.g. to compile for a kernel that you aren't currently running | ||
23 | KSRC ?= /lib/modules/$(shell uname -r)/build | ||
24 | KBUILD_OUTPUT ?= | ||
25 | ARCH ?= | ||
26 | V ?= 0 | ||
27 | |||
28 | # this is the basic Kbuild out-of-tree invocation, with the M= option | ||
29 | KBUILD_BASE = +$(MAKE) -C $(KSRC) M=`pwd` KBUILD_OUTPUT=$(KBUILD_OUTPUT) ARCH=$(ARCH) V=$(V) | ||
30 | |||
31 | all: libosd | ||
32 | |||
33 | libosd: ; | ||
34 | $(KBUILD_BASE) OSD_INC=$(OSD_INC) modules | ||
35 | |||
36 | clean: | ||
37 | $(KBUILD_BASE) clean | ||
diff --git a/drivers/scsi/osd/osd_debug.h b/drivers/scsi/osd/osd_debug.h new file mode 100644 index 000000000000..579e491f11df --- /dev/null +++ b/drivers/scsi/osd/osd_debug.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * osd_debug.h - Some kprintf macros | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <bharrosh@panasas.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __OSD_DEBUG_H__ | ||
15 | #define __OSD_DEBUG_H__ | ||
16 | |||
17 | #define OSD_ERR(fmt, a...) printk(KERN_ERR "osd: " fmt, ##a) | ||
18 | #define OSD_INFO(fmt, a...) printk(KERN_NOTICE "osd: " fmt, ##a) | ||
19 | |||
20 | #ifdef CONFIG_SCSI_OSD_DEBUG | ||
21 | #define OSD_DEBUG(fmt, a...) \ | ||
22 | printk(KERN_NOTICE "osd @%s:%d: " fmt, __func__, __LINE__, ##a) | ||
23 | #else | ||
24 | #define OSD_DEBUG(fmt, a...) do {} while (0) | ||
25 | #endif | ||
26 | |||
27 | /* u64 has problems with printk this will cast it to unsigned long long */ | ||
28 | #define _LLU(x) (unsigned long long)(x) | ||
29 | |||
30 | #endif /* ndef __OSD_DEBUG_H__ */ | ||
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c new file mode 100644 index 000000000000..0e6d906f1113 --- /dev/null +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -0,0 +1,448 @@ | |||
1 | /* | ||
2 | * osd_initiator - Main body of the osd initiator library. | ||
3 | * | ||
4 | * Note: The file does not contain the advanced security functionality which | ||
5 | * is only needed by the security_manager's initiators. | ||
6 | * | ||
7 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
8 | * | ||
9 | * Authors: | ||
10 | * Boaz Harrosh <bharrosh@panasas.com> | ||
11 | * Benny Halevy <bhalevy@panasas.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 | ||
15 | * | ||
16 | * Redistribution and use in source and binary forms, with or without | ||
17 | * modification, are permitted provided that the following conditions | ||
18 | * are met: | ||
19 | * | ||
20 | * 1. Redistributions of source code must retain the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer. | ||
22 | * 2. Redistributions in binary form must reproduce the above copyright | ||
23 | * notice, this list of conditions and the following disclaimer in the | ||
24 | * documentation and/or other materials provided with the distribution. | ||
25 | * 3. Neither the name of the Panasas company nor the names of its | ||
26 | * contributors may be used to endorse or promote products derived | ||
27 | * from this software without specific prior written permission. | ||
28 | * | ||
29 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
30 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
31 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
32 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
33 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
34 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
35 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
36 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
37 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
38 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
39 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
40 | */ | ||
41 | |||
42 | #include <scsi/osd_initiator.h> | ||
43 | #include <scsi/osd_sec.h> | ||
44 | #include <scsi/scsi_device.h> | ||
45 | |||
46 | #include "osd_debug.h" | ||
47 | |||
48 | enum { OSD_REQ_RETRIES = 1 }; | ||
49 | |||
50 | MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); | ||
51 | MODULE_DESCRIPTION("open-osd initiator library libosd.ko"); | ||
52 | MODULE_LICENSE("GPL"); | ||
53 | |||
54 | static inline void build_test(void) | ||
55 | { | ||
56 | /* structures were not packed */ | ||
57 | BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); | ||
58 | BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); | ||
59 | } | ||
60 | |||
61 | static unsigned _osd_req_cdb_len(struct osd_request *or) | ||
62 | { | ||
63 | return OSDv1_TOTAL_CDB_LEN; | ||
64 | } | ||
65 | |||
66 | void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) | ||
67 | { | ||
68 | memset(osdd, 0, sizeof(*osdd)); | ||
69 | osdd->scsi_device = scsi_device; | ||
70 | osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; | ||
71 | /* TODO: Allocate pools for osd_request attributes ... */ | ||
72 | } | ||
73 | EXPORT_SYMBOL(osd_dev_init); | ||
74 | |||
75 | void osd_dev_fini(struct osd_dev *osdd) | ||
76 | { | ||
77 | /* TODO: De-allocate pools */ | ||
78 | |||
79 | osdd->scsi_device = NULL; | ||
80 | } | ||
81 | EXPORT_SYMBOL(osd_dev_fini); | ||
82 | |||
83 | static struct osd_request *_osd_request_alloc(gfp_t gfp) | ||
84 | { | ||
85 | struct osd_request *or; | ||
86 | |||
87 | /* TODO: Use mempool with one saved request */ | ||
88 | or = kzalloc(sizeof(*or), gfp); | ||
89 | return or; | ||
90 | } | ||
91 | |||
92 | static void _osd_request_free(struct osd_request *or) | ||
93 | { | ||
94 | kfree(or); | ||
95 | } | ||
96 | |||
97 | struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp) | ||
98 | { | ||
99 | struct osd_request *or; | ||
100 | |||
101 | or = _osd_request_alloc(gfp); | ||
102 | if (!or) | ||
103 | return NULL; | ||
104 | |||
105 | or->osd_dev = dev; | ||
106 | or->alloc_flags = gfp; | ||
107 | or->timeout = dev->def_timeout; | ||
108 | or->retries = OSD_REQ_RETRIES; | ||
109 | |||
110 | return or; | ||
111 | } | ||
112 | EXPORT_SYMBOL(osd_start_request); | ||
113 | |||
114 | /* | ||
115 | * If osd_finalize_request() was called but the request was not executed through | ||
116 | * the block layer, then we must release BIOs. | ||
117 | */ | ||
118 | static void _abort_unexecuted_bios(struct request *rq) | ||
119 | { | ||
120 | struct bio *bio; | ||
121 | |||
122 | while ((bio = rq->bio) != NULL) { | ||
123 | rq->bio = bio->bi_next; | ||
124 | bio_endio(bio, 0); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | void osd_end_request(struct osd_request *or) | ||
129 | { | ||
130 | struct request *rq = or->request; | ||
131 | |||
132 | if (rq) { | ||
133 | if (rq->next_rq) { | ||
134 | _abort_unexecuted_bios(rq->next_rq); | ||
135 | blk_put_request(rq->next_rq); | ||
136 | } | ||
137 | |||
138 | _abort_unexecuted_bios(rq); | ||
139 | blk_put_request(rq); | ||
140 | } | ||
141 | _osd_request_free(or); | ||
142 | } | ||
143 | EXPORT_SYMBOL(osd_end_request); | ||
144 | |||
145 | int osd_execute_request(struct osd_request *or) | ||
146 | { | ||
147 | return blk_execute_rq(or->request->q, NULL, or->request, 0); | ||
148 | } | ||
149 | EXPORT_SYMBOL(osd_execute_request); | ||
150 | |||
151 | static void osd_request_async_done(struct request *req, int error) | ||
152 | { | ||
153 | struct osd_request *or = req->end_io_data; | ||
154 | |||
155 | or->async_error = error; | ||
156 | |||
157 | if (error) | ||
158 | OSD_DEBUG("osd_request_async_done error recieved %d\n", error); | ||
159 | |||
160 | if (or->async_done) | ||
161 | or->async_done(or, or->async_private); | ||
162 | else | ||
163 | osd_end_request(or); | ||
164 | } | ||
165 | |||
166 | int osd_execute_request_async(struct osd_request *or, | ||
167 | osd_req_done_fn *done, void *private) | ||
168 | { | ||
169 | or->request->end_io_data = or; | ||
170 | or->async_private = private; | ||
171 | or->async_done = done; | ||
172 | |||
173 | blk_execute_rq_nowait(or->request->q, NULL, or->request, 0, | ||
174 | osd_request_async_done); | ||
175 | return 0; | ||
176 | } | ||
177 | EXPORT_SYMBOL(osd_execute_request_async); | ||
178 | |||
179 | /* | ||
180 | * Common to all OSD commands | ||
181 | */ | ||
182 | |||
183 | static void _osdv1_req_encode_common(struct osd_request *or, | ||
184 | __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) | ||
185 | { | ||
186 | struct osdv1_cdb *ocdb = &or->cdb.v1; | ||
187 | |||
188 | /* | ||
189 | * For speed, the commands | ||
190 | * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C | ||
191 | * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D | ||
192 | * are not supported here. Should pass zero and set after the call | ||
193 | */ | ||
194 | act &= cpu_to_be16(~0x0080); /* V1 action code */ | ||
195 | |||
196 | OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act)); | ||
197 | |||
198 | ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; | ||
199 | ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; | ||
200 | ocdb->h.varlen_cdb.service_action = act; | ||
201 | |||
202 | ocdb->h.partition = cpu_to_be64(obj->partition); | ||
203 | ocdb->h.object = cpu_to_be64(obj->id); | ||
204 | ocdb->h.v1.length = cpu_to_be64(len); | ||
205 | ocdb->h.v1.start_address = cpu_to_be64(offset); | ||
206 | } | ||
207 | |||
208 | static void _osd_req_encode_common(struct osd_request *or, | ||
209 | __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) | ||
210 | { | ||
211 | _osdv1_req_encode_common(or, act, obj, offset, len); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Device commands | ||
216 | */ | ||
217 | void osd_req_format(struct osd_request *or, u64 tot_capacity) | ||
218 | { | ||
219 | _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0, | ||
220 | tot_capacity); | ||
221 | } | ||
222 | EXPORT_SYMBOL(osd_req_format); | ||
223 | |||
224 | /* | ||
225 | * Partition commands | ||
226 | */ | ||
227 | static void _osd_req_encode_partition(struct osd_request *or, | ||
228 | __be16 act, osd_id partition) | ||
229 | { | ||
230 | struct osd_obj_id par = { | ||
231 | .partition = partition, | ||
232 | .id = 0, | ||
233 | }; | ||
234 | |||
235 | _osd_req_encode_common(or, act, &par, 0, 0); | ||
236 | } | ||
237 | |||
238 | void osd_req_create_partition(struct osd_request *or, osd_id partition) | ||
239 | { | ||
240 | _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition); | ||
241 | } | ||
242 | EXPORT_SYMBOL(osd_req_create_partition); | ||
243 | |||
244 | void osd_req_remove_partition(struct osd_request *or, osd_id partition) | ||
245 | { | ||
246 | _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition); | ||
247 | } | ||
248 | EXPORT_SYMBOL(osd_req_remove_partition); | ||
249 | |||
250 | /* | ||
251 | * Object commands | ||
252 | */ | ||
253 | void osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj) | ||
254 | { | ||
255 | _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0); | ||
256 | } | ||
257 | EXPORT_SYMBOL(osd_req_create_object); | ||
258 | |||
259 | void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj) | ||
260 | { | ||
261 | _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0); | ||
262 | } | ||
263 | EXPORT_SYMBOL(osd_req_remove_object); | ||
264 | |||
265 | void osd_req_write(struct osd_request *or, | ||
266 | const struct osd_obj_id *obj, struct bio *bio, u64 offset) | ||
267 | { | ||
268 | _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, bio->bi_size); | ||
269 | WARN_ON(or->out.bio || or->out.total_bytes); | ||
270 | bio->bi_rw |= (1 << BIO_RW); | ||
271 | or->out.bio = bio; | ||
272 | or->out.total_bytes = bio->bi_size; | ||
273 | } | ||
274 | EXPORT_SYMBOL(osd_req_write); | ||
275 | |||
276 | void osd_req_read(struct osd_request *or, | ||
277 | const struct osd_obj_id *obj, struct bio *bio, u64 offset) | ||
278 | { | ||
279 | _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, bio->bi_size); | ||
280 | WARN_ON(or->in.bio || or->in.total_bytes); | ||
281 | bio->bi_rw &= ~(1 << BIO_RW); | ||
282 | or->in.bio = bio; | ||
283 | or->in.total_bytes = bio->bi_size; | ||
284 | } | ||
285 | EXPORT_SYMBOL(osd_req_read); | ||
286 | |||
287 | /* | ||
288 | * osd_finalize_request and helpers | ||
289 | */ | ||
290 | |||
291 | static int _init_blk_request(struct osd_request *or, | ||
292 | bool has_in, bool has_out) | ||
293 | { | ||
294 | gfp_t flags = or->alloc_flags; | ||
295 | struct scsi_device *scsi_device = or->osd_dev->scsi_device; | ||
296 | struct request_queue *q = scsi_device->request_queue; | ||
297 | struct request *req; | ||
298 | int ret = -ENOMEM; | ||
299 | |||
300 | req = blk_get_request(q, has_out, flags); | ||
301 | if (!req) | ||
302 | goto out; | ||
303 | |||
304 | or->request = req; | ||
305 | req->cmd_type = REQ_TYPE_BLOCK_PC; | ||
306 | req->timeout = or->timeout; | ||
307 | req->retries = or->retries; | ||
308 | req->sense = or->sense; | ||
309 | req->sense_len = 0; | ||
310 | |||
311 | if (has_out) { | ||
312 | or->out.req = req; | ||
313 | if (has_in) { | ||
314 | /* allocate bidi request */ | ||
315 | req = blk_get_request(q, READ, flags); | ||
316 | if (!req) { | ||
317 | OSD_DEBUG("blk_get_request for bidi failed\n"); | ||
318 | goto out; | ||
319 | } | ||
320 | req->cmd_type = REQ_TYPE_BLOCK_PC; | ||
321 | or->in.req = or->request->next_rq = req; | ||
322 | } | ||
323 | } else if (has_in) | ||
324 | or->in.req = req; | ||
325 | |||
326 | ret = 0; | ||
327 | out: | ||
328 | OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n", | ||
329 | or, has_in, has_out, ret, or->request); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | int osd_finalize_request(struct osd_request *or, | ||
334 | u8 options, const void *cap, const u8 *cap_key) | ||
335 | { | ||
336 | struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); | ||
337 | bool has_in, has_out; | ||
338 | int ret; | ||
339 | |||
340 | if (options & OSD_REQ_FUA) | ||
341 | cdbh->options |= OSD_CDB_FUA; | ||
342 | |||
343 | if (options & OSD_REQ_DPO) | ||
344 | cdbh->options |= OSD_CDB_DPO; | ||
345 | |||
346 | if (options & OSD_REQ_BYPASS_TIMESTAMPS) | ||
347 | cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS; | ||
348 | |||
349 | osd_set_caps(&or->cdb, cap); | ||
350 | |||
351 | has_in = or->in.bio || or->get_attr.total_bytes; | ||
352 | has_out = or->out.bio || or->set_attr.total_bytes || | ||
353 | or->enc_get_attr.total_bytes; | ||
354 | |||
355 | ret = _init_blk_request(or, has_in, has_out); | ||
356 | if (ret) { | ||
357 | OSD_DEBUG("_init_blk_request failed\n"); | ||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | if (or->out.bio) { | ||
362 | ret = blk_rq_append_bio(or->request->q, or->out.req, | ||
363 | or->out.bio); | ||
364 | if (ret) { | ||
365 | OSD_DEBUG("blk_rq_append_bio out failed\n"); | ||
366 | return ret; | ||
367 | } | ||
368 | OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n", | ||
369 | _LLU(or->out.total_bytes), or->out.req->data_len); | ||
370 | } | ||
371 | if (or->in.bio) { | ||
372 | ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio); | ||
373 | if (ret) { | ||
374 | OSD_DEBUG("blk_rq_append_bio in failed\n"); | ||
375 | return ret; | ||
376 | } | ||
377 | OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n", | ||
378 | _LLU(or->in.total_bytes), or->in.req->data_len); | ||
379 | } | ||
380 | |||
381 | if (!or->attributes_mode) | ||
382 | or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; | ||
383 | cdbh->command_specific_options |= or->attributes_mode; | ||
384 | |||
385 | or->request->cmd = or->cdb.buff; | ||
386 | or->request->cmd_len = _osd_req_cdb_len(or); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | EXPORT_SYMBOL(osd_finalize_request); | ||
391 | |||
392 | /* | ||
393 | * Implementation of osd_sec.h API | ||
394 | * TODO: Move to a separate osd_sec.c file at a later stage. | ||
395 | */ | ||
396 | |||
397 | enum { OSD_SEC_CAP_V1_ALL_CAPS = | ||
398 | OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE | | ||
399 | OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR | | ||
400 | OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC | | ||
401 | OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT | ||
402 | }; | ||
403 | |||
404 | void osd_sec_init_nosec_doall_caps(void *caps, | ||
405 | const struct osd_obj_id *obj, bool is_collection, const bool is_v1) | ||
406 | { | ||
407 | struct osd_capability *cap = caps; | ||
408 | u8 type; | ||
409 | u8 descriptor_type; | ||
410 | |||
411 | if (likely(obj->id)) { | ||
412 | if (unlikely(is_collection)) { | ||
413 | type = OSD_SEC_OBJ_COLLECTION; | ||
414 | descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ : | ||
415 | OSD_SEC_OBJ_DESC_COL; | ||
416 | } else { | ||
417 | type = OSD_SEC_OBJ_USER; | ||
418 | descriptor_type = OSD_SEC_OBJ_DESC_OBJ; | ||
419 | } | ||
420 | WARN_ON(!obj->partition); | ||
421 | } else { | ||
422 | type = obj->partition ? OSD_SEC_OBJ_PARTITION : | ||
423 | OSD_SEC_OBJ_ROOT; | ||
424 | descriptor_type = OSD_SEC_OBJ_DESC_PAR; | ||
425 | } | ||
426 | |||
427 | memset(cap, 0, sizeof(*cap)); | ||
428 | |||
429 | cap->h.format = OSD_SEC_CAP_FORMAT_VER1; | ||
430 | cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */ | ||
431 | cap->h.security_method = OSD_SEC_NOSEC; | ||
432 | /* cap->expiration_time; | ||
433 | cap->AUDIT[30-10]; | ||
434 | cap->discriminator[42-30]; | ||
435 | cap->object_created_time; */ | ||
436 | cap->h.object_type = type; | ||
437 | osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS); | ||
438 | cap->h.object_descriptor_type = descriptor_type; | ||
439 | cap->od.obj_desc.policy_access_tag = 0; | ||
440 | cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition); | ||
441 | cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id); | ||
442 | } | ||
443 | EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); | ||
444 | |||
445 | void osd_set_caps(struct osd_cdb *cdb, const void *caps) | ||
446 | { | ||
447 | memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); | ||
448 | } | ||