osd_initiator.c revision 4ef1a3d70d02663f6bfe901db629e8e608da15b1
102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_initiator - Main body of the osd initiator library. 302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Note: The file does not contain the advanced security functionality which 502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * is only needed by the security_manager's initiators. 602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Copyright (C) 2008 Panasas Inc. All rights reserved. 802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Authors: 1002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Boaz Harrosh <bharrosh@panasas.com> 1102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Benny Halevy <bhalevy@panasas.com> 1202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * This program is free software; you can redistribute it and/or modify 1402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * it under the terms of the GNU General Public License version 2 1502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Redistribution and use in source and binary forms, with or without 1702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * modification, are permitted provided that the following conditions 1802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are met: 1902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1. Redistributions of source code must retain the above copyright 2102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * notice, this list of conditions and the following disclaimer. 2202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2. Redistributions in binary form must reproduce the above copyright 2302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * notice, this list of conditions and the following disclaimer in the 2402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * documentation and/or other materials provided with the distribution. 2502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 3. Neither the name of the Panasas company nor the names of its 2602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * contributors may be used to endorse or promote products derived 2702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * from this software without specific prior written permission. 2802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 3002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 3102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 4102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_initiator.h> 4302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_sec.h> 4402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/scsi_device.h> 4502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include "osd_debug.h" 4702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#ifndef __unused 494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh# define __unused __attribute__((unused)) 504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#endif 514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_REQ_RETRIES = 1 }; 5302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); 5502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_DESCRIPTION("open-osd initiator library libosd.ko"); 5602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_LICENSE("GPL"); 5702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic inline void build_test(void) 5902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 6002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* structures were not packed */ 6102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); 6202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 6302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 6402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 6502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic unsigned _osd_req_cdb_len(struct osd_request *or) 6602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 6702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return OSDv1_TOTAL_CDB_LEN; 6802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 6902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) 714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return osdv1_attr_list_elem_size(len); 734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return osdv1_list_size(list_head); 784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_sizeof_alist_header(struct osd_request *or) 814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return sizeof(struct osdv1_attributes_list_header); 834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_req_set_alist_type(struct osd_request *or, 864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memset(attr_list, 0, sizeof(*attr_list)); 914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_list->type = list_type; 924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic bool _osd_req_is_alist_type(struct osd_request *or, 954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!list) 984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return false; 994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (1) { 1014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 1024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return attr_list->type == list_type; 1044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 1054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic osd_cdb_offset osd_req_encode_offset(struct osd_request *or, 1084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding) 1094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 1104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return __osd_encode_offset(offset, padding, 1114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 1124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 11502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 11602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(osdd, 0, sizeof(*osdd)); 11702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = scsi_device; 11802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; 11902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Allocate pools for osd_request attributes ... */ 12002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 12102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_init); 12202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 12302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_fini(struct osd_dev *osdd) 12402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 12502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: De-allocate pools */ 12602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 12702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = NULL; 12802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 12902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_fini); 13002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 13102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic struct osd_request *_osd_request_alloc(gfp_t gfp) 13202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 13302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 13402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 13502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Use mempool with one saved request */ 13602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = kzalloc(sizeof(*or), gfp); 13702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 13802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 13902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 14002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_request_free(struct osd_request *or) 14102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 14202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh kfree(or); 14302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 14402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 14502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstruct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp) 14602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 14702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 14802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 14902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = _osd_request_alloc(gfp); 15002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or) 15102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return NULL; 15202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 15302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->osd_dev = dev; 15402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->alloc_flags = gfp; 15502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->timeout = dev->def_timeout; 15602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->retries = OSD_REQ_RETRIES; 15702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 15802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 15902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 16002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_start_request); 16102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 16202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 16302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * If osd_finalize_request() was called but the request was not executed through 16402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * the block layer, then we must release BIOs. 16502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 16602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _abort_unexecuted_bios(struct request *rq) 16702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 16802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct bio *bio; 16902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 17002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh while ((bio = rq->bio) != NULL) { 17102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh rq->bio = bio->bi_next; 17202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio_endio(bio, 0); 17302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 17402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 17502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_free_seg(struct osd_request *or __unused, 1774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg) 1784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 1794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!seg->buff || !seg->alloc_size) 1804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return; 1814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh kfree(seg->buff); 1834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = NULL; 1844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = 0; 1854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 18702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_end_request(struct osd_request *or) 18802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 18902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *rq = or->request; 19002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->set_attr); 1924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->enc_get_attr); 1934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->get_attr); 1944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 19502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq) { 19602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq->next_rq) { 19702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _abort_unexecuted_bios(rq->next_rq); 19802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_put_request(rq->next_rq); 19902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 20002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 20102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _abort_unexecuted_bios(rq); 20202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_put_request(rq); 20302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 20402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_request_free(or); 20502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 20602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_end_request); 20702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 20802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request(struct osd_request *or) 20902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 21002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return blk_execute_rq(or->request->q, NULL, or->request, 0); 21102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 21202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request); 21302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 21402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void osd_request_async_done(struct request *req, int error) 21502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 21602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or = req->end_io_data; 21702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 21802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_error = error; 21902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (error) 22102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("osd_request_async_done error recieved %d\n", error); 22202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->async_done) 22402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done(or, or->async_private); 22502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh else 22602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_end_request(or); 22702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 22802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request_async(struct osd_request *or, 23002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_req_done_fn *done, void *private) 23102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 23202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->end_io_data = or; 23302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_private = private; 23402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done = done; 23502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 23602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_execute_rq_nowait(or->request->q, NULL, or->request, 0, 23702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_request_async_done); 23802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 23902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 24002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request_async); 24102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 2424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 2434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 2444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_realloc_seg(struct osd_request *or, 2464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg, unsigned max_bytes) 2474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *buff; 2494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (seg->alloc_size >= max_bytes) 2514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 2524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh buff = krealloc(seg->buff, max_bytes, or->alloc_flags); 2544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!buff) { 2554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes, 2564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size); 2574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -ENOMEM; 2584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 2594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size); 2614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = buff; 2624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = max_bytes; 2634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 2644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_set_attr_list(struct osd_request *or, 2674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem, unsigned add_bytes) 2684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = add_bytes; 2704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem, ++oa) 2724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += _osd_req_alist_elem_size(or, oa->len); 2734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", total_bytes); 2754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->set_attr, total_bytes); 2764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes) 2794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", max_bytes); 2814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes); 2824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_list(struct osd_request *or) 2854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes); 2874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes); 2884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 29002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 29102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Common to all OSD commands 29202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 29302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 29402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osdv1_req_encode_common(struct osd_request *or, 29502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 29602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 29702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osdv1_cdb *ocdb = &or->cdb.v1; 29802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 29902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* 30002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * For speed, the commands 30102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C 30202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D 30302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are not supported here. Should pass zero and set after the call 30402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 30502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh act &= cpu_to_be16(~0x0080); /* V1 action code */ 30602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 30702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act)); 30802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 30902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 31002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 31102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.service_action = act; 31202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 31302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.partition = cpu_to_be64(obj->partition); 31402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.object = cpu_to_be64(obj->id); 31502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.length = cpu_to_be64(len); 31602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.start_address = cpu_to_be64(offset); 31702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 31802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 31902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_common(struct osd_request *or, 32002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 32102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 32202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osdv1_req_encode_common(or, act, obj, offset, len); 32302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 32402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 32502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 32602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Device commands 32702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 32802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_format(struct osd_request *or, u64 tot_capacity) 32902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 33002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0, 33102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh tot_capacity); 33202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 33302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_format); 33402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 33502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 33602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Partition commands 33702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 33802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_partition(struct osd_request *or, 33902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, osd_id partition) 34002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 34102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_obj_id par = { 34202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .partition = partition, 34302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .id = 0, 34402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh }; 34502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 34602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, act, &par, 0, 0); 34702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 34802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 34902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_partition(struct osd_request *or, osd_id partition) 35002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 35102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition); 35202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 35302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_partition); 35402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 35502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_partition(struct osd_request *or, osd_id partition) 35602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 35702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition); 35802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 35902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_partition); 36002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 36102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 36202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Object commands 36302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 36402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj) 36502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 36602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0); 36702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 36802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_object); 36902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 37002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj) 37102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 37202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0); 37302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 37402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_object); 37502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 37602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_write(struct osd_request *or, 37702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, u64 offset) 37802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 37902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, bio->bi_size); 38002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->out.bio || or->out.total_bytes); 38102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio->bi_rw |= (1 << BIO_RW); 38202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.bio = bio; 38302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.total_bytes = bio->bi_size; 38402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 38502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_write); 38602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 38702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_read(struct osd_request *or, 38802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, u64 offset) 38902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 39002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, bio->bi_size); 39102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->in.bio || or->in.total_bytes); 39202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio->bi_rw &= ~(1 << BIO_RW); 39302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.bio = bio; 39402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.total_bytes = bio->bi_size; 39502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 39602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_read); 39702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 3984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_get_attributes(struct osd_request *or, 3994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 4004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0); 4024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_get_attributes); 4044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_set_attributes(struct osd_request *or, 4064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 4074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0); 4094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_set_attributes); 4114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 4134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes List-mode 4144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 4154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_set_attr_list(struct osd_request *or, 4174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 4184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->set_attr.total_bytes; 4204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 4214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 4224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 4244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 4254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 4264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 4274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 4294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 4314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 4324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 4334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 4344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->set_attr.buff, 4364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE); 4374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->set_attr.buff + total_bytes; 4394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 4414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_element *attr; 4424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); 4434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += elem_size; 4454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->set_attr.alloc_size < total_bytes)) { 4464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes - elem_size; 4474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 4484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 4494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = 4514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.buff + or->set_attr.total_bytes; 4524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr = attr_last; 4554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_page = cpu_to_be32(oa->attr_page); 4564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_id = cpu_to_be32(oa->attr_id); 4574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_bytes = cpu_to_be16(oa->len); 4584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memcpy(attr->attr_val, oa->val_ptr, oa->len); 4594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += elem_size; 4614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 4624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes; 4654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 4664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_set_attr_list); 4684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _append_map_kern(struct request *req, 4704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *buff, unsigned len, gfp_t flags) 4714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct bio *bio; 4734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 4744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh bio = bio_map_kern(req->q, buff, len, flags); 4764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (IS_ERR(bio)) { 4774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed bio_map_kern(%p, %d) => %ld\n", buff, len, 4784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh PTR_ERR(bio)); 4794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return PTR_ERR(bio); 4804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = blk_rq_append_bio(req->q, req, bio); 4824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 4834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed blk_rq_append_bio(%p) => %d\n", bio, ret); 4844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh bio_put(bio); 4854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _req_append_segment(struct osd_request *or, 4904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding, struct _osd_req_data_segment *seg, 4914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *last_seg, struct _osd_io_info *io) 4924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *pad_buff; 4944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 4954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (padding) { 4974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* check if we can just add it to last buffer */ 4984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (last_seg && 4994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (padding <= last_seg->alloc_size - last_seg->total_bytes)) 5004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = last_seg->buff + last_seg->total_bytes; 5014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh else 5024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = io->pad_buff; 5034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _append_map_kern(io->req, pad_buff, padding, 5054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 5064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += padding; 5094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _append_map_kern(io->req, seg->buff, seg->total_bytes, 5124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 5134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += seg->total_bytes; 5174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff, 5184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->total_bytes); 5194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_set_attr_list(struct osd_request *or) 5234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 5254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding; 5264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 5274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->set_attr.total_bytes) { 5294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED; 5304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes); 5344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = 5354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &padding); 5364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, padding, &or->set_attr, 5384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 5394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->set_attr; 5434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_list(struct osd_request *or, 5474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 5484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->enc_get_attr.total_bytes; 5504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 5514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 5524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 5544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 5554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 5564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 5574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 5594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* first time calc data-in list header size */ 5614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->get_attr.total_bytes) 5624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or); 5634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-out info */ 5654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 5664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned max_bytes; 5674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 5694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh max_bytes = total_bytes + 5704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh nelem * sizeof(struct osd_attributes_list_attrid); 5714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, max_bytes); 5724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->enc_get_attr.buff, 5764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_GET); 5774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + total_bytes; 5794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 5814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_attrid *attrid; 5824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned cur_size = sizeof(*attrid); 5834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += cur_size; 5854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) { 5864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes - cur_size; 5874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, 5884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes + nelem * sizeof(*attrid)); 5894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + 5924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes; 5934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid = attr_last; 5964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_page = cpu_to_be32(oa->attr_page); 5974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_id = cpu_to_be32(oa->attr_id); 5984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += cur_size; 6004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-in size */ 6024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes += 6034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_alist_elem_size(or, oa->len); 6044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 6054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes; 6084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG( 6104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n", 6114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes, 6124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or), 6134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes, 6144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or)) 6154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh / sizeof(struct osd_attributes_list_attrid)); 6164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 6194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_list); 6204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_get_attr_list(struct osd_request *or) 6224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 6234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 6244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned out_padding; 6254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding; 6264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 6274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->enc_get_attr.total_bytes) { 6294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED; 6304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED; 6314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_list(or); 6354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The out-going buffer info update */ 6394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("out-going\n"); 6404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_bytes = 6414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->enc_get_attr.total_bytes); 6424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = 6444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 6454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->enc_get_attr, 6474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 6484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->enc_get_attr; 6514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The incoming buffer info update */ 6534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("in-coming\n"); 6544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_alloc_length = 6554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->get_attr.total_bytes); 6564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = 6584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 6594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 6614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 6624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.last_seg = &or->get_attr; 6654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 6684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_decode_get_attr_list(struct osd_request *or, 6704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attr *oa, int *nelem, void **iterator) 6714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 6724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned cur_bytes, returned_bytes; 6734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int n; 6744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or); 6754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *cur_p; 6764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!_osd_req_is_alist_type(or, or->get_attr.buff, 6784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE)) { 6794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_page = 0; 6804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_id = 0; 6814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 6824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len = 0; 6834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = NULL; 6844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (*iterator) { 6884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON((*iterator < or->get_attr.buff) || 6894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->get_attr.buff + or->get_attr.alloc_size < *iterator)); 6904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = *iterator; 6914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list; 6924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = or->get_attr.total_bytes; 6934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { /* first time decode the list header */ 6944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = sizeof_attr_list; 6954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) + 6964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh sizeof_attr_list; 6974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = or->get_attr.buff + sizeof_attr_list; 6994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (returned_bytes > or->get_attr.alloc_size) { 7014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("target report: space was not big enough! " 7024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "Allocate=%u Needed=%u\n", 7034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size, 7044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes + sizeof_attr_list); 7054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = 7074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size - sizeof_attr_list; 7084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = returned_bytes; 7104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { 7134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_element *attr = cur_p; 7144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned inc; 7154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len = be16_to_cpu(attr->attr_bytes); 7174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh inc = _osd_req_alist_elem_size(or, oa->len); 7184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n", 7194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len, inc, cur_bytes); 7204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes += inc; 7214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (cur_bytes > returned_bytes) { 7224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("BAD FOOD from target. list not valid!" 7234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "c=%d r=%d n=%d\n", 7244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes, returned_bytes, n); 7254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 7264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 7274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_page = be32_to_cpu(attr->attr_page); 7304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_id = be32_to_cpu(attr->attr_id); 7314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = attr->attr_val; 7324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p += inc; 7344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 7354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL; 7384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *nelem = n; 7394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return returned_bytes - cur_bytes; 7404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 7414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_decode_get_attr_list); 7424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 7444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes Page-mode 7454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 7464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_page(struct osd_request *or, 7484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u32 page_id, void *attar_page, unsigned max_page_len, 7494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *set_one_attr) 7504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 7514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 7524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 7544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 7554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 7564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 7574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE; 7594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.buff = attar_page; 7614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = max_page_len; 7624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.buff = set_one_attr->val_ptr; 7644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = set_one_attr->len; 7654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id); 7674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len); 7684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* ocdb->attrs_page.get_attr_offset; */ 7694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page); 7714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id); 7724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len); 7734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* ocdb->attrs_page.set_attr_offset; */ 7744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 7754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 7764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_page); 7774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_attr_page(struct osd_request *or) 7794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 7804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 7814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding, out_padding; 7824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 7834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* returned page */ 7854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_offset = 7864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 7874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 7894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 7904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 7914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 7924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* set one value */ 7944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_offset = 7954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 7964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->enc_get_attr, NULL, 7984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->out); 7994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 8004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 8014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 80202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 80302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_finalize_request and helpers 80402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 80502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 80602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic int _init_blk_request(struct osd_request *or, 80702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, bool has_out) 80802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 80902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh gfp_t flags = or->alloc_flags; 81002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct scsi_device *scsi_device = or->osd_dev->scsi_device; 81102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request_queue *q = scsi_device->request_queue; 81202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *req; 81302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh int ret = -ENOMEM; 81402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 81502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req = blk_get_request(q, has_out, flags); 81602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!req) 81702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 81802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 81902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request = req; 82002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->cmd_type = REQ_TYPE_BLOCK_PC; 82102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->timeout = or->timeout; 82202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->retries = or->retries; 82302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense = or->sense; 82402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense_len = 0; 82502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 82602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_out) { 82702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.req = req; 82802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_in) { 82902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* allocate bidi request */ 83002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req = blk_get_request(q, READ, flags); 83102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!req) { 83202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_get_request for bidi failed\n"); 83302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 83402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 83502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->cmd_type = REQ_TYPE_BLOCK_PC; 83602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = or->request->next_rq = req; 83702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 83802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else if (has_in) 83902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = req; 84002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 84102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = 0; 84202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshout: 84302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n", 84402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or, has_in, has_out, ret, or->request); 84502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 84602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 84702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 84802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_finalize_request(struct osd_request *or, 84902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 options, const void *cap, const u8 *cap_key) 85002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 85102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 85202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, has_out; 85302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh int ret; 85402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 85502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_FUA) 85602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_FUA; 85702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 85802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_DPO) 85902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_DPO; 86002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 86102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_BYPASS_TIMESTAMPS) 86202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS; 86302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 86402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_set_caps(&or->cdb, cap); 86502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 86602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh has_in = or->in.bio || or->get_attr.total_bytes; 86702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh has_out = or->out.bio || or->set_attr.total_bytes || 86802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->enc_get_attr.total_bytes; 86902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 87002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = _init_blk_request(or, has_in, has_out); 87102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 87202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("_init_blk_request failed\n"); 87302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 87402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 87502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 87602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->out.bio) { 87702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = blk_rq_append_bio(or->request->q, or->out.req, 87802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.bio); 87902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 88002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_rq_append_bio out failed\n"); 88102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 88202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 88302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n", 88402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _LLU(or->out.total_bytes), or->out.req->data_len); 88502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 88602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->in.bio) { 88702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio); 88802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 88902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_rq_append_bio in failed\n"); 89002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 89102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 89202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n", 89302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _LLU(or->in.total_bytes), or->in.req->data_len); 89402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 89502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 8964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.pad_buff = sg_out_pad_buffer; 8974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.pad_buff = sg_in_pad_buffer; 8984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 89902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or->attributes_mode) 90002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 90102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->command_specific_options |= or->attributes_mode; 9024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 9034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_attr_page(or); 9044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { 9054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* TODO: I think that for the GET_ATTR command these 2 should 9064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * be reversed to keep them in execution order (for embeded 9074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * targets with low memory footprint) 9084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 9094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_set_attr_list(or); 9104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 9114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n"); 9124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 9134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 9144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 9154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_get_attr_list(or); 9164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 9174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n"); 9184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 9194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 9204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 92102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd = or->cdb.buff; 92302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd_len = _osd_req_cdb_len(or); 92402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 92602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 92702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_finalize_request); 92802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 93002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Implementation of osd_sec.h API 93102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * TODO: Move to a separate osd_sec.c file at a later stage. 93202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 93302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 93402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_SEC_CAP_V1_ALL_CAPS = 93502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE | 93602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR | 93702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC | 93802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT 93902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}; 94002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 94102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_sec_init_nosec_doall_caps(void *caps, 94202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, bool is_collection, const bool is_v1) 94302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 94402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_capability *cap = caps; 94502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 type; 94602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 descriptor_type; 94702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 94802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (likely(obj->id)) { 94902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (unlikely(is_collection)) { 95002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_COLLECTION; 95102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ : 95202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_DESC_COL; 95302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 95402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_USER; 95502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_OBJ; 95602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 95702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(!obj->partition); 95802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 95902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = obj->partition ? OSD_SEC_OBJ_PARTITION : 96002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_ROOT; 96102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_PAR; 96202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 96302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 96402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(cap, 0, sizeof(*cap)); 96502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 96602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.format = OSD_SEC_CAP_FORMAT_VER1; 96702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */ 96802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.security_method = OSD_SEC_NOSEC; 96902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* cap->expiration_time; 97002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->AUDIT[30-10]; 97102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->discriminator[42-30]; 97202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->object_created_time; */ 97302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_type = type; 97402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS); 97502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_descriptor_type = descriptor_type; 97602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.policy_access_tag = 0; 97702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition); 97802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id); 97902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 98002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); 98102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 98202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_set_caps(struct osd_cdb *cdb, const void *caps) 98302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 98402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); 98502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 9864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 9874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 9884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Declared in osd_protocol.h 9894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * 4.12.5 Data-In and Data-Out buffer offsets 9904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * byte offset = mantissa * (2^(exponent+8)) 9914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Returns the smallest allowed encoded offset that contains given @offset 9924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * The actual encoded offset returned is @offset + *@padding. 9934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 9944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshosd_cdb_offset __osd_encode_offset( 9954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding, int min_shift, int max_shift) 9964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 9974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 try_offset = -1, mod, align; 9984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_cdb_offset be32_offset; 9994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int shift; 10004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = 0; 10024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!offset) 10034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 10044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (shift = min_shift; shift < max_shift; ++shift) { 10064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset = offset >> shift; 10074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (try_offset < (1 << OSD_OFFSET_MAX_BITS)) 10084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 10094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 10104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON(shift == max_shift); 10124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh align = 1 << shift; 10144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh mod = offset & (align - 1); 10154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (mod) { 10164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = align - mod; 10174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset += 1; 10184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 10194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset |= ((shift - 8) & 0xf) << 28; 10214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset = cpu_to_be32((u32)try_offset); 10224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n", 10244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift, 10254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset, *padding); 10264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return be32_offset; 10274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1028