Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: remove the SCSI OSD library

Now that all the users are gone the SCSI OSD library can be removed as
well.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Christoph Hellwig and committed by
Martin K. Petersen
19fcae3d 80f21213

-3659
-192
Documentation/scsi/osd.txt
··· 1 - The OSD Standard 2 - ================ 3 - OSD (Object-Based Storage Device) is a T10 SCSI command set that is designed 4 - to provide efficient operation of input/output logical units that manage the 5 - allocation, placement, and accessing of variable-size data-storage containers, 6 - called objects. Objects are intended to contain operating system and application 7 - constructs. Each object has associated attributes attached to it, which are 8 - integral part of the object and provide metadata about the object. The standard 9 - defines some common obligatory attributes, but user attributes can be added as 10 - needed. 11 - 12 - See: http://www.t10.org/ftp/t10/drafts/osd2/ for the latest draft for OSD 2 13 - or search the web for "OSD SCSI" 14 - 15 - OSD in the Linux Kernel 16 - ======================= 17 - osd-initiator: 18 - The main component of OSD in Kernel is the osd-initiator library. Its main 19 - user is intended to be the pNFS-over-objects layout driver, which uses objects 20 - as its back-end data storage. Other clients are the other osd parts listed below. 21 - 22 - osd-uld: 23 - This is a SCSI ULD that registers for OSD type devices and provides a testing 24 - platform, both for the in-kernel initiator as well as connected targets. It 25 - currently has no useful user-mode API, though it could have if need be. 26 - 27 - osd target: 28 - There are no current plans for an OSD target implementation in kernel. For all 29 - needs, a user-mode target that is based on the scsi tgt target framework is 30 - available from Ohio Supercomputer Center (OSC) at: 31 - http://www.open-osd.org/bin/view/Main/OscOsdProject 32 - There are several other target implementations. See http://open-osd.org for more 33 - links. 34 - 35 - Files and Folders 36 - ================= 37 - This is the complete list of files included in this work: 38 - include/scsi/ 39 - osd_initiator.h Main API for the initiator library 40 - osd_types.h Common OSD types 41 - osd_sec.h Security Manager API 42 - osd_protocol.h Wire definitions of the OSD standard protocol 43 - osd_attributes.h Wire definitions of OSD attributes 44 - 45 - drivers/scsi/osd/ 46 - osd_initiator.c OSD-Initiator library implementation 47 - osd_uld.c The OSD scsi ULD 48 - osd_ktest.{h,c} In-kernel test suite (called by osd_uld) 49 - osd_debug.h Some printk macros 50 - Makefile For both in-tree and out-of-tree compilation 51 - Kconfig Enables inclusion of the different pieces 52 - osd_test.c User-mode application to call the kernel tests 53 - 54 - The OSD-Initiator Library 55 - ========================= 56 - osd_initiator is a low level implementation of an osd initiator encoder. 57 - But even though, it should be intuitive and easy to use. Perhaps over time an 58 - higher lever will form that automates some of the more common recipes. 59 - 60 - init/fini: 61 - - osd_dev_init() associates a scsi_device with an osd_dev structure 62 - and initializes some global pools. This should be done once per scsi_device 63 - (OSD LUN). The osd_dev structure is needed for calling osd_start_request(). 64 - 65 - - osd_dev_fini() cleans up before a osd_dev/scsi_device destruction. 66 - 67 - OSD commands encoding, execution, and decoding of results: 68 - 69 - struct osd_request's is used to iteratively encode an OSD command and carry 70 - its state throughout execution. Each request goes through these stages: 71 - 72 - a. osd_start_request() allocates the request. 73 - 74 - b. Any of the osd_req_* methods is used to encode a request of the specified 75 - type. 76 - 77 - c. osd_req_add_{get,set}_attr_* may be called to add get/set attributes to the 78 - CDB. "List" or "Page" mode can be used exclusively. The attribute-list API 79 - can be called multiple times on the same request. However, only one 80 - attribute-page can be read, as mandated by the OSD standard. 81 - 82 - d. osd_finalize_request() computes offsets into the data-in and data-out buffers 83 - and signs the request using the provided capability key and integrity- 84 - check parameters. 85 - 86 - e. osd_execute_request() may be called to execute the request via the block 87 - layer and wait for its completion. The request can be executed 88 - asynchronously by calling the block layer API directly. 89 - 90 - f. After execution, osd_req_decode_sense() can be called to decode the request's 91 - sense information. 92 - 93 - g. osd_req_decode_get_attr() may be called to retrieve osd_add_get_attr_list() 94 - values. 95 - 96 - h. osd_end_request() must be called to deallocate the request and any resource 97 - associated with it. Note that osd_end_request cleans up the request at any 98 - stage and it must always be called after a successful osd_start_request(). 99 - 100 - osd_request's structure: 101 - 102 - The OSD standard defines a complex structure of IO segments pointed to by 103 - members in the CDB. Up to 3 segments can be deployed in the IN-Buffer and up to 104 - 4 in the OUT-Buffer. The ASCII illustration below depicts a secure-read with 105 - associated get+set of attributes-lists. Other combinations very on the same 106 - basic theme. From no-segments-used up to all-segments-used. 107 - 108 - |________OSD-CDB__________| 109 - | | 110 - |read_len (offset=0) -|---------\ 111 - | | | 112 - |get_attrs_list_length | | 113 - |get_attrs_list_offset -|----\ | 114 - | | | | 115 - |retrieved_attrs_alloc_len| | | 116 - |retrieved_attrs_offset -|----|----|-\ 117 - | | | | | 118 - |set_attrs_list_length | | | | 119 - |set_attrs_list_offset -|-\ | | | 120 - | | | | | | 121 - |in_data_integ_offset -|-|--|----|-|-\ 122 - |out_data_integ_offset -|-|--|--\ | | | 123 - \_________________________/ | | | | | | 124 - | | | | | | 125 - |_______OUT-BUFFER________| | | | | | | 126 - | Set attr list |</ | | | | | 127 - | | | | | | | 128 - |-------------------------| | | | | | 129 - | Get attr descriptors |<---/ | | | | 130 - | | | | | | 131 - |-------------------------| | | | | 132 - | Out-data integrity |<------/ | | | 133 - | | | | | 134 - \_________________________/ | | | 135 - | | | 136 - |________IN-BUFFER________| | | | 137 - | In-Data read |<--------/ | | 138 - | | | | 139 - |-------------------------| | | 140 - | Get attr list |<----------/ | 141 - | | | 142 - |-------------------------| | 143 - | In-data integrity |<------------/ 144 - | | 145 - \_________________________/ 146 - 147 - A block device request can carry bidirectional payload by means of associating 148 - a bidi_read request with a main write-request. Each in/out request is described 149 - by a chain of BIOs associated with each request. 150 - The CDB is of a SCSI VARLEN CDB format, as described by OSD standard. 151 - The OSD standard also mandates alignment restrictions at start of each segment. 152 - 153 - In the code, in struct osd_request, there are two _osd_io_info structures to 154 - describe the IN/OUT buffers above, two BIOs for the data payload and up to five 155 - _osd_req_data_segment structures to hold the different segments allocation and 156 - information. 157 - 158 - Important: We have chosen to disregard the assumption that a BIO-chain (and 159 - the resulting sg-list) describes a linear memory buffer. Meaning only first and 160 - last scatter chain can be incomplete and all the middle chains are of PAGE_SIZE. 161 - For us, a scatter-gather-list, as its name implies and as used by the Networking 162 - layer, is to describe a vector of buffers that will be transferred to/from the 163 - wire. It works very well with current iSCSI transport. iSCSI is currently the 164 - only deployed OSD transport. In the future we anticipate SAS and FC attached OSD 165 - devices as well. 166 - 167 - The OSD Testing ULD 168 - =================== 169 - TODO: More user-mode control on tests. 170 - 171 - Authors, Mailing list 172 - ===================== 173 - Please communicate with us on any deployment of osd, whether using this code 174 - or not. 175 - 176 - Any problems, questions, bug reports, lonely OSD nights, please email: 177 - OSD Dev List <osd-dev@open-osd.org> 178 - 179 - More up-to-date information can be found on: 180 - http://open-osd.org 181 - 182 - Boaz Harrosh <ooo@electrozaur.com> 183 - 184 - References 185 - ========== 186 - Weber, R., "SCSI Object-Based Storage Device Commands", 187 - T10/1355-D ANSI/INCITS 400-2004, 188 - http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf 189 - 190 - Weber, R., "SCSI Object-Based Storage Device Commands -2 (OSD-2)" 191 - T10/1729-D, Working Draft, rev. 3 192 - http://www.t10.org/ftp/t10/drafts/osd2/osd2r03.pdf
-6
MAINTAINERS
··· 11385 11385 S: Orphan 11386 11386 F: drivers/net/wireless/intersil/orinoco/ 11387 11387 11388 - OSD LIBRARY and FILESYSTEM 11389 - M: Boaz Harrosh <ooo@electrozaur.com> 11390 - S: Maintained 11391 - F: drivers/scsi/osd/ 11392 - F: include/scsi/osd_* 11393 - 11394 11388 OV2659 OMNIVISION SENSOR DRIVER 11395 11389 M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com> 11396 11390 L: linux-media@vger.kernel.org
-2
drivers/scsi/Kconfig
··· 1515 1515 1516 1516 source "drivers/scsi/device_handler/Kconfig" 1517 1517 1518 - source "drivers/scsi/osd/Kconfig" 1519 - 1520 1518 endmenu
-1
drivers/scsi/Makefile
··· 150 150 obj-$(CONFIG_CHR_DEV_SCH) += ch.o 151 151 obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o 152 152 153 - obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/ 154 153 obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas/ 155 154 156 155 # This goes last, so that "real" scsi devices probe earlier
-20
drivers/scsi/osd/Kbuild
··· 1 - # 2 - # Kbuild for the OSD modules 3 - # 4 - # Copyright (C) 2008 Panasas Inc. All rights reserved. 5 - # 6 - # Authors: 7 - # Boaz Harrosh <ooo@electrozaur.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 - # libosd.ko - osd-initiator library 15 - libosd-y := osd_initiator.o 16 - obj-$(CONFIG_SCSI_OSD_INITIATOR) += libosd.o 17 - 18 - # osd.ko - SCSI ULD and char-device 19 - osd-y := osd_uld.o 20 - obj-$(CONFIG_SCSI_OSD_ULD) += osd.o
-49
drivers/scsi/osd/Kconfig
··· 1 - # 2 - # Kernel configuration file for the OSD scsi protocol 3 - # 4 - # Copyright (C) 2008 Panasas Inc. All rights reserved. 5 - # 6 - # Authors: 7 - # Boaz Harrosh <ooo@electrozaur.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 version 2 License as 12 - # published by the Free Software Foundation 13 - # 14 - config SCSI_OSD_INITIATOR 15 - tristate "OSD-Initiator library" 16 - depends on SCSI 17 - help 18 - Enable the OSD-Initiator library (libosd.ko). 19 - NOTE: You must also select CRYPTO_SHA1 + CRYPTO_HMAC and their 20 - dependencies 21 - 22 - config SCSI_OSD_ULD 23 - tristate "OSD Upper Level driver" 24 - depends on SCSI_OSD_INITIATOR 25 - help 26 - Build a SCSI upper layer driver that exports /dev/osdX devices 27 - to user-mode for testing and controlling OSD devices. It is also 28 - needed by exofs, for mounting an OSD based file system. 29 - 30 - config SCSI_OSD_DPRINT_SENSE 31 - int "(0-2) When sense is returned, DEBUG print all sense descriptors" 32 - default 1 33 - depends on SCSI_OSD_INITIATOR 34 - help 35 - When a CHECK_CONDITION status is returned from a target, and a 36 - sense-buffer is retrieved, turning this on will dump a full 37 - sense-decoding message. Setting to 2 will also print recoverable 38 - errors that might be regularly returned for some filesystem 39 - operations. 40 - 41 - config SCSI_OSD_DEBUG 42 - bool "Compile All OSD modules with lots of DEBUG prints" 43 - default n 44 - depends on SCSI_OSD_INITIATOR 45 - help 46 - OSD Code is populated with lots of OSD_DEBUG(..) printouts to 47 - dmesg. Enable this if you found a bug and you want to help us 48 - track the problem (see also MAINTAINERS). Setting this will also 49 - force SCSI_OSD_DPRINT_SENSE=2.
-30
drivers/scsi/osd/osd_debug.h
··· 1 - /* 2 - * osd_debug.h - Some kprintf macros 3 - * 4 - * Copyright (C) 2008 Panasas Inc. All rights reserved. 5 - * 6 - * Authors: 7 - * Boaz Harrosh <ooo@electrozaur.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__ */
-2076
drivers/scsi/osd/osd_initiator.c
··· 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 <ooo@electrozaur.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 <linux/slab.h> 43 - #include <linux/module.h> 44 - 45 - #include <scsi/osd_initiator.h> 46 - #include <scsi/osd_sec.h> 47 - #include <scsi/osd_attributes.h> 48 - #include <scsi/osd_sense.h> 49 - 50 - #include <scsi/scsi_device.h> 51 - #include <scsi/scsi_request.h> 52 - 53 - #include "osd_debug.h" 54 - 55 - #ifndef __unused 56 - # define __unused __attribute__((unused)) 57 - #endif 58 - 59 - enum { OSD_REQ_RETRIES = 1 }; 60 - 61 - MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>"); 62 - MODULE_DESCRIPTION("open-osd initiator library libosd.ko"); 63 - MODULE_LICENSE("GPL"); 64 - 65 - static inline void build_test(void) 66 - { 67 - /* structures were not packed */ 68 - BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); 69 - BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN); 70 - BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 71 - } 72 - 73 - static const char *_osd_ver_desc(struct osd_request *or) 74 - { 75 - return osd_req_is_ver1(or) ? "OSD1" : "OSD2"; 76 - } 77 - 78 - #define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len) 79 - 80 - static int _osd_get_print_system_info(struct osd_dev *od, 81 - void *caps, struct osd_dev_info *odi) 82 - { 83 - struct osd_request *or; 84 - struct osd_attr get_attrs[] = { 85 - ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8), 86 - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16), 87 - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32), 88 - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4), 89 - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/), 90 - ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/), 91 - ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8), 92 - ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8), 93 - ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8), 94 - ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6), 95 - /* IBM-OSD-SIM Has a bug with this one put it last */ 96 - ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20), 97 - }; 98 - void *iter = NULL, *pFirst; 99 - int nelem = ARRAY_SIZE(get_attrs), a = 0; 100 - int ret; 101 - 102 - or = osd_start_request(od); 103 - if (!or) 104 - return -ENOMEM; 105 - 106 - /* get attrs */ 107 - osd_req_get_attributes(or, &osd_root_object); 108 - osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs)); 109 - 110 - ret = osd_finalize_request(or, 0, caps, NULL); 111 - if (ret) 112 - goto out; 113 - 114 - ret = osd_execute_request(or); 115 - if (ret) { 116 - OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret); 117 - goto out; 118 - } 119 - 120 - osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter); 121 - 122 - OSD_INFO("Detected %s device\n", 123 - _osd_ver_desc(or)); 124 - 125 - pFirst = get_attrs[a++].val_ptr; 126 - OSD_INFO("VENDOR_IDENTIFICATION [%s]\n", 127 - (char *)pFirst); 128 - 129 - pFirst = get_attrs[a++].val_ptr; 130 - OSD_INFO("PRODUCT_IDENTIFICATION [%s]\n", 131 - (char *)pFirst); 132 - 133 - pFirst = get_attrs[a++].val_ptr; 134 - OSD_INFO("PRODUCT_MODEL [%s]\n", 135 - (char *)pFirst); 136 - 137 - pFirst = get_attrs[a++].val_ptr; 138 - OSD_INFO("PRODUCT_REVISION_LEVEL [%u]\n", 139 - pFirst ? get_unaligned_be32(pFirst) : ~0U); 140 - 141 - pFirst = get_attrs[a++].val_ptr; 142 - OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n", 143 - (char *)pFirst); 144 - 145 - odi->osdname_len = get_attrs[a].len; 146 - /* Avoid NULL for memcmp optimization 0-length is good enough */ 147 - odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL); 148 - if (!odi->osdname) { 149 - ret = -ENOMEM; 150 - goto out; 151 - } 152 - if (odi->osdname_len) 153 - memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len); 154 - OSD_INFO("OSD_NAME [%s]\n", odi->osdname); 155 - a++; 156 - 157 - pFirst = get_attrs[a++].val_ptr; 158 - OSD_INFO("TOTAL_CAPACITY [0x%llx]\n", 159 - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 160 - 161 - pFirst = get_attrs[a++].val_ptr; 162 - OSD_INFO("USED_CAPACITY [0x%llx]\n", 163 - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 164 - 165 - pFirst = get_attrs[a++].val_ptr; 166 - OSD_INFO("NUMBER_OF_PARTITIONS [%llu]\n", 167 - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 168 - 169 - if (a >= nelem) 170 - goto out; 171 - 172 - /* FIXME: Where are the time utilities */ 173 - pFirst = get_attrs[a++].val_ptr; 174 - OSD_INFO("CLOCK [0x%6phN]\n", pFirst); 175 - 176 - if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */ 177 - unsigned len = get_attrs[a].len; 178 - char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */ 179 - 180 - hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1, 181 - sid_dump, sizeof(sid_dump), true); 182 - OSD_INFO("OSD_SYSTEM_ID(%d)\n" 183 - " [%s]\n", len, sid_dump); 184 - 185 - if (unlikely(len > sizeof(odi->systemid))) { 186 - OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). " 187 - "device identification might not work\n", len); 188 - len = sizeof(odi->systemid); 189 - } 190 - odi->systemid_len = len; 191 - memcpy(odi->systemid, get_attrs[a].val_ptr, len); 192 - a++; 193 - } 194 - out: 195 - osd_end_request(or); 196 - return ret; 197 - } 198 - 199 - int osd_auto_detect_ver(struct osd_dev *od, 200 - void *caps, struct osd_dev_info *odi) 201 - { 202 - int ret; 203 - 204 - /* Auto-detect the osd version */ 205 - ret = _osd_get_print_system_info(od, caps, odi); 206 - if (ret) { 207 - osd_dev_set_ver(od, OSD_VER1); 208 - OSD_DEBUG("converting to OSD1\n"); 209 - ret = _osd_get_print_system_info(od, caps, odi); 210 - } 211 - 212 - return ret; 213 - } 214 - EXPORT_SYMBOL(osd_auto_detect_ver); 215 - 216 - static unsigned _osd_req_cdb_len(struct osd_request *or) 217 - { 218 - return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN; 219 - } 220 - 221 - static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) 222 - { 223 - return osd_req_is_ver1(or) ? 224 - osdv1_attr_list_elem_size(len) : 225 - osdv2_attr_list_elem_size(len); 226 - } 227 - 228 - static void _osd_req_alist_elem_encode(struct osd_request *or, 229 - void *attr_last, const struct osd_attr *oa) 230 - { 231 - if (osd_req_is_ver1(or)) { 232 - struct osdv1_attributes_list_element *attr = attr_last; 233 - 234 - attr->attr_page = cpu_to_be32(oa->attr_page); 235 - attr->attr_id = cpu_to_be32(oa->attr_id); 236 - attr->attr_bytes = cpu_to_be16(oa->len); 237 - memcpy(attr->attr_val, oa->val_ptr, oa->len); 238 - } else { 239 - struct osdv2_attributes_list_element *attr = attr_last; 240 - 241 - attr->attr_page = cpu_to_be32(oa->attr_page); 242 - attr->attr_id = cpu_to_be32(oa->attr_id); 243 - attr->attr_bytes = cpu_to_be16(oa->len); 244 - memcpy(attr->attr_val, oa->val_ptr, oa->len); 245 - } 246 - } 247 - 248 - static int _osd_req_alist_elem_decode(struct osd_request *or, 249 - void *cur_p, struct osd_attr *oa, unsigned max_bytes) 250 - { 251 - unsigned inc; 252 - if (osd_req_is_ver1(or)) { 253 - struct osdv1_attributes_list_element *attr = cur_p; 254 - 255 - if (max_bytes < sizeof(*attr)) 256 - return -1; 257 - 258 - oa->len = be16_to_cpu(attr->attr_bytes); 259 - inc = _osd_req_alist_elem_size(or, oa->len); 260 - if (inc > max_bytes) 261 - return -1; 262 - 263 - oa->attr_page = be32_to_cpu(attr->attr_page); 264 - oa->attr_id = be32_to_cpu(attr->attr_id); 265 - 266 - /* OSD1: On empty attributes we return a pointer to 2 bytes 267 - * of zeros. This keeps similar behaviour with OSD2. 268 - * (See below) 269 - */ 270 - oa->val_ptr = likely(oa->len) ? attr->attr_val : 271 - (u8 *)&attr->attr_bytes; 272 - } else { 273 - struct osdv2_attributes_list_element *attr = cur_p; 274 - 275 - if (max_bytes < sizeof(*attr)) 276 - return -1; 277 - 278 - oa->len = be16_to_cpu(attr->attr_bytes); 279 - inc = _osd_req_alist_elem_size(or, oa->len); 280 - if (inc > max_bytes) 281 - return -1; 282 - 283 - oa->attr_page = be32_to_cpu(attr->attr_page); 284 - oa->attr_id = be32_to_cpu(attr->attr_id); 285 - 286 - /* OSD2: For convenience, on empty attributes, we return 8 bytes 287 - * of zeros here. This keeps the same behaviour with OSD2r04, 288 - * and is nice with null terminating ASCII fields. 289 - * oa->val_ptr == NULL marks the end-of-list, or error. 290 - */ 291 - oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved; 292 - } 293 - return inc; 294 - } 295 - 296 - static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 297 - { 298 - return osd_req_is_ver1(or) ? 299 - osdv1_list_size(list_head) : 300 - osdv2_list_size(list_head); 301 - } 302 - 303 - static unsigned _osd_req_sizeof_alist_header(struct osd_request *or) 304 - { 305 - return osd_req_is_ver1(or) ? 306 - sizeof(struct osdv1_attributes_list_header) : 307 - sizeof(struct osdv2_attributes_list_header); 308 - } 309 - 310 - static void _osd_req_set_alist_type(struct osd_request *or, 311 - void *list, int list_type) 312 - { 313 - if (osd_req_is_ver1(or)) { 314 - struct osdv1_attributes_list_header *attr_list = list; 315 - 316 - memset(attr_list, 0, sizeof(*attr_list)); 317 - attr_list->type = list_type; 318 - } else { 319 - struct osdv2_attributes_list_header *attr_list = list; 320 - 321 - memset(attr_list, 0, sizeof(*attr_list)); 322 - attr_list->type = list_type; 323 - } 324 - } 325 - 326 - static bool _osd_req_is_alist_type(struct osd_request *or, 327 - void *list, int list_type) 328 - { 329 - if (!list) 330 - return false; 331 - 332 - if (osd_req_is_ver1(or)) { 333 - struct osdv1_attributes_list_header *attr_list = list; 334 - 335 - return attr_list->type == list_type; 336 - } else { 337 - struct osdv2_attributes_list_header *attr_list = list; 338 - 339 - return attr_list->type == list_type; 340 - } 341 - } 342 - 343 - /* This is for List-objects not Attributes-Lists */ 344 - static void _osd_req_encode_olist(struct osd_request *or, 345 - struct osd_obj_id_list *list) 346 - { 347 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 348 - 349 - if (osd_req_is_ver1(or)) { 350 - cdbh->v1.list_identifier = list->list_identifier; 351 - cdbh->v1.start_address = list->continuation_id; 352 - } else { 353 - cdbh->v2.list_identifier = list->list_identifier; 354 - cdbh->v2.start_address = list->continuation_id; 355 - } 356 - } 357 - 358 - static osd_cdb_offset osd_req_encode_offset(struct osd_request *or, 359 - u64 offset, unsigned *padding) 360 - { 361 - return __osd_encode_offset(offset, padding, 362 - osd_req_is_ver1(or) ? 363 - OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT, 364 - OSD_OFFSET_MAX_SHIFT); 365 - } 366 - 367 - static struct osd_security_parameters * 368 - _osd_req_sec_params(struct osd_request *or) 369 - { 370 - struct osd_cdb *ocdb = &or->cdb; 371 - 372 - if (osd_req_is_ver1(or)) 373 - return (struct osd_security_parameters *)&ocdb->v1.sec_params; 374 - else 375 - return (struct osd_security_parameters *)&ocdb->v2.sec_params; 376 - } 377 - 378 - void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 379 - { 380 - memset(osdd, 0, sizeof(*osdd)); 381 - osdd->scsi_device = scsi_device; 382 - osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; 383 - #ifdef OSD_VER1_SUPPORT 384 - osdd->version = OSD_VER2; 385 - #endif 386 - /* TODO: Allocate pools for osd_request attributes ... */ 387 - } 388 - EXPORT_SYMBOL(osd_dev_init); 389 - 390 - void osd_dev_fini(struct osd_dev *osdd) 391 - { 392 - /* TODO: De-allocate pools */ 393 - 394 - osdd->scsi_device = NULL; 395 - } 396 - EXPORT_SYMBOL(osd_dev_fini); 397 - 398 - static struct osd_request *_osd_request_alloc(gfp_t gfp) 399 - { 400 - struct osd_request *or; 401 - 402 - /* TODO: Use mempool with one saved request */ 403 - or = kzalloc(sizeof(*or), gfp); 404 - return or; 405 - } 406 - 407 - static void _osd_request_free(struct osd_request *or) 408 - { 409 - kfree(or); 410 - } 411 - 412 - struct osd_request *osd_start_request(struct osd_dev *dev) 413 - { 414 - struct osd_request *or; 415 - 416 - or = _osd_request_alloc(GFP_KERNEL); 417 - if (!or) 418 - return NULL; 419 - 420 - or->osd_dev = dev; 421 - or->timeout = dev->def_timeout; 422 - or->retries = OSD_REQ_RETRIES; 423 - 424 - return or; 425 - } 426 - EXPORT_SYMBOL(osd_start_request); 427 - 428 - static void _osd_free_seg(struct osd_request *or __unused, 429 - struct _osd_req_data_segment *seg) 430 - { 431 - if (!seg->buff || !seg->alloc_size) 432 - return; 433 - 434 - kfree(seg->buff); 435 - seg->buff = NULL; 436 - seg->alloc_size = 0; 437 - } 438 - 439 - static void _put_request(struct request *rq) 440 - { 441 - /* 442 - * If osd_finalize_request() was called but the request was not 443 - * executed through the block layer, then we must release BIOs. 444 - * TODO: Keep error code in or->async_error. Need to audit all 445 - * code paths. 446 - */ 447 - if (unlikely(rq->bio)) 448 - blk_mq_end_request(rq, BLK_STS_IOERR); 449 - else 450 - blk_put_request(rq); 451 - } 452 - 453 - void osd_end_request(struct osd_request *or) 454 - { 455 - struct request *rq = or->request; 456 - 457 - if (rq) { 458 - if (rq->next_rq) { 459 - _put_request(rq->next_rq); 460 - rq->next_rq = NULL; 461 - } 462 - 463 - _put_request(rq); 464 - } 465 - 466 - _osd_free_seg(or, &or->get_attr); 467 - _osd_free_seg(or, &or->enc_get_attr); 468 - _osd_free_seg(or, &or->set_attr); 469 - _osd_free_seg(or, &or->cdb_cont); 470 - 471 - _osd_request_free(or); 472 - } 473 - EXPORT_SYMBOL(osd_end_request); 474 - 475 - static void _set_error_resid(struct osd_request *or, struct request *req, 476 - blk_status_t error) 477 - { 478 - or->async_error = error; 479 - or->req_errors = scsi_req(req)->result; 480 - or->sense_len = scsi_req(req)->sense_len; 481 - if (or->sense_len) 482 - memcpy(or->sense, scsi_req(req)->sense, or->sense_len); 483 - if (or->out.req) 484 - or->out.residual = scsi_req(or->out.req)->resid_len; 485 - if (or->in.req) 486 - or->in.residual = scsi_req(or->in.req)->resid_len; 487 - } 488 - 489 - int osd_execute_request(struct osd_request *or) 490 - { 491 - blk_execute_rq(or->request->q, NULL, or->request, 0); 492 - 493 - if (scsi_req(or->request)->result) { 494 - _set_error_resid(or, or->request, BLK_STS_IOERR); 495 - return -EIO; 496 - } 497 - 498 - _set_error_resid(or, or->request, BLK_STS_OK); 499 - return 0; 500 - } 501 - EXPORT_SYMBOL(osd_execute_request); 502 - 503 - static void osd_request_async_done(struct request *req, blk_status_t error) 504 - { 505 - struct osd_request *or = req->end_io_data; 506 - 507 - _set_error_resid(or, req, error); 508 - if (req->next_rq) { 509 - blk_put_request(req->next_rq); 510 - req->next_rq = NULL; 511 - } 512 - 513 - blk_put_request(req); 514 - or->request = NULL; 515 - or->in.req = NULL; 516 - or->out.req = NULL; 517 - 518 - if (or->async_done) 519 - or->async_done(or, or->async_private); 520 - else 521 - osd_end_request(or); 522 - } 523 - 524 - int osd_execute_request_async(struct osd_request *or, 525 - osd_req_done_fn *done, void *private) 526 - { 527 - or->request->end_io_data = or; 528 - or->async_private = private; 529 - or->async_done = done; 530 - 531 - blk_execute_rq_nowait(or->request->q, NULL, or->request, 0, 532 - osd_request_async_done); 533 - return 0; 534 - } 535 - EXPORT_SYMBOL(osd_execute_request_async); 536 - 537 - u8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 538 - u8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 539 - 540 - static int _osd_realloc_seg(struct osd_request *or, 541 - struct _osd_req_data_segment *seg, unsigned max_bytes) 542 - { 543 - void *buff; 544 - 545 - if (seg->alloc_size >= max_bytes) 546 - return 0; 547 - 548 - buff = krealloc(seg->buff, max_bytes, GFP_KERNEL); 549 - if (!buff) { 550 - OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes, 551 - seg->alloc_size); 552 - return -ENOMEM; 553 - } 554 - 555 - memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size); 556 - seg->buff = buff; 557 - seg->alloc_size = max_bytes; 558 - return 0; 559 - } 560 - 561 - static int _alloc_cdb_cont(struct osd_request *or, unsigned total_bytes) 562 - { 563 - OSD_DEBUG("total_bytes=%d\n", total_bytes); 564 - return _osd_realloc_seg(or, &or->cdb_cont, total_bytes); 565 - } 566 - 567 - static int _alloc_set_attr_list(struct osd_request *or, 568 - const struct osd_attr *oa, unsigned nelem, unsigned add_bytes) 569 - { 570 - unsigned total_bytes = add_bytes; 571 - 572 - for (; nelem; --nelem, ++oa) 573 - total_bytes += _osd_req_alist_elem_size(or, oa->len); 574 - 575 - OSD_DEBUG("total_bytes=%d\n", total_bytes); 576 - return _osd_realloc_seg(or, &or->set_attr, total_bytes); 577 - } 578 - 579 - static int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes) 580 - { 581 - OSD_DEBUG("total_bytes=%d\n", max_bytes); 582 - return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes); 583 - } 584 - 585 - static int _alloc_get_attr_list(struct osd_request *or) 586 - { 587 - OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes); 588 - return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes); 589 - } 590 - 591 - /* 592 - * Common to all OSD commands 593 - */ 594 - 595 - static void _osdv1_req_encode_common(struct osd_request *or, 596 - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 597 - { 598 - struct osdv1_cdb *ocdb = &or->cdb.v1; 599 - 600 - /* 601 - * For speed, the commands 602 - * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C 603 - * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D 604 - * are not supported here. Should pass zero and set after the call 605 - */ 606 - act &= cpu_to_be16(~0x0080); /* V1 action code */ 607 - 608 - OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act)); 609 - 610 - ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 611 - ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 612 - ocdb->h.varlen_cdb.service_action = act; 613 - 614 - ocdb->h.partition = cpu_to_be64(obj->partition); 615 - ocdb->h.object = cpu_to_be64(obj->id); 616 - ocdb->h.v1.length = cpu_to_be64(len); 617 - ocdb->h.v1.start_address = cpu_to_be64(offset); 618 - } 619 - 620 - static void _osdv2_req_encode_common(struct osd_request *or, 621 - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 622 - { 623 - struct osdv2_cdb *ocdb = &or->cdb.v2; 624 - 625 - OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act)); 626 - 627 - ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 628 - ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 629 - ocdb->h.varlen_cdb.service_action = act; 630 - 631 - ocdb->h.partition = cpu_to_be64(obj->partition); 632 - ocdb->h.object = cpu_to_be64(obj->id); 633 - ocdb->h.v2.length = cpu_to_be64(len); 634 - ocdb->h.v2.start_address = cpu_to_be64(offset); 635 - } 636 - 637 - static void _osd_req_encode_common(struct osd_request *or, 638 - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 639 - { 640 - if (osd_req_is_ver1(or)) 641 - _osdv1_req_encode_common(or, act, obj, offset, len); 642 - else 643 - _osdv2_req_encode_common(or, act, obj, offset, len); 644 - } 645 - 646 - /* 647 - * Device commands 648 - */ 649 - /*TODO: void osd_req_set_master_seed_xchg(struct osd_request *, ...); */ 650 - /*TODO: void osd_req_set_master_key(struct osd_request *, ...); */ 651 - 652 - void osd_req_format(struct osd_request *or, u64 tot_capacity) 653 - { 654 - _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0, 655 - tot_capacity); 656 - } 657 - EXPORT_SYMBOL(osd_req_format); 658 - 659 - int osd_req_list_dev_partitions(struct osd_request *or, 660 - osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem) 661 - { 662 - return osd_req_list_partition_objects(or, 0, initial_id, list, nelem); 663 - } 664 - EXPORT_SYMBOL(osd_req_list_dev_partitions); 665 - 666 - static void _osd_req_encode_flush(struct osd_request *or, 667 - enum osd_options_flush_scope_values op) 668 - { 669 - struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb); 670 - 671 - ocdb->command_specific_options = op; 672 - } 673 - 674 - void osd_req_flush_obsd(struct osd_request *or, 675 - enum osd_options_flush_scope_values op) 676 - { 677 - _osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0); 678 - _osd_req_encode_flush(or, op); 679 - } 680 - EXPORT_SYMBOL(osd_req_flush_obsd); 681 - 682 - /*TODO: void osd_req_perform_scsi_command(struct osd_request *, 683 - const u8 *cdb, ...); */ 684 - /*TODO: void osd_req_task_management(struct osd_request *, ...); */ 685 - 686 - /* 687 - * Partition commands 688 - */ 689 - static void _osd_req_encode_partition(struct osd_request *or, 690 - __be16 act, osd_id partition) 691 - { 692 - struct osd_obj_id par = { 693 - .partition = partition, 694 - .id = 0, 695 - }; 696 - 697 - _osd_req_encode_common(or, act, &par, 0, 0); 698 - } 699 - 700 - void osd_req_create_partition(struct osd_request *or, osd_id partition) 701 - { 702 - _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition); 703 - } 704 - EXPORT_SYMBOL(osd_req_create_partition); 705 - 706 - void osd_req_remove_partition(struct osd_request *or, osd_id partition) 707 - { 708 - _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition); 709 - } 710 - EXPORT_SYMBOL(osd_req_remove_partition); 711 - 712 - /*TODO: void osd_req_set_partition_key(struct osd_request *, 713 - osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE], 714 - u8 seed[OSD_CRYPTO_SEED_SIZE]); */ 715 - 716 - static int _osd_req_list_objects(struct osd_request *or, 717 - __be16 action, const struct osd_obj_id *obj, osd_id initial_id, 718 - struct osd_obj_id_list *list, unsigned nelem) 719 - { 720 - struct request_queue *q = osd_request_queue(or->osd_dev); 721 - u64 len = nelem * sizeof(osd_id) + sizeof(*list); 722 - struct bio *bio; 723 - 724 - _osd_req_encode_common(or, action, obj, (u64)initial_id, len); 725 - 726 - if (list->list_identifier) 727 - _osd_req_encode_olist(or, list); 728 - 729 - WARN_ON(or->in.bio); 730 - bio = bio_map_kern(q, list, len, GFP_KERNEL); 731 - if (IS_ERR(bio)) { 732 - OSD_ERR("!!! Failed to allocate list_objects BIO\n"); 733 - return PTR_ERR(bio); 734 - } 735 - 736 - bio_set_op_attrs(bio, REQ_OP_READ, 0); 737 - or->in.bio = bio; 738 - or->in.total_bytes = bio->bi_iter.bi_size; 739 - return 0; 740 - } 741 - 742 - int osd_req_list_partition_collections(struct osd_request *or, 743 - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 744 - unsigned nelem) 745 - { 746 - struct osd_obj_id par = { 747 - .partition = partition, 748 - .id = 0, 749 - }; 750 - 751 - return osd_req_list_collection_objects(or, &par, initial_id, list, 752 - nelem); 753 - } 754 - EXPORT_SYMBOL(osd_req_list_partition_collections); 755 - 756 - int osd_req_list_partition_objects(struct osd_request *or, 757 - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 758 - unsigned nelem) 759 - { 760 - struct osd_obj_id par = { 761 - .partition = partition, 762 - .id = 0, 763 - }; 764 - 765 - return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list, 766 - nelem); 767 - } 768 - EXPORT_SYMBOL(osd_req_list_partition_objects); 769 - 770 - void osd_req_flush_partition(struct osd_request *or, 771 - osd_id partition, enum osd_options_flush_scope_values op) 772 - { 773 - _osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition); 774 - _osd_req_encode_flush(or, op); 775 - } 776 - EXPORT_SYMBOL(osd_req_flush_partition); 777 - 778 - /* 779 - * Collection commands 780 - */ 781 - /*TODO: void osd_req_create_collection(struct osd_request *, 782 - const struct osd_obj_id *); */ 783 - /*TODO: void osd_req_remove_collection(struct osd_request *, 784 - const struct osd_obj_id *); */ 785 - 786 - int osd_req_list_collection_objects(struct osd_request *or, 787 - const struct osd_obj_id *obj, osd_id initial_id, 788 - struct osd_obj_id_list *list, unsigned nelem) 789 - { 790 - return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj, 791 - initial_id, list, nelem); 792 - } 793 - EXPORT_SYMBOL(osd_req_list_collection_objects); 794 - 795 - /*TODO: void query(struct osd_request *, ...); V2 */ 796 - 797 - void osd_req_flush_collection(struct osd_request *or, 798 - const struct osd_obj_id *obj, enum osd_options_flush_scope_values op) 799 - { 800 - _osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0); 801 - _osd_req_encode_flush(or, op); 802 - } 803 - EXPORT_SYMBOL(osd_req_flush_collection); 804 - 805 - /*TODO: void get_member_attrs(struct osd_request *, ...); V2 */ 806 - /*TODO: void set_member_attrs(struct osd_request *, ...); V2 */ 807 - 808 - /* 809 - * Object commands 810 - */ 811 - void osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj) 812 - { 813 - _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0); 814 - } 815 - EXPORT_SYMBOL(osd_req_create_object); 816 - 817 - void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj) 818 - { 819 - _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0); 820 - } 821 - EXPORT_SYMBOL(osd_req_remove_object); 822 - 823 - 824 - /*TODO: void osd_req_create_multi(struct osd_request *or, 825 - struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem); 826 - */ 827 - 828 - void osd_req_write(struct osd_request *or, 829 - const struct osd_obj_id *obj, u64 offset, 830 - struct bio *bio, u64 len) 831 - { 832 - _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, len); 833 - WARN_ON(or->out.bio || or->out.total_bytes); 834 - WARN_ON(!op_is_write(bio_op(bio))); 835 - or->out.bio = bio; 836 - or->out.total_bytes = len; 837 - } 838 - EXPORT_SYMBOL(osd_req_write); 839 - 840 - int osd_req_write_kern(struct osd_request *or, 841 - const struct osd_obj_id *obj, u64 offset, void* buff, u64 len) 842 - { 843 - struct request_queue *req_q = osd_request_queue(or->osd_dev); 844 - struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL); 845 - 846 - if (IS_ERR(bio)) 847 - return PTR_ERR(bio); 848 - 849 - bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 850 - osd_req_write(or, obj, offset, bio, len); 851 - return 0; 852 - } 853 - EXPORT_SYMBOL(osd_req_write_kern); 854 - 855 - /*TODO: void osd_req_append(struct osd_request *, 856 - const struct osd_obj_id *, struct bio *data_out); */ 857 - /*TODO: void osd_req_create_write(struct osd_request *, 858 - const struct osd_obj_id *, struct bio *data_out, u64 offset); */ 859 - /*TODO: void osd_req_clear(struct osd_request *, 860 - const struct osd_obj_id *, u64 offset, u64 len); */ 861 - /*TODO: void osd_req_punch(struct osd_request *, 862 - const struct osd_obj_id *, u64 offset, u64 len); V2 */ 863 - 864 - void osd_req_flush_object(struct osd_request *or, 865 - const struct osd_obj_id *obj, enum osd_options_flush_scope_values op, 866 - /*V2*/ u64 offset, /*V2*/ u64 len) 867 - { 868 - if (unlikely(osd_req_is_ver1(or) && (offset || len))) { 869 - OSD_DEBUG("OSD Ver1 flush on specific range ignored\n"); 870 - offset = 0; 871 - len = 0; 872 - } 873 - 874 - _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len); 875 - _osd_req_encode_flush(or, op); 876 - } 877 - EXPORT_SYMBOL(osd_req_flush_object); 878 - 879 - void osd_req_read(struct osd_request *or, 880 - const struct osd_obj_id *obj, u64 offset, 881 - struct bio *bio, u64 len) 882 - { 883 - _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len); 884 - WARN_ON(or->in.bio || or->in.total_bytes); 885 - WARN_ON(op_is_write(bio_op(bio))); 886 - or->in.bio = bio; 887 - or->in.total_bytes = len; 888 - } 889 - EXPORT_SYMBOL(osd_req_read); 890 - 891 - int osd_req_read_kern(struct osd_request *or, 892 - const struct osd_obj_id *obj, u64 offset, void* buff, u64 len) 893 - { 894 - struct request_queue *req_q = osd_request_queue(or->osd_dev); 895 - struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL); 896 - 897 - if (IS_ERR(bio)) 898 - return PTR_ERR(bio); 899 - 900 - osd_req_read(or, obj, offset, bio, len); 901 - return 0; 902 - } 903 - EXPORT_SYMBOL(osd_req_read_kern); 904 - 905 - static int _add_sg_continuation_descriptor(struct osd_request *or, 906 - const struct osd_sg_entry *sglist, unsigned numentries, u64 *len) 907 - { 908 - struct osd_sg_continuation_descriptor *oscd; 909 - u32 oscd_size; 910 - unsigned i; 911 - int ret; 912 - 913 - oscd_size = sizeof(*oscd) + numentries * sizeof(oscd->entries[0]); 914 - 915 - if (!or->cdb_cont.total_bytes) { 916 - /* First time, jump over the header, we will write to: 917 - * cdb_cont.buff + cdb_cont.total_bytes 918 - */ 919 - or->cdb_cont.total_bytes = 920 - sizeof(struct osd_continuation_segment_header); 921 - } 922 - 923 - ret = _alloc_cdb_cont(or, or->cdb_cont.total_bytes + oscd_size); 924 - if (unlikely(ret)) 925 - return ret; 926 - 927 - oscd = or->cdb_cont.buff + or->cdb_cont.total_bytes; 928 - oscd->hdr.type = cpu_to_be16(SCATTER_GATHER_LIST); 929 - oscd->hdr.pad_length = 0; 930 - oscd->hdr.length = cpu_to_be32(oscd_size - sizeof(*oscd)); 931 - 932 - *len = 0; 933 - /* copy the sg entries and convert to network byte order */ 934 - for (i = 0; i < numentries; i++) { 935 - oscd->entries[i].offset = cpu_to_be64(sglist[i].offset); 936 - oscd->entries[i].len = cpu_to_be64(sglist[i].len); 937 - *len += sglist[i].len; 938 - } 939 - 940 - or->cdb_cont.total_bytes += oscd_size; 941 - OSD_DEBUG("total_bytes=%d oscd_size=%d numentries=%d\n", 942 - or->cdb_cont.total_bytes, oscd_size, numentries); 943 - return 0; 944 - } 945 - 946 - static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) 947 - { 948 - struct request_queue *req_q = osd_request_queue(or->osd_dev); 949 - struct bio *bio; 950 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 951 - struct osd_continuation_segment_header *cont_seg_hdr; 952 - 953 - if (!or->cdb_cont.total_bytes) 954 - return 0; 955 - 956 - cont_seg_hdr = or->cdb_cont.buff; 957 - cont_seg_hdr->format = CDB_CONTINUATION_FORMAT_V2; 958 - cont_seg_hdr->service_action = cdbh->varlen_cdb.service_action; 959 - 960 - /* create a bio for continuation segment */ 961 - bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, 962 - GFP_KERNEL); 963 - if (IS_ERR(bio)) 964 - return PTR_ERR(bio); 965 - 966 - bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 967 - 968 - /* integrity check the continuation before the bio is linked 969 - * with the other data segments since the continuation 970 - * integrity is separate from the other data segments. 971 - */ 972 - osd_sec_sign_data(cont_seg_hdr->integrity_check, bio, cap_key); 973 - 974 - cdbh->v2.cdb_continuation_length = cpu_to_be32(or->cdb_cont.total_bytes); 975 - 976 - /* we can't use _req_append_segment, because we need to link in the 977 - * continuation bio to the head of the bio list - the 978 - * continuation segment (if it exists) is always the first segment in 979 - * the out data buffer. 980 - */ 981 - bio->bi_next = or->out.bio; 982 - or->out.bio = bio; 983 - or->out.total_bytes += or->cdb_cont.total_bytes; 984 - 985 - return 0; 986 - } 987 - 988 - /* osd_req_write_sg: Takes a @bio that points to the data out buffer and an 989 - * @sglist that has the scatter gather entries. Scatter-gather enables a write 990 - * of multiple none-contiguous areas of an object, in a single call. The extents 991 - * may overlap and/or be in any order. The only constrain is that: 992 - * total_bytes(sglist) >= total_bytes(bio) 993 - */ 994 - int osd_req_write_sg(struct osd_request *or, 995 - const struct osd_obj_id *obj, struct bio *bio, 996 - const struct osd_sg_entry *sglist, unsigned numentries) 997 - { 998 - u64 len; 999 - int ret = _add_sg_continuation_descriptor(or, sglist, numentries, &len); 1000 - 1001 - if (ret) 1002 - return ret; 1003 - osd_req_write(or, obj, 0, bio, len); 1004 - 1005 - return 0; 1006 - } 1007 - EXPORT_SYMBOL(osd_req_write_sg); 1008 - 1009 - /* osd_req_read_sg: Read multiple extents of an object into @bio 1010 - * See osd_req_write_sg 1011 - */ 1012 - int osd_req_read_sg(struct osd_request *or, 1013 - const struct osd_obj_id *obj, struct bio *bio, 1014 - const struct osd_sg_entry *sglist, unsigned numentries) 1015 - { 1016 - u64 len; 1017 - u64 off; 1018 - int ret; 1019 - 1020 - if (numentries > 1) { 1021 - off = 0; 1022 - ret = _add_sg_continuation_descriptor(or, sglist, numentries, 1023 - &len); 1024 - if (ret) 1025 - return ret; 1026 - } else { 1027 - /* Optimize the case of single segment, read_sg is a 1028 - * bidi operation. 1029 - */ 1030 - len = sglist->len; 1031 - off = sglist->offset; 1032 - } 1033 - osd_req_read(or, obj, off, bio, len); 1034 - 1035 - return 0; 1036 - } 1037 - EXPORT_SYMBOL(osd_req_read_sg); 1038 - 1039 - /* SG-list write/read Kern API 1040 - * 1041 - * osd_req_{write,read}_sg_kern takes an array of @buff pointers and an array 1042 - * of sg_entries. @numentries indicates how many pointers and sg_entries there 1043 - * are. By requiring an array of buff pointers. This allows a caller to do a 1044 - * single write/read and scatter into multiple buffers. 1045 - * NOTE: Each buffer + len should not cross a page boundary. 1046 - */ 1047 - static struct bio *_create_sg_bios(struct osd_request *or, 1048 - void **buff, const struct osd_sg_entry *sglist, unsigned numentries) 1049 - { 1050 - struct request_queue *q = osd_request_queue(or->osd_dev); 1051 - struct bio *bio; 1052 - unsigned i; 1053 - 1054 - bio = bio_kmalloc(GFP_KERNEL, numentries); 1055 - if (unlikely(!bio)) { 1056 - OSD_DEBUG("Failed to allocate BIO size=%u\n", numentries); 1057 - return ERR_PTR(-ENOMEM); 1058 - } 1059 - 1060 - for (i = 0; i < numentries; i++) { 1061 - unsigned offset = offset_in_page(buff[i]); 1062 - struct page *page = virt_to_page(buff[i]); 1063 - unsigned len = sglist[i].len; 1064 - unsigned added_len; 1065 - 1066 - BUG_ON(offset + len > PAGE_SIZE); 1067 - added_len = bio_add_pc_page(q, bio, page, len, offset); 1068 - if (unlikely(len != added_len)) { 1069 - OSD_DEBUG("bio_add_pc_page len(%d) != added_len(%d)\n", 1070 - len, added_len); 1071 - bio_put(bio); 1072 - return ERR_PTR(-ENOMEM); 1073 - } 1074 - } 1075 - 1076 - return bio; 1077 - } 1078 - 1079 - int osd_req_write_sg_kern(struct osd_request *or, 1080 - const struct osd_obj_id *obj, void **buff, 1081 - const struct osd_sg_entry *sglist, unsigned numentries) 1082 - { 1083 - struct bio *bio = _create_sg_bios(or, buff, sglist, numentries); 1084 - if (IS_ERR(bio)) 1085 - return PTR_ERR(bio); 1086 - 1087 - bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 1088 - osd_req_write_sg(or, obj, bio, sglist, numentries); 1089 - 1090 - return 0; 1091 - } 1092 - EXPORT_SYMBOL(osd_req_write_sg_kern); 1093 - 1094 - int osd_req_read_sg_kern(struct osd_request *or, 1095 - const struct osd_obj_id *obj, void **buff, 1096 - const struct osd_sg_entry *sglist, unsigned numentries) 1097 - { 1098 - struct bio *bio = _create_sg_bios(or, buff, sglist, numentries); 1099 - if (IS_ERR(bio)) 1100 - return PTR_ERR(bio); 1101 - 1102 - osd_req_read_sg(or, obj, bio, sglist, numentries); 1103 - 1104 - return 0; 1105 - } 1106 - EXPORT_SYMBOL(osd_req_read_sg_kern); 1107 - 1108 - 1109 - 1110 - void osd_req_get_attributes(struct osd_request *or, 1111 - const struct osd_obj_id *obj) 1112 - { 1113 - _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0); 1114 - } 1115 - EXPORT_SYMBOL(osd_req_get_attributes); 1116 - 1117 - void osd_req_set_attributes(struct osd_request *or, 1118 - const struct osd_obj_id *obj) 1119 - { 1120 - _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0); 1121 - } 1122 - EXPORT_SYMBOL(osd_req_set_attributes); 1123 - 1124 - /* 1125 - * Attributes List-mode 1126 - */ 1127 - 1128 - int osd_req_add_set_attr_list(struct osd_request *or, 1129 - const struct osd_attr *oa, unsigned nelem) 1130 - { 1131 - unsigned total_bytes = or->set_attr.total_bytes; 1132 - void *attr_last; 1133 - int ret; 1134 - 1135 - if (or->attributes_mode && 1136 - or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 1137 - WARN_ON(1); 1138 - return -EINVAL; 1139 - } 1140 - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 1141 - 1142 - if (!total_bytes) { /* first-time: allocate and put list header */ 1143 - total_bytes = _osd_req_sizeof_alist_header(or); 1144 - ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 1145 - if (ret) 1146 - return ret; 1147 - _osd_req_set_alist_type(or, or->set_attr.buff, 1148 - OSD_ATTR_LIST_SET_RETRIEVE); 1149 - } 1150 - attr_last = or->set_attr.buff + total_bytes; 1151 - 1152 - for (; nelem; --nelem) { 1153 - unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); 1154 - 1155 - total_bytes += elem_size; 1156 - if (unlikely(or->set_attr.alloc_size < total_bytes)) { 1157 - or->set_attr.total_bytes = total_bytes - elem_size; 1158 - ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 1159 - if (ret) 1160 - return ret; 1161 - attr_last = 1162 - or->set_attr.buff + or->set_attr.total_bytes; 1163 - } 1164 - 1165 - _osd_req_alist_elem_encode(or, attr_last, oa); 1166 - 1167 - attr_last += elem_size; 1168 - ++oa; 1169 - } 1170 - 1171 - or->set_attr.total_bytes = total_bytes; 1172 - return 0; 1173 - } 1174 - EXPORT_SYMBOL(osd_req_add_set_attr_list); 1175 - 1176 - static int _req_append_segment(struct osd_request *or, 1177 - unsigned padding, struct _osd_req_data_segment *seg, 1178 - struct _osd_req_data_segment *last_seg, struct _osd_io_info *io) 1179 - { 1180 - void *pad_buff; 1181 - int ret; 1182 - 1183 - if (padding) { 1184 - /* check if we can just add it to last buffer */ 1185 - if (last_seg && 1186 - (padding <= last_seg->alloc_size - last_seg->total_bytes)) 1187 - pad_buff = last_seg->buff + last_seg->total_bytes; 1188 - else 1189 - pad_buff = io->pad_buff; 1190 - 1191 - ret = blk_rq_map_kern(io->req->q, io->req, pad_buff, padding, 1192 - GFP_KERNEL); 1193 - if (ret) 1194 - return ret; 1195 - io->total_bytes += padding; 1196 - } 1197 - 1198 - ret = blk_rq_map_kern(io->req->q, io->req, seg->buff, seg->total_bytes, 1199 - GFP_KERNEL); 1200 - if (ret) 1201 - return ret; 1202 - 1203 - io->total_bytes += seg->total_bytes; 1204 - OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff, 1205 - seg->total_bytes); 1206 - return 0; 1207 - } 1208 - 1209 - static int _osd_req_finalize_set_attr_list(struct osd_request *or) 1210 - { 1211 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 1212 - unsigned padding; 1213 - int ret; 1214 - 1215 - if (!or->set_attr.total_bytes) { 1216 - cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED; 1217 - return 0; 1218 - } 1219 - 1220 - cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes); 1221 - cdbh->attrs_list.set_attr_offset = 1222 - osd_req_encode_offset(or, or->out.total_bytes, &padding); 1223 - 1224 - ret = _req_append_segment(or, padding, &or->set_attr, 1225 - or->out.last_seg, &or->out); 1226 - if (ret) 1227 - return ret; 1228 - 1229 - or->out.last_seg = &or->set_attr; 1230 - return 0; 1231 - } 1232 - 1233 - int osd_req_add_get_attr_list(struct osd_request *or, 1234 - const struct osd_attr *oa, unsigned nelem) 1235 - { 1236 - unsigned total_bytes = or->enc_get_attr.total_bytes; 1237 - void *attr_last; 1238 - int ret; 1239 - 1240 - if (or->attributes_mode && 1241 - or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 1242 - WARN_ON(1); 1243 - return -EINVAL; 1244 - } 1245 - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 1246 - 1247 - /* first time calc data-in list header size */ 1248 - if (!or->get_attr.total_bytes) 1249 - or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or); 1250 - 1251 - /* calc data-out info */ 1252 - if (!total_bytes) { /* first-time: allocate and put list header */ 1253 - unsigned max_bytes; 1254 - 1255 - total_bytes = _osd_req_sizeof_alist_header(or); 1256 - max_bytes = total_bytes + 1257 - nelem * sizeof(struct osd_attributes_list_attrid); 1258 - ret = _alloc_get_attr_desc(or, max_bytes); 1259 - if (ret) 1260 - return ret; 1261 - 1262 - _osd_req_set_alist_type(or, or->enc_get_attr.buff, 1263 - OSD_ATTR_LIST_GET); 1264 - } 1265 - attr_last = or->enc_get_attr.buff + total_bytes; 1266 - 1267 - for (; nelem; --nelem) { 1268 - struct osd_attributes_list_attrid *attrid; 1269 - const unsigned cur_size = sizeof(*attrid); 1270 - 1271 - total_bytes += cur_size; 1272 - if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) { 1273 - or->enc_get_attr.total_bytes = total_bytes - cur_size; 1274 - ret = _alloc_get_attr_desc(or, 1275 - total_bytes + nelem * sizeof(*attrid)); 1276 - if (ret) 1277 - return ret; 1278 - attr_last = or->enc_get_attr.buff + 1279 - or->enc_get_attr.total_bytes; 1280 - } 1281 - 1282 - attrid = attr_last; 1283 - attrid->attr_page = cpu_to_be32(oa->attr_page); 1284 - attrid->attr_id = cpu_to_be32(oa->attr_id); 1285 - 1286 - attr_last += cur_size; 1287 - 1288 - /* calc data-in size */ 1289 - or->get_attr.total_bytes += 1290 - _osd_req_alist_elem_size(or, oa->len); 1291 - ++oa; 1292 - } 1293 - 1294 - or->enc_get_attr.total_bytes = total_bytes; 1295 - 1296 - OSD_DEBUG( 1297 - "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%zu)\n", 1298 - or->get_attr.total_bytes, 1299 - or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or), 1300 - or->enc_get_attr.total_bytes, 1301 - (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or)) 1302 - / sizeof(struct osd_attributes_list_attrid)); 1303 - 1304 - return 0; 1305 - } 1306 - EXPORT_SYMBOL(osd_req_add_get_attr_list); 1307 - 1308 - static int _osd_req_finalize_get_attr_list(struct osd_request *or) 1309 - { 1310 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 1311 - unsigned out_padding; 1312 - unsigned in_padding; 1313 - int ret; 1314 - 1315 - if (!or->enc_get_attr.total_bytes) { 1316 - cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED; 1317 - cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED; 1318 - return 0; 1319 - } 1320 - 1321 - ret = _alloc_get_attr_list(or); 1322 - if (ret) 1323 - return ret; 1324 - 1325 - /* The out-going buffer info update */ 1326 - OSD_DEBUG("out-going\n"); 1327 - cdbh->attrs_list.get_attr_desc_bytes = 1328 - cpu_to_be32(or->enc_get_attr.total_bytes); 1329 - 1330 - cdbh->attrs_list.get_attr_desc_offset = 1331 - osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 1332 - 1333 - ret = _req_append_segment(or, out_padding, &or->enc_get_attr, 1334 - or->out.last_seg, &or->out); 1335 - if (ret) 1336 - return ret; 1337 - or->out.last_seg = &or->enc_get_attr; 1338 - 1339 - /* The incoming buffer info update */ 1340 - OSD_DEBUG("in-coming\n"); 1341 - cdbh->attrs_list.get_attr_alloc_length = 1342 - cpu_to_be32(or->get_attr.total_bytes); 1343 - 1344 - cdbh->attrs_list.get_attr_offset = 1345 - osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 1346 - 1347 - ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 1348 - &or->in); 1349 - if (ret) 1350 - return ret; 1351 - or->in.last_seg = &or->get_attr; 1352 - 1353 - return 0; 1354 - } 1355 - 1356 - int osd_req_decode_get_attr_list(struct osd_request *or, 1357 - struct osd_attr *oa, int *nelem, void **iterator) 1358 - { 1359 - unsigned cur_bytes, returned_bytes; 1360 - int n; 1361 - const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or); 1362 - void *cur_p; 1363 - 1364 - if (!_osd_req_is_alist_type(or, or->get_attr.buff, 1365 - OSD_ATTR_LIST_SET_RETRIEVE)) { 1366 - oa->attr_page = 0; 1367 - oa->attr_id = 0; 1368 - oa->val_ptr = NULL; 1369 - oa->len = 0; 1370 - *iterator = NULL; 1371 - return 0; 1372 - } 1373 - 1374 - if (*iterator) { 1375 - BUG_ON((*iterator < or->get_attr.buff) || 1376 - (or->get_attr.buff + or->get_attr.alloc_size < *iterator)); 1377 - cur_p = *iterator; 1378 - cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list; 1379 - returned_bytes = or->get_attr.total_bytes; 1380 - } else { /* first time decode the list header */ 1381 - cur_bytes = sizeof_attr_list; 1382 - returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) + 1383 - sizeof_attr_list; 1384 - 1385 - cur_p = or->get_attr.buff + sizeof_attr_list; 1386 - 1387 - if (returned_bytes > or->get_attr.alloc_size) { 1388 - OSD_DEBUG("target report: space was not big enough! " 1389 - "Allocate=%u Needed=%u\n", 1390 - or->get_attr.alloc_size, 1391 - returned_bytes + sizeof_attr_list); 1392 - 1393 - returned_bytes = 1394 - or->get_attr.alloc_size - sizeof_attr_list; 1395 - } 1396 - or->get_attr.total_bytes = returned_bytes; 1397 - } 1398 - 1399 - for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { 1400 - int inc = _osd_req_alist_elem_decode(or, cur_p, oa, 1401 - returned_bytes - cur_bytes); 1402 - 1403 - if (inc < 0) { 1404 - OSD_ERR("BAD FOOD from target. list not valid!" 1405 - "c=%d r=%d n=%d\n", 1406 - cur_bytes, returned_bytes, n); 1407 - oa->val_ptr = NULL; 1408 - cur_bytes = returned_bytes; /* break the caller loop */ 1409 - break; 1410 - } 1411 - 1412 - cur_bytes += inc; 1413 - cur_p += inc; 1414 - ++oa; 1415 - } 1416 - 1417 - *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL; 1418 - *nelem = n; 1419 - return returned_bytes - cur_bytes; 1420 - } 1421 - EXPORT_SYMBOL(osd_req_decode_get_attr_list); 1422 - 1423 - /* 1424 - * Attributes Page-mode 1425 - */ 1426 - 1427 - int osd_req_add_get_attr_page(struct osd_request *or, 1428 - u32 page_id, void *attar_page, unsigned max_page_len, 1429 - const struct osd_attr *set_one_attr) 1430 - { 1431 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 1432 - 1433 - if (or->attributes_mode && 1434 - or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 1435 - WARN_ON(1); 1436 - return -EINVAL; 1437 - } 1438 - or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE; 1439 - 1440 - or->get_attr.buff = attar_page; 1441 - or->get_attr.total_bytes = max_page_len; 1442 - 1443 - cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id); 1444 - cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len); 1445 - 1446 - if (!set_one_attr || !set_one_attr->attr_page) 1447 - return 0; /* The set is optional */ 1448 - 1449 - or->set_attr.buff = set_one_attr->val_ptr; 1450 - or->set_attr.total_bytes = set_one_attr->len; 1451 - 1452 - cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page); 1453 - cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id); 1454 - cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len); 1455 - return 0; 1456 - } 1457 - EXPORT_SYMBOL(osd_req_add_get_attr_page); 1458 - 1459 - static int _osd_req_finalize_attr_page(struct osd_request *or) 1460 - { 1461 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 1462 - unsigned in_padding, out_padding; 1463 - int ret; 1464 - 1465 - /* returned page */ 1466 - cdbh->attrs_page.get_attr_offset = 1467 - osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 1468 - 1469 - ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 1470 - &or->in); 1471 - if (ret) 1472 - return ret; 1473 - 1474 - if (or->set_attr.total_bytes == 0) 1475 - return 0; 1476 - 1477 - /* set one value */ 1478 - cdbh->attrs_page.set_attr_offset = 1479 - osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 1480 - 1481 - ret = _req_append_segment(or, out_padding, &or->set_attr, NULL, 1482 - &or->out); 1483 - return ret; 1484 - } 1485 - 1486 - static inline void osd_sec_parms_set_out_offset(bool is_v1, 1487 - struct osd_security_parameters *sec_parms, osd_cdb_offset offset) 1488 - { 1489 - if (is_v1) 1490 - sec_parms->v1.data_out_integrity_check_offset = offset; 1491 - else 1492 - sec_parms->v2.data_out_integrity_check_offset = offset; 1493 - } 1494 - 1495 - static inline void osd_sec_parms_set_in_offset(bool is_v1, 1496 - struct osd_security_parameters *sec_parms, osd_cdb_offset offset) 1497 - { 1498 - if (is_v1) 1499 - sec_parms->v1.data_in_integrity_check_offset = offset; 1500 - else 1501 - sec_parms->v2.data_in_integrity_check_offset = offset; 1502 - } 1503 - 1504 - static int _osd_req_finalize_data_integrity(struct osd_request *or, 1505 - bool has_in, bool has_out, struct bio *out_data_bio, u64 out_data_bytes, 1506 - const u8 *cap_key) 1507 - { 1508 - struct osd_security_parameters *sec_parms = _osd_req_sec_params(or); 1509 - int ret; 1510 - 1511 - if (!osd_is_sec_alldata(sec_parms)) 1512 - return 0; 1513 - 1514 - if (has_out) { 1515 - struct _osd_req_data_segment seg = { 1516 - .buff = &or->out_data_integ, 1517 - .total_bytes = sizeof(or->out_data_integ), 1518 - }; 1519 - unsigned pad; 1520 - 1521 - or->out_data_integ.data_bytes = cpu_to_be64(out_data_bytes); 1522 - or->out_data_integ.set_attributes_bytes = cpu_to_be64( 1523 - or->set_attr.total_bytes); 1524 - or->out_data_integ.get_attributes_bytes = cpu_to_be64( 1525 - or->enc_get_attr.total_bytes); 1526 - 1527 - osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms, 1528 - osd_req_encode_offset(or, or->out.total_bytes, &pad)); 1529 - 1530 - ret = _req_append_segment(or, pad, &seg, or->out.last_seg, 1531 - &or->out); 1532 - if (ret) 1533 - return ret; 1534 - or->out.last_seg = NULL; 1535 - 1536 - /* they are now all chained to request sign them all together */ 1537 - osd_sec_sign_data(&or->out_data_integ, out_data_bio, 1538 - cap_key); 1539 - } 1540 - 1541 - if (has_in) { 1542 - struct _osd_req_data_segment seg = { 1543 - .buff = &or->in_data_integ, 1544 - .total_bytes = sizeof(or->in_data_integ), 1545 - }; 1546 - unsigned pad; 1547 - 1548 - osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms, 1549 - osd_req_encode_offset(or, or->in.total_bytes, &pad)); 1550 - 1551 - ret = _req_append_segment(or, pad, &seg, or->in.last_seg, 1552 - &or->in); 1553 - if (ret) 1554 - return ret; 1555 - 1556 - or->in.last_seg = NULL; 1557 - } 1558 - 1559 - return 0; 1560 - } 1561 - 1562 - /* 1563 - * osd_finalize_request and helpers 1564 - */ 1565 - static struct request *_make_request(struct request_queue *q, bool has_write, 1566 - struct _osd_io_info *oii) 1567 - { 1568 - struct request *req; 1569 - struct bio *bio = oii->bio; 1570 - int ret; 1571 - 1572 - req = blk_get_request(q, has_write ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 1573 - 0); 1574 - if (IS_ERR(req)) 1575 - return req; 1576 - 1577 - for_each_bio(bio) { 1578 - struct bio *bounce_bio = bio; 1579 - 1580 - ret = blk_rq_append_bio(req, &bounce_bio); 1581 - if (ret) 1582 - return ERR_PTR(ret); 1583 - } 1584 - 1585 - return req; 1586 - } 1587 - 1588 - static int _init_blk_request(struct osd_request *or, 1589 - bool has_in, bool has_out) 1590 - { 1591 - struct scsi_device *scsi_device = or->osd_dev->scsi_device; 1592 - struct request_queue *q = scsi_device->request_queue; 1593 - struct request *req; 1594 - int ret; 1595 - 1596 - req = _make_request(q, has_out, has_out ? &or->out : &or->in); 1597 - if (IS_ERR(req)) { 1598 - ret = PTR_ERR(req); 1599 - goto out; 1600 - } 1601 - 1602 - or->request = req; 1603 - req->rq_flags |= RQF_QUIET; 1604 - 1605 - req->timeout = or->timeout; 1606 - scsi_req(req)->retries = or->retries; 1607 - 1608 - if (has_out) { 1609 - or->out.req = req; 1610 - if (has_in) { 1611 - /* allocate bidi request */ 1612 - req = _make_request(q, false, &or->in); 1613 - if (IS_ERR(req)) { 1614 - OSD_DEBUG("blk_get_request for bidi failed\n"); 1615 - ret = PTR_ERR(req); 1616 - goto out; 1617 - } 1618 - or->in.req = or->request->next_rq = req; 1619 - } 1620 - } else if (has_in) 1621 - or->in.req = req; 1622 - 1623 - ret = 0; 1624 - out: 1625 - OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n", 1626 - or, has_in, has_out, ret, or->request); 1627 - return ret; 1628 - } 1629 - 1630 - int osd_finalize_request(struct osd_request *or, 1631 - u8 options, const void *cap, const u8 *cap_key) 1632 - { 1633 - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 1634 - bool has_in, has_out; 1635 - /* Save for data_integrity without the cdb_continuation */ 1636 - struct bio *out_data_bio = or->out.bio; 1637 - u64 out_data_bytes = or->out.total_bytes; 1638 - int ret; 1639 - 1640 - if (options & OSD_REQ_FUA) 1641 - cdbh->options |= OSD_CDB_FUA; 1642 - 1643 - if (options & OSD_REQ_DPO) 1644 - cdbh->options |= OSD_CDB_DPO; 1645 - 1646 - if (options & OSD_REQ_BYPASS_TIMESTAMPS) 1647 - cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS; 1648 - 1649 - osd_set_caps(&or->cdb, cap); 1650 - 1651 - has_in = or->in.bio || or->get_attr.total_bytes; 1652 - has_out = or->out.bio || or->cdb_cont.total_bytes || 1653 - or->set_attr.total_bytes || or->enc_get_attr.total_bytes; 1654 - 1655 - ret = _osd_req_finalize_cdb_cont(or, cap_key); 1656 - if (ret) { 1657 - OSD_DEBUG("_osd_req_finalize_cdb_cont failed\n"); 1658 - return ret; 1659 - } 1660 - ret = _init_blk_request(or, has_in, has_out); 1661 - if (ret) { 1662 - OSD_DEBUG("_init_blk_request failed\n"); 1663 - return ret; 1664 - } 1665 - 1666 - or->out.pad_buff = sg_out_pad_buffer; 1667 - or->in.pad_buff = sg_in_pad_buffer; 1668 - 1669 - if (!or->attributes_mode) 1670 - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 1671 - cdbh->command_specific_options |= or->attributes_mode; 1672 - if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 1673 - ret = _osd_req_finalize_attr_page(or); 1674 - if (ret) { 1675 - OSD_DEBUG("_osd_req_finalize_attr_page failed\n"); 1676 - return ret; 1677 - } 1678 - } else { 1679 - /* TODO: I think that for the GET_ATTR command these 2 should 1680 - * be reversed to keep them in execution order (for embedded 1681 - * targets with low memory footprint) 1682 - */ 1683 - ret = _osd_req_finalize_set_attr_list(or); 1684 - if (ret) { 1685 - OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n"); 1686 - return ret; 1687 - } 1688 - 1689 - ret = _osd_req_finalize_get_attr_list(or); 1690 - if (ret) { 1691 - OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n"); 1692 - return ret; 1693 - } 1694 - } 1695 - 1696 - ret = _osd_req_finalize_data_integrity(or, has_in, has_out, 1697 - out_data_bio, out_data_bytes, 1698 - cap_key); 1699 - if (ret) 1700 - return ret; 1701 - 1702 - osd_sec_sign_cdb(&or->cdb, cap_key); 1703 - 1704 - scsi_req(or->request)->cmd = or->cdb.buff; 1705 - scsi_req(or->request)->cmd_len = _osd_req_cdb_len(or); 1706 - 1707 - return 0; 1708 - } 1709 - EXPORT_SYMBOL(osd_finalize_request); 1710 - 1711 - static bool _is_osd_security_code(int code) 1712 - { 1713 - return (code == osd_security_audit_value_frozen) || 1714 - (code == osd_security_working_key_frozen) || 1715 - (code == osd_nonce_not_unique) || 1716 - (code == osd_nonce_timestamp_out_of_range) || 1717 - (code == osd_invalid_dataout_buffer_integrity_check_value); 1718 - } 1719 - 1720 - #define OSD_SENSE_PRINT1(fmt, a...) \ 1721 - do { \ 1722 - if (__cur_sense_need_output) \ 1723 - OSD_ERR(fmt, ##a); \ 1724 - } while (0) 1725 - 1726 - #define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1(" " fmt, ##a) 1727 - 1728 - int osd_req_decode_sense_full(struct osd_request *or, 1729 - struct osd_sense_info *osi, bool silent, 1730 - struct osd_obj_id *bad_obj_list __unused, int max_obj __unused, 1731 - struct osd_attr *bad_attr_list, int max_attr) 1732 - { 1733 - int sense_len, original_sense_len; 1734 - struct osd_sense_info local_osi; 1735 - struct scsi_sense_descriptor_based *ssdb; 1736 - void *cur_descriptor; 1737 - #if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0) 1738 - const bool __cur_sense_need_output = false; 1739 - #else 1740 - bool __cur_sense_need_output = !silent; 1741 - #endif 1742 - int ret; 1743 - 1744 - if (likely(!or->req_errors)) 1745 - return 0; 1746 - 1747 - osi = osi ? : &local_osi; 1748 - memset(osi, 0, sizeof(*osi)); 1749 - 1750 - ssdb = (typeof(ssdb))or->sense; 1751 - sense_len = or->sense_len; 1752 - if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) { 1753 - OSD_ERR("Block-layer returned error(0x%x) but " 1754 - "sense_len(%u) || key(%d) is empty\n", 1755 - or->req_errors, sense_len, ssdb->sense_key); 1756 - goto analyze; 1757 - } 1758 - 1759 - if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) { 1760 - OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n", 1761 - ssdb->response_code, sense_len); 1762 - goto analyze; 1763 - } 1764 - 1765 - osi->key = ssdb->sense_key; 1766 - osi->additional_code = be16_to_cpu(ssdb->additional_sense_code); 1767 - original_sense_len = ssdb->additional_sense_length + 8; 1768 - 1769 - #if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1) 1770 - if (__cur_sense_need_output) 1771 - __cur_sense_need_output = (osi->key > scsi_sk_recovered_error); 1772 - #endif 1773 - OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) " 1774 - "additional_code=0x%x async_error=%d errors=0x%x\n", 1775 - osi->key, original_sense_len, sense_len, 1776 - osi->additional_code, or->async_error, 1777 - or->req_errors); 1778 - 1779 - if (original_sense_len < sense_len) 1780 - sense_len = original_sense_len; 1781 - 1782 - cur_descriptor = ssdb->ssd; 1783 - sense_len -= sizeof(*ssdb); 1784 - while (sense_len > 0) { 1785 - struct scsi_sense_descriptor *ssd = cur_descriptor; 1786 - int cur_len = ssd->additional_length + 2; 1787 - 1788 - sense_len -= cur_len; 1789 - 1790 - if (sense_len < 0) 1791 - break; /* sense was truncated */ 1792 - 1793 - switch (ssd->descriptor_type) { 1794 - case scsi_sense_information: 1795 - case scsi_sense_command_specific_information: 1796 - { 1797 - struct scsi_sense_command_specific_data_descriptor 1798 - *sscd = cur_descriptor; 1799 - 1800 - osi->command_info = 1801 - get_unaligned_be64(&sscd->information) ; 1802 - OSD_SENSE_PRINT2( 1803 - "command_specific_information 0x%llx \n", 1804 - _LLU(osi->command_info)); 1805 - break; 1806 - } 1807 - case scsi_sense_key_specific: 1808 - { 1809 - struct scsi_sense_key_specific_data_descriptor 1810 - *ssks = cur_descriptor; 1811 - 1812 - osi->sense_info = get_unaligned_be16(&ssks->value); 1813 - OSD_SENSE_PRINT2( 1814 - "sense_key_specific_information %u" 1815 - "sksv_cd_bpv_bp (0x%x)\n", 1816 - osi->sense_info, ssks->sksv_cd_bpv_bp); 1817 - break; 1818 - } 1819 - case osd_sense_object_identification: 1820 - { /*FIXME: Keep first not last, Store in array*/ 1821 - struct osd_sense_identification_data_descriptor 1822 - *osidd = cur_descriptor; 1823 - 1824 - osi->not_initiated_command_functions = 1825 - le32_to_cpu(osidd->not_initiated_functions); 1826 - osi->completed_command_functions = 1827 - le32_to_cpu(osidd->completed_functions); 1828 - osi->obj.partition = be64_to_cpu(osidd->partition_id); 1829 - osi->obj.id = be64_to_cpu(osidd->object_id); 1830 - OSD_SENSE_PRINT2( 1831 - "object_identification pid=0x%llx oid=0x%llx\n", 1832 - _LLU(osi->obj.partition), _LLU(osi->obj.id)); 1833 - OSD_SENSE_PRINT2( 1834 - "not_initiated_bits(%x) " 1835 - "completed_command_bits(%x)\n", 1836 - osi->not_initiated_command_functions, 1837 - osi->completed_command_functions); 1838 - break; 1839 - } 1840 - case osd_sense_response_integrity_check: 1841 - { 1842 - struct osd_sense_response_integrity_check_descriptor 1843 - *d = cur_descriptor; 1844 - /* 2nibbles+space+ASCII */ 1845 - char dump[sizeof(d->integrity_check_value) * 4 + 2]; 1846 - 1847 - hex_dump_to_buffer(d->integrity_check_value, 1848 - sizeof(d->integrity_check_value), 1849 - 32, 1, dump, sizeof(dump), true); 1850 - OSD_SENSE_PRINT2("response_integrity [%s]\n", dump); 1851 - } 1852 - case osd_sense_attribute_identification: 1853 - { 1854 - struct osd_sense_attributes_data_descriptor 1855 - *osadd = cur_descriptor; 1856 - unsigned len = min(cur_len, sense_len); 1857 - struct osd_sense_attr *pattr = osadd->sense_attrs; 1858 - 1859 - while (len >= sizeof(*pattr)) { 1860 - u32 attr_page = be32_to_cpu(pattr->attr_page); 1861 - u32 attr_id = be32_to_cpu(pattr->attr_id); 1862 - 1863 - if (!osi->attr.attr_page) { 1864 - osi->attr.attr_page = attr_page; 1865 - osi->attr.attr_id = attr_id; 1866 - } 1867 - 1868 - if (bad_attr_list && max_attr) { 1869 - bad_attr_list->attr_page = attr_page; 1870 - bad_attr_list->attr_id = attr_id; 1871 - bad_attr_list++; 1872 - max_attr--; 1873 - } 1874 - 1875 - len -= sizeof(*pattr); 1876 - OSD_SENSE_PRINT2( 1877 - "osd_sense_attribute_identification" 1878 - "attr_page=0x%x attr_id=0x%x\n", 1879 - attr_page, attr_id); 1880 - } 1881 - } 1882 - /*These are not legal for OSD*/ 1883 - case scsi_sense_field_replaceable_unit: 1884 - OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n"); 1885 - break; 1886 - case scsi_sense_stream_commands: 1887 - OSD_SENSE_PRINT2("scsi_sense_stream_commands\n"); 1888 - break; 1889 - case scsi_sense_block_commands: 1890 - OSD_SENSE_PRINT2("scsi_sense_block_commands\n"); 1891 - break; 1892 - case scsi_sense_ata_return: 1893 - OSD_SENSE_PRINT2("scsi_sense_ata_return\n"); 1894 - break; 1895 - default: 1896 - if (ssd->descriptor_type <= scsi_sense_Reserved_last) 1897 - OSD_SENSE_PRINT2( 1898 - "scsi_sense Reserved descriptor (0x%x)", 1899 - ssd->descriptor_type); 1900 - else 1901 - OSD_SENSE_PRINT2( 1902 - "scsi_sense Vendor descriptor (0x%x)", 1903 - ssd->descriptor_type); 1904 - } 1905 - 1906 - cur_descriptor += cur_len; 1907 - } 1908 - 1909 - analyze: 1910 - if (!osi->key) { 1911 - /* scsi sense is Empty, the request was never issued to target 1912 - * linux return code might tell us what happened. 1913 - */ 1914 - if (or->async_error == BLK_STS_RESOURCE) 1915 - osi->osd_err_pri = OSD_ERR_PRI_RESOURCE; 1916 - else 1917 - osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE; 1918 - ret = or->async_error; 1919 - } else if (osi->key <= scsi_sk_recovered_error) { 1920 - osi->osd_err_pri = 0; 1921 - ret = 0; 1922 - } else if (osi->additional_code == scsi_invalid_field_in_cdb) { 1923 - if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) { 1924 - osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES; 1925 - ret = -EFAULT; /* caller should recover from this */ 1926 - } else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) { 1927 - osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND; 1928 - ret = -ENOENT; 1929 - } else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) { 1930 - osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS; 1931 - ret = -EACCES; 1932 - } else { 1933 - osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED; 1934 - ret = -EINVAL; 1935 - } 1936 - } else if (osi->additional_code == osd_quota_error) { 1937 - osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE; 1938 - ret = -ENOSPC; 1939 - } else if (_is_osd_security_code(osi->additional_code)) { 1940 - osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED; 1941 - ret = -EINVAL; 1942 - } else { 1943 - osi->osd_err_pri = OSD_ERR_PRI_EIO; 1944 - ret = -EIO; 1945 - } 1946 - 1947 - if (!or->out.residual) 1948 - or->out.residual = or->out.total_bytes; 1949 - if (!or->in.residual) 1950 - or->in.residual = or->in.total_bytes; 1951 - 1952 - return ret; 1953 - } 1954 - EXPORT_SYMBOL(osd_req_decode_sense_full); 1955 - 1956 - /* 1957 - * Implementation of osd_sec.h API 1958 - * TODO: Move to a separate osd_sec.c file at a later stage. 1959 - */ 1960 - 1961 - enum { OSD_SEC_CAP_V1_ALL_CAPS = 1962 - OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE | 1963 - OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR | 1964 - OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC | 1965 - OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT 1966 - }; 1967 - 1968 - enum { OSD_SEC_CAP_V2_ALL_CAPS = 1969 - OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT 1970 - }; 1971 - 1972 - void osd_sec_init_nosec_doall_caps(void *caps, 1973 - const struct osd_obj_id *obj, bool is_collection, const bool is_v1) 1974 - { 1975 - struct osd_capability *cap = caps; 1976 - u8 type; 1977 - u8 descriptor_type; 1978 - 1979 - if (likely(obj->id)) { 1980 - if (unlikely(is_collection)) { 1981 - type = OSD_SEC_OBJ_COLLECTION; 1982 - descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ : 1983 - OSD_SEC_OBJ_DESC_COL; 1984 - } else { 1985 - type = OSD_SEC_OBJ_USER; 1986 - descriptor_type = OSD_SEC_OBJ_DESC_OBJ; 1987 - } 1988 - WARN_ON(!obj->partition); 1989 - } else { 1990 - type = obj->partition ? OSD_SEC_OBJ_PARTITION : 1991 - OSD_SEC_OBJ_ROOT; 1992 - descriptor_type = OSD_SEC_OBJ_DESC_PAR; 1993 - } 1994 - 1995 - memset(cap, 0, sizeof(*cap)); 1996 - 1997 - cap->h.format = OSD_SEC_CAP_FORMAT_VER1; 1998 - cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */ 1999 - cap->h.security_method = OSD_SEC_NOSEC; 2000 - /* cap->expiration_time; 2001 - cap->AUDIT[30-10]; 2002 - cap->discriminator[42-30]; 2003 - cap->object_created_time; */ 2004 - cap->h.object_type = type; 2005 - osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS); 2006 - cap->h.object_descriptor_type = descriptor_type; 2007 - cap->od.obj_desc.policy_access_tag = 0; 2008 - cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition); 2009 - cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id); 2010 - } 2011 - EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); 2012 - 2013 - /* FIXME: Extract version from caps pointer. 2014 - * Also Pete's target only supports caps from OSDv1 for now 2015 - */ 2016 - void osd_set_caps(struct osd_cdb *cdb, const void *caps) 2017 - { 2018 - /* NOTE: They start at same address */ 2019 - memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); 2020 - } 2021 - 2022 - bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused) 2023 - { 2024 - return false; 2025 - } 2026 - 2027 - void osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused) 2028 - { 2029 - } 2030 - 2031 - void osd_sec_sign_data(void *data_integ __unused, 2032 - struct bio *bio __unused, const u8 *cap_key __unused) 2033 - { 2034 - } 2035 - 2036 - /* 2037 - * Declared in osd_protocol.h 2038 - * 4.12.5 Data-In and Data-Out buffer offsets 2039 - * byte offset = mantissa * (2^(exponent+8)) 2040 - * Returns the smallest allowed encoded offset that contains given @offset 2041 - * The actual encoded offset returned is @offset + *@padding. 2042 - */ 2043 - osd_cdb_offset __osd_encode_offset( 2044 - u64 offset, unsigned *padding, int min_shift, int max_shift) 2045 - { 2046 - u64 try_offset = -1, mod, align; 2047 - osd_cdb_offset be32_offset; 2048 - int shift; 2049 - 2050 - *padding = 0; 2051 - if (!offset) 2052 - return 0; 2053 - 2054 - for (shift = min_shift; shift < max_shift; ++shift) { 2055 - try_offset = offset >> shift; 2056 - if (try_offset < (1 << OSD_OFFSET_MAX_BITS)) 2057 - break; 2058 - } 2059 - 2060 - BUG_ON(shift == max_shift); 2061 - 2062 - align = 1 << shift; 2063 - mod = offset & (align - 1); 2064 - if (mod) { 2065 - *padding = align - mod; 2066 - try_offset += 1; 2067 - } 2068 - 2069 - try_offset |= ((shift - 8) & 0xf) << 28; 2070 - be32_offset = cpu_to_be32((u32)try_offset); 2071 - 2072 - OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n", 2073 - _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift, 2074 - be32_offset, *padding); 2075 - return be32_offset; 2076 - }
-571
drivers/scsi/osd/osd_uld.c
··· 1 - /* 2 - * osd_uld.c - OSD Upper Layer Driver 3 - * 4 - * A Linux driver module that registers as a SCSI ULD and probes 5 - * for OSD type SCSI devices. 6 - * It's main function is to export osd devices to in-kernel users like 7 - * osdfs and pNFS-objects-LD. It also provides one ioctl for running 8 - * in Kernel tests. 9 - * 10 - * Copyright (C) 2008 Panasas Inc. All rights reserved. 11 - * 12 - * Authors: 13 - * Boaz Harrosh <ooo@electrozaur.com> 14 - * Benny Halevy <bhalevy@panasas.com> 15 - * 16 - * This program is free software; you can redistribute it and/or modify 17 - * it under the terms of the GNU General Public License version 2 18 - * 19 - * Redistribution and use in source and binary forms, with or without 20 - * modification, are permitted provided that the following conditions 21 - * are met: 22 - * 23 - * 1. Redistributions of source code must retain the above copyright 24 - * notice, this list of conditions and the following disclaimer. 25 - * 2. Redistributions in binary form must reproduce the above copyright 26 - * notice, this list of conditions and the following disclaimer in the 27 - * documentation and/or other materials provided with the distribution. 28 - * 3. Neither the name of the Panasas company nor the names of its 29 - * contributors may be used to endorse or promote products derived 30 - * from this software without specific prior written permission. 31 - * 32 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 33 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 34 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 37 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 38 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 39 - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 40 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 41 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 42 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 - */ 44 - 45 - #include <linux/namei.h> 46 - #include <linux/cdev.h> 47 - #include <linux/fs.h> 48 - #include <linux/module.h> 49 - #include <linux/device.h> 50 - #include <linux/idr.h> 51 - #include <linux/major.h> 52 - #include <linux/file.h> 53 - #include <linux/slab.h> 54 - 55 - #include <scsi/scsi.h> 56 - #include <scsi/scsi_driver.h> 57 - #include <scsi/scsi_device.h> 58 - #include <scsi/scsi_ioctl.h> 59 - 60 - #include <scsi/osd_initiator.h> 61 - #include <scsi/osd_sec.h> 62 - 63 - #include "osd_debug.h" 64 - 65 - #ifndef TYPE_OSD 66 - # define TYPE_OSD 0x11 67 - #endif 68 - 69 - #ifndef SCSI_OSD_MAJOR 70 - # define SCSI_OSD_MAJOR 260 71 - #endif 72 - #define SCSI_OSD_MAX_MINOR MINORMASK 73 - 74 - static const char osd_name[] = "osd"; 75 - static const char *osd_version_string = "open-osd 0.2.1"; 76 - 77 - MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>"); 78 - MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko"); 79 - MODULE_LICENSE("GPL"); 80 - MODULE_ALIAS_CHARDEV_MAJOR(SCSI_OSD_MAJOR); 81 - MODULE_ALIAS_SCSI_DEVICE(TYPE_OSD); 82 - 83 - struct osd_uld_device { 84 - int minor; 85 - struct device class_dev; 86 - struct cdev cdev; 87 - struct osd_dev od; 88 - struct osd_dev_info odi; 89 - struct gendisk *disk; 90 - }; 91 - 92 - struct osd_dev_handle { 93 - struct osd_dev od; 94 - struct file *file; 95 - struct osd_uld_device *oud; 96 - } ; 97 - 98 - static DEFINE_IDA(osd_minor_ida); 99 - 100 - /* 101 - * scsi sysfs attribute operations 102 - */ 103 - static ssize_t osdname_show(struct device *dev, struct device_attribute *attr, 104 - char *buf) 105 - { 106 - struct osd_uld_device *ould = container_of(dev, struct osd_uld_device, 107 - class_dev); 108 - return sprintf(buf, "%s\n", ould->odi.osdname); 109 - } 110 - static DEVICE_ATTR_RO(osdname); 111 - 112 - static ssize_t systemid_show(struct device *dev, struct device_attribute *attr, 113 - char *buf) 114 - { 115 - struct osd_uld_device *ould = container_of(dev, struct osd_uld_device, 116 - class_dev); 117 - 118 - memcpy(buf, ould->odi.systemid, ould->odi.systemid_len); 119 - return ould->odi.systemid_len; 120 - } 121 - static DEVICE_ATTR_RO(systemid); 122 - 123 - static struct attribute *osd_uld_attrs[] = { 124 - &dev_attr_osdname.attr, 125 - &dev_attr_systemid.attr, 126 - NULL, 127 - }; 128 - ATTRIBUTE_GROUPS(osd_uld); 129 - 130 - static struct class osd_uld_class = { 131 - .owner = THIS_MODULE, 132 - .name = "scsi_osd", 133 - .dev_groups = osd_uld_groups, 134 - }; 135 - 136 - /* 137 - * Char Device operations 138 - */ 139 - 140 - static int osd_uld_open(struct inode *inode, struct file *file) 141 - { 142 - struct osd_uld_device *oud = container_of(inode->i_cdev, 143 - struct osd_uld_device, cdev); 144 - 145 - get_device(&oud->class_dev); 146 - /* cache osd_uld_device on file handle */ 147 - file->private_data = oud; 148 - OSD_DEBUG("osd_uld_open %p\n", oud); 149 - return 0; 150 - } 151 - 152 - static int osd_uld_release(struct inode *inode, struct file *file) 153 - { 154 - struct osd_uld_device *oud = file->private_data; 155 - 156 - OSD_DEBUG("osd_uld_release %p\n", file->private_data); 157 - file->private_data = NULL; 158 - put_device(&oud->class_dev); 159 - return 0; 160 - } 161 - 162 - /* FIXME: Only one vector for now */ 163 - unsigned g_test_ioctl; 164 - do_test_fn *g_do_test; 165 - 166 - int osduld_register_test(unsigned ioctl, do_test_fn *do_test) 167 - { 168 - if (g_test_ioctl) 169 - return -EINVAL; 170 - 171 - g_test_ioctl = ioctl; 172 - g_do_test = do_test; 173 - return 0; 174 - } 175 - EXPORT_SYMBOL(osduld_register_test); 176 - 177 - void osduld_unregister_test(unsigned ioctl) 178 - { 179 - if (ioctl == g_test_ioctl) { 180 - g_test_ioctl = 0; 181 - g_do_test = NULL; 182 - } 183 - } 184 - EXPORT_SYMBOL(osduld_unregister_test); 185 - 186 - static do_test_fn *_find_ioctl(unsigned cmd) 187 - { 188 - if (g_test_ioctl == cmd) 189 - return g_do_test; 190 - else 191 - return NULL; 192 - } 193 - 194 - static long osd_uld_ioctl(struct file *file, unsigned int cmd, 195 - unsigned long arg) 196 - { 197 - struct osd_uld_device *oud = file->private_data; 198 - int ret; 199 - do_test_fn *do_test; 200 - 201 - do_test = _find_ioctl(cmd); 202 - if (do_test) 203 - ret = do_test(&oud->od, cmd, arg); 204 - else { 205 - OSD_ERR("Unknown ioctl %d: osd_uld_device=%p\n", cmd, oud); 206 - ret = -ENOIOCTLCMD; 207 - } 208 - return ret; 209 - } 210 - 211 - static const struct file_operations osd_fops = { 212 - .owner = THIS_MODULE, 213 - .open = osd_uld_open, 214 - .release = osd_uld_release, 215 - .unlocked_ioctl = osd_uld_ioctl, 216 - .llseek = noop_llseek, 217 - }; 218 - 219 - struct osd_dev *osduld_path_lookup(const char *name) 220 - { 221 - struct osd_uld_device *oud; 222 - struct osd_dev_handle *odh; 223 - struct file *file; 224 - int error; 225 - 226 - if (!name || !*name) { 227 - OSD_ERR("Mount with !path || !*path\n"); 228 - return ERR_PTR(-EINVAL); 229 - } 230 - 231 - odh = kzalloc(sizeof(*odh), GFP_KERNEL); 232 - if (unlikely(!odh)) 233 - return ERR_PTR(-ENOMEM); 234 - 235 - file = filp_open(name, O_RDWR, 0); 236 - if (IS_ERR(file)) { 237 - error = PTR_ERR(file); 238 - goto free_od; 239 - } 240 - 241 - if (file->f_op != &osd_fops){ 242 - error = -EINVAL; 243 - goto close_file; 244 - } 245 - 246 - oud = file->private_data; 247 - 248 - odh->od = oud->od; 249 - odh->file = file; 250 - odh->oud = oud; 251 - 252 - return &odh->od; 253 - 254 - close_file: 255 - fput(file); 256 - free_od: 257 - kfree(odh); 258 - return ERR_PTR(error); 259 - } 260 - EXPORT_SYMBOL(osduld_path_lookup); 261 - 262 - static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len, 263 - const u8 *a2, unsigned a2_len) 264 - { 265 - if (!a2_len) /* User string is Empty means don't care */ 266 - return true; 267 - 268 - if (a1_len != a2_len) 269 - return false; 270 - 271 - return 0 == memcmp(a1, a2, a1_len); 272 - } 273 - 274 - static int _match_odi(struct device *dev, const void *find_data) 275 - { 276 - struct osd_uld_device *oud = container_of(dev, struct osd_uld_device, 277 - class_dev); 278 - const struct osd_dev_info *odi = find_data; 279 - 280 - if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len, 281 - odi->systemid, odi->systemid_len) && 282 - _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len, 283 - odi->osdname, odi->osdname_len)) { 284 - OSD_DEBUG("found device sysid_len=%d osdname=%d\n", 285 - odi->systemid_len, odi->osdname_len); 286 - return 1; 287 - } else { 288 - return 0; 289 - } 290 - } 291 - 292 - /* osduld_info_lookup - Loop through all devices, return the requested osd_dev. 293 - * 294 - * if @odi->systemid_len and/or @odi->osdname_len are zero, they act as a don't 295 - * care. .e.g if they're both zero /dev/osd0 is returned. 296 - */ 297 - struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi) 298 - { 299 - struct device *dev = class_find_device(&osd_uld_class, NULL, odi, _match_odi); 300 - if (likely(dev)) { 301 - struct osd_dev_handle *odh = kzalloc(sizeof(*odh), GFP_KERNEL); 302 - struct osd_uld_device *oud = container_of(dev, 303 - struct osd_uld_device, class_dev); 304 - 305 - if (unlikely(!odh)) { 306 - put_device(dev); 307 - return ERR_PTR(-ENOMEM); 308 - } 309 - 310 - odh->od = oud->od; 311 - odh->oud = oud; 312 - 313 - return &odh->od; 314 - } 315 - 316 - return ERR_PTR(-ENODEV); 317 - } 318 - EXPORT_SYMBOL(osduld_info_lookup); 319 - 320 - void osduld_put_device(struct osd_dev *od) 321 - { 322 - if (od && !IS_ERR(od)) { 323 - struct osd_dev_handle *odh = 324 - container_of(od, struct osd_dev_handle, od); 325 - struct osd_uld_device *oud = odh->oud; 326 - 327 - BUG_ON(od->scsi_device != oud->od.scsi_device); 328 - 329 - /* If scsi has released the device (logout), and exofs has last 330 - * reference on oud it will be freed by above osd_uld_release 331 - * within fput below. But this will oops in cdev_release which 332 - * is called after the fops->release. A get_/put_ pair makes 333 - * sure we have a cdev for the duration of fput 334 - */ 335 - if (odh->file) { 336 - get_device(&oud->class_dev); 337 - fput(odh->file); 338 - } 339 - put_device(&oud->class_dev); 340 - kfree(odh); 341 - } 342 - } 343 - EXPORT_SYMBOL(osduld_put_device); 344 - 345 - const struct osd_dev_info *osduld_device_info(struct osd_dev *od) 346 - { 347 - struct osd_dev_handle *odh = 348 - container_of(od, struct osd_dev_handle, od); 349 - return &odh->oud->odi; 350 - } 351 - EXPORT_SYMBOL(osduld_device_info); 352 - 353 - bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi) 354 - { 355 - struct osd_dev_handle *odh = 356 - container_of(od, struct osd_dev_handle, od); 357 - struct osd_uld_device *oud = odh->oud; 358 - 359 - return (oud->odi.systemid_len == odi->systemid_len) && 360 - _the_same_or_null(oud->odi.systemid, oud->odi.systemid_len, 361 - odi->systemid, odi->systemid_len) && 362 - (oud->odi.osdname_len == odi->osdname_len) && 363 - _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len, 364 - odi->osdname, odi->osdname_len); 365 - } 366 - EXPORT_SYMBOL(osduld_device_same); 367 - 368 - /* 369 - * Scsi Device operations 370 - */ 371 - 372 - static int __detect_osd(struct osd_uld_device *oud) 373 - { 374 - struct scsi_device *scsi_device = oud->od.scsi_device; 375 - struct scsi_sense_hdr sense_hdr; 376 - char caps[OSD_CAP_LEN]; 377 - int error; 378 - 379 - /* sending a test_unit_ready as first command seems to be needed 380 - * by some targets 381 - */ 382 - OSD_DEBUG("start scsi_test_unit_ready %p %p %p\n", 383 - oud, scsi_device, scsi_device->request_queue); 384 - error = scsi_test_unit_ready(scsi_device, 10*HZ, 5, &sense_hdr); 385 - if (error) 386 - OSD_ERR("warning: scsi_test_unit_ready failed\n"); 387 - 388 - osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true); 389 - if (osd_auto_detect_ver(&oud->od, caps, &oud->odi)) 390 - return -ENODEV; 391 - 392 - return 0; 393 - } 394 - 395 - static void __remove(struct device *dev) 396 - { 397 - struct osd_uld_device *oud = container_of(dev, struct osd_uld_device, 398 - class_dev); 399 - struct scsi_device *scsi_device = oud->od.scsi_device; 400 - 401 - kfree(oud->odi.osdname); 402 - 403 - osd_dev_fini(&oud->od); 404 - scsi_device_put(scsi_device); 405 - 406 - OSD_INFO("osd_remove %s\n", 407 - oud->disk ? oud->disk->disk_name : NULL); 408 - 409 - if (oud->disk) 410 - put_disk(oud->disk); 411 - 412 - kfree(oud); 413 - } 414 - 415 - static int osd_probe(struct device *dev) 416 - { 417 - struct scsi_device *scsi_device = to_scsi_device(dev); 418 - struct gendisk *disk; 419 - struct osd_uld_device *oud; 420 - int minor; 421 - int error; 422 - 423 - if (scsi_device->type != TYPE_OSD) 424 - return -ENODEV; 425 - 426 - minor = ida_alloc_max(&osd_minor_ida, SCSI_OSD_MAX_MINOR, GFP_KERNEL); 427 - if (minor == -ENOSPC) 428 - return -EBUSY; 429 - if (minor < 0) 430 - return -ENODEV; 431 - 432 - error = -ENOMEM; 433 - oud = kzalloc(sizeof(*oud), GFP_KERNEL); 434 - if (NULL == oud) 435 - goto err_retract_minor; 436 - 437 - /* class device member */ 438 - device_initialize(&oud->class_dev); 439 - dev_set_drvdata(dev, oud); 440 - oud->minor = minor; 441 - oud->class_dev.devt = MKDEV(SCSI_OSD_MAJOR, oud->minor); 442 - oud->class_dev.class = &osd_uld_class; 443 - oud->class_dev.parent = dev; 444 - oud->class_dev.release = __remove; 445 - 446 - /* hold one more reference to the scsi_device that will get released 447 - * in __release, in case a logout is happening while fs is mounted 448 - */ 449 - if (scsi_device_get(scsi_device)) 450 - goto err_retract_minor; 451 - osd_dev_init(&oud->od, scsi_device); 452 - 453 - /* allocate a disk and set it up */ 454 - /* FIXME: do we need this since sg has already done that */ 455 - disk = alloc_disk(1); 456 - if (!disk) { 457 - OSD_ERR("alloc_disk failed\n"); 458 - goto err_free_osd; 459 - } 460 - disk->major = SCSI_OSD_MAJOR; 461 - disk->first_minor = oud->minor; 462 - sprintf(disk->disk_name, "osd%d", oud->minor); 463 - oud->disk = disk; 464 - 465 - /* Detect the OSD Version */ 466 - error = __detect_osd(oud); 467 - if (error) { 468 - OSD_ERR("osd detection failed, non-compatible OSD device\n"); 469 - goto err_free_osd; 470 - } 471 - 472 - /* init the char-device for communication with user-mode */ 473 - cdev_init(&oud->cdev, &osd_fops); 474 - oud->cdev.owner = THIS_MODULE; 475 - 476 - error = dev_set_name(&oud->class_dev, "%s", disk->disk_name); 477 - if (error) { 478 - OSD_ERR("dev_set_name failed => %d\n", error); 479 - goto err_free_osd; 480 - } 481 - 482 - error = cdev_device_add(&oud->cdev, &oud->class_dev); 483 - if (error) { 484 - OSD_ERR("device_register failed => %d\n", error); 485 - goto err_free_osd; 486 - } 487 - 488 - OSD_INFO("osd_probe %s\n", disk->disk_name); 489 - return 0; 490 - 491 - err_free_osd: 492 - put_device(&oud->class_dev); 493 - err_retract_minor: 494 - ida_free(&osd_minor_ida, minor); 495 - return error; 496 - } 497 - 498 - static int osd_remove(struct device *dev) 499 - { 500 - struct scsi_device *scsi_device = to_scsi_device(dev); 501 - struct osd_uld_device *oud = dev_get_drvdata(dev); 502 - 503 - if (oud->od.scsi_device != scsi_device) { 504 - OSD_ERR("Half cooked osd-device %p, || %p!=%p", 505 - dev, oud->od.scsi_device, scsi_device); 506 - } 507 - 508 - cdev_device_del(&oud->cdev, &oud->class_dev); 509 - ida_free(&osd_minor_ida, oud->minor); 510 - put_device(&oud->class_dev); 511 - 512 - return 0; 513 - } 514 - 515 - /* 516 - * Global driver and scsi registration 517 - */ 518 - 519 - static struct scsi_driver osd_driver = { 520 - .gendrv = { 521 - .name = osd_name, 522 - .owner = THIS_MODULE, 523 - .probe = osd_probe, 524 - .remove = osd_remove, 525 - } 526 - }; 527 - 528 - static int __init osd_uld_init(void) 529 - { 530 - int err; 531 - 532 - err = class_register(&osd_uld_class); 533 - if (err) { 534 - OSD_ERR("Unable to register sysfs class => %d\n", err); 535 - return err; 536 - } 537 - 538 - err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), 539 - SCSI_OSD_MAX_MINOR, osd_name); 540 - if (err) { 541 - OSD_ERR("Unable to register major %d for osd ULD => %d\n", 542 - SCSI_OSD_MAJOR, err); 543 - goto err_out; 544 - } 545 - 546 - err = scsi_register_driver(&osd_driver.gendrv); 547 - if (err) { 548 - OSD_ERR("scsi_register_driver failed => %d\n", err); 549 - goto err_out_chrdev; 550 - } 551 - 552 - OSD_INFO("LOADED %s\n", osd_version_string); 553 - return 0; 554 - 555 - err_out_chrdev: 556 - unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR); 557 - err_out: 558 - class_unregister(&osd_uld_class); 559 - return err; 560 - } 561 - 562 - static void __exit osd_uld_exit(void) 563 - { 564 - scsi_unregister_driver(&osd_driver.gendrv); 565 - unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR); 566 - class_unregister(&osd_uld_class); 567 - OSD_INFO("UNLOADED %s\n", osd_version_string); 568 - } 569 - 570 - module_init(osd_uld_init); 571 - module_exit(osd_uld_exit);
-511
include/scsi/osd_initiator.h
··· 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 <ooo@electrozaur.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 <scsi/osd_protocol.h> 18 - #include <scsi/osd_types.h> 19 - 20 - #include <linux/blkdev.h> 21 - #include <scsi/scsi_device.h> 22 - 23 - /* Note: "NI" in comments below means "Not Implemented yet" */ 24 - 25 - /* Configure of code: 26 - * #undef if you *don't* want OSD v1 support in runtime. 27 - * If #defined the initiator will dynamically configure to encode OSD v1 28 - * CDB's if the target is detected to be OSD v1 only. 29 - * OSD v2 only commands, options, and attributes will be ignored if target 30 - * is v1 only. 31 - * If #defined will result in bigger/slower code (OK Slower maybe not) 32 - * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig? 33 - */ 34 - #define OSD_VER1_SUPPORT y 35 - 36 - enum osd_std_version { 37 - OSD_VER_NONE = 0, 38 - OSD_VER1 = 1, 39 - OSD_VER2 = 2, 40 - }; 41 - 42 - /* 43 - * Object-based Storage Device. 44 - * This object represents an OSD device. 45 - * It is not a full linux device in any way. It is only 46 - * a place to hang resources associated with a Linux 47 - * request Q and some default properties. 48 - */ 49 - struct osd_dev { 50 - struct scsi_device *scsi_device; 51 - unsigned def_timeout; 52 - 53 - #ifdef OSD_VER1_SUPPORT 54 - enum osd_std_version version; 55 - #endif 56 - }; 57 - 58 - /* Unique Identification of an OSD device */ 59 - struct osd_dev_info { 60 - unsigned systemid_len; 61 - u8 systemid[OSD_SYSTEMID_LEN]; 62 - unsigned osdname_len; 63 - u8 *osdname; 64 - }; 65 - 66 - /* Retrieve/return osd_dev(s) for use by Kernel clients 67 - * Use IS_ERR/ERR_PTR on returned "osd_dev *". 68 - */ 69 - struct osd_dev *osduld_path_lookup(const char *dev_name); 70 - struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi); 71 - void osduld_put_device(struct osd_dev *od); 72 - 73 - const struct osd_dev_info *osduld_device_info(struct osd_dev *od); 74 - bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi); 75 - 76 - /* Add/remove test ioctls from external modules */ 77 - typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg); 78 - int osduld_register_test(unsigned ioctl, do_test_fn *do_test); 79 - void osduld_unregister_test(unsigned ioctl); 80 - 81 - /* These are called by uld at probe time */ 82 - void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); 83 - void osd_dev_fini(struct osd_dev *od); 84 - 85 - /** 86 - * osd_auto_detect_ver - Detect the OSD version, return Unique Identification 87 - * 88 - * @od: OSD target lun handle 89 - * @caps: Capabilities authorizing OSD root read attributes access 90 - * @odi: Retrieved information uniquely identifying the osd target lun 91 - * Note: odi->osdname must be kfreed by caller. 92 - * 93 - * Auto detects the OSD version of the OSD target and sets the @od 94 - * accordingly. Meanwhile also returns the "system id" and "osd name" root 95 - * attributes which uniquely identify the OSD target. This member is usually 96 - * called by the ULD. ULD users should call osduld_device_info(). 97 - * This rutine allocates osd requests and memory at GFP_KERNEL level and might 98 - * sleep. 99 - */ 100 - int osd_auto_detect_ver(struct osd_dev *od, 101 - void *caps, struct osd_dev_info *odi); 102 - 103 - static inline struct request_queue *osd_request_queue(struct osd_dev *od) 104 - { 105 - return od->scsi_device->request_queue; 106 - } 107 - 108 - /* we might want to use function vector in the future */ 109 - static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) 110 - { 111 - #ifdef OSD_VER1_SUPPORT 112 - od->version = v; 113 - #endif 114 - } 115 - 116 - static inline bool osd_dev_is_ver1(struct osd_dev *od) 117 - { 118 - #ifdef OSD_VER1_SUPPORT 119 - return od->version == OSD_VER1; 120 - #else 121 - return false; 122 - #endif 123 - } 124 - 125 - struct osd_request; 126 - typedef void (osd_req_done_fn)(struct osd_request *or, void *private); 127 - 128 - struct osd_request { 129 - struct osd_cdb cdb; 130 - struct osd_data_out_integrity_info out_data_integ; 131 - struct osd_data_in_integrity_info in_data_integ; 132 - 133 - struct osd_dev *osd_dev; 134 - struct request *request; 135 - 136 - struct _osd_req_data_segment { 137 - void *buff; 138 - unsigned alloc_size; /* 0 here means: don't call kfree */ 139 - unsigned total_bytes; 140 - } cdb_cont, set_attr, enc_get_attr, get_attr; 141 - 142 - struct _osd_io_info { 143 - struct bio *bio; 144 - u64 total_bytes; 145 - u64 residual; 146 - struct request *req; 147 - struct _osd_req_data_segment *last_seg; 148 - u8 *pad_buff; 149 - } out, in; 150 - 151 - unsigned timeout; 152 - unsigned retries; 153 - unsigned sense_len; 154 - u8 sense[OSD_MAX_SENSE_LEN]; 155 - enum osd_attributes_mode attributes_mode; 156 - 157 - osd_req_done_fn *async_done; 158 - void *async_private; 159 - blk_status_t async_error; 160 - int req_errors; 161 - }; 162 - 163 - static inline bool osd_req_is_ver1(struct osd_request *or) 164 - { 165 - return osd_dev_is_ver1(or->osd_dev); 166 - } 167 - 168 - /* 169 - * How to use the osd library: 170 - * 171 - * osd_start_request 172 - * Allocates a request. 173 - * 174 - * osd_req_* 175 - * Call one of, to encode the desired operation. 176 - * 177 - * osd_add_{get,set}_attr 178 - * Optionally add attributes to the CDB, list or page mode. 179 - * 180 - * osd_finalize_request 181 - * Computes final data out/in offsets and signs the request, 182 - * making it ready for execution. 183 - * 184 - * osd_execute_request 185 - * May be called to execute it through the block layer. Other wise submit 186 - * the associated block request in some other way. 187 - * 188 - * After execution: 189 - * osd_req_decode_sense 190 - * Decodes sense information to verify execution results. 191 - * 192 - * osd_req_decode_get_attr 193 - * Retrieve osd_add_get_attr_list() values if used. 194 - * 195 - * osd_end_request 196 - * Must be called to deallocate the request. 197 - */ 198 - 199 - /** 200 - * osd_start_request - Allocate and initialize an osd_request 201 - * 202 - * @osd_dev: OSD device that holds the scsi-device and default values 203 - * that the request is associated with. 204 - * 205 - * Allocate osd_request and initialize all members to the 206 - * default/initial state. 207 - */ 208 - struct osd_request *osd_start_request(struct osd_dev *od); 209 - 210 - enum osd_req_options { 211 - OSD_REQ_FUA = 0x08, /* Force Unit Access */ 212 - OSD_REQ_DPO = 0x10, /* Disable Page Out */ 213 - 214 - OSD_REQ_BYPASS_TIMESTAMPS = 0x80, 215 - }; 216 - 217 - /** 218 - * osd_finalize_request - Sign request and prepare request for execution 219 - * 220 - * @or: osd_request to prepare 221 - * @options: combination of osd_req_options bit flags or 0. 222 - * @cap: A Pointer to an OSD_CAP_LEN bytes buffer that is received from 223 - * The security manager as capabilities for this cdb. 224 - * @cap_key: The cryptographic key used to sign the cdb/data. Can be null 225 - * if NOSEC is used. 226 - * 227 - * The actual request and bios are only allocated here, so are the get_attr 228 - * buffers that will receive the returned attributes. Copy's @cap to cdb. 229 - * Sign the cdb/data with @cap_key. 230 - */ 231 - int osd_finalize_request(struct osd_request *or, 232 - u8 options, const void *cap, const u8 *cap_key); 233 - 234 - /** 235 - * osd_execute_request - Execute the request synchronously through block-layer 236 - * 237 - * @or: osd_request to Executed 238 - * 239 - * Calls blk_execute_rq to q the command and waits for completion. 240 - */ 241 - int osd_execute_request(struct osd_request *or); 242 - 243 - /** 244 - * osd_execute_request_async - Execute the request without waitting. 245 - * 246 - * @or: - osd_request to Executed 247 - * @done: (Optional) - Called at end of execution 248 - * @private: - Will be passed to @done function 249 - * 250 - * Calls blk_execute_rq_nowait to queue the command. When execution is done 251 - * optionally calls @done with @private as parameter. @or->async_error will 252 - * have the return code 253 - */ 254 - int osd_execute_request_async(struct osd_request *or, 255 - osd_req_done_fn *done, void *private); 256 - 257 - /** 258 - * osd_req_decode_sense_full - Decode sense information after execution. 259 - * 260 - * @or: - osd_request to examine 261 - * @osi - Receives a more detailed error report information (optional). 262 - * @silent - Do not print to dmsg (Even if enabled) 263 - * @bad_obj_list - Some commands act on multiple objects. Failed objects will 264 - * be received here (optional) 265 - * @max_obj - Size of @bad_obj_list. 266 - * @bad_attr_list - List of failing attributes (optional) 267 - * @max_attr - Size of @bad_attr_list. 268 - * 269 - * After execution, osd_request results are analyzed using this function. The 270 - * return code is the final disposition on the error. So it is possible that a 271 - * CHECK_CONDITION was returned from target but this will return NO_ERROR, for 272 - * example on recovered errors. All parameters are optional if caller does 273 - * not need any returned information. 274 - * Note: This function will also dump the error to dmsg according to settings 275 - * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the 276 - * command would routinely fail, to not spam the dmsg file. 277 - */ 278 - 279 - /** 280 - * osd_err_priority - osd categorized return codes in ascending severity. 281 - * 282 - * The categories are borrowed from the pnfs_osd_errno enum. 283 - * See comments for translated Linux codes returned by osd_req_decode_sense. 284 - */ 285 - enum osd_err_priority { 286 - OSD_ERR_PRI_NO_ERROR = 0, 287 - /* Recoverable, caller should clear_highpage() all pages */ 288 - OSD_ERR_PRI_CLEAR_PAGES = 1, /* -EFAULT */ 289 - OSD_ERR_PRI_RESOURCE = 2, /* -ENOMEM */ 290 - OSD_ERR_PRI_BAD_CRED = 3, /* -EINVAL */ 291 - OSD_ERR_PRI_NO_ACCESS = 4, /* -EACCES */ 292 - OSD_ERR_PRI_UNREACHABLE = 5, /* any other */ 293 - OSD_ERR_PRI_NOT_FOUND = 6, /* -ENOENT */ 294 - OSD_ERR_PRI_NO_SPACE = 7, /* -ENOSPC */ 295 - OSD_ERR_PRI_EIO = 8, /* -EIO */ 296 - }; 297 - 298 - struct osd_sense_info { 299 - enum osd_err_priority osd_err_pri; 300 - 301 - int key; /* one of enum scsi_sense_keys */ 302 - int additional_code ; /* enum osd_additional_sense_codes */ 303 - union { /* Sense specific information */ 304 - u16 sense_info; 305 - u16 cdb_field_offset; /* scsi_invalid_field_in_cdb */ 306 - }; 307 - union { /* Command specific information */ 308 - u64 command_info; 309 - }; 310 - 311 - u32 not_initiated_command_functions; /* osd_command_functions_bits */ 312 - u32 completed_command_functions; /* osd_command_functions_bits */ 313 - struct osd_obj_id obj; 314 - struct osd_attr attr; 315 - }; 316 - 317 - int osd_req_decode_sense_full(struct osd_request *or, 318 - struct osd_sense_info *osi, bool silent, 319 - struct osd_obj_id *bad_obj_list, int max_obj, 320 - struct osd_attr *bad_attr_list, int max_attr); 321 - 322 - static inline int osd_req_decode_sense(struct osd_request *or, 323 - struct osd_sense_info *osi) 324 - { 325 - return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0); 326 - } 327 - 328 - /** 329 - * osd_end_request - return osd_request to free store 330 - * 331 - * @or: osd_request to free 332 - * 333 - * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.) 334 - */ 335 - void osd_end_request(struct osd_request *or); 336 - 337 - /* 338 - * CDB Encoding 339 - * 340 - * Note: call only one of the following methods. 341 - */ 342 - 343 - /* 344 - * Device commands 345 - */ 346 - void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */ 347 - void osd_req_set_master_key(struct osd_request *or, ...);/* NI */ 348 - 349 - void osd_req_format(struct osd_request *or, u64 tot_capacity); 350 - 351 - /* list all partitions 352 - * @list header must be initialized to zero on first run. 353 - * 354 - * Call osd_is_obj_list_done() to find if we got the complete list. 355 - */ 356 - int osd_req_list_dev_partitions(struct osd_request *or, 357 - osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem); 358 - 359 - void osd_req_flush_obsd(struct osd_request *or, 360 - enum osd_options_flush_scope_values); 361 - 362 - void osd_req_perform_scsi_command(struct osd_request *or, 363 - const u8 *cdb, ...);/* NI */ 364 - void osd_req_task_management(struct osd_request *or, ...);/* NI */ 365 - 366 - /* 367 - * Partition commands 368 - */ 369 - void osd_req_create_partition(struct osd_request *or, osd_id partition); 370 - void osd_req_remove_partition(struct osd_request *or, osd_id partition); 371 - 372 - void osd_req_set_partition_key(struct osd_request *or, 373 - osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE], 374 - u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */ 375 - 376 - /* list all collections in the partition 377 - * @list header must be init to zero on first run. 378 - * 379 - * Call osd_is_obj_list_done() to find if we got the complete list. 380 - */ 381 - int osd_req_list_partition_collections(struct osd_request *or, 382 - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 383 - unsigned nelem); 384 - 385 - /* list all objects in the partition 386 - * @list header must be init to zero on first run. 387 - * 388 - * Call osd_is_obj_list_done() to find if we got the complete list. 389 - */ 390 - int osd_req_list_partition_objects(struct osd_request *or, 391 - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 392 - unsigned nelem); 393 - 394 - void osd_req_flush_partition(struct osd_request *or, 395 - osd_id partition, enum osd_options_flush_scope_values); 396 - 397 - /* 398 - * Collection commands 399 - */ 400 - void osd_req_create_collection(struct osd_request *or, 401 - const struct osd_obj_id *);/* NI */ 402 - void osd_req_remove_collection(struct osd_request *or, 403 - const struct osd_obj_id *);/* NI */ 404 - 405 - /* list all objects in the collection */ 406 - int osd_req_list_collection_objects(struct osd_request *or, 407 - const struct osd_obj_id *, osd_id initial_id, 408 - struct osd_obj_id_list *list, unsigned nelem); 409 - 410 - /* V2 only filtered list of objects in the collection */ 411 - void osd_req_query(struct osd_request *or, ...);/* NI */ 412 - 413 - void osd_req_flush_collection(struct osd_request *or, 414 - const struct osd_obj_id *, enum osd_options_flush_scope_values); 415 - 416 - void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */ 417 - void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */ 418 - 419 - /* 420 - * Object commands 421 - */ 422 - void osd_req_create_object(struct osd_request *or, struct osd_obj_id *); 423 - void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *); 424 - 425 - void osd_req_write(struct osd_request *or, 426 - const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len); 427 - int osd_req_write_kern(struct osd_request *or, 428 - const struct osd_obj_id *obj, u64 offset, void *buff, u64 len); 429 - void osd_req_append(struct osd_request *or, 430 - const struct osd_obj_id *, struct bio *data_out);/* NI */ 431 - void osd_req_create_write(struct osd_request *or, 432 - const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */ 433 - void osd_req_clear(struct osd_request *or, 434 - const struct osd_obj_id *, u64 offset, u64 len);/* NI */ 435 - void osd_req_punch(struct osd_request *or, 436 - const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */ 437 - 438 - void osd_req_flush_object(struct osd_request *or, 439 - const struct osd_obj_id *, enum osd_options_flush_scope_values, 440 - /*V2*/ u64 offset, /*V2*/ u64 len); 441 - 442 - void osd_req_read(struct osd_request *or, 443 - const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len); 444 - int osd_req_read_kern(struct osd_request *or, 445 - const struct osd_obj_id *obj, u64 offset, void *buff, u64 len); 446 - 447 - /* Scatter/Gather write/read commands */ 448 - int osd_req_write_sg(struct osd_request *or, 449 - const struct osd_obj_id *obj, struct bio *bio, 450 - const struct osd_sg_entry *sglist, unsigned numentries); 451 - int osd_req_read_sg(struct osd_request *or, 452 - const struct osd_obj_id *obj, struct bio *bio, 453 - const struct osd_sg_entry *sglist, unsigned numentries); 454 - int osd_req_write_sg_kern(struct osd_request *or, 455 - const struct osd_obj_id *obj, void **buff, 456 - const struct osd_sg_entry *sglist, unsigned numentries); 457 - int osd_req_read_sg_kern(struct osd_request *or, 458 - const struct osd_obj_id *obj, void **buff, 459 - const struct osd_sg_entry *sglist, unsigned numentries); 460 - 461 - /* 462 - * Root/Partition/Collection/Object Attributes commands 463 - */ 464 - 465 - /* get before set */ 466 - void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *); 467 - 468 - /* set before get */ 469 - void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *); 470 - 471 - /* 472 - * Attributes appended to most commands 473 - */ 474 - 475 - /* Attributes List mode (or V2 CDB) */ 476 - /* 477 - * TODO: In ver2 if at finalize time only one attr was set and no gets, 478 - * then the Attributes CDB mode is used automatically to save IO. 479 - */ 480 - 481 - /* set a list of attributes. */ 482 - int osd_req_add_set_attr_list(struct osd_request *or, 483 - const struct osd_attr *, unsigned nelem); 484 - 485 - /* get a list of attributes */ 486 - int osd_req_add_get_attr_list(struct osd_request *or, 487 - const struct osd_attr *, unsigned nelem); 488 - 489 - /* 490 - * Attributes list decoding 491 - * Must be called after osd_request.request was executed 492 - * It is called in a loop to decode the returned get_attr 493 - * (see osd_add_get_attr) 494 - */ 495 - int osd_req_decode_get_attr_list(struct osd_request *or, 496 - struct osd_attr *, int *nelem, void **iterator); 497 - 498 - /* Attributes Page mode */ 499 - 500 - /* 501 - * Read an attribute page and optionally set one attribute 502 - * 503 - * Retrieves the attribute page directly to a user buffer. 504 - * @attr_page_data shall stay valid until end of execution. 505 - * See osd_attributes.h for common page structures 506 - */ 507 - int osd_req_add_get_attr_page(struct osd_request *or, 508 - u32 page_id, void *attr_page_data, unsigned max_page_len, 509 - const struct osd_attr *set_one); 510 - 511 - #endif /* __OSD_LIB_H__ */
-201
include/scsi/osd_ore.h
··· 1 - /* 2 - * Copyright (C) 2011 3 - * Boaz Harrosh <ooo@electrozaur.com> 4 - * 5 - * Public Declarations of the ORE API 6 - * 7 - * This file is part of the ORE (Object Raid Engine) library. 8 - * 9 - * ORE is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as published 11 - * by the Free Software Foundation. (GPL v2) 12 - * 13 - * ORE is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * You should have received a copy of the GNU General Public License 19 - * along with the ORE; if not, write to the Free Software 20 - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 - */ 22 - #ifndef __ORE_H__ 23 - #define __ORE_H__ 24 - 25 - #include <scsi/osd_initiator.h> 26 - #include <scsi/osd_attributes.h> 27 - #include <scsi/osd_sec.h> 28 - #include <linux/pnfs_osd_xdr.h> 29 - #include <linux/bug.h> 30 - 31 - struct ore_comp { 32 - struct osd_obj_id obj; 33 - u8 cred[OSD_CAP_LEN]; 34 - }; 35 - 36 - struct ore_layout { 37 - /* Our way of looking at the data_map */ 38 - enum pnfs_osd_raid_algorithm4 39 - raid_algorithm; 40 - unsigned stripe_unit; 41 - unsigned mirrors_p1; 42 - 43 - unsigned group_width; 44 - unsigned parity; 45 - u64 group_depth; 46 - unsigned group_count; 47 - 48 - /* Cached often needed calculations filled in by 49 - * ore_verify_layout 50 - */ 51 - unsigned long max_io_length; /* Max length that should be passed to 52 - * ore_get_rw_state 53 - */ 54 - }; 55 - 56 - struct ore_dev { 57 - struct osd_dev *od; 58 - }; 59 - 60 - struct ore_components { 61 - unsigned first_dev; /* First logical device no */ 62 - unsigned numdevs; /* Num of devices in array */ 63 - /* If @single_comp == EC_SINGLE_COMP, @comps points to a single 64 - * component. else there are @numdevs components 65 - */ 66 - enum EC_COMP_USAGE { 67 - EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff 68 - } single_comp; 69 - struct ore_comp *comps; 70 - 71 - /* Array of pointers to ore_dev-* . User will usually have these pointed 72 - * too a bigger struct which contain an "ore_dev ored" member and use 73 - * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger 74 - * structure. 75 - */ 76 - struct ore_dev **ods; 77 - }; 78 - 79 - /* ore_comp_dev Recievies a logical device index */ 80 - static inline struct osd_dev *ore_comp_dev( 81 - const struct ore_components *oc, unsigned i) 82 - { 83 - BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i)); 84 - return oc->ods[i - oc->first_dev]->od; 85 - } 86 - 87 - static inline void ore_comp_set_dev( 88 - struct ore_components *oc, unsigned i, struct osd_dev *od) 89 - { 90 - oc->ods[i - oc->first_dev]->od = od; 91 - } 92 - 93 - struct ore_striping_info { 94 - u64 offset; 95 - u64 obj_offset; 96 - u64 length; 97 - u64 first_stripe_start; /* only used in raid writes */ 98 - u64 M; /* for truncate */ 99 - unsigned bytes_in_stripe; 100 - unsigned dev; 101 - unsigned par_dev; 102 - unsigned unit_off; 103 - unsigned cur_pg; 104 - unsigned cur_comp; 105 - unsigned maxdevUnits; 106 - }; 107 - 108 - struct ore_io_state; 109 - typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private); 110 - struct _ore_r4w_op { 111 - /* @Priv given here is passed ios->private */ 112 - struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate); 113 - void (*put_page)(void *priv, struct page *page); 114 - }; 115 - 116 - struct ore_io_state { 117 - struct kref kref; 118 - struct ore_striping_info si; 119 - 120 - void *private; 121 - ore_io_done_fn done; 122 - 123 - struct ore_layout *layout; 124 - struct ore_components *oc; 125 - 126 - /* Global read/write IO*/ 127 - loff_t offset; 128 - unsigned long length; 129 - void *kern_buff; 130 - 131 - struct page **pages; 132 - unsigned nr_pages; 133 - unsigned pgbase; 134 - unsigned pages_consumed; 135 - 136 - /* Attributes */ 137 - unsigned in_attr_len; 138 - struct osd_attr *in_attr; 139 - unsigned out_attr_len; 140 - struct osd_attr *out_attr; 141 - 142 - bool reading; 143 - 144 - /* House keeping of Parity pages */ 145 - bool extra_part_alloc; 146 - struct page **parity_pages; 147 - unsigned max_par_pages; 148 - unsigned cur_par_page; 149 - unsigned sgs_per_dev; 150 - struct __stripe_pages_2d *sp2d; 151 - struct ore_io_state *ios_read_4_write; 152 - const struct _ore_r4w_op *r4w; 153 - 154 - /* Variable array of size numdevs */ 155 - unsigned numdevs; 156 - struct ore_per_dev_state { 157 - struct osd_request *or; 158 - struct bio *bio; 159 - loff_t offset; 160 - unsigned length; 161 - unsigned last_sgs_total; 162 - unsigned dev; 163 - struct osd_sg_entry *sglist; 164 - unsigned cur_sg; 165 - } per_dev[]; 166 - }; 167 - 168 - static inline unsigned ore_io_state_size(unsigned numdevs) 169 - { 170 - return sizeof(struct ore_io_state) + 171 - sizeof(struct ore_per_dev_state) * numdevs; 172 - } 173 - 174 - /* ore.c */ 175 - int ore_verify_layout(unsigned total_comps, struct ore_layout *layout); 176 - void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, 177 - u64 length, struct ore_striping_info *si); 178 - int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, 179 - bool is_reading, u64 offset, u64 length, 180 - struct ore_io_state **ios); 181 - int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps, 182 - struct ore_io_state **ios); 183 - void ore_put_io_state(struct ore_io_state *ios); 184 - 185 - typedef void (*ore_on_dev_error)(struct ore_io_state *ios, struct ore_dev *od, 186 - unsigned dev_index, enum osd_err_priority oep, 187 - u64 dev_offset, u64 dev_len); 188 - int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep); 189 - 190 - int ore_create(struct ore_io_state *ios); 191 - int ore_remove(struct ore_io_state *ios); 192 - int ore_write(struct ore_io_state *ios); 193 - int ore_read(struct ore_io_state *ios); 194 - int ore_truncate(struct ore_layout *layout, struct ore_components *comps, 195 - u64 size); 196 - 197 - int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr); 198 - 199 - extern const struct osd_attr g_attr_logical_length; 200 - 201 - #endif