aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2009-01-25 09:54:10 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 13:58:06 -0400
commitde258bf5e63863f42e0f9a7c5ffd29916a41e399 (patch)
treec90aa5f4dd86b61df7915864589562ef9fabe625
parent82443a58d361123d418033e9e32ac29a842fce68 (diff)
[SCSI] libosd: OSDv1 Headers
Headers only patch. osd_protocol.h Contains a C-fied definition of the T10 OSD standard osd_types.h Contains CPU order common used types osd_initiator.h API definition of the osd_initiator library osd_sec.h Contains High level API for the security manager. [Note that checkpatch spews errors on things that are valid in this context and will not be fixed] Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Reviewed-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--include/scsi/osd_initiator.h332
-rw-r--r--include/scsi/osd_protocol.h497
-rw-r--r--include/scsi/osd_sec.h45
-rw-r--r--include/scsi/osd_types.h40
4 files changed, 914 insertions, 0 deletions
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
new file mode 100644
index 000000000000..1d92247f820b
--- /dev/null
+++ b/include/scsi/osd_initiator.h
@@ -0,0 +1,332 @@
1/*
2 * osd_initiator.h - OSD initiator API definition
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_INITIATOR_H__
15#define __OSD_INITIATOR_H__
16
17#include "osd_protocol.h"
18#include "osd_types.h"
19
20#include <linux/blkdev.h>
21
22/* Note: "NI" in comments below means "Not Implemented yet" */
23
24/*
25 * Object-based Storage Device.
26 * This object represents an OSD device.
27 * It is not a full linux device in any way. It is only
28 * a place to hang resources associated with a Linux
29 * request Q and some default properties.
30 */
31struct osd_dev {
32 struct scsi_device *scsi_device;
33 unsigned def_timeout;
34};
35
36void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
37void osd_dev_fini(struct osd_dev *od);
38
39struct osd_request;
40typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
41
42struct osd_request {
43 struct osd_cdb cdb;
44 struct osd_data_out_integrity_info out_data_integ;
45 struct osd_data_in_integrity_info in_data_integ;
46
47 struct osd_dev *osd_dev;
48 struct request *request;
49
50 struct _osd_req_data_segment {
51 void *buff;
52 unsigned alloc_size; /* 0 here means: don't call kfree */
53 unsigned total_bytes;
54 } set_attr, enc_get_attr, get_attr;
55
56 struct _osd_io_info {
57 struct bio *bio;
58 u64 total_bytes;
59 struct request *req;
60 struct _osd_req_data_segment *last_seg;
61 u8 *pad_buff;
62 } out, in;
63
64 gfp_t alloc_flags;
65 unsigned timeout;
66 unsigned retries;
67 u8 sense[OSD_MAX_SENSE_LEN];
68 enum osd_attributes_mode attributes_mode;
69
70 osd_req_done_fn *async_done;
71 void *async_private;
72 int async_error;
73};
74
75/*
76 * How to use the osd library:
77 *
78 * osd_start_request
79 * Allocates a request.
80 *
81 * osd_req_*
82 * Call one of, to encode the desired operation.
83 *
84 * osd_add_{get,set}_attr
85 * Optionally add attributes to the CDB, list or page mode.
86 *
87 * osd_finalize_request
88 * Computes final data out/in offsets and signs the request,
89 * making it ready for execution.
90 *
91 * osd_execute_request
92 * May be called to execute it through the block layer. Other wise submit
93 * the associated block request in some other way.
94 *
95 * After execution:
96 * osd_req_decode_sense
97 * Decodes sense information to verify execution results.
98 *
99 * osd_req_decode_get_attr
100 * Retrieve osd_add_get_attr_list() values if used.
101 *
102 * osd_end_request
103 * Must be called to deallocate the request.
104 */
105
106/**
107 * osd_start_request - Allocate and initialize an osd_request
108 *
109 * @osd_dev: OSD device that holds the scsi-device and default values
110 * that the request is associated with.
111 * @gfp: The allocation flags to use for request allocation, and all
112 * subsequent allocations. This will be stored at
113 * osd_request->alloc_flags, can be changed by user later
114 *
115 * Allocate osd_request and initialize all members to the
116 * default/initial state.
117 */
118struct osd_request *osd_start_request(struct osd_dev *od, gfp_t gfp);
119
120enum osd_req_options {
121 OSD_REQ_FUA = 0x08, /* Force Unit Access */
122 OSD_REQ_DPO = 0x10, /* Disable Page Out */
123
124 OSD_REQ_BYPASS_TIMESTAMPS = 0x80,
125};
126
127/**
128 * osd_finalize_request - Sign request and prepare request for execution
129 *
130 * @or: osd_request to prepare
131 * @options: combination of osd_req_options bit flags or 0.
132 * @cap: A Pointer to an OSD_CAP_LEN bytes buffer that is received from
133 * The security manager as capabilities for this cdb.
134 * @cap_key: The cryptographic key used to sign the cdb/data. Can be null
135 * if NOSEC is used.
136 *
137 * The actual request and bios are only allocated here, so are the get_attr
138 * buffers that will receive the returned attributes. Copy's @cap to cdb.
139 * Sign the cdb/data with @cap_key.
140 */
141int osd_finalize_request(struct osd_request *or,
142 u8 options, const void *cap, const u8 *cap_key);
143
144/**
145 * osd_execute_request - Execute the request synchronously through block-layer
146 *
147 * @or: osd_request to Executed
148 *
149 * Calls blk_execute_rq to q the command and waits for completion.
150 */
151int osd_execute_request(struct osd_request *or);
152
153/**
154 * osd_execute_request_async - Execute the request without waitting.
155 *
156 * @or: - osd_request to Executed
157 * @done: (Optional) - Called at end of execution
158 * @private: - Will be passed to @done function
159 *
160 * Calls blk_execute_rq_nowait to queue the command. When execution is done
161 * optionally calls @done with @private as parameter. @or->async_error will
162 * have the return code
163 */
164int osd_execute_request_async(struct osd_request *or,
165 osd_req_done_fn *done, void *private);
166
167/**
168 * osd_end_request - return osd_request to free store
169 *
170 * @or: osd_request to free
171 *
172 * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.)
173 */
174void osd_end_request(struct osd_request *or);
175
176/*
177 * CDB Encoding
178 *
179 * Note: call only one of the following methods.
180 */
181
182/*
183 * Device commands
184 */
185void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */
186void osd_req_set_master_key(struct osd_request *or, ...);/* NI */
187
188void osd_req_format(struct osd_request *or, u64 tot_capacity);
189
190/* list all partitions
191 * @list header must be initialized to zero on first run.
192 *
193 * Call osd_is_obj_list_done() to find if we got the complete list.
194 */
195int osd_req_list_dev_partitions(struct osd_request *or,
196 osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem);
197
198void osd_req_flush_obsd(struct osd_request *or,
199 enum osd_options_flush_scope_values);
200
201void osd_req_perform_scsi_command(struct osd_request *or,
202 const u8 *cdb, ...);/* NI */
203void osd_req_task_management(struct osd_request *or, ...);/* NI */
204
205/*
206 * Partition commands
207 */
208void osd_req_create_partition(struct osd_request *or, osd_id partition);
209void osd_req_remove_partition(struct osd_request *or, osd_id partition);
210
211void osd_req_set_partition_key(struct osd_request *or,
212 osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
213 u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */
214
215/* list all collections in the partition
216 * @list header must be init to zero on first run.
217 *
218 * Call osd_is_obj_list_done() to find if we got the complete list.
219 */
220int osd_req_list_partition_collections(struct osd_request *or,
221 osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
222 unsigned nelem);
223
224/* list all objects in the partition
225 * @list header must be init to zero on first run.
226 *
227 * Call osd_is_obj_list_done() to find if we got the complete list.
228 */
229int osd_req_list_partition_objects(struct osd_request *or,
230 osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
231 unsigned nelem);
232
233void osd_req_flush_partition(struct osd_request *or,
234 osd_id partition, enum osd_options_flush_scope_values);
235
236/*
237 * Collection commands
238 */
239void osd_req_create_collection(struct osd_request *or,
240 const struct osd_obj_id *);/* NI */
241void osd_req_remove_collection(struct osd_request *or,
242 const struct osd_obj_id *);/* NI */
243
244/* list all objects in the collection */
245int osd_req_list_collection_objects(struct osd_request *or,
246 const struct osd_obj_id *, osd_id initial_id,
247 struct osd_obj_id_list *list, unsigned nelem);
248
249/* V2 only filtered list of objects in the collection */
250void osd_req_query(struct osd_request *or, ...);/* NI */
251
252void osd_req_flush_collection(struct osd_request *or,
253 const struct osd_obj_id *, enum osd_options_flush_scope_values);
254
255void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */
256void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */
257
258/*
259 * Object commands
260 */
261void osd_req_create_object(struct osd_request *or, struct osd_obj_id *);
262void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *);
263
264void osd_req_write(struct osd_request *or,
265 const struct osd_obj_id *, struct bio *data_out, u64 offset);
266void osd_req_append(struct osd_request *or,
267 const struct osd_obj_id *, struct bio *data_out);/* NI */
268void osd_req_create_write(struct osd_request *or,
269 const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */
270void osd_req_clear(struct osd_request *or,
271 const struct osd_obj_id *, u64 offset, u64 len);/* NI */
272void osd_req_punch(struct osd_request *or,
273 const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */
274
275void osd_req_flush_object(struct osd_request *or,
276 const struct osd_obj_id *, enum osd_options_flush_scope_values,
277 /*V2*/ u64 offset, /*V2*/ u64 len);
278
279void osd_req_read(struct osd_request *or,
280 const struct osd_obj_id *, struct bio *data_in, u64 offset);
281
282/*
283 * Root/Partition/Collection/Object Attributes commands
284 */
285
286/* get before set */
287void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *);
288
289/* set before get */
290void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *);
291
292/*
293 * Attributes appended to most commands
294 */
295
296/* Attributes List mode (or V2 CDB) */
297 /*
298 * TODO: In ver2 if at finalize time only one attr was set and no gets,
299 * then the Attributes CDB mode is used automatically to save IO.
300 */
301
302/* set a list of attributes. */
303int osd_req_add_set_attr_list(struct osd_request *or,
304 const struct osd_attr *, unsigned nelem);
305
306/* get a list of attributes */
307int osd_req_add_get_attr_list(struct osd_request *or,
308 const struct osd_attr *, unsigned nelem);
309
310/*
311 * Attributes list decoding
312 * Must be called after osd_request.request was executed
313 * It is called in a loop to decode the returned get_attr
314 * (see osd_add_get_attr)
315 */
316int osd_req_decode_get_attr_list(struct osd_request *or,
317 struct osd_attr *, int *nelem, void **iterator);
318
319/* Attributes Page mode */
320
321/*
322 * Read an attribute page and optionally set one attribute
323 *
324 * Retrieves the attribute page directly to a user buffer.
325 * @attr_page_data shall stay valid until end of execution.
326 * See osd_attributes.h for common page structures
327 */
328int osd_req_add_get_attr_page(struct osd_request *or,
329 u32 page_id, void *attr_page_data, unsigned max_page_len,
330 const struct osd_attr *set_one);
331
332#endif /* __OSD_LIB_H__ */
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h
new file mode 100644
index 000000000000..ce1a8771ea71
--- /dev/null
+++ b/include/scsi/osd_protocol.h
@@ -0,0 +1,497 @@
1/*
2 * osd_protocol.h - OSD T10 standard C definitions.
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 file contains types and constants that are defined by the protocol
14 * Note: All names and symbols are taken from the OSD standard's text.
15 */
16#ifndef __OSD_PROTOCOL_H__
17#define __OSD_PROTOCOL_H__
18
19#include <linux/types.h>
20#include <asm/unaligned.h>
21#include <scsi/scsi.h>
22
23enum {
24 OSDv1_ADDITIONAL_CDB_LENGTH = 192,
25 OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8,
26 OSDv1_CAP_LEN = 80,
27 /* Latest supported version */
28 OSD_ADDITIONAL_CDB_LENGTH = OSDv1_ADDITIONAL_CDB_LENGTH,
29 OSD_TOTAL_CDB_LEN = OSDv1_TOTAL_CDB_LEN,
30 OSD_CAP_LEN = OSDv1_CAP_LEN,
31
32 OSD_SYSTEMID_LEN = 20,
33 OSD_CRYPTO_KEYID_SIZE = 20,
34 OSD_CRYPTO_SEED_SIZE = 4,
35 OSD_CRYPTO_NONCE_SIZE = 12,
36 OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */
37
38 OSD_PARTITION_FIRST_ID = 0x10000,
39 OSD_OBJECT_FIRST_ID = 0x10000,
40};
41
42/* (osd-r10 5.2.4)
43 * osd2r03: 5.2.3 Caching control bits
44 */
45enum osd_options_byte {
46 OSD_CDB_FUA = 0x08, /* Force Unit Access */
47 OSD_CDB_DPO = 0x10, /* Disable Page Out */
48};
49
50/*
51 * osd2r03: 5.2.5 Isolation.
52 * First 3 bits, V2-only.
53 * Also for attr 110h "default isolation method" at Root Information page
54 */
55enum osd_options_byte_isolation {
56 OSD_ISOLATION_DEFAULT = 0,
57 OSD_ISOLATION_NONE = 1,
58 OSD_ISOLATION_STRICT = 2,
59 OSD_ISOLATION_RANGE = 4,
60 OSD_ISOLATION_FUNCTIONAL = 5,
61 OSD_ISOLATION_VENDOR = 7,
62};
63
64/* (osd-r10: 6.7)
65 * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION
66 */
67enum osd_options_flush_scope_values {
68 OSD_CDB_FLUSH_ALL = 0,
69 OSD_CDB_FLUSH_ATTR_ONLY = 1,
70
71 OSD_CDB_FLUSH_ALL_RECURSIVE = 2,
72 /* V2-only */
73 OSD_CDB_FLUSH_ALL_RANGE = 2,
74};
75
76/* osd2r03: 5.2.10 Timestamps control */
77enum {
78 OSD_CDB_NORMAL_TIMESTAMPS = 0,
79 OSD_CDB_BYPASS_TIMESTAMPS = 0x7f,
80};
81
82/* (osd-r10: 5.2.2.1)
83 * osd2r03: 5.2.4.1 Get and set attributes CDB format selection
84 * 2 bits at second nibble of command_specific_options byte
85 */
86enum osd_attributes_mode {
87 /* V2-only */
88 OSD_CDB_SET_ONE_ATTR = 0x10,
89
90 OSD_CDB_GET_ATTR_PAGE_SET_ONE = 0x20,
91 OSD_CDB_GET_SET_ATTR_LISTS = 0x30,
92
93 OSD_CDB_GET_SET_ATTR_MASK = 0x30,
94};
95
96/* (osd-r10: 4.12.5)
97 * osd2r03: 4.14.5 Data-In and Data-Out buffer offsets
98 * byte offset = mantissa * (2^(exponent+8))
99 * struct {
100 * unsigned mantissa: 28;
101 * int exponent: 04;
102 * }
103 */
104typedef __be32 __bitwise osd_cdb_offset;
105
106enum {
107 OSD_OFFSET_UNUSED = 0xFFFFFFFF,
108 OSD_OFFSET_MAX_BITS = 28,
109
110 OSDv1_OFFSET_MIN_SHIFT = 8,
111 OSD_OFFSET_MAX_SHIFT = 16,
112};
113
114/* Return the smallest allowed encoded offset that contains @offset.
115 *
116 * The actual encoded offset returned is @offset + *padding.
117 * (up to max_shift, non-inclusive)
118 */
119osd_cdb_offset __osd_encode_offset(u64 offset, unsigned *padding,
120 int min_shift, int max_shift);
121
122/* Minimum alignment is 256 bytes
123 * Note: Seems from std v1 that exponent can be from 0+8 to 0xE+8 (inclusive)
124 * which is 8 to 23 but IBM code restricts it to 16, so be it.
125 */
126static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding)
127{
128 return __osd_encode_offset(offset, padding,
129 OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT);
130}
131
132/* osd2r03: 5.2.1 Overview */
133struct osd_cdb_head {
134 struct scsi_varlen_cdb_hdr varlen_cdb;
135/*10*/ u8 options;
136 u8 command_specific_options;
137 u8 timestamp_control;
138/*13*/ u8 reserved1[3];
139/*16*/ __be64 partition;
140/*24*/ __be64 object;
141/*32*/ union { /* V1 vs V2 alignment differences */
142 struct __osdv1_cdb_addr_len {
143/*32*/ __be32 list_identifier;/* Rarely used */
144/*36*/ __be64 length;
145/*44*/ __be64 start_address;
146 } __packed v1;
147 };
148/*52*/ union { /* selected attributes mode Page/List/Single */
149 struct osd_attributes_page_mode {
150/*52*/ __be32 get_attr_page;
151/*56*/ __be32 get_attr_alloc_length;
152/*60*/ osd_cdb_offset get_attr_offset;
153
154/*64*/ __be32 set_attr_page;
155/*68*/ __be32 set_attr_id;
156/*72*/ __be32 set_attr_length;
157/*76*/ osd_cdb_offset set_attr_offset;
158/*80*/ } __packed attrs_page;
159
160 struct osd_attributes_list_mode {
161/*52*/ __be32 get_attr_desc_bytes;
162/*56*/ osd_cdb_offset get_attr_desc_offset;
163
164/*60*/ __be32 get_attr_alloc_length;
165/*64*/ osd_cdb_offset get_attr_offset;
166
167/*68*/ __be32 set_attr_bytes;
168/*72*/ osd_cdb_offset set_attr_offset;
169 __be32 not_used;
170/*80*/ } __packed attrs_list;
171
172 /* osd2r03:5.2.4.2 Set one attribute value using CDB fields */
173 struct osd_attributes_cdb_mode {
174/*52*/ __be32 set_attr_page;
175/*56*/ __be32 set_attr_id;
176/*60*/ __be16 set_attr_len;
177/*62*/ u8 set_attr_val[18];
178/*80*/ } __packed attrs_cdb;
179/*52*/ u8 get_set_attributes_parameters[28];
180 };
181} __packed;
182/*80*/
183
184/*160 v1*/
185struct osd_security_parameters {
186/*160*/u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE];
187/*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE];
188/*192*/osd_cdb_offset data_in_integrity_check_offset;
189/*196*/osd_cdb_offset data_out_integrity_check_offset;
190} __packed;
191/*200 v1*/
192
193struct osdv1_cdb {
194 struct osd_cdb_head h;
195 u8 caps[OSDv1_CAP_LEN];
196 struct osd_security_parameters sec_params;
197} __packed;
198
199struct osd_cdb {
200 union {
201 struct osdv1_cdb v1;
202 u8 buff[OSD_TOTAL_CDB_LEN];
203 };
204} __packed;
205
206static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb)
207{
208 return (struct osd_cdb_head *)ocdb->buff;
209}
210
211/* define both version actions
212 * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD
213 */
214#define OSD_ACT___(Name, Num) \
215 OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), \
216 OSDv1_ACT_##Name = __constant_cpu_to_be16(0x8800 + Num),
217
218/* V2 only actions */
219#define OSD_ACT_V2(Name, Num) \
220 OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num),
221
222#define OSD_ACT_V1_V2(Name, Num1, Num2) \
223 OSD_ACT_##Name = __constant_cpu_to_be16(Num2), \
224 OSDv1_ACT_##Name = __constant_cpu_to_be16(Num1),
225
226enum osd_service_actions {
227 OSD_ACT_V2(OBJECT_STRUCTURE_CHECK, 0x00)
228 OSD_ACT___(FORMAT_OSD, 0x01)
229 OSD_ACT___(CREATE, 0x02)
230 OSD_ACT___(LIST, 0x03)
231 OSD_ACT_V2(PUNCH, 0x04)
232 OSD_ACT___(READ, 0x05)
233 OSD_ACT___(WRITE, 0x06)
234 OSD_ACT___(APPEND, 0x07)
235 OSD_ACT___(FLUSH, 0x08)
236 OSD_ACT_V2(CLEAR, 0x09)
237 OSD_ACT___(REMOVE, 0x0A)
238 OSD_ACT___(CREATE_PARTITION, 0x0B)
239 OSD_ACT___(REMOVE_PARTITION, 0x0C)
240 OSD_ACT___(GET_ATTRIBUTES, 0x0E)
241 OSD_ACT___(SET_ATTRIBUTES, 0x0F)
242 OSD_ACT___(CREATE_AND_WRITE, 0x12)
243 OSD_ACT___(CREATE_COLLECTION, 0x15)
244 OSD_ACT___(REMOVE_COLLECTION, 0x16)
245 OSD_ACT___(LIST_COLLECTION, 0x17)
246 OSD_ACT___(SET_KEY, 0x18)
247 OSD_ACT___(SET_MASTER_KEY, 0x19)
248 OSD_ACT___(FLUSH_COLLECTION, 0x1A)
249 OSD_ACT___(FLUSH_PARTITION, 0x1B)
250 OSD_ACT___(FLUSH_OSD, 0x1C)
251
252 OSD_ACT_V2(QUERY, 0x20)
253 OSD_ACT_V2(REMOVE_MEMBER_OBJECTS, 0x21)
254 OSD_ACT_V2(GET_MEMBER_ATTRIBUTES, 0x22)
255 OSD_ACT_V2(SET_MEMBER_ATTRIBUTES, 0x23)
256 OSD_ACT_V2(READ_MAP, 0x31)
257
258 OSD_ACT_V1_V2(PERFORM_SCSI_COMMAND, 0x8F7E, 0x8F7C)
259 OSD_ACT_V1_V2(SCSI_TASK_MANAGEMENT, 0x8F7F, 0x8F7D)
260 /* 0x8F80 to 0x8FFF are Vendor specific */
261};
262
263/* osd2r03: 7.1.3.2 List entry format for retrieving attributes */
264struct osd_attributes_list_attrid {
265 __be32 attr_page;
266 __be32 attr_id;
267} __packed;
268
269/*
270 * osd2r03: 7.1.3.3 List entry format for retrieved attributes and
271 * for setting attributes
272 */
273struct osd_attributes_list_element {
274 __be32 attr_page;
275 __be32 attr_id;
276 __be16 attr_bytes;
277 u8 attr_val[0];
278} __packed;
279
280enum {
281 OSDv1_ATTRIBUTES_ELEM_ALIGN = 1,
282};
283
284enum {
285 OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF,
286 OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF,
287};
288
289static inline unsigned osdv1_attr_list_elem_size(unsigned len)
290{
291 return ALIGN(len + sizeof(struct osd_attributes_list_element),
292 OSDv1_ATTRIBUTES_ELEM_ALIGN);
293}
294
295/*
296 * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values
297 */
298enum osd_attr_list_types {
299 OSD_ATTR_LIST_GET = 0x1, /* descriptors only */
300 OSD_ATTR_LIST_SET_RETRIEVE = 0x9, /*descriptors/values variable-length*/
301 OSD_V2_ATTR_LIST_MULTIPLE = 0xE, /* ver2, Multiple Objects lists*/
302 OSD_V1_ATTR_LIST_CREATE_MULTIPLE = 0xF,/*ver1, used by create_multple*/
303};
304
305/* osd2r03: 7.1.3.4 Multi-object retrieved attributes format */
306struct osd_attributes_list_multi_header {
307 __be64 object_id;
308 u8 object_type; /* object_type enum below */
309 u8 reserved[5];
310 __be16 list_bytes;
311 /* followed by struct osd_attributes_list_element's */
312};
313
314struct osdv1_attributes_list_header {
315 u8 type; /* low 4-bit only */
316 u8 pad;
317 __be16 list_bytes; /* Initiator shall set to Zero. Only set by target */
318 /*
319 * type=9 followed by struct osd_attributes_list_element's
320 * type=E followed by struct osd_attributes_list_multi_header's
321 */
322} __packed;
323
324static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h)
325{
326 return be16_to_cpu(h->list_bytes);
327}
328
329/* (osd-r10 6.13)
330 * osd2r03: 6.15 LIST (Table 79) LIST command parameter data.
331 * for root_lstchg below
332 */
333enum {
334 OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */
335 OSD_OBJ_ID_LIST_LSTCHG = 0x2,
336};
337
338/*
339 * osd2r03: 6.15.2 LIST command parameter data
340 * (Also for LIST COLLECTION)
341 */
342struct osd_obj_id_list {
343 __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */
344 __be64 continuation_id;
345 __be32 list_identifier;
346 u8 pad[3];
347 u8 root_lstchg;
348 __be64 object_ids[0];
349} __packed;
350
351static inline bool osd_is_obj_list_done(struct osd_obj_id_list *list,
352 bool *is_changed)
353{
354 *is_changed = (0 != (list->root_lstchg & OSD_OBJ_ID_LIST_LSTCHG));
355 return 0 != list->continuation_id;
356}
357
358/*
359 * osd2r03: 4.12.4.5 The ALLDATA security method
360 */
361struct osd_data_out_integrity_info {
362 __be64 data_bytes;
363 __be64 set_attributes_bytes;
364 __be64 get_attributes_bytes;
365 __be64 integrity_check_value;
366} __packed;
367
368struct osd_data_in_integrity_info {
369 __be64 data_bytes;
370 __be64 retrieved_attributes_bytes;
371 __be64 integrity_check_value;
372} __packed;
373
374struct osd_timestamp {
375 u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */
376} __packed;
377/* FIXME: define helper functions to convert to/from osd time format */
378
379/*
380 * Capability & Security definitions
381 * osd2r03: 4.11.2.2 Capability format
382 * osd2r03: 5.2.8 Security parameters
383 */
384
385struct osd_key_identifier {
386 u8 id[7]; /* if you know why 7 please email bharrosh@panasas.com */
387} __packed;
388
389/* for osd_capability.format */
390enum {
391 OSD_SEC_CAP_FORMAT_NO_CAPS = 0,
392 OSD_SEC_CAP_FORMAT_VER1 = 1,
393 OSD_SEC_CAP_FORMAT_VER2 = 2,
394};
395
396/* security_method */
397enum {
398 OSD_SEC_NOSEC = 0,
399 OSD_SEC_CAPKEY = 1,
400 OSD_SEC_CMDRSP = 2,
401 OSD_SEC_ALLDATA = 3,
402};
403
404enum object_type {
405 OSD_SEC_OBJ_ROOT = 0x1,
406 OSD_SEC_OBJ_PARTITION = 0x2,
407 OSD_SEC_OBJ_COLLECTION = 0x40,
408 OSD_SEC_OBJ_USER = 0x80,
409};
410
411enum osd_capability_bit_masks {
412 OSD_SEC_CAP_APPEND = BIT(0),
413 OSD_SEC_CAP_OBJ_MGMT = BIT(1),
414 OSD_SEC_CAP_REMOVE = BIT(2),
415 OSD_SEC_CAP_CREATE = BIT(3),
416 OSD_SEC_CAP_SET_ATTR = BIT(4),
417 OSD_SEC_CAP_GET_ATTR = BIT(5),
418 OSD_SEC_CAP_WRITE = BIT(6),
419 OSD_SEC_CAP_READ = BIT(7),
420
421 OSD_SEC_CAP_NONE1 = BIT(8),
422 OSD_SEC_CAP_NONE2 = BIT(9),
423 OSD_SEC_CAP_NONE3 = BIT(10),
424 OSD_SEC_CAP_QUERY = BIT(11), /*v2 only*/
425 OSD_SEC_CAP_M_OBJECT = BIT(12), /*v2 only*/
426 OSD_SEC_CAP_POL_SEC = BIT(13),
427 OSD_SEC_CAP_GLOBAL = BIT(14),
428 OSD_SEC_CAP_DEV_MGMT = BIT(15),
429};
430
431/* for object_descriptor_type (hi nibble used) */
432enum {
433 OSD_SEC_OBJ_DESC_NONE = 0, /* Not allowed */
434 OSD_SEC_OBJ_DESC_OBJ = 1 << 4, /* v1: also collection */
435 OSD_SEC_OBJ_DESC_PAR = 2 << 4, /* also root */
436 OSD_SEC_OBJ_DESC_COL = 3 << 4, /* v2 only */
437};
438
439/* (osd-r10:4.9.2.2)
440 * osd2r03:4.11.2.2 Capability format
441 */
442struct osd_capability_head {
443 u8 format; /* low nibble */
444 u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */
445 u8 security_method;
446 u8 reserved1;
447/*04*/ struct osd_timestamp expiration_time;
448/*10*/ u8 audit[20];
449/*30*/ u8 discriminator[12];
450/*42*/ struct osd_timestamp object_created_time;
451/*48*/ u8 object_type;
452/*49*/ u8 permissions_bit_mask[5];
453/*54*/ u8 reserved2;
454/*55*/ u8 object_descriptor_type; /* high nibble */
455} __packed;
456
457/*56 v1*/
458struct osdv1_cap_object_descriptor {
459 union {
460 struct {
461/*56*/ __be32 policy_access_tag;
462/*60*/ __be64 allowed_partition_id;
463/*68*/ __be64 allowed_object_id;
464/*76*/ __be32 reserved;
465 } __packed obj_desc;
466
467/*56*/ u8 object_descriptor[24];
468 };
469} __packed;
470/*80 v1*/
471
472struct osd_capability {
473 struct osd_capability_head h;
474 struct osdv1_cap_object_descriptor od;
475} __packed;
476
477/**
478 * osd_sec_set_caps - set cap-bits into the capabilities header
479 *
480 * @cap: The osd_capability_head to set cap bits to.
481 * @bit_mask: Use an ORed list of enum osd_capability_bit_masks values
482 *
483 * permissions_bit_mask is unaligned use below to set into caps
484 * in a version independent way
485 */
486static inline void osd_sec_set_caps(struct osd_capability_head *cap,
487 u16 bit_mask)
488{
489 /*
490 *Note: The bits above are defined LE order this is because this way
491 * they can grow in the future to more then 16, and still retain
492 * there constant values.
493 */
494 put_unaligned_le16(bit_mask, &cap->permissions_bit_mask);
495}
496
497#endif /* ndef __OSD_PROTOCOL_H__ */
diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h
new file mode 100644
index 000000000000..4c09fee8ae1e
--- /dev/null
+++ b/include/scsi/osd_sec.h
@@ -0,0 +1,45 @@
1/*
2 * osd_sec.h - OSD security manager API
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_SEC_H__
15#define __OSD_SEC_H__
16
17#include "osd_protocol.h"
18#include "osd_types.h"
19
20/*
21 * Contains types and constants of osd capabilities and security
22 * encoding/decoding.
23 * API is trying to keep security abstract so initiator of an object
24 * based pNFS client knows as little as possible about security and
25 * capabilities. It is the Server's osd-initiator place to know more.
26 * Also can be used by osd-target.
27 */
28void osd_sec_encode_caps(void *caps, ...);/* NI */
29void osd_sec_init_nosec_doall_caps(void *caps,
30 const struct osd_obj_id *obj, bool is_collection, const bool is_v1);
31
32bool osd_is_sec_alldata(struct osd_security_parameters *sec_params);
33
34/* Conditionally sign the CDB according to security setting in ocdb
35 * with cap_key */
36void osd_sec_sign_cdb(struct osd_cdb *ocdb, const u8 *cap_key);
37
38/* Unconditionally sign the BIO data with cap_key.
39 * Check for osd_is_sec_alldata() was done prior to calling this. */
40void osd_sec_sign_data(void *data_integ, struct bio *bio, const u8 *cap_key);
41
42/* Version independent copy of caps into the cdb */
43void osd_set_caps(struct osd_cdb *cdb, const void *caps);
44
45#endif /* ndef __OSD_SEC_H__ */
diff --git a/include/scsi/osd_types.h b/include/scsi/osd_types.h
new file mode 100644
index 000000000000..3f5e88cc75c0
--- /dev/null
+++ b/include/scsi/osd_types.h
@@ -0,0 +1,40 @@
1/*
2 * osd_types.h - Types and constants which are not part of the protocol.
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 * Contains types and constants that are implementation specific and are
14 * used by more than one part of the osd library.
15 * (Eg initiator/target/security_manager/...)
16 */
17#ifndef __OSD_TYPES_H__
18#define __OSD_TYPES_H__
19
20struct osd_systemid {
21 u8 data[OSD_SYSTEMID_LEN];
22};
23
24typedef u64 __bitwise osd_id;
25
26struct osd_obj_id {
27 osd_id partition;
28 osd_id id;
29};
30
31static const struct __weak osd_obj_id osd_root_object = {0, 0};
32
33struct osd_attr {
34 u32 attr_page;
35 u32 attr_id;
36 u16 len; /* byte count of operand */
37 void *val_ptr; /* in network order */
38};
39
40#endif /* ndef __OSD_TYPES_H__ */