lkml.org 
[lkml]   [2018]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/8] scsi: remove the SCSI OSD library
    Date
    Now that all the users are gone the SCSI OSD library can be removed
    as well.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    ---
    Documentation/scsi/osd.txt | 192 ---
    drivers/scsi/Kconfig | 2 -
    drivers/scsi/Makefile | 1 -
    drivers/scsi/osd/Kbuild | 20 -
    drivers/scsi/osd/Kconfig | 49 -
    drivers/scsi/osd/osd_debug.h | 30 -
    drivers/scsi/osd/osd_initiator.c | 2076 ------------------------------
    drivers/scsi/osd/osd_uld.c | 571 --------
    include/scsi/osd_initiator.h | 511 --------
    include/scsi/osd_ore.h | 201 ---
    10 files changed, 3653 deletions(-)
    delete mode 100644 Documentation/scsi/osd.txt
    delete mode 100644 drivers/scsi/osd/Kbuild
    delete mode 100644 drivers/scsi/osd/Kconfig
    delete mode 100644 drivers/scsi/osd/osd_debug.h
    delete mode 100644 drivers/scsi/osd/osd_initiator.c
    delete mode 100644 drivers/scsi/osd/osd_uld.c
    delete mode 100644 include/scsi/osd_initiator.h
    delete mode 100644 include/scsi/osd_ore.h

    diff --git a/Documentation/scsi/osd.txt b/Documentation/scsi/osd.txt
    deleted file mode 100644
    index 2bc2ab06b0c0..000000000000
    --- a/Documentation/scsi/osd.txt
    +++ /dev/null
    @@ -1,192 +0,0 @@
    -The OSD Standard
    -================
    -OSD (Object-Based Storage Device) is a T10 SCSI command set that is designed
    -to provide efficient operation of input/output logical units that manage the
    -allocation, placement, and accessing of variable-size data-storage containers,
    -called objects. Objects are intended to contain operating system and application
    -constructs. Each object has associated attributes attached to it, which are
    -integral part of the object and provide metadata about the object. The standard
    -defines some common obligatory attributes, but user attributes can be added as
    -needed.
    -
    -See: http://www.t10.org/ftp/t10/drafts/osd2/ for the latest draft for OSD 2
    -or search the web for "OSD SCSI"
    -
    -OSD in the Linux Kernel
    -=======================
    -osd-initiator:
    - The main component of OSD in Kernel is the osd-initiator library. Its main
    -user is intended to be the pNFS-over-objects layout driver, which uses objects
    -as its back-end data storage. Other clients are the other osd parts listed below.
    -
    -osd-uld:
    - This is a SCSI ULD that registers for OSD type devices and provides a testing
    -platform, both for the in-kernel initiator as well as connected targets. It
    -currently has no useful user-mode API, though it could have if need be.
    -
    -osd target:
    - There are no current plans for an OSD target implementation in kernel. For all
    -needs, a user-mode target that is based on the scsi tgt target framework is
    -available from Ohio Supercomputer Center (OSC) at:
    -http://www.open-osd.org/bin/view/Main/OscOsdProject
    -There are several other target implementations. See http://open-osd.org for more
    -links.
    -
    -Files and Folders
    -=================
    -This is the complete list of files included in this work:
    -include/scsi/
    - osd_initiator.h Main API for the initiator library
    - osd_types.h Common OSD types
    - osd_sec.h Security Manager API
    - osd_protocol.h Wire definitions of the OSD standard protocol
    - osd_attributes.h Wire definitions of OSD attributes
    -
    -drivers/scsi/osd/
    - osd_initiator.c OSD-Initiator library implementation
    - osd_uld.c The OSD scsi ULD
    - osd_ktest.{h,c} In-kernel test suite (called by osd_uld)
    - osd_debug.h Some printk macros
    - Makefile For both in-tree and out-of-tree compilation
    - Kconfig Enables inclusion of the different pieces
    - osd_test.c User-mode application to call the kernel tests
    -
    -The OSD-Initiator Library
    -=========================
    -osd_initiator is a low level implementation of an osd initiator encoder.
    -But even though, it should be intuitive and easy to use. Perhaps over time an
    -higher lever will form that automates some of the more common recipes.
    -
    -init/fini:
    -- osd_dev_init() associates a scsi_device with an osd_dev structure
    - and initializes some global pools. This should be done once per scsi_device
    - (OSD LUN). The osd_dev structure is needed for calling osd_start_request().
    -
    -- osd_dev_fini() cleans up before a osd_dev/scsi_device destruction.
    -
    -OSD commands encoding, execution, and decoding of results:
    -
    -struct osd_request's is used to iteratively encode an OSD command and carry
    -its state throughout execution. Each request goes through these stages:
    -
    -a. osd_start_request() allocates the request.
    -
    -b. Any of the osd_req_* methods is used to encode a request of the specified
    - type.
    -
    -c. osd_req_add_{get,set}_attr_* may be called to add get/set attributes to the
    - CDB. "List" or "Page" mode can be used exclusively. The attribute-list API
    - can be called multiple times on the same request. However, only one
    - attribute-page can be read, as mandated by the OSD standard.
    -
    -d. osd_finalize_request() computes offsets into the data-in and data-out buffers
    - and signs the request using the provided capability key and integrity-
    - check parameters.
    -
    -e. osd_execute_request() may be called to execute the request via the block
    - layer and wait for its completion. The request can be executed
    - asynchronously by calling the block layer API directly.
    -
    -f. After execution, osd_req_decode_sense() can be called to decode the request's
    - sense information.
    -
    -g. osd_req_decode_get_attr() may be called to retrieve osd_add_get_attr_list()
    - values.
    -
    -h. osd_end_request() must be called to deallocate the request and any resource
    - associated with it. Note that osd_end_request cleans up the request at any
    - stage and it must always be called after a successful osd_start_request().
    -
    -osd_request's structure:
    -
    -The OSD standard defines a complex structure of IO segments pointed to by
    -members in the CDB. Up to 3 segments can be deployed in the IN-Buffer and up to
    -4 in the OUT-Buffer. The ASCII illustration below depicts a secure-read with
    -associated get+set of attributes-lists. Other combinations very on the same
    -basic theme. From no-segments-used up to all-segments-used.
    -
    -|________OSD-CDB__________|
    -| |
    -|read_len (offset=0) -|---------\
    -| | |
    -|get_attrs_list_length | |
    -|get_attrs_list_offset -|----\ |
    -| | | |
    -|retrieved_attrs_alloc_len| | |
    -|retrieved_attrs_offset -|----|----|-\
    -| | | | |
    -|set_attrs_list_length | | | |
    -|set_attrs_list_offset -|-\ | | |
    -| | | | | |
    -|in_data_integ_offset -|-|--|----|-|-\
    -|out_data_integ_offset -|-|--|--\ | | |
    -\_________________________/ | | | | | |
    - | | | | | |
    -|_______OUT-BUFFER________| | | | | | |
    -| Set attr list |</ | | | | |
    -| | | | | | |
    -|-------------------------| | | | | |
    -| Get attr descriptors |<---/ | | | |
    -| | | | | |
    -|-------------------------| | | | |
    -| Out-data integrity |<------/ | | |
    -| | | | |
    -\_________________________/ | | |
    - | | |
    -|________IN-BUFFER________| | | |
    -| In-Data read |<--------/ | |
    -| | | |
    -|-------------------------| | |
    -| Get attr list |<----------/ |
    -| | |
    -|-------------------------| |
    -| In-data integrity |<------------/
    -| |
    -\_________________________/
    -
    -A block device request can carry bidirectional payload by means of associating
    -a bidi_read request with a main write-request. Each in/out request is described
    -by a chain of BIOs associated with each request.
    -The CDB is of a SCSI VARLEN CDB format, as described by OSD standard.
    -The OSD standard also mandates alignment restrictions at start of each segment.
    -
    -In the code, in struct osd_request, there are two _osd_io_info structures to
    -describe the IN/OUT buffers above, two BIOs for the data payload and up to five
    -_osd_req_data_segment structures to hold the different segments allocation and
    -information.
    -
    -Important: We have chosen to disregard the assumption that a BIO-chain (and
    -the resulting sg-list) describes a linear memory buffer. Meaning only first and
    -last scatter chain can be incomplete and all the middle chains are of PAGE_SIZE.
    -For us, a scatter-gather-list, as its name implies and as used by the Networking
    -layer, is to describe a vector of buffers that will be transferred to/from the
    -wire. It works very well with current iSCSI transport. iSCSI is currently the
    -only deployed OSD transport. In the future we anticipate SAS and FC attached OSD
    -devices as well.
    -
    -The OSD Testing ULD
    -===================
    -TODO: More user-mode control on tests.
    -
    -Authors, Mailing list
    -=====================
    -Please communicate with us on any deployment of osd, whether using this code
    -or not.
    -
    -Any problems, questions, bug reports, lonely OSD nights, please email:
    - OSD Dev List <osd-dev@open-osd.org>
    -
    -More up-to-date information can be found on:
    -http://open-osd.org
    -
    -Boaz Harrosh <ooo@electrozaur.com>
    -
    -References
    -==========
    -Weber, R., "SCSI Object-Based Storage Device Commands",
    -T10/1355-D ANSI/INCITS 400-2004,
    -http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf
    -
    -Weber, R., "SCSI Object-Based Storage Device Commands -2 (OSD-2)"
    -T10/1729-D, Working Draft, rev. 3
    -http://www.t10.org/ftp/t10/drafts/osd2/osd2r03.pdf
    diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
    index dfdc6940de2f..167e9824b597 100644
    --- a/drivers/scsi/Kconfig
    +++ b/drivers/scsi/Kconfig
    @@ -1516,6 +1516,4 @@ source "drivers/scsi/pcmcia/Kconfig"

    source "drivers/scsi/device_handler/Kconfig"

    -source "drivers/scsi/osd/Kconfig"
    -
    endmenu
    diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
    index fcb41ae329c4..8826111fdf4a 100644
    --- a/drivers/scsi/Makefile
    +++ b/drivers/scsi/Makefile
    @@ -150,7 +150,6 @@ obj-$(CONFIG_CHR_DEV_SG) += sg.o
    obj-$(CONFIG_CHR_DEV_SCH) += ch.o
    obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o

    -obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/
    obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas/

    # This goes last, so that "real" scsi devices probe earlier
    diff --git a/drivers/scsi/osd/Kbuild b/drivers/scsi/osd/Kbuild
    deleted file mode 100644
    index 58cecd45b0f5..000000000000
    --- a/drivers/scsi/osd/Kbuild
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -#
    -# Kbuild for the OSD modules
    -#
    -# Copyright (C) 2008 Panasas Inc. All rights reserved.
    -#
    -# Authors:
    -# Boaz Harrosh <ooo@electrozaur.com>
    -# Benny Halevy <bhalevy@panasas.com>
    -#
    -# This program is free software; you can redistribute it and/or modify
    -# it under the terms of the GNU General Public License version 2
    -#
    -
    -# libosd.ko - osd-initiator library
    -libosd-y := osd_initiator.o
    -obj-$(CONFIG_SCSI_OSD_INITIATOR) += libosd.o
    -
    -# osd.ko - SCSI ULD and char-device
    -osd-y := osd_uld.o
    -obj-$(CONFIG_SCSI_OSD_ULD) += osd.o
    diff --git a/drivers/scsi/osd/Kconfig b/drivers/scsi/osd/Kconfig
    deleted file mode 100644
    index 347cc5e33749..000000000000
    --- a/drivers/scsi/osd/Kconfig
    +++ /dev/null
    @@ -1,49 +0,0 @@
    -#
    -# Kernel configuration file for the OSD scsi protocol
    -#
    -# Copyright (C) 2008 Panasas Inc. All rights reserved.
    -#
    -# Authors:
    -# Boaz Harrosh <ooo@electrozaur.com>
    -# Benny Halevy <bhalevy@panasas.com>
    -#
    -# This program is free software; you can redistribute it and/or modify
    -# it under the terms of the GNU General Public version 2 License as
    -# published by the Free Software Foundation
    -#
    -config SCSI_OSD_INITIATOR
    - tristate "OSD-Initiator library"
    - depends on SCSI
    - help
    - Enable the OSD-Initiator library (libosd.ko).
    - NOTE: You must also select CRYPTO_SHA1 + CRYPTO_HMAC and their
    - dependencies
    -
    -config SCSI_OSD_ULD
    - tristate "OSD Upper Level driver"
    - depends on SCSI_OSD_INITIATOR
    - help
    - Build a SCSI upper layer driver that exports /dev/osdX devices
    - to user-mode for testing and controlling OSD devices. It is also
    - needed by exofs, for mounting an OSD based file system.
    -
    -config SCSI_OSD_DPRINT_SENSE
    - int "(0-2) When sense is returned, DEBUG print all sense descriptors"
    - default 1
    - depends on SCSI_OSD_INITIATOR
    - help
    - When a CHECK_CONDITION status is returned from a target, and a
    - sense-buffer is retrieved, turning this on will dump a full
    - sense-decoding message. Setting to 2 will also print recoverable
    - errors that might be regularly returned for some filesystem
    - operations.
    -
    -config SCSI_OSD_DEBUG
    - bool "Compile All OSD modules with lots of DEBUG prints"
    - default n
    - depends on SCSI_OSD_INITIATOR
    - help
    - OSD Code is populated with lots of OSD_DEBUG(..) printouts to
    - dmesg. Enable this if you found a bug and you want to help us
    - track the problem (see also MAINTAINERS). Setting this will also
    - force SCSI_OSD_DPRINT_SENSE=2.
    diff --git a/drivers/scsi/osd/osd_debug.h b/drivers/scsi/osd/osd_debug.h
    deleted file mode 100644
    index 26341261bb5c..000000000000
    --- a/drivers/scsi/osd/osd_debug.h
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -/*
    - * osd_debug.h - Some kprintf macros
    - *
    - * Copyright (C) 2008 Panasas Inc. All rights reserved.
    - *
    - * Authors:
    - * Boaz Harrosh <ooo@electrozaur.com>
    - * Benny Halevy <bhalevy@panasas.com>
    - *
    - * This program is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License version 2
    - *
    - */
    -#ifndef __OSD_DEBUG_H__
    -#define __OSD_DEBUG_H__
    -
    -#define OSD_ERR(fmt, a...) printk(KERN_ERR "osd: " fmt, ##a)
    -#define OSD_INFO(fmt, a...) printk(KERN_NOTICE "osd: " fmt, ##a)
    -
    -#ifdef CONFIG_SCSI_OSD_DEBUG
    -#define OSD_DEBUG(fmt, a...) \
    - printk(KERN_NOTICE "osd @%s:%d: " fmt, __func__, __LINE__, ##a)
    -#else
    -#define OSD_DEBUG(fmt, a...) do {} while (0)
    -#endif
    -
    -/* u64 has problems with printk this will cast it to unsigned long long */
    -#define _LLU(x) (unsigned long long)(x)
    -
    -#endif /* ndef __OSD_DEBUG_H__ */
    diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
    deleted file mode 100644
    index 60cf7c5eb880..000000000000
    --- a/drivers/scsi/osd/osd_initiator.c
    +++ /dev/null
    @@ -1,2076 +0,0 @@
    -/*
    - * osd_initiator - Main body of the osd initiator library.
    - *
    - * Note: The file does not contain the advanced security functionality which
    - * is only needed by the security_manager's initiators.
    - *
    - * Copyright (C) 2008 Panasas Inc. All rights reserved.
    - *
    - * Authors:
    - * Boaz Harrosh <ooo@electrozaur.com>
    - * Benny Halevy <bhalevy@panasas.com>
    - *
    - * This program is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License version 2
    - *
    - * Redistribution and use in source and binary forms, with or without
    - * modification, are permitted provided that the following conditions
    - * are met:
    - *
    - * 1. Redistributions of source code must retain the above copyright
    - * notice, this list of conditions and the following disclaimer.
    - * 2. Redistributions in binary form must reproduce the above copyright
    - * notice, this list of conditions and the following disclaimer in the
    - * documentation and/or other materials provided with the distribution.
    - * 3. Neither the name of the Panasas company nor the names of its
    - * contributors may be used to endorse or promote products derived
    - * from this software without specific prior written permission.
    - *
    - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
    - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    - */
    -
    -#include <linux/slab.h>
    -#include <linux/module.h>
    -
    -#include <scsi/osd_initiator.h>
    -#include <scsi/osd_sec.h>
    -#include <scsi/osd_attributes.h>
    -#include <scsi/osd_sense.h>
    -
    -#include <scsi/scsi_device.h>
    -#include <scsi/scsi_request.h>
    -
    -#include "osd_debug.h"
    -
    -#ifndef __unused
    -# define __unused __attribute__((unused))
    -#endif
    -
    -enum { OSD_REQ_RETRIES = 1 };
    -
    -MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>");
    -MODULE_DESCRIPTION("open-osd initiator library libosd.ko");
    -MODULE_LICENSE("GPL");
    -
    -static inline void build_test(void)
    -{
    - /* structures were not packed */
    - BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN);
    - BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
    - BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
    -}
    -
    -static const char *_osd_ver_desc(struct osd_request *or)
    -{
    - return osd_req_is_ver1(or) ? "OSD1" : "OSD2";
    -}
    -
    -#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
    -
    -static int _osd_get_print_system_info(struct osd_dev *od,
    - void *caps, struct osd_dev_info *odi)
    -{
    - struct osd_request *or;
    - struct osd_attr get_attrs[] = {
    - ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8),
    - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16),
    - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32),
    - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4),
    - ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/),
    - ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/),
    - ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8),
    - ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8),
    - ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8),
    - ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6),
    - /* IBM-OSD-SIM Has a bug with this one put it last */
    - ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20),
    - };
    - void *iter = NULL, *pFirst;
    - int nelem = ARRAY_SIZE(get_attrs), a = 0;
    - int ret;
    -
    - or = osd_start_request(od);
    - if (!or)
    - return -ENOMEM;
    -
    - /* get attrs */
    - osd_req_get_attributes(or, &osd_root_object);
    - osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs));
    -
    - ret = osd_finalize_request(or, 0, caps, NULL);
    - if (ret)
    - goto out;
    -
    - ret = osd_execute_request(or);
    - if (ret) {
    - OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret);
    - goto out;
    - }
    -
    - osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter);
    -
    - OSD_INFO("Detected %s device\n",
    - _osd_ver_desc(or));
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("VENDOR_IDENTIFICATION [%s]\n",
    - (char *)pFirst);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("PRODUCT_IDENTIFICATION [%s]\n",
    - (char *)pFirst);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("PRODUCT_MODEL [%s]\n",
    - (char *)pFirst);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("PRODUCT_REVISION_LEVEL [%u]\n",
    - pFirst ? get_unaligned_be32(pFirst) : ~0U);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n",
    - (char *)pFirst);
    -
    - odi->osdname_len = get_attrs[a].len;
    - /* Avoid NULL for memcmp optimization 0-length is good enough */
    - odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL);
    - if (!odi->osdname) {
    - ret = -ENOMEM;
    - goto out;
    - }
    - if (odi->osdname_len)
    - memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len);
    - OSD_INFO("OSD_NAME [%s]\n", odi->osdname);
    - a++;
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("TOTAL_CAPACITY [0x%llx]\n",
    - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("USED_CAPACITY [0x%llx]\n",
    - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
    -
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("NUMBER_OF_PARTITIONS [%llu]\n",
    - pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
    -
    - if (a >= nelem)
    - goto out;
    -
    - /* FIXME: Where are the time utilities */
    - pFirst = get_attrs[a++].val_ptr;
    - OSD_INFO("CLOCK [0x%6phN]\n", pFirst);
    -
    - if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */
    - unsigned len = get_attrs[a].len;
    - char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */
    -
    - hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1,
    - sid_dump, sizeof(sid_dump), true);
    - OSD_INFO("OSD_SYSTEM_ID(%d)\n"
    - " [%s]\n", len, sid_dump);
    -
    - if (unlikely(len > sizeof(odi->systemid))) {
    - OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). "
    - "device identification might not work\n", len);
    - len = sizeof(odi->systemid);
    - }
    - odi->systemid_len = len;
    - memcpy(odi->systemid, get_attrs[a].val_ptr, len);
    - a++;
    - }
    -out:
    - osd_end_request(or);
    - return ret;
    -}
    -
    -int osd_auto_detect_ver(struct osd_dev *od,
    - void *caps, struct osd_dev_info *odi)
    -{
    - int ret;
    -
    - /* Auto-detect the osd version */
    - ret = _osd_get_print_system_info(od, caps, odi);
    - if (ret) {
    - osd_dev_set_ver(od, OSD_VER1);
    - OSD_DEBUG("converting to OSD1\n");
    - ret = _osd_get_print_system_info(od, caps, odi);
    - }
    -
    - return ret;
    -}
    -EXPORT_SYMBOL(osd_auto_detect_ver);
    -
    -static unsigned _osd_req_cdb_len(struct osd_request *or)
    -{
    - return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN;
    -}
    -
    -static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len)
    -{
    - return osd_req_is_ver1(or) ?
    - osdv1_attr_list_elem_size(len) :
    - osdv2_attr_list_elem_size(len);
    -}
    -
    -static void _osd_req_alist_elem_encode(struct osd_request *or,
    - void *attr_last, const struct osd_attr *oa)
    -{
    - if (osd_req_is_ver1(or)) {
    - struct osdv1_attributes_list_element *attr = attr_last;
    -
    - attr->attr_page = cpu_to_be32(oa->attr_page);
    - attr->attr_id = cpu_to_be32(oa->attr_id);
    - attr->attr_bytes = cpu_to_be16(oa->len);
    - memcpy(attr->attr_val, oa->val_ptr, oa->len);
    - } else {
    - struct osdv2_attributes_list_element *attr = attr_last;
    -
    - attr->attr_page = cpu_to_be32(oa->attr_page);
    - attr->attr_id = cpu_to_be32(oa->attr_id);
    - attr->attr_bytes = cpu_to_be16(oa->len);
    - memcpy(attr->attr_val, oa->val_ptr, oa->len);
    - }
    -}
    -
    -static int _osd_req_alist_elem_decode(struct osd_request *or,
    - void *cur_p, struct osd_attr *oa, unsigned max_bytes)
    -{
    - unsigned inc;
    - if (osd_req_is_ver1(or)) {
    - struct osdv1_attributes_list_element *attr = cur_p;
    -
    - if (max_bytes < sizeof(*attr))
    - return -1;
    -
    - oa->len = be16_to_cpu(attr->attr_bytes);
    - inc = _osd_req_alist_elem_size(or, oa->len);
    - if (inc > max_bytes)
    - return -1;
    -
    - oa->attr_page = be32_to_cpu(attr->attr_page);
    - oa->attr_id = be32_to_cpu(attr->attr_id);
    -
    - /* OSD1: On empty attributes we return a pointer to 2 bytes
    - * of zeros. This keeps similar behaviour with OSD2.
    - * (See below)
    - */
    - oa->val_ptr = likely(oa->len) ? attr->attr_val :
    - (u8 *)&attr->attr_bytes;
    - } else {
    - struct osdv2_attributes_list_element *attr = cur_p;
    -
    - if (max_bytes < sizeof(*attr))
    - return -1;
    -
    - oa->len = be16_to_cpu(attr->attr_bytes);
    - inc = _osd_req_alist_elem_size(or, oa->len);
    - if (inc > max_bytes)
    - return -1;
    -
    - oa->attr_page = be32_to_cpu(attr->attr_page);
    - oa->attr_id = be32_to_cpu(attr->attr_id);
    -
    - /* OSD2: For convenience, on empty attributes, we return 8 bytes
    - * of zeros here. This keeps the same behaviour with OSD2r04,
    - * and is nice with null terminating ASCII fields.
    - * oa->val_ptr == NULL marks the end-of-list, or error.
    - */
    - oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved;
    - }
    - return inc;
    -}
    -
    -static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
    -{
    - return osd_req_is_ver1(or) ?
    - osdv1_list_size(list_head) :
    - osdv2_list_size(list_head);
    -}
    -
    -static unsigned _osd_req_sizeof_alist_header(struct osd_request *or)
    -{
    - return osd_req_is_ver1(or) ?
    - sizeof(struct osdv1_attributes_list_header) :
    - sizeof(struct osdv2_attributes_list_header);
    -}
    -
    -static void _osd_req_set_alist_type(struct osd_request *or,
    - void *list, int list_type)
    -{
    - if (osd_req_is_ver1(or)) {
    - struct osdv1_attributes_list_header *attr_list = list;
    -
    - memset(attr_list, 0, sizeof(*attr_list));
    - attr_list->type = list_type;
    - } else {
    - struct osdv2_attributes_list_header *attr_list = list;
    -
    - memset(attr_list, 0, sizeof(*attr_list));
    - attr_list->type = list_type;
    - }
    -}
    -
    -static bool _osd_req_is_alist_type(struct osd_request *or,
    - void *list, int list_type)
    -{
    - if (!list)
    - return false;
    -
    - if (osd_req_is_ver1(or)) {
    - struct osdv1_attributes_list_header *attr_list = list;
    -
    - return attr_list->type == list_type;
    - } else {
    - struct osdv2_attributes_list_header *attr_list = list;
    -
    - return attr_list->type == list_type;
    - }
    -}
    -
    -/* This is for List-objects not Attributes-Lists */
    -static void _osd_req_encode_olist(struct osd_request *or,
    - struct osd_obj_id_list *list)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    -
    - if (osd_req_is_ver1(or)) {
    - cdbh->v1.list_identifier = list->list_identifier;
    - cdbh->v1.start_address = list->continuation_id;
    - } else {
    - cdbh->v2.list_identifier = list->list_identifier;
    - cdbh->v2.start_address = list->continuation_id;
    - }
    -}
    -
    -static osd_cdb_offset osd_req_encode_offset(struct osd_request *or,
    - u64 offset, unsigned *padding)
    -{
    - return __osd_encode_offset(offset, padding,
    - osd_req_is_ver1(or) ?
    - OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT,
    - OSD_OFFSET_MAX_SHIFT);
    -}
    -
    -static struct osd_security_parameters *
    -_osd_req_sec_params(struct osd_request *or)
    -{
    - struct osd_cdb *ocdb = &or->cdb;
    -
    - if (osd_req_is_ver1(or))
    - return (struct osd_security_parameters *)&ocdb->v1.sec_params;
    - else
    - return (struct osd_security_parameters *)&ocdb->v2.sec_params;
    -}
    -
    -void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
    -{
    - memset(osdd, 0, sizeof(*osdd));
    - osdd->scsi_device = scsi_device;
    - osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT;
    -#ifdef OSD_VER1_SUPPORT
    - osdd->version = OSD_VER2;
    -#endif
    - /* TODO: Allocate pools for osd_request attributes ... */
    -}
    -EXPORT_SYMBOL(osd_dev_init);
    -
    -void osd_dev_fini(struct osd_dev *osdd)
    -{
    - /* TODO: De-allocate pools */
    -
    - osdd->scsi_device = NULL;
    -}
    -EXPORT_SYMBOL(osd_dev_fini);
    -
    -static struct osd_request *_osd_request_alloc(gfp_t gfp)
    -{
    - struct osd_request *or;
    -
    - /* TODO: Use mempool with one saved request */
    - or = kzalloc(sizeof(*or), gfp);
    - return or;
    -}
    -
    -static void _osd_request_free(struct osd_request *or)
    -{
    - kfree(or);
    -}
    -
    -struct osd_request *osd_start_request(struct osd_dev *dev)
    -{
    - struct osd_request *or;
    -
    - or = _osd_request_alloc(GFP_KERNEL);
    - if (!or)
    - return NULL;
    -
    - or->osd_dev = dev;
    - or->timeout = dev->def_timeout;
    - or->retries = OSD_REQ_RETRIES;
    -
    - return or;
    -}
    -EXPORT_SYMBOL(osd_start_request);
    -
    -static void _osd_free_seg(struct osd_request *or __unused,
    - struct _osd_req_data_segment *seg)
    -{
    - if (!seg->buff || !seg->alloc_size)
    - return;
    -
    - kfree(seg->buff);
    - seg->buff = NULL;
    - seg->alloc_size = 0;
    -}
    -
    -static void _put_request(struct request *rq)
    -{
    - /*
    - * If osd_finalize_request() was called but the request was not
    - * executed through the block layer, then we must release BIOs.
    - * TODO: Keep error code in or->async_error. Need to audit all
    - * code paths.
    - */
    - if (unlikely(rq->bio))
    - blk_mq_end_request(rq, BLK_STS_IOERR);
    - else
    - blk_put_request(rq);
    -}
    -
    -void osd_end_request(struct osd_request *or)
    -{
    - struct request *rq = or->request;
    -
    - if (rq) {
    - if (rq->next_rq) {
    - _put_request(rq->next_rq);
    - rq->next_rq = NULL;
    - }
    -
    - _put_request(rq);
    - }
    -
    - _osd_free_seg(or, &or->get_attr);
    - _osd_free_seg(or, &or->enc_get_attr);
    - _osd_free_seg(or, &or->set_attr);
    - _osd_free_seg(or, &or->cdb_cont);
    -
    - _osd_request_free(or);
    -}
    -EXPORT_SYMBOL(osd_end_request);
    -
    -static void _set_error_resid(struct osd_request *or, struct request *req,
    - blk_status_t error)
    -{
    - or->async_error = error;
    - or->req_errors = scsi_req(req)->result;
    - or->sense_len = scsi_req(req)->sense_len;
    - if (or->sense_len)
    - memcpy(or->sense, scsi_req(req)->sense, or->sense_len);
    - if (or->out.req)
    - or->out.residual = scsi_req(or->out.req)->resid_len;
    - if (or->in.req)
    - or->in.residual = scsi_req(or->in.req)->resid_len;
    -}
    -
    -int osd_execute_request(struct osd_request *or)
    -{
    - blk_execute_rq(or->request->q, NULL, or->request, 0);
    -
    - if (scsi_req(or->request)->result) {
    - _set_error_resid(or, or->request, BLK_STS_IOERR);
    - return -EIO;
    - }
    -
    - _set_error_resid(or, or->request, BLK_STS_OK);
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_execute_request);
    -
    -static void osd_request_async_done(struct request *req, blk_status_t error)
    -{
    - struct osd_request *or = req->end_io_data;
    -
    - _set_error_resid(or, req, error);
    - if (req->next_rq) {
    - blk_put_request(req->next_rq);
    - req->next_rq = NULL;
    - }
    -
    - blk_put_request(req);
    - or->request = NULL;
    - or->in.req = NULL;
    - or->out.req = NULL;
    -
    - if (or->async_done)
    - or->async_done(or, or->async_private);
    - else
    - osd_end_request(or);
    -}
    -
    -int osd_execute_request_async(struct osd_request *or,
    - osd_req_done_fn *done, void *private)
    -{
    - or->request->end_io_data = or;
    - or->async_private = private;
    - or->async_done = done;
    -
    - blk_execute_rq_nowait(or->request->q, NULL, or->request, 0,
    - osd_request_async_done);
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_execute_request_async);
    -
    -u8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
    -u8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
    -
    -static int _osd_realloc_seg(struct osd_request *or,
    - struct _osd_req_data_segment *seg, unsigned max_bytes)
    -{
    - void *buff;
    -
    - if (seg->alloc_size >= max_bytes)
    - return 0;
    -
    - buff = krealloc(seg->buff, max_bytes, GFP_KERNEL);
    - if (!buff) {
    - OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes,
    - seg->alloc_size);
    - return -ENOMEM;
    - }
    -
    - memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size);
    - seg->buff = buff;
    - seg->alloc_size = max_bytes;
    - return 0;
    -}
    -
    -static int _alloc_cdb_cont(struct osd_request *or, unsigned total_bytes)
    -{
    - OSD_DEBUG("total_bytes=%d\n", total_bytes);
    - return _osd_realloc_seg(or, &or->cdb_cont, total_bytes);
    -}
    -
    -static int _alloc_set_attr_list(struct osd_request *or,
    - const struct osd_attr *oa, unsigned nelem, unsigned add_bytes)
    -{
    - unsigned total_bytes = add_bytes;
    -
    - for (; nelem; --nelem, ++oa)
    - total_bytes += _osd_req_alist_elem_size(or, oa->len);
    -
    - OSD_DEBUG("total_bytes=%d\n", total_bytes);
    - return _osd_realloc_seg(or, &or->set_attr, total_bytes);
    -}
    -
    -static int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes)
    -{
    - OSD_DEBUG("total_bytes=%d\n", max_bytes);
    - return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes);
    -}
    -
    -static int _alloc_get_attr_list(struct osd_request *or)
    -{
    - OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes);
    - return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes);
    -}
    -
    -/*
    - * Common to all OSD commands
    - */
    -
    -static void _osdv1_req_encode_common(struct osd_request *or,
    - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
    -{
    - struct osdv1_cdb *ocdb = &or->cdb.v1;
    -
    - /*
    - * For speed, the commands
    - * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C
    - * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D
    - * are not supported here. Should pass zero and set after the call
    - */
    - act &= cpu_to_be16(~0x0080); /* V1 action code */
    -
    - OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act));
    -
    - ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
    - ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
    - ocdb->h.varlen_cdb.service_action = act;
    -
    - ocdb->h.partition = cpu_to_be64(obj->partition);
    - ocdb->h.object = cpu_to_be64(obj->id);
    - ocdb->h.v1.length = cpu_to_be64(len);
    - ocdb->h.v1.start_address = cpu_to_be64(offset);
    -}
    -
    -static void _osdv2_req_encode_common(struct osd_request *or,
    - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
    -{
    - struct osdv2_cdb *ocdb = &or->cdb.v2;
    -
    - OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act));
    -
    - ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
    - ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
    - ocdb->h.varlen_cdb.service_action = act;
    -
    - ocdb->h.partition = cpu_to_be64(obj->partition);
    - ocdb->h.object = cpu_to_be64(obj->id);
    - ocdb->h.v2.length = cpu_to_be64(len);
    - ocdb->h.v2.start_address = cpu_to_be64(offset);
    -}
    -
    -static void _osd_req_encode_common(struct osd_request *or,
    - __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
    -{
    - if (osd_req_is_ver1(or))
    - _osdv1_req_encode_common(or, act, obj, offset, len);
    - else
    - _osdv2_req_encode_common(or, act, obj, offset, len);
    -}
    -
    -/*
    - * Device commands
    - */
    -/*TODO: void osd_req_set_master_seed_xchg(struct osd_request *, ...); */
    -/*TODO: void osd_req_set_master_key(struct osd_request *, ...); */
    -
    -void osd_req_format(struct osd_request *or, u64 tot_capacity)
    -{
    - _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0,
    - tot_capacity);
    -}
    -EXPORT_SYMBOL(osd_req_format);
    -
    -int osd_req_list_dev_partitions(struct osd_request *or,
    - osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem)
    -{
    - return osd_req_list_partition_objects(or, 0, initial_id, list, nelem);
    -}
    -EXPORT_SYMBOL(osd_req_list_dev_partitions);
    -
    -static void _osd_req_encode_flush(struct osd_request *or,
    - enum osd_options_flush_scope_values op)
    -{
    - struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb);
    -
    - ocdb->command_specific_options = op;
    -}
    -
    -void osd_req_flush_obsd(struct osd_request *or,
    - enum osd_options_flush_scope_values op)
    -{
    - _osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0);
    - _osd_req_encode_flush(or, op);
    -}
    -EXPORT_SYMBOL(osd_req_flush_obsd);
    -
    -/*TODO: void osd_req_perform_scsi_command(struct osd_request *,
    - const u8 *cdb, ...); */
    -/*TODO: void osd_req_task_management(struct osd_request *, ...); */
    -
    -/*
    - * Partition commands
    - */
    -static void _osd_req_encode_partition(struct osd_request *or,
    - __be16 act, osd_id partition)
    -{
    - struct osd_obj_id par = {
    - .partition = partition,
    - .id = 0,
    - };
    -
    - _osd_req_encode_common(or, act, &par, 0, 0);
    -}
    -
    -void osd_req_create_partition(struct osd_request *or, osd_id partition)
    -{
    - _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition);
    -}
    -EXPORT_SYMBOL(osd_req_create_partition);
    -
    -void osd_req_remove_partition(struct osd_request *or, osd_id partition)
    -{
    - _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition);
    -}
    -EXPORT_SYMBOL(osd_req_remove_partition);
    -
    -/*TODO: void osd_req_set_partition_key(struct osd_request *,
    - osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
    - u8 seed[OSD_CRYPTO_SEED_SIZE]); */
    -
    -static int _osd_req_list_objects(struct osd_request *or,
    - __be16 action, const struct osd_obj_id *obj, osd_id initial_id,
    - struct osd_obj_id_list *list, unsigned nelem)
    -{
    - struct request_queue *q = osd_request_queue(or->osd_dev);
    - u64 len = nelem * sizeof(osd_id) + sizeof(*list);
    - struct bio *bio;
    -
    - _osd_req_encode_common(or, action, obj, (u64)initial_id, len);
    -
    - if (list->list_identifier)
    - _osd_req_encode_olist(or, list);
    -
    - WARN_ON(or->in.bio);
    - bio = bio_map_kern(q, list, len, GFP_KERNEL);
    - if (IS_ERR(bio)) {
    - OSD_ERR("!!! Failed to allocate list_objects BIO\n");
    - return PTR_ERR(bio);
    - }
    -
    - bio_set_op_attrs(bio, REQ_OP_READ, 0);
    - or->in.bio = bio;
    - or->in.total_bytes = bio->bi_iter.bi_size;
    - return 0;
    -}
    -
    -int osd_req_list_partition_collections(struct osd_request *or,
    - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
    - unsigned nelem)
    -{
    - struct osd_obj_id par = {
    - .partition = partition,
    - .id = 0,
    - };
    -
    - return osd_req_list_collection_objects(or, &par, initial_id, list,
    - nelem);
    -}
    -EXPORT_SYMBOL(osd_req_list_partition_collections);
    -
    -int osd_req_list_partition_objects(struct osd_request *or,
    - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
    - unsigned nelem)
    -{
    - struct osd_obj_id par = {
    - .partition = partition,
    - .id = 0,
    - };
    -
    - return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list,
    - nelem);
    -}
    -EXPORT_SYMBOL(osd_req_list_partition_objects);
    -
    -void osd_req_flush_partition(struct osd_request *or,
    - osd_id partition, enum osd_options_flush_scope_values op)
    -{
    - _osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition);
    - _osd_req_encode_flush(or, op);
    -}
    -EXPORT_SYMBOL(osd_req_flush_partition);
    -
    -/*
    - * Collection commands
    - */
    -/*TODO: void osd_req_create_collection(struct osd_request *,
    - const struct osd_obj_id *); */
    -/*TODO: void osd_req_remove_collection(struct osd_request *,
    - const struct osd_obj_id *); */
    -
    -int osd_req_list_collection_objects(struct osd_request *or,
    - const struct osd_obj_id *obj, osd_id initial_id,
    - struct osd_obj_id_list *list, unsigned nelem)
    -{
    - return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj,
    - initial_id, list, nelem);
    -}
    -EXPORT_SYMBOL(osd_req_list_collection_objects);
    -
    -/*TODO: void query(struct osd_request *, ...); V2 */
    -
    -void osd_req_flush_collection(struct osd_request *or,
    - const struct osd_obj_id *obj, enum osd_options_flush_scope_values op)
    -{
    - _osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0);
    - _osd_req_encode_flush(or, op);
    -}
    -EXPORT_SYMBOL(osd_req_flush_collection);
    -
    -/*TODO: void get_member_attrs(struct osd_request *, ...); V2 */
    -/*TODO: void set_member_attrs(struct osd_request *, ...); V2 */
    -
    -/*
    - * Object commands
    - */
    -void osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj)
    -{
    - _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0);
    -}
    -EXPORT_SYMBOL(osd_req_create_object);
    -
    -void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj)
    -{
    - _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0);
    -}
    -EXPORT_SYMBOL(osd_req_remove_object);
    -
    -
    -/*TODO: void osd_req_create_multi(struct osd_request *or,
    - struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem);
    -*/
    -
    -void osd_req_write(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset,
    - struct bio *bio, u64 len)
    -{
    - _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, len);
    - WARN_ON(or->out.bio || or->out.total_bytes);
    - WARN_ON(!op_is_write(bio_op(bio)));
    - or->out.bio = bio;
    - or->out.total_bytes = len;
    -}
    -EXPORT_SYMBOL(osd_req_write);
    -
    -int osd_req_write_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
    -{
    - struct request_queue *req_q = osd_request_queue(or->osd_dev);
    - struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
    -
    - if (IS_ERR(bio))
    - return PTR_ERR(bio);
    -
    - bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
    - osd_req_write(or, obj, offset, bio, len);
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_write_kern);
    -
    -/*TODO: void osd_req_append(struct osd_request *,
    - const struct osd_obj_id *, struct bio *data_out); */
    -/*TODO: void osd_req_create_write(struct osd_request *,
    - const struct osd_obj_id *, struct bio *data_out, u64 offset); */
    -/*TODO: void osd_req_clear(struct osd_request *,
    - const struct osd_obj_id *, u64 offset, u64 len); */
    -/*TODO: void osd_req_punch(struct osd_request *,
    - const struct osd_obj_id *, u64 offset, u64 len); V2 */
    -
    -void osd_req_flush_object(struct osd_request *or,
    - const struct osd_obj_id *obj, enum osd_options_flush_scope_values op,
    - /*V2*/ u64 offset, /*V2*/ u64 len)
    -{
    - if (unlikely(osd_req_is_ver1(or) && (offset || len))) {
    - OSD_DEBUG("OSD Ver1 flush on specific range ignored\n");
    - offset = 0;
    - len = 0;
    - }
    -
    - _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len);
    - _osd_req_encode_flush(or, op);
    -}
    -EXPORT_SYMBOL(osd_req_flush_object);
    -
    -void osd_req_read(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset,
    - struct bio *bio, u64 len)
    -{
    - _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len);
    - WARN_ON(or->in.bio || or->in.total_bytes);
    - WARN_ON(op_is_write(bio_op(bio)));
    - or->in.bio = bio;
    - or->in.total_bytes = len;
    -}
    -EXPORT_SYMBOL(osd_req_read);
    -
    -int osd_req_read_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
    -{
    - struct request_queue *req_q = osd_request_queue(or->osd_dev);
    - struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
    -
    - if (IS_ERR(bio))
    - return PTR_ERR(bio);
    -
    - osd_req_read(or, obj, offset, bio, len);
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_read_kern);
    -
    -static int _add_sg_continuation_descriptor(struct osd_request *or,
    - const struct osd_sg_entry *sglist, unsigned numentries, u64 *len)
    -{
    - struct osd_sg_continuation_descriptor *oscd;
    - u32 oscd_size;
    - unsigned i;
    - int ret;
    -
    - oscd_size = sizeof(*oscd) + numentries * sizeof(oscd->entries[0]);
    -
    - if (!or->cdb_cont.total_bytes) {
    - /* First time, jump over the header, we will write to:
    - * cdb_cont.buff + cdb_cont.total_bytes
    - */
    - or->cdb_cont.total_bytes =
    - sizeof(struct osd_continuation_segment_header);
    - }
    -
    - ret = _alloc_cdb_cont(or, or->cdb_cont.total_bytes + oscd_size);
    - if (unlikely(ret))
    - return ret;
    -
    - oscd = or->cdb_cont.buff + or->cdb_cont.total_bytes;
    - oscd->hdr.type = cpu_to_be16(SCATTER_GATHER_LIST);
    - oscd->hdr.pad_length = 0;
    - oscd->hdr.length = cpu_to_be32(oscd_size - sizeof(*oscd));
    -
    - *len = 0;
    - /* copy the sg entries and convert to network byte order */
    - for (i = 0; i < numentries; i++) {
    - oscd->entries[i].offset = cpu_to_be64(sglist[i].offset);
    - oscd->entries[i].len = cpu_to_be64(sglist[i].len);
    - *len += sglist[i].len;
    - }
    -
    - or->cdb_cont.total_bytes += oscd_size;
    - OSD_DEBUG("total_bytes=%d oscd_size=%d numentries=%d\n",
    - or->cdb_cont.total_bytes, oscd_size, numentries);
    - return 0;
    -}
    -
    -static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
    -{
    - struct request_queue *req_q = osd_request_queue(or->osd_dev);
    - struct bio *bio;
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    - struct osd_continuation_segment_header *cont_seg_hdr;
    -
    - if (!or->cdb_cont.total_bytes)
    - return 0;
    -
    - cont_seg_hdr = or->cdb_cont.buff;
    - cont_seg_hdr->format = CDB_CONTINUATION_FORMAT_V2;
    - cont_seg_hdr->service_action = cdbh->varlen_cdb.service_action;
    -
    - /* create a bio for continuation segment */
    - bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
    - GFP_KERNEL);
    - if (IS_ERR(bio))
    - return PTR_ERR(bio);
    -
    - bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
    -
    - /* integrity check the continuation before the bio is linked
    - * with the other data segments since the continuation
    - * integrity is separate from the other data segments.
    - */
    - osd_sec_sign_data(cont_seg_hdr->integrity_check, bio, cap_key);
    -
    - cdbh->v2.cdb_continuation_length = cpu_to_be32(or->cdb_cont.total_bytes);
    -
    - /* we can't use _req_append_segment, because we need to link in the
    - * continuation bio to the head of the bio list - the
    - * continuation segment (if it exists) is always the first segment in
    - * the out data buffer.
    - */
    - bio->bi_next = or->out.bio;
    - or->out.bio = bio;
    - or->out.total_bytes += or->cdb_cont.total_bytes;
    -
    - return 0;
    -}
    -
    -/* osd_req_write_sg: Takes a @bio that points to the data out buffer and an
    - * @sglist that has the scatter gather entries. Scatter-gather enables a write
    - * of multiple none-contiguous areas of an object, in a single call. The extents
    - * may overlap and/or be in any order. The only constrain is that:
    - * total_bytes(sglist) >= total_bytes(bio)
    - */
    -int osd_req_write_sg(struct osd_request *or,
    - const struct osd_obj_id *obj, struct bio *bio,
    - const struct osd_sg_entry *sglist, unsigned numentries)
    -{
    - u64 len;
    - int ret = _add_sg_continuation_descriptor(or, sglist, numentries, &len);
    -
    - if (ret)
    - return ret;
    - osd_req_write(or, obj, 0, bio, len);
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_write_sg);
    -
    -/* osd_req_read_sg: Read multiple extents of an object into @bio
    - * See osd_req_write_sg
    - */
    -int osd_req_read_sg(struct osd_request *or,
    - const struct osd_obj_id *obj, struct bio *bio,
    - const struct osd_sg_entry *sglist, unsigned numentries)
    -{
    - u64 len;
    - u64 off;
    - int ret;
    -
    - if (numentries > 1) {
    - off = 0;
    - ret = _add_sg_continuation_descriptor(or, sglist, numentries,
    - &len);
    - if (ret)
    - return ret;
    - } else {
    - /* Optimize the case of single segment, read_sg is a
    - * bidi operation.
    - */
    - len = sglist->len;
    - off = sglist->offset;
    - }
    - osd_req_read(or, obj, off, bio, len);
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_read_sg);
    -
    -/* SG-list write/read Kern API
    - *
    - * osd_req_{write,read}_sg_kern takes an array of @buff pointers and an array
    - * of sg_entries. @numentries indicates how many pointers and sg_entries there
    - * are. By requiring an array of buff pointers. This allows a caller to do a
    - * single write/read and scatter into multiple buffers.
    - * NOTE: Each buffer + len should not cross a page boundary.
    - */
    -static struct bio *_create_sg_bios(struct osd_request *or,
    - void **buff, const struct osd_sg_entry *sglist, unsigned numentries)
    -{
    - struct request_queue *q = osd_request_queue(or->osd_dev);
    - struct bio *bio;
    - unsigned i;
    -
    - bio = bio_kmalloc(GFP_KERNEL, numentries);
    - if (unlikely(!bio)) {
    - OSD_DEBUG("Failed to allocate BIO size=%u\n", numentries);
    - return ERR_PTR(-ENOMEM);
    - }
    -
    - for (i = 0; i < numentries; i++) {
    - unsigned offset = offset_in_page(buff[i]);
    - struct page *page = virt_to_page(buff[i]);
    - unsigned len = sglist[i].len;
    - unsigned added_len;
    -
    - BUG_ON(offset + len > PAGE_SIZE);
    - added_len = bio_add_pc_page(q, bio, page, len, offset);
    - if (unlikely(len != added_len)) {
    - OSD_DEBUG("bio_add_pc_page len(%d) != added_len(%d)\n",
    - len, added_len);
    - bio_put(bio);
    - return ERR_PTR(-ENOMEM);
    - }
    - }
    -
    - return bio;
    -}
    -
    -int osd_req_write_sg_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, void **buff,
    - const struct osd_sg_entry *sglist, unsigned numentries)
    -{
    - struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
    - if (IS_ERR(bio))
    - return PTR_ERR(bio);
    -
    - bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
    - osd_req_write_sg(or, obj, bio, sglist, numentries);
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_write_sg_kern);
    -
    -int osd_req_read_sg_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, void **buff,
    - const struct osd_sg_entry *sglist, unsigned numentries)
    -{
    - struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
    - if (IS_ERR(bio))
    - return PTR_ERR(bio);
    -
    - osd_req_read_sg(or, obj, bio, sglist, numentries);
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_read_sg_kern);
    -
    -
    -
    -void osd_req_get_attributes(struct osd_request *or,
    - const struct osd_obj_id *obj)
    -{
    - _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0);
    -}
    -EXPORT_SYMBOL(osd_req_get_attributes);
    -
    -void osd_req_set_attributes(struct osd_request *or,
    - const struct osd_obj_id *obj)
    -{
    - _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0);
    -}
    -EXPORT_SYMBOL(osd_req_set_attributes);
    -
    -/*
    - * Attributes List-mode
    - */
    -
    -int osd_req_add_set_attr_list(struct osd_request *or,
    - const struct osd_attr *oa, unsigned nelem)
    -{
    - unsigned total_bytes = or->set_attr.total_bytes;
    - void *attr_last;
    - int ret;
    -
    - if (or->attributes_mode &&
    - or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
    - WARN_ON(1);
    - return -EINVAL;
    - }
    - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
    -
    - if (!total_bytes) { /* first-time: allocate and put list header */
    - total_bytes = _osd_req_sizeof_alist_header(or);
    - ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
    - if (ret)
    - return ret;
    - _osd_req_set_alist_type(or, or->set_attr.buff,
    - OSD_ATTR_LIST_SET_RETRIEVE);
    - }
    - attr_last = or->set_attr.buff + total_bytes;
    -
    - for (; nelem; --nelem) {
    - unsigned elem_size = _osd_req_alist_elem_size(or, oa->len);
    -
    - total_bytes += elem_size;
    - if (unlikely(or->set_attr.alloc_size < total_bytes)) {
    - or->set_attr.total_bytes = total_bytes - elem_size;
    - ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
    - if (ret)
    - return ret;
    - attr_last =
    - or->set_attr.buff + or->set_attr.total_bytes;
    - }
    -
    - _osd_req_alist_elem_encode(or, attr_last, oa);
    -
    - attr_last += elem_size;
    - ++oa;
    - }
    -
    - or->set_attr.total_bytes = total_bytes;
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_add_set_attr_list);
    -
    -static int _req_append_segment(struct osd_request *or,
    - unsigned padding, struct _osd_req_data_segment *seg,
    - struct _osd_req_data_segment *last_seg, struct _osd_io_info *io)
    -{
    - void *pad_buff;
    - int ret;
    -
    - if (padding) {
    - /* check if we can just add it to last buffer */
    - if (last_seg &&
    - (padding <= last_seg->alloc_size - last_seg->total_bytes))
    - pad_buff = last_seg->buff + last_seg->total_bytes;
    - else
    - pad_buff = io->pad_buff;
    -
    - ret = blk_rq_map_kern(io->req->q, io->req, pad_buff, padding,
    - GFP_KERNEL);
    - if (ret)
    - return ret;
    - io->total_bytes += padding;
    - }
    -
    - ret = blk_rq_map_kern(io->req->q, io->req, seg->buff, seg->total_bytes,
    - GFP_KERNEL);
    - if (ret)
    - return ret;
    -
    - io->total_bytes += seg->total_bytes;
    - OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff,
    - seg->total_bytes);
    - return 0;
    -}
    -
    -static int _osd_req_finalize_set_attr_list(struct osd_request *or)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    - unsigned padding;
    - int ret;
    -
    - if (!or->set_attr.total_bytes) {
    - cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED;
    - return 0;
    - }
    -
    - cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes);
    - cdbh->attrs_list.set_attr_offset =
    - osd_req_encode_offset(or, or->out.total_bytes, &padding);
    -
    - ret = _req_append_segment(or, padding, &or->set_attr,
    - or->out.last_seg, &or->out);
    - if (ret)
    - return ret;
    -
    - or->out.last_seg = &or->set_attr;
    - return 0;
    -}
    -
    -int osd_req_add_get_attr_list(struct osd_request *or,
    - const struct osd_attr *oa, unsigned nelem)
    -{
    - unsigned total_bytes = or->enc_get_attr.total_bytes;
    - void *attr_last;
    - int ret;
    -
    - if (or->attributes_mode &&
    - or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
    - WARN_ON(1);
    - return -EINVAL;
    - }
    - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
    -
    - /* first time calc data-in list header size */
    - if (!or->get_attr.total_bytes)
    - or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or);
    -
    - /* calc data-out info */
    - if (!total_bytes) { /* first-time: allocate and put list header */
    - unsigned max_bytes;
    -
    - total_bytes = _osd_req_sizeof_alist_header(or);
    - max_bytes = total_bytes +
    - nelem * sizeof(struct osd_attributes_list_attrid);
    - ret = _alloc_get_attr_desc(or, max_bytes);
    - if (ret)
    - return ret;
    -
    - _osd_req_set_alist_type(or, or->enc_get_attr.buff,
    - OSD_ATTR_LIST_GET);
    - }
    - attr_last = or->enc_get_attr.buff + total_bytes;
    -
    - for (; nelem; --nelem) {
    - struct osd_attributes_list_attrid *attrid;
    - const unsigned cur_size = sizeof(*attrid);
    -
    - total_bytes += cur_size;
    - if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) {
    - or->enc_get_attr.total_bytes = total_bytes - cur_size;
    - ret = _alloc_get_attr_desc(or,
    - total_bytes + nelem * sizeof(*attrid));
    - if (ret)
    - return ret;
    - attr_last = or->enc_get_attr.buff +
    - or->enc_get_attr.total_bytes;
    - }
    -
    - attrid = attr_last;
    - attrid->attr_page = cpu_to_be32(oa->attr_page);
    - attrid->attr_id = cpu_to_be32(oa->attr_id);
    -
    - attr_last += cur_size;
    -
    - /* calc data-in size */
    - or->get_attr.total_bytes +=
    - _osd_req_alist_elem_size(or, oa->len);
    - ++oa;
    - }
    -
    - or->enc_get_attr.total_bytes = total_bytes;
    -
    - OSD_DEBUG(
    - "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%zu)\n",
    - or->get_attr.total_bytes,
    - or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or),
    - or->enc_get_attr.total_bytes,
    - (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or))
    - / sizeof(struct osd_attributes_list_attrid));
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_add_get_attr_list);
    -
    -static int _osd_req_finalize_get_attr_list(struct osd_request *or)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    - unsigned out_padding;
    - unsigned in_padding;
    - int ret;
    -
    - if (!or->enc_get_attr.total_bytes) {
    - cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED;
    - cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED;
    - return 0;
    - }
    -
    - ret = _alloc_get_attr_list(or);
    - if (ret)
    - return ret;
    -
    - /* The out-going buffer info update */
    - OSD_DEBUG("out-going\n");
    - cdbh->attrs_list.get_attr_desc_bytes =
    - cpu_to_be32(or->enc_get_attr.total_bytes);
    -
    - cdbh->attrs_list.get_attr_desc_offset =
    - osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
    -
    - ret = _req_append_segment(or, out_padding, &or->enc_get_attr,
    - or->out.last_seg, &or->out);
    - if (ret)
    - return ret;
    - or->out.last_seg = &or->enc_get_attr;
    -
    - /* The incoming buffer info update */
    - OSD_DEBUG("in-coming\n");
    - cdbh->attrs_list.get_attr_alloc_length =
    - cpu_to_be32(or->get_attr.total_bytes);
    -
    - cdbh->attrs_list.get_attr_offset =
    - osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
    -
    - ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
    - &or->in);
    - if (ret)
    - return ret;
    - or->in.last_seg = &or->get_attr;
    -
    - return 0;
    -}
    -
    -int osd_req_decode_get_attr_list(struct osd_request *or,
    - struct osd_attr *oa, int *nelem, void **iterator)
    -{
    - unsigned cur_bytes, returned_bytes;
    - int n;
    - const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or);
    - void *cur_p;
    -
    - if (!_osd_req_is_alist_type(or, or->get_attr.buff,
    - OSD_ATTR_LIST_SET_RETRIEVE)) {
    - oa->attr_page = 0;
    - oa->attr_id = 0;
    - oa->val_ptr = NULL;
    - oa->len = 0;
    - *iterator = NULL;
    - return 0;
    - }
    -
    - if (*iterator) {
    - BUG_ON((*iterator < or->get_attr.buff) ||
    - (or->get_attr.buff + or->get_attr.alloc_size < *iterator));
    - cur_p = *iterator;
    - cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list;
    - returned_bytes = or->get_attr.total_bytes;
    - } else { /* first time decode the list header */
    - cur_bytes = sizeof_attr_list;
    - returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) +
    - sizeof_attr_list;
    -
    - cur_p = or->get_attr.buff + sizeof_attr_list;
    -
    - if (returned_bytes > or->get_attr.alloc_size) {
    - OSD_DEBUG("target report: space was not big enough! "
    - "Allocate=%u Needed=%u\n",
    - or->get_attr.alloc_size,
    - returned_bytes + sizeof_attr_list);
    -
    - returned_bytes =
    - or->get_attr.alloc_size - sizeof_attr_list;
    - }
    - or->get_attr.total_bytes = returned_bytes;
    - }
    -
    - for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) {
    - int inc = _osd_req_alist_elem_decode(or, cur_p, oa,
    - returned_bytes - cur_bytes);
    -
    - if (inc < 0) {
    - OSD_ERR("BAD FOOD from target. list not valid!"
    - "c=%d r=%d n=%d\n",
    - cur_bytes, returned_bytes, n);
    - oa->val_ptr = NULL;
    - cur_bytes = returned_bytes; /* break the caller loop */
    - break;
    - }
    -
    - cur_bytes += inc;
    - cur_p += inc;
    - ++oa;
    - }
    -
    - *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL;
    - *nelem = n;
    - return returned_bytes - cur_bytes;
    -}
    -EXPORT_SYMBOL(osd_req_decode_get_attr_list);
    -
    -/*
    - * Attributes Page-mode
    - */
    -
    -int osd_req_add_get_attr_page(struct osd_request *or,
    - u32 page_id, void *attar_page, unsigned max_page_len,
    - const struct osd_attr *set_one_attr)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    -
    - if (or->attributes_mode &&
    - or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
    - WARN_ON(1);
    - return -EINVAL;
    - }
    - or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE;
    -
    - or->get_attr.buff = attar_page;
    - or->get_attr.total_bytes = max_page_len;
    -
    - cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id);
    - cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len);
    -
    - if (!set_one_attr || !set_one_attr->attr_page)
    - return 0; /* The set is optional */
    -
    - or->set_attr.buff = set_one_attr->val_ptr;
    - or->set_attr.total_bytes = set_one_attr->len;
    -
    - cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page);
    - cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id);
    - cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len);
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_req_add_get_attr_page);
    -
    -static int _osd_req_finalize_attr_page(struct osd_request *or)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    - unsigned in_padding, out_padding;
    - int ret;
    -
    - /* returned page */
    - cdbh->attrs_page.get_attr_offset =
    - osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
    -
    - ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
    - &or->in);
    - if (ret)
    - return ret;
    -
    - if (or->set_attr.total_bytes == 0)
    - return 0;
    -
    - /* set one value */
    - cdbh->attrs_page.set_attr_offset =
    - osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
    -
    - ret = _req_append_segment(or, out_padding, &or->set_attr, NULL,
    - &or->out);
    - return ret;
    -}
    -
    -static inline void osd_sec_parms_set_out_offset(bool is_v1,
    - struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
    -{
    - if (is_v1)
    - sec_parms->v1.data_out_integrity_check_offset = offset;
    - else
    - sec_parms->v2.data_out_integrity_check_offset = offset;
    -}
    -
    -static inline void osd_sec_parms_set_in_offset(bool is_v1,
    - struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
    -{
    - if (is_v1)
    - sec_parms->v1.data_in_integrity_check_offset = offset;
    - else
    - sec_parms->v2.data_in_integrity_check_offset = offset;
    -}
    -
    -static int _osd_req_finalize_data_integrity(struct osd_request *or,
    - bool has_in, bool has_out, struct bio *out_data_bio, u64 out_data_bytes,
    - const u8 *cap_key)
    -{
    - struct osd_security_parameters *sec_parms = _osd_req_sec_params(or);
    - int ret;
    -
    - if (!osd_is_sec_alldata(sec_parms))
    - return 0;
    -
    - if (has_out) {
    - struct _osd_req_data_segment seg = {
    - .buff = &or->out_data_integ,
    - .total_bytes = sizeof(or->out_data_integ),
    - };
    - unsigned pad;
    -
    - or->out_data_integ.data_bytes = cpu_to_be64(out_data_bytes);
    - or->out_data_integ.set_attributes_bytes = cpu_to_be64(
    - or->set_attr.total_bytes);
    - or->out_data_integ.get_attributes_bytes = cpu_to_be64(
    - or->enc_get_attr.total_bytes);
    -
    - osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms,
    - osd_req_encode_offset(or, or->out.total_bytes, &pad));
    -
    - ret = _req_append_segment(or, pad, &seg, or->out.last_seg,
    - &or->out);
    - if (ret)
    - return ret;
    - or->out.last_seg = NULL;
    -
    - /* they are now all chained to request sign them all together */
    - osd_sec_sign_data(&or->out_data_integ, out_data_bio,
    - cap_key);
    - }
    -
    - if (has_in) {
    - struct _osd_req_data_segment seg = {
    - .buff = &or->in_data_integ,
    - .total_bytes = sizeof(or->in_data_integ),
    - };
    - unsigned pad;
    -
    - osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms,
    - osd_req_encode_offset(or, or->in.total_bytes, &pad));
    -
    - ret = _req_append_segment(or, pad, &seg, or->in.last_seg,
    - &or->in);
    - if (ret)
    - return ret;
    -
    - or->in.last_seg = NULL;
    - }
    -
    - return 0;
    -}
    -
    -/*
    - * osd_finalize_request and helpers
    - */
    -static struct request *_make_request(struct request_queue *q, bool has_write,
    - struct _osd_io_info *oii)
    -{
    - struct request *req;
    - struct bio *bio = oii->bio;
    - int ret;
    -
    - req = blk_get_request(q, has_write ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
    - 0);
    - if (IS_ERR(req))
    - return req;
    -
    - for_each_bio(bio) {
    - struct bio *bounce_bio = bio;
    -
    - ret = blk_rq_append_bio(req, &bounce_bio);
    - if (ret)
    - return ERR_PTR(ret);
    - }
    -
    - return req;
    -}
    -
    -static int _init_blk_request(struct osd_request *or,
    - bool has_in, bool has_out)
    -{
    - struct scsi_device *scsi_device = or->osd_dev->scsi_device;
    - struct request_queue *q = scsi_device->request_queue;
    - struct request *req;
    - int ret;
    -
    - req = _make_request(q, has_out, has_out ? &or->out : &or->in);
    - if (IS_ERR(req)) {
    - ret = PTR_ERR(req);
    - goto out;
    - }
    -
    - or->request = req;
    - req->rq_flags |= RQF_QUIET;
    -
    - req->timeout = or->timeout;
    - scsi_req(req)->retries = or->retries;
    -
    - if (has_out) {
    - or->out.req = req;
    - if (has_in) {
    - /* allocate bidi request */
    - req = _make_request(q, false, &or->in);
    - if (IS_ERR(req)) {
    - OSD_DEBUG("blk_get_request for bidi failed\n");
    - ret = PTR_ERR(req);
    - goto out;
    - }
    - or->in.req = or->request->next_rq = req;
    - }
    - } else if (has_in)
    - or->in.req = req;
    -
    - ret = 0;
    -out:
    - OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n",
    - or, has_in, has_out, ret, or->request);
    - return ret;
    -}
    -
    -int osd_finalize_request(struct osd_request *or,
    - u8 options, const void *cap, const u8 *cap_key)
    -{
    - struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
    - bool has_in, has_out;
    - /* Save for data_integrity without the cdb_continuation */
    - struct bio *out_data_bio = or->out.bio;
    - u64 out_data_bytes = or->out.total_bytes;
    - int ret;
    -
    - if (options & OSD_REQ_FUA)
    - cdbh->options |= OSD_CDB_FUA;
    -
    - if (options & OSD_REQ_DPO)
    - cdbh->options |= OSD_CDB_DPO;
    -
    - if (options & OSD_REQ_BYPASS_TIMESTAMPS)
    - cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS;
    -
    - osd_set_caps(&or->cdb, cap);
    -
    - has_in = or->in.bio || or->get_attr.total_bytes;
    - has_out = or->out.bio || or->cdb_cont.total_bytes ||
    - or->set_attr.total_bytes || or->enc_get_attr.total_bytes;
    -
    - ret = _osd_req_finalize_cdb_cont(or, cap_key);
    - if (ret) {
    - OSD_DEBUG("_osd_req_finalize_cdb_cont failed\n");
    - return ret;
    - }
    - ret = _init_blk_request(or, has_in, has_out);
    - if (ret) {
    - OSD_DEBUG("_init_blk_request failed\n");
    - return ret;
    - }
    -
    - or->out.pad_buff = sg_out_pad_buffer;
    - or->in.pad_buff = sg_in_pad_buffer;
    -
    - if (!or->attributes_mode)
    - or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
    - cdbh->command_specific_options |= or->attributes_mode;
    - if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
    - ret = _osd_req_finalize_attr_page(or);
    - if (ret) {
    - OSD_DEBUG("_osd_req_finalize_attr_page failed\n");
    - return ret;
    - }
    - } else {
    - /* TODO: I think that for the GET_ATTR command these 2 should
    - * be reversed to keep them in execution order (for embedded
    - * targets with low memory footprint)
    - */
    - ret = _osd_req_finalize_set_attr_list(or);
    - if (ret) {
    - OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n");
    - return ret;
    - }
    -
    - ret = _osd_req_finalize_get_attr_list(or);
    - if (ret) {
    - OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n");
    - return ret;
    - }
    - }
    -
    - ret = _osd_req_finalize_data_integrity(or, has_in, has_out,
    - out_data_bio, out_data_bytes,
    - cap_key);
    - if (ret)
    - return ret;
    -
    - osd_sec_sign_cdb(&or->cdb, cap_key);
    -
    - scsi_req(or->request)->cmd = or->cdb.buff;
    - scsi_req(or->request)->cmd_len = _osd_req_cdb_len(or);
    -
    - return 0;
    -}
    -EXPORT_SYMBOL(osd_finalize_request);
    -
    -static bool _is_osd_security_code(int code)
    -{
    - return (code == osd_security_audit_value_frozen) ||
    - (code == osd_security_working_key_frozen) ||
    - (code == osd_nonce_not_unique) ||
    - (code == osd_nonce_timestamp_out_of_range) ||
    - (code == osd_invalid_dataout_buffer_integrity_check_value);
    -}
    -
    -#define OSD_SENSE_PRINT1(fmt, a...) \
    - do { \
    - if (__cur_sense_need_output) \
    - OSD_ERR(fmt, ##a); \
    - } while (0)
    -
    -#define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1(" " fmt, ##a)
    -
    -int osd_req_decode_sense_full(struct osd_request *or,
    - struct osd_sense_info *osi, bool silent,
    - struct osd_obj_id *bad_obj_list __unused, int max_obj __unused,
    - struct osd_attr *bad_attr_list, int max_attr)
    -{
    - int sense_len, original_sense_len;
    - struct osd_sense_info local_osi;
    - struct scsi_sense_descriptor_based *ssdb;
    - void *cur_descriptor;
    -#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0)
    - const bool __cur_sense_need_output = false;
    -#else
    - bool __cur_sense_need_output = !silent;
    -#endif
    - int ret;
    -
    - if (likely(!or->req_errors))
    - return 0;
    -
    - osi = osi ? : &local_osi;
    - memset(osi, 0, sizeof(*osi));
    -
    - ssdb = (typeof(ssdb))or->sense;
    - sense_len = or->sense_len;
    - if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) {
    - OSD_ERR("Block-layer returned error(0x%x) but "
    - "sense_len(%u) || key(%d) is empty\n",
    - or->req_errors, sense_len, ssdb->sense_key);
    - goto analyze;
    - }
    -
    - if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) {
    - OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n",
    - ssdb->response_code, sense_len);
    - goto analyze;
    - }
    -
    - osi->key = ssdb->sense_key;
    - osi->additional_code = be16_to_cpu(ssdb->additional_sense_code);
    - original_sense_len = ssdb->additional_sense_length + 8;
    -
    -#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1)
    - if (__cur_sense_need_output)
    - __cur_sense_need_output = (osi->key > scsi_sk_recovered_error);
    -#endif
    - OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) "
    - "additional_code=0x%x async_error=%d errors=0x%x\n",
    - osi->key, original_sense_len, sense_len,
    - osi->additional_code, or->async_error,
    - or->req_errors);
    -
    - if (original_sense_len < sense_len)
    - sense_len = original_sense_len;
    -
    - cur_descriptor = ssdb->ssd;
    - sense_len -= sizeof(*ssdb);
    - while (sense_len > 0) {
    - struct scsi_sense_descriptor *ssd = cur_descriptor;
    - int cur_len = ssd->additional_length + 2;
    -
    - sense_len -= cur_len;
    -
    - if (sense_len < 0)
    - break; /* sense was truncated */
    -
    - switch (ssd->descriptor_type) {
    - case scsi_sense_information:
    - case scsi_sense_command_specific_information:
    - {
    - struct scsi_sense_command_specific_data_descriptor
    - *sscd = cur_descriptor;
    -
    - osi->command_info =
    - get_unaligned_be64(&sscd->information) ;
    - OSD_SENSE_PRINT2(
    - "command_specific_information 0x%llx \n",
    - _LLU(osi->command_info));
    - break;
    - }
    - case scsi_sense_key_specific:
    - {
    - struct scsi_sense_key_specific_data_descriptor
    - *ssks = cur_descriptor;
    -
    - osi->sense_info = get_unaligned_be16(&ssks->value);
    - OSD_SENSE_PRINT2(
    - "sense_key_specific_information %u"
    - "sksv_cd_bpv_bp (0x%x)\n",
    - osi->sense_info, ssks->sksv_cd_bpv_bp);
    - break;
    - }
    - case osd_sense_object_identification:
    - { /*FIXME: Keep first not last, Store in array*/
    - struct osd_sense_identification_data_descriptor
    - *osidd = cur_descriptor;
    -
    - osi->not_initiated_command_functions =
    - le32_to_cpu(osidd->not_initiated_functions);
    - osi->completed_command_functions =
    - le32_to_cpu(osidd->completed_functions);
    - osi->obj.partition = be64_to_cpu(osidd->partition_id);
    - osi->obj.id = be64_to_cpu(osidd->object_id);
    - OSD_SENSE_PRINT2(
    - "object_identification pid=0x%llx oid=0x%llx\n",
    - _LLU(osi->obj.partition), _LLU(osi->obj.id));
    - OSD_SENSE_PRINT2(
    - "not_initiated_bits(%x) "
    - "completed_command_bits(%x)\n",
    - osi->not_initiated_command_functions,
    - osi->completed_command_functions);
    - break;
    - }
    - case osd_sense_response_integrity_check:
    - {
    - struct osd_sense_response_integrity_check_descriptor
    - *d = cur_descriptor;
    - /* 2nibbles+space+ASCII */
    - char dump[sizeof(d->integrity_check_value) * 4 + 2];
    -
    - hex_dump_to_buffer(d->integrity_check_value,
    - sizeof(d->integrity_check_value),
    - 32, 1, dump, sizeof(dump), true);
    - OSD_SENSE_PRINT2("response_integrity [%s]\n", dump);
    - }
    - case osd_sense_attribute_identification:
    - {
    - struct osd_sense_attributes_data_descriptor
    - *osadd = cur_descriptor;
    - unsigned len = min(cur_len, sense_len);
    - struct osd_sense_attr *pattr = osadd->sense_attrs;
    -
    - while (len >= sizeof(*pattr)) {
    - u32 attr_page = be32_to_cpu(pattr->attr_page);
    - u32 attr_id = be32_to_cpu(pattr->attr_id);
    -
    - if (!osi->attr.attr_page) {
    - osi->attr.attr_page = attr_page;
    - osi->attr.attr_id = attr_id;
    - }
    -
    - if (bad_attr_list && max_attr) {
    - bad_attr_list->attr_page = attr_page;
    - bad_attr_list->attr_id = attr_id;
    - bad_attr_list++;
    - max_attr--;
    - }
    -
    - len -= sizeof(*pattr);
    - OSD_SENSE_PRINT2(
    - "osd_sense_attribute_identification"
    - "attr_page=0x%x attr_id=0x%x\n",
    - attr_page, attr_id);
    - }
    - }
    - /*These are not legal for OSD*/
    - case scsi_sense_field_replaceable_unit:
    - OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n");
    - break;
    - case scsi_sense_stream_commands:
    - OSD_SENSE_PRINT2("scsi_sense_stream_commands\n");
    - break;
    - case scsi_sense_block_commands:
    - OSD_SENSE_PRINT2("scsi_sense_block_commands\n");
    - break;
    - case scsi_sense_ata_return:
    - OSD_SENSE_PRINT2("scsi_sense_ata_return\n");
    - break;
    - default:
    - if (ssd->descriptor_type <= scsi_sense_Reserved_last)
    - OSD_SENSE_PRINT2(
    - "scsi_sense Reserved descriptor (0x%x)",
    - ssd->descriptor_type);
    - else
    - OSD_SENSE_PRINT2(
    - "scsi_sense Vendor descriptor (0x%x)",
    - ssd->descriptor_type);
    - }
    -
    - cur_descriptor += cur_len;
    - }
    -
    -analyze:
    - if (!osi->key) {
    - /* scsi sense is Empty, the request was never issued to target
    - * linux return code might tell us what happened.
    - */
    - if (or->async_error == BLK_STS_RESOURCE)
    - osi->osd_err_pri = OSD_ERR_PRI_RESOURCE;
    - else
    - osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE;
    - ret = or->async_error;
    - } else if (osi->key <= scsi_sk_recovered_error) {
    - osi->osd_err_pri = 0;
    - ret = 0;
    - } else if (osi->additional_code == scsi_invalid_field_in_cdb) {
    - if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) {
    - osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES;
    - ret = -EFAULT; /* caller should recover from this */
    - } else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) {
    - osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND;
    - ret = -ENOENT;
    - } else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) {
    - osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS;
    - ret = -EACCES;
    - } else {
    - osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
    - ret = -EINVAL;
    - }
    - } else if (osi->additional_code == osd_quota_error) {
    - osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE;
    - ret = -ENOSPC;
    - } else if (_is_osd_security_code(osi->additional_code)) {
    - osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
    - ret = -EINVAL;
    - } else {
    - osi->osd_err_pri = OSD_ERR_PRI_EIO;
    - ret = -EIO;
    - }
    -
    - if (!or->out.residual)
    - or->out.residual = or->out.total_bytes;
    - if (!or->in.residual)
    - or->in.residual = or->in.total_bytes;
    -
    - return ret;
    -}
    -EXPORT_SYMBOL(osd_req_decode_sense_full);
    -
    -/*
    - * Implementation of osd_sec.h API
    - * TODO: Move to a separate osd_sec.c file at a later stage.
    - */
    -
    -enum { OSD_SEC_CAP_V1_ALL_CAPS =
    - OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE |
    - OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR |
    - OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC |
    - OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT
    -};
    -
    -enum { OSD_SEC_CAP_V2_ALL_CAPS =
    - OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT
    -};
    -
    -void osd_sec_init_nosec_doall_caps(void *caps,
    - const struct osd_obj_id *obj, bool is_collection, const bool is_v1)
    -{
    - struct osd_capability *cap = caps;
    - u8 type;
    - u8 descriptor_type;
    -
    - if (likely(obj->id)) {
    - if (unlikely(is_collection)) {
    - type = OSD_SEC_OBJ_COLLECTION;
    - descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ :
    - OSD_SEC_OBJ_DESC_COL;
    - } else {
    - type = OSD_SEC_OBJ_USER;
    - descriptor_type = OSD_SEC_OBJ_DESC_OBJ;
    - }
    - WARN_ON(!obj->partition);
    - } else {
    - type = obj->partition ? OSD_SEC_OBJ_PARTITION :
    - OSD_SEC_OBJ_ROOT;
    - descriptor_type = OSD_SEC_OBJ_DESC_PAR;
    - }
    -
    - memset(cap, 0, sizeof(*cap));
    -
    - cap->h.format = OSD_SEC_CAP_FORMAT_VER1;
    - cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */
    - cap->h.security_method = OSD_SEC_NOSEC;
    -/* cap->expiration_time;
    - cap->AUDIT[30-10];
    - cap->discriminator[42-30];
    - cap->object_created_time; */
    - cap->h.object_type = type;
    - osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS);
    - cap->h.object_descriptor_type = descriptor_type;
    - cap->od.obj_desc.policy_access_tag = 0;
    - cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition);
    - cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id);
    -}
    -EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps);
    -
    -/* FIXME: Extract version from caps pointer.
    - * Also Pete's target only supports caps from OSDv1 for now
    - */
    -void osd_set_caps(struct osd_cdb *cdb, const void *caps)
    -{
    - /* NOTE: They start at same address */
    - memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN);
    -}
    -
    -bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused)
    -{
    - return false;
    -}
    -
    -void osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused)
    -{
    -}
    -
    -void osd_sec_sign_data(void *data_integ __unused,
    - struct bio *bio __unused, const u8 *cap_key __unused)
    -{
    -}
    -
    -/*
    - * Declared in osd_protocol.h
    - * 4.12.5 Data-In and Data-Out buffer offsets
    - * byte offset = mantissa * (2^(exponent+8))
    - * Returns the smallest allowed encoded offset that contains given @offset
    - * The actual encoded offset returned is @offset + *@padding.
    - */
    -osd_cdb_offset __osd_encode_offset(
    - u64 offset, unsigned *padding, int min_shift, int max_shift)
    -{
    - u64 try_offset = -1, mod, align;
    - osd_cdb_offset be32_offset;
    - int shift;
    -
    - *padding = 0;
    - if (!offset)
    - return 0;
    -
    - for (shift = min_shift; shift < max_shift; ++shift) {
    - try_offset = offset >> shift;
    - if (try_offset < (1 << OSD_OFFSET_MAX_BITS))
    - break;
    - }
    -
    - BUG_ON(shift == max_shift);
    -
    - align = 1 << shift;
    - mod = offset & (align - 1);
    - if (mod) {
    - *padding = align - mod;
    - try_offset += 1;
    - }
    -
    - try_offset |= ((shift - 8) & 0xf) << 28;
    - be32_offset = cpu_to_be32((u32)try_offset);
    -
    - OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n",
    - _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift,
    - be32_offset, *padding);
    - return be32_offset;
    -}
    diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
    deleted file mode 100644
    index eaf36ccf58db..000000000000
    --- a/drivers/scsi/osd/osd_uld.c
    +++ /dev/null
    @@ -1,571 +0,0 @@
    -/*
    - * osd_uld.c - OSD Upper Layer Driver
    - *
    - * A Linux driver module that registers as a SCSI ULD and probes
    - * for OSD type SCSI devices.
    - * It's main function is to export osd devices to in-kernel users like
    - * osdfs and pNFS-objects-LD. It also provides one ioctl for running
    - * in Kernel tests.
    - *
    - * Copyright (C) 2008 Panasas Inc. All rights reserved.
    - *
    - * Authors:
    - * Boaz Harrosh <ooo@electrozaur.com>
    - * Benny Halevy <bhalevy@panasas.com>
    - *
    - * This program is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License version 2
    - *
    - * Redistribution and use in source and binary forms, with or without
    - * modification, are permitted provided that the following conditions
    - * are met:
    - *
    - * 1. Redistributions of source code must retain the above copyright
    - * notice, this list of conditions and the following disclaimer.
    - * 2. Redistributions in binary form must reproduce the above copyright
    - * notice, this list of conditions and the following disclaimer in the
    - * documentation and/or other materials provided with the distribution.
    - * 3. Neither the name of the Panasas company nor the names of its
    - * contributors may be used to endorse or promote products derived
    - * from this software without specific prior written permission.
    - *
    - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
    - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    - */
    -
    -#include <linux/namei.h>
    -#include <linux/cdev.h>
    -#include <linux/fs.h>
    -#include <linux/module.h>
    -#include <linux/device.h>
    -#include <linux/idr.h>
    -#include <linux/major.h>
    -#include <linux/file.h>
    -#include <linux/slab.h>
    -
    -#include <scsi/scsi.h>
    -#include <scsi/scsi_driver.h>
    -#include <scsi/scsi_device.h>
    -#include <scsi/scsi_ioctl.h>
    -
    -#include <scsi/osd_initiator.h>
    -#include <scsi/osd_sec.h>
    -
    -#include "osd_debug.h"
    -
    -#ifndef TYPE_OSD
    -# define TYPE_OSD 0x11
    -#endif
    -
    -#ifndef SCSI_OSD_MAJOR
    -# define SCSI_OSD_MAJOR 260
    -#endif
    -#define SCSI_OSD_MAX_MINOR MINORMASK
    -
    -static const char osd_name[] = "osd";
    -static const char *osd_version_string = "open-osd 0.2.1";
    -
    -MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>");
    -MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
    -MODULE_LICENSE("GPL");
    -MODULE_ALIAS_CHARDEV_MAJOR(SCSI_OSD_MAJOR);
    -MODULE_ALIAS_SCSI_DEVICE(TYPE_OSD);
    -
    -struct osd_uld_device {
    - int minor;
    - struct device class_dev;
    - struct cdev cdev;
    - struct osd_dev od;
    - struct osd_dev_info odi;
    - struct gendisk *disk;
    -};
    -
    -struct osd_dev_handle {
    - struct osd_dev od;
    - struct file *file;
    - struct osd_uld_device *oud;
    -} ;
    -
    -static DEFINE_IDA(osd_minor_ida);
    -
    -/*
    - * scsi sysfs attribute operations
    - */
    -static ssize_t osdname_show(struct device *dev, struct device_attribute *attr,
    - char *buf)
    -{
    - struct osd_uld_device *ould = container_of(dev, struct osd_uld_device,
    - class_dev);
    - return sprintf(buf, "%s\n", ould->odi.osdname);
    -}
    -static DEVICE_ATTR_RO(osdname);
    -
    -static ssize_t systemid_show(struct device *dev, struct device_attribute *attr,
    - char *buf)
    -{
    - struct osd_uld_device *ould = container_of(dev, struct osd_uld_device,
    - class_dev);
    -
    - memcpy(buf, ould->odi.systemid, ould->odi.systemid_len);
    - return ould->odi.systemid_len;
    -}
    -static DEVICE_ATTR_RO(systemid);
    -
    -static struct attribute *osd_uld_attrs[] = {
    - &dev_attr_osdname.attr,
    - &dev_attr_systemid.attr,
    - NULL,
    -};
    -ATTRIBUTE_GROUPS(osd_uld);
    -
    -static struct class osd_uld_class = {
    - .owner = THIS_MODULE,
    - .name = "scsi_osd",
    - .dev_groups = osd_uld_groups,
    -};
    -
    -/*
    - * Char Device operations
    - */
    -
    -static int osd_uld_open(struct inode *inode, struct file *file)
    -{
    - struct osd_uld_device *oud = container_of(inode->i_cdev,
    - struct osd_uld_device, cdev);
    -
    - get_device(&oud->class_dev);
    - /* cache osd_uld_device on file handle */
    - file->private_data = oud;
    - OSD_DEBUG("osd_uld_open %p\n", oud);
    - return 0;
    -}
    -
    -static int osd_uld_release(struct inode *inode, struct file *file)
    -{
    - struct osd_uld_device *oud = file->private_data;
    -
    - OSD_DEBUG("osd_uld_release %p\n", file->private_data);
    - file->private_data = NULL;
    - put_device(&oud->class_dev);
    - return 0;
    -}
    -
    -/* FIXME: Only one vector for now */
    -unsigned g_test_ioctl;
    -do_test_fn *g_do_test;
    -
    -int osduld_register_test(unsigned ioctl, do_test_fn *do_test)
    -{
    - if (g_test_ioctl)
    - return -EINVAL;
    -
    - g_test_ioctl = ioctl;
    - g_do_test = do_test;
    - return 0;
    -}
    -EXPORT_SYMBOL(osduld_register_test);
    -
    -void osduld_unregister_test(unsigned ioctl)
    -{
    - if (ioctl == g_test_ioctl) {
    - g_test_ioctl = 0;
    - g_do_test = NULL;
    - }
    -}
    -EXPORT_SYMBOL(osduld_unregister_test);
    -
    -static do_test_fn *_find_ioctl(unsigned cmd)
    -{
    - if (g_test_ioctl == cmd)
    - return g_do_test;
    - else
    - return NULL;
    -}
    -
    -static long osd_uld_ioctl(struct file *file, unsigned int cmd,
    - unsigned long arg)
    -{
    - struct osd_uld_device *oud = file->private_data;
    - int ret;
    - do_test_fn *do_test;
    -
    - do_test = _find_ioctl(cmd);
    - if (do_test)
    - ret = do_test(&oud->od, cmd, arg);
    - else {
    - OSD_ERR("Unknown ioctl %d: osd_uld_device=%p\n", cmd, oud);
    - ret = -ENOIOCTLCMD;
    - }
    - return ret;
    -}
    -
    -static const struct file_operations osd_fops = {
    - .owner = THIS_MODULE,
    - .open = osd_uld_open,
    - .release = osd_uld_release,
    - .unlocked_ioctl = osd_uld_ioctl,
    - .llseek = noop_llseek,
    -};
    -
    -struct osd_dev *osduld_path_lookup(const char *name)
    -{
    - struct osd_uld_device *oud;
    - struct osd_dev_handle *odh;
    - struct file *file;
    - int error;
    -
    - if (!name || !*name) {
    - OSD_ERR("Mount with !path || !*path\n");
    - return ERR_PTR(-EINVAL);
    - }
    -
    - odh = kzalloc(sizeof(*odh), GFP_KERNEL);
    - if (unlikely(!odh))
    - return ERR_PTR(-ENOMEM);
    -
    - file = filp_open(name, O_RDWR, 0);
    - if (IS_ERR(file)) {
    - error = PTR_ERR(file);
    - goto free_od;
    - }
    -
    - if (file->f_op != &osd_fops){
    - error = -EINVAL;
    - goto close_file;
    - }
    -
    - oud = file->private_data;
    -
    - odh->od = oud->od;
    - odh->file = file;
    - odh->oud = oud;
    -
    - return &odh->od;
    -
    -close_file:
    - fput(file);
    -free_od:
    - kfree(odh);
    - return ERR_PTR(error);
    -}
    -EXPORT_SYMBOL(osduld_path_lookup);
    -
    -static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len,
    - const u8 *a2, unsigned a2_len)
    -{
    - if (!a2_len) /* User string is Empty means don't care */
    - return true;
    -
    - if (a1_len != a2_len)
    - return false;
    -
    - return 0 == memcmp(a1, a2, a1_len);
    -}
    -
    -static int _match_odi(struct device *dev, const void *find_data)
    -{
    - struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
    - class_dev);
    - const struct osd_dev_info *odi = find_data;
    -
    - if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
    - odi->systemid, odi->systemid_len) &&
    - _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
    - odi->osdname, odi->osdname_len)) {
    - OSD_DEBUG("found device sysid_len=%d osdname=%d\n",
    - odi->systemid_len, odi->osdname_len);
    - return 1;
    - } else {
    - return 0;
    - }
    -}
    -
    -/* osduld_info_lookup - Loop through all devices, return the requested osd_dev.
    - *
    - * if @odi->systemid_len and/or @odi->osdname_len are zero, they act as a don't
    - * care. .e.g if they're both zero /dev/osd0 is returned.
    - */
    -struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi)
    -{
    - struct device *dev = class_find_device(&osd_uld_class, NULL, odi, _match_odi);
    - if (likely(dev)) {
    - struct osd_dev_handle *odh = kzalloc(sizeof(*odh), GFP_KERNEL);
    - struct osd_uld_device *oud = container_of(dev,
    - struct osd_uld_device, class_dev);
    -
    - if (unlikely(!odh)) {
    - put_device(dev);
    - return ERR_PTR(-ENOMEM);
    - }
    -
    - odh->od = oud->od;
    - odh->oud = oud;
    -
    - return &odh->od;
    - }
    -
    - return ERR_PTR(-ENODEV);
    -}
    -EXPORT_SYMBOL(osduld_info_lookup);
    -
    -void osduld_put_device(struct osd_dev *od)
    -{
    - if (od && !IS_ERR(od)) {
    - struct osd_dev_handle *odh =
    - container_of(od, struct osd_dev_handle, od);
    - struct osd_uld_device *oud = odh->oud;
    -
    - BUG_ON(od->scsi_device != oud->od.scsi_device);
    -
    - /* If scsi has released the device (logout), and exofs has last
    - * reference on oud it will be freed by above osd_uld_release
    - * within fput below. But this will oops in cdev_release which
    - * is called after the fops->release. A get_/put_ pair makes
    - * sure we have a cdev for the duration of fput
    - */
    - if (odh->file) {
    - get_device(&oud->class_dev);
    - fput(odh->file);
    - }
    - put_device(&oud->class_dev);
    - kfree(odh);
    - }
    -}
    -EXPORT_SYMBOL(osduld_put_device);
    -
    -const struct osd_dev_info *osduld_device_info(struct osd_dev *od)
    -{
    - struct osd_dev_handle *odh =
    - container_of(od, struct osd_dev_handle, od);
    - return &odh->oud->odi;
    -}
    -EXPORT_SYMBOL(osduld_device_info);
    -
    -bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi)
    -{
    - struct osd_dev_handle *odh =
    - container_of(od, struct osd_dev_handle, od);
    - struct osd_uld_device *oud = odh->oud;
    -
    - return (oud->odi.systemid_len == odi->systemid_len) &&
    - _the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
    - odi->systemid, odi->systemid_len) &&
    - (oud->odi.osdname_len == odi->osdname_len) &&
    - _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
    - odi->osdname, odi->osdname_len);
    -}
    -EXPORT_SYMBOL(osduld_device_same);
    -
    -/*
    - * Scsi Device operations
    - */
    -
    -static int __detect_osd(struct osd_uld_device *oud)
    -{
    - struct scsi_device *scsi_device = oud->od.scsi_device;
    - struct scsi_sense_hdr sense_hdr;
    - char caps[OSD_CAP_LEN];
    - int error;
    -
    - /* sending a test_unit_ready as first command seems to be needed
    - * by some targets
    - */
    - OSD_DEBUG("start scsi_test_unit_ready %p %p %p\n",
    - oud, scsi_device, scsi_device->request_queue);
    - error = scsi_test_unit_ready(scsi_device, 10*HZ, 5, &sense_hdr);
    - if (error)
    - OSD_ERR("warning: scsi_test_unit_ready failed\n");
    -
    - osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
    - if (osd_auto_detect_ver(&oud->od, caps, &oud->odi))
    - return -ENODEV;
    -
    - return 0;
    -}
    -
    -static void __remove(struct device *dev)
    -{
    - struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
    - class_dev);
    - struct scsi_device *scsi_device = oud->od.scsi_device;
    -
    - kfree(oud->odi.osdname);
    -
    - osd_dev_fini(&oud->od);
    - scsi_device_put(scsi_device);
    -
    - OSD_INFO("osd_remove %s\n",
    - oud->disk ? oud->disk->disk_name : NULL);
    -
    - if (oud->disk)
    - put_disk(oud->disk);
    -
    - kfree(oud);
    -}
    -
    -static int osd_probe(struct device *dev)
    -{
    - struct scsi_device *scsi_device = to_scsi_device(dev);
    - struct gendisk *disk;
    - struct osd_uld_device *oud;
    - int minor;
    - int error;
    -
    - if (scsi_device->type != TYPE_OSD)
    - return -ENODEV;
    -
    - minor = ida_alloc_max(&osd_minor_ida, SCSI_OSD_MAX_MINOR, GFP_KERNEL);
    - if (minor == -ENOSPC)
    - return -EBUSY;
    - if (minor < 0)
    - return -ENODEV;
    -
    - error = -ENOMEM;
    - oud = kzalloc(sizeof(*oud), GFP_KERNEL);
    - if (NULL == oud)
    - goto err_retract_minor;
    -
    - /* class device member */
    - device_initialize(&oud->class_dev);
    - dev_set_drvdata(dev, oud);
    - oud->minor = minor;
    - oud->class_dev.devt = MKDEV(SCSI_OSD_MAJOR, oud->minor);
    - oud->class_dev.class = &osd_uld_class;
    - oud->class_dev.parent = dev;
    - oud->class_dev.release = __remove;
    -
    - /* hold one more reference to the scsi_device that will get released
    - * in __release, in case a logout is happening while fs is mounted
    - */
    - if (scsi_device_get(scsi_device))
    - goto err_retract_minor;
    - osd_dev_init(&oud->od, scsi_device);
    -
    - /* allocate a disk and set it up */
    - /* FIXME: do we need this since sg has already done that */
    - disk = alloc_disk(1);
    - if (!disk) {
    - OSD_ERR("alloc_disk failed\n");
    - goto err_free_osd;
    - }
    - disk->major = SCSI_OSD_MAJOR;
    - disk->first_minor = oud->minor;
    - sprintf(disk->disk_name, "osd%d", oud->minor);
    - oud->disk = disk;
    -
    - /* Detect the OSD Version */
    - error = __detect_osd(oud);
    - if (error) {
    - OSD_ERR("osd detection failed, non-compatible OSD device\n");
    - goto err_free_osd;
    - }
    -
    - /* init the char-device for communication with user-mode */
    - cdev_init(&oud->cdev, &osd_fops);
    - oud->cdev.owner = THIS_MODULE;
    -
    - error = dev_set_name(&oud->class_dev, "%s", disk->disk_name);
    - if (error) {
    - OSD_ERR("dev_set_name failed => %d\n", error);
    - goto err_free_osd;
    - }
    -
    - error = cdev_device_add(&oud->cdev, &oud->class_dev);
    - if (error) {
    - OSD_ERR("device_register failed => %d\n", error);
    - goto err_free_osd;
    - }
    -
    - OSD_INFO("osd_probe %s\n", disk->disk_name);
    - return 0;
    -
    -err_free_osd:
    - put_device(&oud->class_dev);
    -err_retract_minor:
    - ida_free(&osd_minor_ida, minor);
    - return error;
    -}
    -
    -static int osd_remove(struct device *dev)
    -{
    - struct scsi_device *scsi_device = to_scsi_device(dev);
    - struct osd_uld_device *oud = dev_get_drvdata(dev);
    -
    - if (oud->od.scsi_device != scsi_device) {
    - OSD_ERR("Half cooked osd-device %p, || %p!=%p",
    - dev, oud->od.scsi_device, scsi_device);
    - }
    -
    - cdev_device_del(&oud->cdev, &oud->class_dev);
    - ida_free(&osd_minor_ida, oud->minor);
    - put_device(&oud->class_dev);
    -
    - return 0;
    -}
    -
    -/*
    - * Global driver and scsi registration
    - */
    -
    -static struct scsi_driver osd_driver = {
    - .gendrv = {
    - .name = osd_name,
    - .owner = THIS_MODULE,
    - .probe = osd_probe,
    - .remove = osd_remove,
    - }
    -};
    -
    -static int __init osd_uld_init(void)
    -{
    - int err;
    -
    - err = class_register(&osd_uld_class);
    - if (err) {
    - OSD_ERR("Unable to register sysfs class => %d\n", err);
    - return err;
    - }
    -
    - err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0),
    - SCSI_OSD_MAX_MINOR, osd_name);
    - if (err) {
    - OSD_ERR("Unable to register major %d for osd ULD => %d\n",
    - SCSI_OSD_MAJOR, err);
    - goto err_out;
    - }
    -
    - err = scsi_register_driver(&osd_driver.gendrv);
    - if (err) {
    - OSD_ERR("scsi_register_driver failed => %d\n", err);
    - goto err_out_chrdev;
    - }
    -
    - OSD_INFO("LOADED %s\n", osd_version_string);
    - return 0;
    -
    -err_out_chrdev:
    - unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
    -err_out:
    - class_unregister(&osd_uld_class);
    - return err;
    -}
    -
    -static void __exit osd_uld_exit(void)
    -{
    - scsi_unregister_driver(&osd_driver.gendrv);
    - unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
    - class_unregister(&osd_uld_class);
    - OSD_INFO("UNLOADED %s\n", osd_version_string);
    -}
    -
    -module_init(osd_uld_init);
    -module_exit(osd_uld_exit);
    diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
    deleted file mode 100644
    index 86a569d008b2..000000000000
    --- a/include/scsi/osd_initiator.h
    +++ /dev/null
    @@ -1,511 +0,0 @@
    -/*
    - * osd_initiator.h - OSD initiator API definition
    - *
    - * Copyright (C) 2008 Panasas Inc. All rights reserved.
    - *
    - * Authors:
    - * Boaz Harrosh <ooo@electrozaur.com>
    - * Benny Halevy <bhalevy@panasas.com>
    - *
    - * This program is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License version 2
    - *
    - */
    -#ifndef __OSD_INITIATOR_H__
    -#define __OSD_INITIATOR_H__
    -
    -#include <scsi/osd_protocol.h>
    -#include <scsi/osd_types.h>
    -
    -#include <linux/blkdev.h>
    -#include <scsi/scsi_device.h>
    -
    -/* Note: "NI" in comments below means "Not Implemented yet" */
    -
    -/* Configure of code:
    - * #undef if you *don't* want OSD v1 support in runtime.
    - * If #defined the initiator will dynamically configure to encode OSD v1
    - * CDB's if the target is detected to be OSD v1 only.
    - * OSD v2 only commands, options, and attributes will be ignored if target
    - * is v1 only.
    - * If #defined will result in bigger/slower code (OK Slower maybe not)
    - * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig?
    - */
    -#define OSD_VER1_SUPPORT y
    -
    -enum osd_std_version {
    - OSD_VER_NONE = 0,
    - OSD_VER1 = 1,
    - OSD_VER2 = 2,
    -};
    -
    -/*
    - * Object-based Storage Device.
    - * This object represents an OSD device.
    - * It is not a full linux device in any way. It is only
    - * a place to hang resources associated with a Linux
    - * request Q and some default properties.
    - */
    -struct osd_dev {
    - struct scsi_device *scsi_device;
    - unsigned def_timeout;
    -
    -#ifdef OSD_VER1_SUPPORT
    - enum osd_std_version version;
    -#endif
    -};
    -
    -/* Unique Identification of an OSD device */
    -struct osd_dev_info {
    - unsigned systemid_len;
    - u8 systemid[OSD_SYSTEMID_LEN];
    - unsigned osdname_len;
    - u8 *osdname;
    -};
    -
    -/* Retrieve/return osd_dev(s) for use by Kernel clients
    - * Use IS_ERR/ERR_PTR on returned "osd_dev *".
    - */
    -struct osd_dev *osduld_path_lookup(const char *dev_name);
    -struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi);
    -void osduld_put_device(struct osd_dev *od);
    -
    -const struct osd_dev_info *osduld_device_info(struct osd_dev *od);
    -bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi);
    -
    -/* Add/remove test ioctls from external modules */
    -typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg);
    -int osduld_register_test(unsigned ioctl, do_test_fn *do_test);
    -void osduld_unregister_test(unsigned ioctl);
    -
    -/* These are called by uld at probe time */
    -void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
    -void osd_dev_fini(struct osd_dev *od);
    -
    -/**
    - * osd_auto_detect_ver - Detect the OSD version, return Unique Identification
    - *
    - * @od: OSD target lun handle
    - * @caps: Capabilities authorizing OSD root read attributes access
    - * @odi: Retrieved information uniquely identifying the osd target lun
    - * Note: odi->osdname must be kfreed by caller.
    - *
    - * Auto detects the OSD version of the OSD target and sets the @od
    - * accordingly. Meanwhile also returns the "system id" and "osd name" root
    - * attributes which uniquely identify the OSD target. This member is usually
    - * called by the ULD. ULD users should call osduld_device_info().
    - * This rutine allocates osd requests and memory at GFP_KERNEL level and might
    - * sleep.
    - */
    -int osd_auto_detect_ver(struct osd_dev *od,
    - void *caps, struct osd_dev_info *odi);
    -
    -static inline struct request_queue *osd_request_queue(struct osd_dev *od)
    -{
    - return od->scsi_device->request_queue;
    -}
    -
    -/* we might want to use function vector in the future */
    -static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v)
    -{
    -#ifdef OSD_VER1_SUPPORT
    - od->version = v;
    -#endif
    -}
    -
    -static inline bool osd_dev_is_ver1(struct osd_dev *od)
    -{
    -#ifdef OSD_VER1_SUPPORT
    - return od->version == OSD_VER1;
    -#else
    - return false;
    -#endif
    -}
    -
    -struct osd_request;
    -typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
    -
    -struct osd_request {
    - struct osd_cdb cdb;
    - struct osd_data_out_integrity_info out_data_integ;
    - struct osd_data_in_integrity_info in_data_integ;
    -
    - struct osd_dev *osd_dev;
    - struct request *request;
    -
    - struct _osd_req_data_segment {
    - void *buff;
    - unsigned alloc_size; /* 0 here means: don't call kfree */
    - unsigned total_bytes;
    - } cdb_cont, set_attr, enc_get_attr, get_attr;
    -
    - struct _osd_io_info {
    - struct bio *bio;
    - u64 total_bytes;
    - u64 residual;
    - struct request *req;
    - struct _osd_req_data_segment *last_seg;
    - u8 *pad_buff;
    - } out, in;
    -
    - unsigned timeout;
    - unsigned retries;
    - unsigned sense_len;
    - u8 sense[OSD_MAX_SENSE_LEN];
    - enum osd_attributes_mode attributes_mode;
    -
    - osd_req_done_fn *async_done;
    - void *async_private;
    - blk_status_t async_error;
    - int req_errors;
    -};
    -
    -static inline bool osd_req_is_ver1(struct osd_request *or)
    -{
    - return osd_dev_is_ver1(or->osd_dev);
    -}
    -
    -/*
    - * How to use the osd library:
    - *
    - * osd_start_request
    - * Allocates a request.
    - *
    - * osd_req_*
    - * Call one of, to encode the desired operation.
    - *
    - * osd_add_{get,set}_attr
    - * Optionally add attributes to the CDB, list or page mode.
    - *
    - * osd_finalize_request
    - * Computes final data out/in offsets and signs the request,
    - * making it ready for execution.
    - *
    - * osd_execute_request
    - * May be called to execute it through the block layer. Other wise submit
    - * the associated block request in some other way.
    - *
    - * After execution:
    - * osd_req_decode_sense
    - * Decodes sense information to verify execution results.
    - *
    - * osd_req_decode_get_attr
    - * Retrieve osd_add_get_attr_list() values if used.
    - *
    - * osd_end_request
    - * Must be called to deallocate the request.
    - */
    -
    -/**
    - * osd_start_request - Allocate and initialize an osd_request
    - *
    - * @osd_dev: OSD device that holds the scsi-device and default values
    - * that the request is associated with.
    - *
    - * Allocate osd_request and initialize all members to the
    - * default/initial state.
    - */
    -struct osd_request *osd_start_request(struct osd_dev *od);
    -
    -enum osd_req_options {
    - OSD_REQ_FUA = 0x08, /* Force Unit Access */
    - OSD_REQ_DPO = 0x10, /* Disable Page Out */
    -
    - OSD_REQ_BYPASS_TIMESTAMPS = 0x80,
    -};
    -
    -/**
    - * osd_finalize_request - Sign request and prepare request for execution
    - *
    - * @or: osd_request to prepare
    - * @options: combination of osd_req_options bit flags or 0.
    - * @cap: A Pointer to an OSD_CAP_LEN bytes buffer that is received from
    - * The security manager as capabilities for this cdb.
    - * @cap_key: The cryptographic key used to sign the cdb/data. Can be null
    - * if NOSEC is used.
    - *
    - * The actual request and bios are only allocated here, so are the get_attr
    - * buffers that will receive the returned attributes. Copy's @cap to cdb.
    - * Sign the cdb/data with @cap_key.
    - */
    -int osd_finalize_request(struct osd_request *or,
    - u8 options, const void *cap, const u8 *cap_key);
    -
    -/**
    - * osd_execute_request - Execute the request synchronously through block-layer
    - *
    - * @or: osd_request to Executed
    - *
    - * Calls blk_execute_rq to q the command and waits for completion.
    - */
    -int osd_execute_request(struct osd_request *or);
    -
    -/**
    - * osd_execute_request_async - Execute the request without waitting.
    - *
    - * @or: - osd_request to Executed
    - * @done: (Optional) - Called at end of execution
    - * @private: - Will be passed to @done function
    - *
    - * Calls blk_execute_rq_nowait to queue the command. When execution is done
    - * optionally calls @done with @private as parameter. @or->async_error will
    - * have the return code
    - */
    -int osd_execute_request_async(struct osd_request *or,
    - osd_req_done_fn *done, void *private);
    -
    -/**
    - * osd_req_decode_sense_full - Decode sense information after execution.
    - *
    - * @or: - osd_request to examine
    - * @osi - Receives a more detailed error report information (optional).
    - * @silent - Do not print to dmsg (Even if enabled)
    - * @bad_obj_list - Some commands act on multiple objects. Failed objects will
    - * be received here (optional)
    - * @max_obj - Size of @bad_obj_list.
    - * @bad_attr_list - List of failing attributes (optional)
    - * @max_attr - Size of @bad_attr_list.
    - *
    - * After execution, osd_request results are analyzed using this function. The
    - * return code is the final disposition on the error. So it is possible that a
    - * CHECK_CONDITION was returned from target but this will return NO_ERROR, for
    - * example on recovered errors. All parameters are optional if caller does
    - * not need any returned information.
    - * Note: This function will also dump the error to dmsg according to settings
    - * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the
    - * command would routinely fail, to not spam the dmsg file.
    - */
    -
    -/**
    - * osd_err_priority - osd categorized return codes in ascending severity.
    - *
    - * The categories are borrowed from the pnfs_osd_errno enum.
    - * See comments for translated Linux codes returned by osd_req_decode_sense.
    - */
    -enum osd_err_priority {
    - OSD_ERR_PRI_NO_ERROR = 0,
    - /* Recoverable, caller should clear_highpage() all pages */
    - OSD_ERR_PRI_CLEAR_PAGES = 1, /* -EFAULT */
    - OSD_ERR_PRI_RESOURCE = 2, /* -ENOMEM */
    - OSD_ERR_PRI_BAD_CRED = 3, /* -EINVAL */
    - OSD_ERR_PRI_NO_ACCESS = 4, /* -EACCES */
    - OSD_ERR_PRI_UNREACHABLE = 5, /* any other */
    - OSD_ERR_PRI_NOT_FOUND = 6, /* -ENOENT */
    - OSD_ERR_PRI_NO_SPACE = 7, /* -ENOSPC */
    - OSD_ERR_PRI_EIO = 8, /* -EIO */
    -};
    -
    -struct osd_sense_info {
    - enum osd_err_priority osd_err_pri;
    -
    - int key; /* one of enum scsi_sense_keys */
    - int additional_code ; /* enum osd_additional_sense_codes */
    - union { /* Sense specific information */
    - u16 sense_info;
    - u16 cdb_field_offset; /* scsi_invalid_field_in_cdb */
    - };
    - union { /* Command specific information */
    - u64 command_info;
    - };
    -
    - u32 not_initiated_command_functions; /* osd_command_functions_bits */
    - u32 completed_command_functions; /* osd_command_functions_bits */
    - struct osd_obj_id obj;
    - struct osd_attr attr;
    -};
    -
    -int osd_req_decode_sense_full(struct osd_request *or,
    - struct osd_sense_info *osi, bool silent,
    - struct osd_obj_id *bad_obj_list, int max_obj,
    - struct osd_attr *bad_attr_list, int max_attr);
    -
    -static inline int osd_req_decode_sense(struct osd_request *or,
    - struct osd_sense_info *osi)
    -{
    - return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0);
    -}
    -
    -/**
    - * osd_end_request - return osd_request to free store
    - *
    - * @or: osd_request to free
    - *
    - * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.)
    - */
    -void osd_end_request(struct osd_request *or);
    -
    -/*
    - * CDB Encoding
    - *
    - * Note: call only one of the following methods.
    - */
    -
    -/*
    - * Device commands
    - */
    -void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */
    -void osd_req_set_master_key(struct osd_request *or, ...);/* NI */
    -
    -void osd_req_format(struct osd_request *or, u64 tot_capacity);
    -
    -/* list all partitions
    - * @list header must be initialized to zero on first run.
    - *
    - * Call osd_is_obj_list_done() to find if we got the complete list.
    - */
    -int osd_req_list_dev_partitions(struct osd_request *or,
    - osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem);
    -
    -void osd_req_flush_obsd(struct osd_request *or,
    - enum osd_options_flush_scope_values);
    -
    -void osd_req_perform_scsi_command(struct osd_request *or,
    - const u8 *cdb, ...);/* NI */
    -void osd_req_task_management(struct osd_request *or, ...);/* NI */
    -
    -/*
    - * Partition commands
    - */
    -void osd_req_create_partition(struct osd_request *or, osd_id partition);
    -void osd_req_remove_partition(struct osd_request *or, osd_id partition);
    -
    -void osd_req_set_partition_key(struct osd_request *or,
    - osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
    - u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */
    -
    -/* list all collections in the partition
    - * @list header must be init to zero on first run.
    - *
    - * Call osd_is_obj_list_done() to find if we got the complete list.
    - */
    -int osd_req_list_partition_collections(struct osd_request *or,
    - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
    - unsigned nelem);
    -
    -/* list all objects in the partition
    - * @list header must be init to zero on first run.
    - *
    - * Call osd_is_obj_list_done() to find if we got the complete list.
    - */
    -int osd_req_list_partition_objects(struct osd_request *or,
    - osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
    - unsigned nelem);
    -
    -void osd_req_flush_partition(struct osd_request *or,
    - osd_id partition, enum osd_options_flush_scope_values);
    -
    -/*
    - * Collection commands
    - */
    -void osd_req_create_collection(struct osd_request *or,
    - const struct osd_obj_id *);/* NI */
    -void osd_req_remove_collection(struct osd_request *or,
    - const struct osd_obj_id *);/* NI */
    -
    -/* list all objects in the collection */
    -int osd_req_list_collection_objects(struct osd_request *or,
    - const struct osd_obj_id *, osd_id initial_id,
    - struct osd_obj_id_list *list, unsigned nelem);
    -
    -/* V2 only filtered list of objects in the collection */
    -void osd_req_query(struct osd_request *or, ...);/* NI */
    -
    -void osd_req_flush_collection(struct osd_request *or,
    - const struct osd_obj_id *, enum osd_options_flush_scope_values);
    -
    -void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */
    -void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */
    -
    -/*
    - * Object commands
    - */
    -void osd_req_create_object(struct osd_request *or, struct osd_obj_id *);
    -void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *);
    -
    -void osd_req_write(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len);
    -int osd_req_write_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
    -void osd_req_append(struct osd_request *or,
    - const struct osd_obj_id *, struct bio *data_out);/* NI */
    -void osd_req_create_write(struct osd_request *or,
    - const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */
    -void osd_req_clear(struct osd_request *or,
    - const struct osd_obj_id *, u64 offset, u64 len);/* NI */
    -void osd_req_punch(struct osd_request *or,
    - const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */
    -
    -void osd_req_flush_object(struct osd_request *or,
    - const struct osd_obj_id *, enum osd_options_flush_scope_values,
    - /*V2*/ u64 offset, /*V2*/ u64 len);
    -
    -void osd_req_read(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, struct bio *bio, u64 len);
    -int osd_req_read_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
    -
    -/* Scatter/Gather write/read commands */
    -int osd_req_write_sg(struct osd_request *or,
    - const struct osd_obj_id *obj, struct bio *bio,
    - const struct osd_sg_entry *sglist, unsigned numentries);
    -int osd_req_read_sg(struct osd_request *or,
    - const struct osd_obj_id *obj, struct bio *bio,
    - const struct osd_sg_entry *sglist, unsigned numentries);
    -int osd_req_write_sg_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, void **buff,
    - const struct osd_sg_entry *sglist, unsigned numentries);
    -int osd_req_read_sg_kern(struct osd_request *or,
    - const struct osd_obj_id *obj, void **buff,
    - const struct osd_sg_entry *sglist, unsigned numentries);
    -
    -/*
    - * Root/Partition/Collection/Object Attributes commands
    - */
    -
    -/* get before set */
    -void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *);
    -
    -/* set before get */
    -void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *);
    -
    -/*
    - * Attributes appended to most commands
    - */
    -
    -/* Attributes List mode (or V2 CDB) */
    - /*
    - * TODO: In ver2 if at finalize time only one attr was set and no gets,
    - * then the Attributes CDB mode is used automatically to save IO.
    - */
    -
    -/* set a list of attributes. */
    -int osd_req_add_set_attr_list(struct osd_request *or,
    - const struct osd_attr *, unsigned nelem);
    -
    -/* get a list of attributes */
    -int osd_req_add_get_attr_list(struct osd_request *or,
    - const struct osd_attr *, unsigned nelem);
    -
    -/*
    - * Attributes list decoding
    - * Must be called after osd_request.request was executed
    - * It is called in a loop to decode the returned get_attr
    - * (see osd_add_get_attr)
    - */
    -int osd_req_decode_get_attr_list(struct osd_request *or,
    - struct osd_attr *, int *nelem, void **iterator);
    -
    -/* Attributes Page mode */
    -
    -/*
    - * Read an attribute page and optionally set one attribute
    - *
    - * Retrieves the attribute page directly to a user buffer.
    - * @attr_page_data shall stay valid until end of execution.
    - * See osd_attributes.h for common page structures
    - */
    -int osd_req_add_get_attr_page(struct osd_request *or,
    - u32 page_id, void *attr_page_data, unsigned max_page_len,
    - const struct osd_attr *set_one);
    -
    -#endif /* __OSD_LIB_H__ */
    diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h
    deleted file mode 100644
    index 7a8d2cd30328..000000000000
    --- a/include/scsi/osd_ore.h
    +++ /dev/null
    @@ -1,201 +0,0 @@
    -/*
    - * Copyright (C) 2011
    - * Boaz Harrosh <ooo@electrozaur.com>
    - *
    - * Public Declarations of the ORE API
    - *
    - * This file is part of the ORE (Object Raid Engine) library.
    - *
    - * ORE is free software; you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License version 2 as published
    - * by the Free Software Foundation. (GPL v2)
    - *
    - * ORE is distributed in the hope that it will be useful,
    - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    - * GNU General Public License for more details.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with the ORE; if not, write to the Free Software
    - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    - */
    -#ifndef __ORE_H__
    -#define __ORE_H__
    -
    -#include <scsi/osd_initiator.h>
    -#include <scsi/osd_attributes.h>
    -#include <scsi/osd_sec.h>
    -#include <linux/pnfs_osd_xdr.h>
    -#include <linux/bug.h>
    -
    -struct ore_comp {
    - struct osd_obj_id obj;
    - u8 cred[OSD_CAP_LEN];
    -};
    -
    -struct ore_layout {
    - /* Our way of looking at the data_map */
    - enum pnfs_osd_raid_algorithm4
    - raid_algorithm;
    - unsigned stripe_unit;
    - unsigned mirrors_p1;
    -
    - unsigned group_width;
    - unsigned parity;
    - u64 group_depth;
    - unsigned group_count;
    -
    - /* Cached often needed calculations filled in by
    - * ore_verify_layout
    - */
    - unsigned long max_io_length; /* Max length that should be passed to
    - * ore_get_rw_state
    - */
    -};
    -
    -struct ore_dev {
    - struct osd_dev *od;
    -};
    -
    -struct ore_components {
    - unsigned first_dev; /* First logical device no */
    - unsigned numdevs; /* Num of devices in array */
    - /* If @single_comp == EC_SINGLE_COMP, @comps points to a single
    - * component. else there are @numdevs components
    - */
    - enum EC_COMP_USAGE {
    - EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff
    - } single_comp;
    - struct ore_comp *comps;
    -
    - /* Array of pointers to ore_dev-* . User will usually have these pointed
    - * too a bigger struct which contain an "ore_dev ored" member and use
    - * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger
    - * structure.
    - */
    - struct ore_dev **ods;
    -};
    -
    -/* ore_comp_dev Recievies a logical device index */
    -static inline struct osd_dev *ore_comp_dev(
    - const struct ore_components *oc, unsigned i)
    -{
    - BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i));
    - return oc->ods[i - oc->first_dev]->od;
    -}
    -
    -static inline void ore_comp_set_dev(
    - struct ore_components *oc, unsigned i, struct osd_dev *od)
    -{
    - oc->ods[i - oc->first_dev]->od = od;
    -}
    -
    -struct ore_striping_info {
    - u64 offset;
    - u64 obj_offset;
    - u64 length;
    - u64 first_stripe_start; /* only used in raid writes */
    - u64 M; /* for truncate */
    - unsigned bytes_in_stripe;
    - unsigned dev;
    - unsigned par_dev;
    - unsigned unit_off;
    - unsigned cur_pg;
    - unsigned cur_comp;
    - unsigned maxdevUnits;
    -};
    -
    -struct ore_io_state;
    -typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private);
    -struct _ore_r4w_op {
    - /* @Priv given here is passed ios->private */
    - struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate);
    - void (*put_page)(void *priv, struct page *page);
    -};
    -
    -struct ore_io_state {
    - struct kref kref;
    - struct ore_striping_info si;
    -
    - void *private;
    - ore_io_done_fn done;
    -
    - struct ore_layout *layout;
    - struct ore_components *oc;
    -
    - /* Global read/write IO*/
    - loff_t offset;
    - unsigned long length;
    - void *kern_buff;
    -
    - struct page **pages;
    - unsigned nr_pages;
    - unsigned pgbase;
    - unsigned pages_consumed;
    -
    - /* Attributes */
    - unsigned in_attr_len;
    - struct osd_attr *in_attr;
    - unsigned out_attr_len;
    - struct osd_attr *out_attr;
    -
    - bool reading;
    -
    - /* House keeping of Parity pages */
    - bool extra_part_alloc;
    - struct page **parity_pages;
    - unsigned max_par_pages;
    - unsigned cur_par_page;
    - unsigned sgs_per_dev;
    - struct __stripe_pages_2d *sp2d;
    - struct ore_io_state *ios_read_4_write;
    - const struct _ore_r4w_op *r4w;
    -
    - /* Variable array of size numdevs */
    - unsigned numdevs;
    - struct ore_per_dev_state {
    - struct osd_request *or;
    - struct bio *bio;
    - loff_t offset;
    - unsigned length;
    - unsigned last_sgs_total;
    - unsigned dev;
    - struct osd_sg_entry *sglist;
    - unsigned cur_sg;
    - } per_dev[];
    -};
    -
    -static inline unsigned ore_io_state_size(unsigned numdevs)
    -{
    - return sizeof(struct ore_io_state) +
    - sizeof(struct ore_per_dev_state) * numdevs;
    -}
    -
    -/* ore.c */
    -int ore_verify_layout(unsigned total_comps, struct ore_layout *layout);
    -void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
    - u64 length, struct ore_striping_info *si);
    -int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps,
    - bool is_reading, u64 offset, u64 length,
    - struct ore_io_state **ios);
    -int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps,
    - struct ore_io_state **ios);
    -void ore_put_io_state(struct ore_io_state *ios);
    -
    -typedef void (*ore_on_dev_error)(struct ore_io_state *ios, struct ore_dev *od,
    - unsigned dev_index, enum osd_err_priority oep,
    - u64 dev_offset, u64 dev_len);
    -int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep);
    -
    -int ore_create(struct ore_io_state *ios);
    -int ore_remove(struct ore_io_state *ios);
    -int ore_write(struct ore_io_state *ios);
    -int ore_read(struct ore_io_state *ios);
    -int ore_truncate(struct ore_layout *layout, struct ore_components *comps,
    - u64 size);
    -
    -int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr);
    -
    -extern const struct osd_attr g_attr_logical_length;
    -
    -#endif
    --
    2.19.1
    \
     
     \ /
      Last update: 2018-11-11 14:34    [W:3.185 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site