109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh/* 209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * pNFS Objects layout driver high level definitions 309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * Copyright (C) 2007 Panasas Inc. [year of first publication] 509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * All rights reserved. 609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * Benny Halevy <bhalevy@panasas.com> 8aa281ac631008b9c18c405c8880007789f659c7dBoaz Harrosh * Boaz Harrosh <ooo@electrozaur.com> 909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 1009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * This program is free software; you can redistribute it and/or modify 1109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * it under the terms of the GNU General Public License version 2 1209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * See the file COPYING included with this distribution for more details. 1309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 1409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * Redistribution and use in source and binary forms, with or without 1509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * modification, are permitted provided that the following conditions 1609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * are met: 1709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 1809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 1. Redistributions of source code must retain the above copyright 1909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * notice, this list of conditions and the following disclaimer. 2009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 2. Redistributions in binary form must reproduce the above copyright 2109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * notice, this list of conditions and the following disclaimer in the 2209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * documentation and/or other materials provided with the distribution. 2309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 3. Neither the name of the Panasas company nor the names of its 2409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * contributors may be used to endorse or promote products derived 2509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * from this software without specific prior written permission. 2609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * 2709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 2809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh */ 3909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 4018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare#include <linux/kmod.h> 4118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare#include <linux/moduleparam.h> 4218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare#include <linux/ratelimit.h> 4309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh#include <scsi/osd_initiator.h> 4409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh#include "objlayout.h" 4509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 4609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh#define NFSDBG_FACILITY NFSDBG_PNFS_LD 4709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh/* 48e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy * Create a objlayout layout structure for the given inode and return it. 49e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy */ 50e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevystruct pnfs_layout_hdr * 51e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevyobjlayout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) 52e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy{ 53e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy struct objlayout *objlay; 54e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy 55e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy objlay = kzalloc(sizeof(struct objlayout), gfp_flags); 560aa61e78a0f262a2f94bd138831c97749cfca5bfTrond Myklebust if (!objlay) 570aa61e78a0f262a2f94bd138831c97749cfca5bfTrond Myklebust return NULL; 580aa61e78a0f262a2f94bd138831c97749cfca5bfTrond Myklebust spin_lock_init(&objlay->lock); 590aa61e78a0f262a2f94bd138831c97749cfca5bfTrond Myklebust INIT_LIST_HEAD(&objlay->err_list); 60e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy dprintk("%s: Return %p\n", __func__, objlay); 61e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy return &objlay->pnfs_layout; 62e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy} 63e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy 64e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy/* 65e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy * Free an objlayout layout structure 66e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy */ 67e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevyvoid 68e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevyobjlayout_free_layout_hdr(struct pnfs_layout_hdr *lo) 69e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy{ 70e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy struct objlayout *objlay = OBJLAYOUT(lo); 71e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy 72e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy dprintk("%s: objlay %p\n", __func__, objlay); 73e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy 74adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh WARN_ON(!list_empty(&objlay->err_list)); 75e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy kfree(objlay); 76e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy} 77e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy 78e51b841dd0be9ff53f740c44c32c32679edcb7c8Benny Halevy/* 7909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * Unmarshall layout and store it in pnfslay. 8009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh */ 8109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harroshstruct pnfs_layout_segment * 8209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harroshobjlayout_alloc_lseg(struct pnfs_layout_hdr *pnfslay, 8309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh struct nfs4_layoutget_res *lgr, 8409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh gfp_t gfp_flags) 8509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh{ 8609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh int status = -ENOMEM; 8709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh struct xdr_stream stream; 8809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh struct xdr_buf buf = { 8909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh .pages = lgr->layoutp->pages, 9009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh .page_len = lgr->layoutp->len, 9109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh .buflen = lgr->layoutp->len, 9209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh .len = lgr->layoutp->len, 9309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh }; 9409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh struct page *scratch; 9509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh struct pnfs_layout_segment *lseg; 9609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 9709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh dprintk("%s: Begin pnfslay %p\n", __func__, pnfslay); 9809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 9909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh scratch = alloc_page(gfp_flags); 10009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh if (!scratch) 10109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh goto err_nofree; 10209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 10309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh xdr_init_decode(&stream, &buf, NULL); 10409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); 10509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 10609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh status = objio_alloc_lseg(&lseg, pnfslay, &lgr->range, &stream, gfp_flags); 10709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh if (unlikely(status)) { 10809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh dprintk("%s: objio_alloc_lseg Return err %d\n", __func__, 10909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh status); 11009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh goto err; 11109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh } 11209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 11309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh __free_page(scratch); 11409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 11509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh dprintk("%s: Return %p\n", __func__, lseg); 11609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh return lseg; 11709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 11809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosherr: 11909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh __free_page(scratch); 12009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosherr_nofree: 12109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh dprintk("%s: Err Return=>%d\n", __func__, status); 12209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh return ERR_PTR(status); 12309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh} 12409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 12509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh/* 12609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh * Free a layout segement 12709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh */ 12809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harroshvoid 12909f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harroshobjlayout_free_lseg(struct pnfs_layout_segment *lseg) 13009f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh{ 13109f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh dprintk("%s: freeing layout segment %p\n", __func__, lseg); 13209f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 13309f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh if (unlikely(!lseg)) 13409f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh return; 13509f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 13609f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh objio_free_lseg(lseg); 13709f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh} 13809f5bf4e6d0607399c16ec7a2d8d166f31086686Boaz Harrosh 139b6c05f1693115164c7b797152ac7ea3ef8e5d296Boaz Harrosh/* 14004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * I/O Operations 14104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 14204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshstatic inline u64 14304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshend_offset(u64 start, u64 len) 14404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 14504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh u64 end; 14604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 14704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh end = start + len; 14804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh return end >= start ? end : NFS4_MAX_UINT64; 14904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 15004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 15117280175c587469b34757263c7cfc608f0ea2334Trond Myklebuststatic void _fix_verify_io_params(struct pnfs_layout_segment *lseg, 15296218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh struct page ***p_pages, unsigned *p_pgbase, 15396218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh u64 offset, unsigned long count) 15404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 15504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh u64 lseg_end_offset; 15604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 15704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh BUG_ON(offset < lseg->pls_range.offset); 15804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh lseg_end_offset = end_offset(lseg->pls_range.offset, 15904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh lseg->pls_range.length); 16004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh BUG_ON(offset >= lseg_end_offset); 16196218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh WARN_ON(offset + count > lseg_end_offset); 16204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 16396218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh if (*p_pgbase > PAGE_SIZE) { 16496218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh dprintk("%s: pgbase(0x%x) > PAGE_SIZE\n", __func__, *p_pgbase); 16596218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh *p_pages += *p_pgbase >> PAGE_SHIFT; 16696218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh *p_pgbase &= ~PAGE_MASK; 16704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh } 16804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 16904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 17004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh/* 17104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * I/O done common code 17204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 17304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshstatic void 174e2e04355d9647305c666462a49223f2942a635f0Boaz Harroshobjlayout_iodone(struct objlayout_io_res *oir) 17504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 176e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh if (likely(oir->status >= 0)) { 177e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh objio_free_result(oir); 178adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } else { 179e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct objlayout *objlay = oir->objlay; 180adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 181adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh spin_lock(&objlay->lock); 182a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh objlay->delta_space_valid = OBJ_DSU_INVALID; 183e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh list_add(&objlay->err_list, &oir->err_list); 184adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh spin_unlock(&objlay->lock); 185adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 186adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh} 187adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 188adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh/* 189adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * objlayout_io_set_result - Set an osd_error code on a specific osd comp. 190adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * 191adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * The @index component IO failed (error returned from target). Register 192adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * the error for later reporting at layout-return. 193adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh */ 194adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshvoid 195e2e04355d9647305c666462a49223f2942a635f0Boaz Harroshobjlayout_io_set_result(struct objlayout_io_res *oir, unsigned index, 196adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh struct pnfs_osd_objid *pooid, int osd_error, 197adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh u64 offset, u64 length, bool is_write) 198adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh{ 199e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[index]; 200adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 201e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh BUG_ON(index >= oir->num_comps); 202adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (osd_error) { 203adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component = *pooid; 204adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_offset = offset; 205adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_length = length; 206adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_iswrite = is_write; 207adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_errno = osd_error; 208adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 209adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dprintk("%s: err[%d]: errno=%d is_write=%d dev(%llx:%llx) " 210adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh "par=0x%llx obj=0x%llx offset=0x%llx length=0x%llx\n", 211adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh __func__, index, ioerr->oer_errno, 212adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_iswrite, 213adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_LO(&ioerr->oer_component.oid_device_id), 214adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_HI(&ioerr->oer_component.oid_device_id), 215adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_partition_id, 216adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_object_id, 217adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_offset, 218adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_length); 219adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } else { 220adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* User need not call if no error is reported */ 221adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_errno = 0; 222adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 22304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 22404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 22504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh/* Function scheduled on rpc workqueue to call ->nfs_readlist_complete(). 22604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * This is because the osd completion is called with ints-off from 22704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * the block layer 22804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 22904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshstatic void _rpc_read_complete(struct work_struct *work) 23004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 23104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh struct rpc_task *task; 232d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson struct nfs_pgio_header *hdr; 23304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 23404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh dprintk("%s enter\n", __func__); 23504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh task = container_of(work, struct rpc_task, u.tk_work); 236d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr = container_of(task, struct nfs_pgio_header, task); 23704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 238d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson pnfs_ld_read_done(hdr); 23904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 24004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 24104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshvoid 242e2e04355d9647305c666462a49223f2942a635f0Boaz Harroshobjlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync) 24304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 244d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson struct nfs_pgio_header *hdr = oir->rpcdata; 24504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 246d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson oir->status = hdr->task.tk_status = status; 2474cdc685c7d06f659ef6c336d4242005cdd8df401Boaz Harrosh if (status >= 0) 248d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->res.count = status; 2495c0b4129c07b902b27d3f3ebc087757f534a3abdBoaz Harrosh else 250d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->pnfs_error = status; 251e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh objlayout_iodone(oir); 252e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh /* must not use oir after this point */ 25304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 25496218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh dprintk("%s: Return status=%zd eof=%d sync=%d\n", __func__, 255d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson status, hdr->res.eof, sync); 25696218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh 25704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh if (sync) 258d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson pnfs_ld_read_done(hdr); 25904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh else { 260d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson INIT_WORK(&hdr->task.u.tk_work, _rpc_read_complete); 261d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson schedule_work(&hdr->task.u.tk_work); 26204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh } 26304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 26404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 26504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh/* 26604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * Perform sync or async reads. 26704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 26804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshenum pnfs_try_status 269d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamsonobjlayout_read_pagelist(struct nfs_pgio_header *hdr) 27004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 271cd841605f7a721878d8a2d1362484723d8abf569Fred Isaman struct inode *inode = hdr->inode; 272d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson loff_t offset = hdr->args.offset; 273d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson size_t count = hdr->args.count; 274e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh int err; 27504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh loff_t eof; 27604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 277cd841605f7a721878d8a2d1362484723d8abf569Fred Isaman eof = i_size_read(inode); 27804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh if (unlikely(offset + count > eof)) { 27904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh if (offset >= eof) { 280e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh err = 0; 281d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->res.count = 0; 282d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->res.eof = 1; 2834cdc685c7d06f659ef6c336d4242005cdd8df401Boaz Harrosh /*FIXME: do we need to call pnfs_ld_read_done() */ 28404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh goto out; 28504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh } 28604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh count = eof - offset; 28704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh } 28804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 289d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->res.eof = (offset + count) >= eof; 290d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson _fix_verify_io_params(hdr->lseg, &hdr->args.pages, 291d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson &hdr->args.pgbase, 292d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->args.offset, hdr->args.count); 2934cdc685c7d06f659ef6c336d4242005cdd8df401Boaz Harrosh 294e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh dprintk("%s: inode(%lx) offset 0x%llx count 0x%Zx eof=%d\n", 295d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson __func__, inode->i_ino, offset, count, hdr->res.eof); 29604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 297d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson err = objio_read_pagelist(hdr); 29804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh out: 299e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh if (unlikely(err)) { 300cd841605f7a721878d8a2d1362484723d8abf569Fred Isaman hdr->pnfs_error = err; 301e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh dprintk("%s: Returned Error %d\n", __func__, err); 302e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh return PNFS_NOT_ATTEMPTED; 303e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh } 30404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh return PNFS_ATTEMPTED; 30504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 30604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 30704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh/* Function scheduled on rpc workqueue to call ->nfs_writelist_complete(). 30804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * This is because the osd completion is called with ints-off from 30904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * the block layer 31004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 31104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshstatic void _rpc_write_complete(struct work_struct *work) 31204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 31304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh struct rpc_task *task; 314d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson struct nfs_pgio_header *hdr; 31504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 31604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh dprintk("%s enter\n", __func__); 31704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh task = container_of(work, struct rpc_task, u.tk_work); 318d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr = container_of(task, struct nfs_pgio_header, task); 31904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 320d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson pnfs_ld_write_done(hdr); 32104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 32204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 32304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshvoid 324e2e04355d9647305c666462a49223f2942a635f0Boaz Harroshobjlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync) 32504f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 326d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson struct nfs_pgio_header *hdr = oir->rpcdata; 32704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 328d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson oir->status = hdr->task.tk_status = status; 32904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh if (status >= 0) { 330d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->res.count = status; 331c65e6254ca4db1584c5bf5f228ee26556477a9fdWeston Andros Adamson hdr->verf.committed = oir->committed; 3325c0b4129c07b902b27d3f3ebc087757f534a3abdBoaz Harrosh } else { 333d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->pnfs_error = status; 33496218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh } 335e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh objlayout_iodone(oir); 33696218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh /* must not use oir after this point */ 33796218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh 33896218556b03d3c6505e2880a097338bf277fd783Boaz Harrosh dprintk("%s: Return status %zd committed %d sync=%d\n", __func__, 339c65e6254ca4db1584c5bf5f228ee26556477a9fdWeston Andros Adamson status, hdr->verf.committed, sync); 34004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 34104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh if (sync) 342d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson pnfs_ld_write_done(hdr); 34304f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh else { 344d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson INIT_WORK(&hdr->task.u.tk_work, _rpc_write_complete); 345d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson schedule_work(&hdr->task.u.tk_work); 34604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh } 34704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 34804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 34904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh/* 35004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh * Perform sync or async writes. 35104f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh */ 35204f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harroshenum pnfs_try_status 353d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamsonobjlayout_write_pagelist(struct nfs_pgio_header *hdr, int how) 35404f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh{ 355e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh int err; 35604f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 357d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson _fix_verify_io_params(hdr->lseg, &hdr->args.pages, 358d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson &hdr->args.pgbase, 359d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson hdr->args.offset, hdr->args.count); 36004f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 361d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson err = objio_write_pagelist(hdr, how); 362e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh if (unlikely(err)) { 363cd841605f7a721878d8a2d1362484723d8abf569Fred Isaman hdr->pnfs_error = err; 364e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh dprintk("%s: Returned Error %d\n", __func__, err); 365e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh return PNFS_NOT_ATTEMPTED; 366e6c40fe3f4c4967f1cb486191ed4a5d5f55f3f7eBoaz Harrosh } 36704f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh return PNFS_ATTEMPTED; 36804f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh} 36904f83450388e87d86b387cf4a27b81eb7e69de7dBoaz Harrosh 370a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harroshvoid 371a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harroshobjlayout_encode_layoutcommit(struct pnfs_layout_hdr *pnfslay, 372a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh struct xdr_stream *xdr, 373a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh const struct nfs4_layoutcommit_args *args) 374a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh{ 375a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh struct objlayout *objlay = OBJLAYOUT(pnfslay); 376a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh struct pnfs_osd_layoutupdate lou; 377a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh __be32 *start; 378a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 379a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh dprintk("%s: Begin\n", __func__); 380a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 381a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh spin_lock(&objlay->lock); 382a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh lou.dsu_valid = (objlay->delta_space_valid == OBJ_DSU_VALID); 383a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh lou.dsu_delta = objlay->delta_space_used; 384a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh objlay->delta_space_used = 0; 385a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh objlay->delta_space_valid = OBJ_DSU_INIT; 386a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh lou.olu_ioerr_flag = !list_empty(&objlay->err_list); 387a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh spin_unlock(&objlay->lock); 388a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 389a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh start = xdr_reserve_space(xdr, 4); 390a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 391a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh BUG_ON(pnfs_osd_xdr_encode_layoutupdate(xdr, &lou)); 392a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 393a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh *start = cpu_to_be32((xdr->p - start - 1) * 4); 394a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 395a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh dprintk("%s: Return delta_space_used %lld err %d\n", __func__, 396a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh lou.dsu_delta, lou.olu_ioerr_flag); 397a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh} 398a0fe8bf427f4987d7b82678292ca03cfd7331467Boaz Harrosh 399adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshstatic int 400adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosherr_prio(u32 oer_errno) 401adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh{ 402adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh switch (oer_errno) { 403adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case 0: 404adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return 0; 405adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 406adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_RESOURCE: 407adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_RESOURCE; 408adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_BAD_CRED: 409adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_BAD_CRED; 410adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_NO_ACCESS: 411adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_NO_ACCESS; 412adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_UNREACHABLE: 413adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_UNREACHABLE; 414adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_NOT_FOUND: 415adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_NOT_FOUND; 416adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_NO_SPACE: 417adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_NO_SPACE; 418adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh default: 419adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh WARN_ON(1); 420adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* fallthrough */ 421adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh case PNFS_OSD_ERR_EIO: 422adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return OSD_ERR_PRI_EIO; 423adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 424adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh} 425adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 426adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshstatic void 427adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshmerge_ioerr(struct pnfs_osd_ioerr *dest_err, 428adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh const struct pnfs_osd_ioerr *src_err) 429adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh{ 430adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh u64 dest_end, src_end; 431adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 432adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (!dest_err->oer_errno) { 433adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh *dest_err = *src_err; 434adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* accumulated device must be blank */ 435adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh memset(&dest_err->oer_component.oid_device_id, 0, 436adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh sizeof(dest_err->oer_component.oid_device_id)); 437adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 438adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh return; 439adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 440adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 441adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (dest_err->oer_component.oid_partition_id != 442adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh src_err->oer_component.oid_partition_id) 443adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_component.oid_partition_id = 0; 444adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 445adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (dest_err->oer_component.oid_object_id != 446adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh src_err->oer_component.oid_object_id) 447adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_component.oid_object_id = 0; 448adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 449adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (dest_err->oer_comp_offset > src_err->oer_comp_offset) 450adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_comp_offset = src_err->oer_comp_offset; 451adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 452adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_end = end_offset(dest_err->oer_comp_offset, 453adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_comp_length); 454adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh src_end = end_offset(src_err->oer_comp_offset, 455adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh src_err->oer_comp_length); 456adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (dest_end < src_end) 457adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_end = src_end; 458adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 459adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_comp_length = dest_end - dest_err->oer_comp_offset; 460adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 461adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if ((src_err->oer_iswrite == dest_err->oer_iswrite) && 462adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh (err_prio(src_err->oer_errno) > err_prio(dest_err->oer_errno))) { 463adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_errno = src_err->oer_errno; 464adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } else if (src_err->oer_iswrite) { 465adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_iswrite = true; 466adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dest_err->oer_errno = src_err->oer_errno; 467adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 468adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh} 469adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 470adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshstatic void 471adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshencode_accumulated_error(struct objlayout *objlay, __be32 *p) 472adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh{ 473e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct objlayout_io_res *oir, *tmp; 474adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0}; 475adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 476e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) { 477adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh unsigned i; 478adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 479e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh for (i = 0; i < oir->num_comps; i++) { 480e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i]; 481adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 482adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (!ioerr->oer_errno) 483adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh continue; 484adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 485a030889a01d1bea921e1a7501010b7b891d2abd2Weston Andros Adamson printk(KERN_ERR "NFS: %s: err[%d]: errno=%d " 486a030889a01d1bea921e1a7501010b7b891d2abd2Weston Andros Adamson "is_write=%d dev(%llx:%llx) par=0x%llx " 487a030889a01d1bea921e1a7501010b7b891d2abd2Weston Andros Adamson "obj=0x%llx offset=0x%llx length=0x%llx\n", 488adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh __func__, i, ioerr->oer_errno, 489adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_iswrite, 490adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_LO(&ioerr->oer_component.oid_device_id), 491adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_HI(&ioerr->oer_component.oid_device_id), 492adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_partition_id, 493adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_object_id, 494adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_offset, 495adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_length); 496adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 497adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh merge_ioerr(&accumulated_err, ioerr); 498adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 499e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh list_del(&oir->err_list); 500e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh objio_free_result(oir); 501adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 502adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 503adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh pnfs_osd_xdr_encode_ioerr(p, &accumulated_err); 504adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh} 505adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 506adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshvoid 507adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshobjlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay, 508adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh struct xdr_stream *xdr, 509adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh const struct nfs4_layoutreturn_args *args) 510adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh{ 511adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh struct objlayout *objlay = OBJLAYOUT(pnfslay); 512e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct objlayout_io_res *oir, *tmp; 513adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh __be32 *start; 514adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 515adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dprintk("%s: Begin\n", __func__); 516adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh start = xdr_reserve_space(xdr, 4); 517adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh BUG_ON(!start); 518adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 519adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh spin_lock(&objlay->lock); 520adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 521e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) { 522adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh __be32 *last_xdr = NULL, *p; 523adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh unsigned i; 524adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh int res = 0; 525adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 526e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh for (i = 0; i < oir->num_comps; i++) { 527e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i]; 528adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 529adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (!ioerr->oer_errno) 530adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh continue; 531adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 532adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dprintk("%s: err[%d]: errno=%d is_write=%d " 533adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh "dev(%llx:%llx) par=0x%llx obj=0x%llx " 534adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh "offset=0x%llx length=0x%llx\n", 535adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh __func__, i, ioerr->oer_errno, 536adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_iswrite, 537adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_LO(&ioerr->oer_component.oid_device_id), 538adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh _DEVID_HI(&ioerr->oer_component.oid_device_id), 539adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_partition_id, 540adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_component.oid_object_id, 541adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_offset, 542adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh ioerr->oer_comp_length); 543adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 544adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh p = pnfs_osd_xdr_ioerr_reserve_space(xdr); 545adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (unlikely(!p)) { 546adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh res = -E2BIG; 547adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh break; /* accumulated_error */ 548adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 549adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 550adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh last_xdr = p; 551e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh pnfs_osd_xdr_encode_ioerr(p, &oir->ioerrs[i]); 552adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 553adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 554adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* TODO: use xdr_write_pages */ 555adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh if (unlikely(res)) { 556adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* no space for even one error descriptor */ 557adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh BUG_ON(!last_xdr); 558adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 559adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh /* we've encountered a situation with lots and lots of 560adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * errors and no space to encode them all. Use the last 561adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * available slot to report the union of all the 562adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh * remaining errors. 563adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh */ 564adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh encode_accumulated_error(objlay, last_xdr); 565adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh goto loop_done; 566adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 567e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh list_del(&oir->err_list); 568e2e04355d9647305c666462a49223f2942a635f0Boaz Harrosh objio_free_result(oir); 569adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh } 570adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harroshloop_done: 571adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh spin_unlock(&objlay->lock); 572adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 573adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh *start = cpu_to_be32((xdr->p - start - 1) * 4); 574adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh dprintk("%s: Return\n", __func__); 575adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh} 576adb58535e604a564495a7d50dfb0afa0ddc21bcbBoaz Harrosh 57718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamareenum { 57818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare OBJLAYOUT_MAX_URI_LEN = 256, OBJLAYOUT_MAX_OSDNAME_LEN = 64, 57918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare OBJLAYOUT_MAX_SYSID_HEX_LEN = OSD_SYSTEMID_LEN * 2 + 1, 58018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare OSD_LOGIN_UPCALL_PATHLEN = 256 58118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare}; 58218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 58318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamarestatic char osd_login_prog[OSD_LOGIN_UPCALL_PATHLEN] = "/sbin/osd_login"; 58418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 58518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamaremodule_param_string(osd_login_prog, osd_login_prog, sizeof(osd_login_prog), 58618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 0600); 58718d98f6c04991dd3c12acf6f39cea40e9510640aSachin BhamareMODULE_PARM_DESC(osd_login_prog, "Path to the osd_login upcall program"); 58818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 58918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamarestruct __auto_login { 59018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char uri[OBJLAYOUT_MAX_URI_LEN]; 59118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char osdname[OBJLAYOUT_MAX_OSDNAME_LEN]; 59218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char systemid_hex[OBJLAYOUT_MAX_SYSID_HEX_LEN]; 59318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare}; 59418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 59518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamarestatic int __objlayout_upcall(struct __auto_login *login) 59618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare{ 59718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare static char *envp[] = { "HOME=/", 59818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare "TERM=linux", 59918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare "PATH=/sbin:/usr/sbin:/bin:/usr/bin", 60018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare NULL 60118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare }; 60218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char *argv[8]; 60318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare int ret; 60418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 60518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (unlikely(!osd_login_prog[0])) { 60618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare dprintk("%s: osd_login_prog is disabled\n", __func__); 60718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return -EACCES; 60818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare } 60918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 61018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare dprintk("%s uri: %s\n", __func__, login->uri); 61118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare dprintk("%s osdname %s\n", __func__, login->osdname); 61218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare dprintk("%s systemid_hex %s\n", __func__, login->systemid_hex); 61318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 61418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[0] = (char *)osd_login_prog; 61518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[1] = "-u"; 61618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[2] = login->uri; 61718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[3] = "-o"; 61818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[4] = login->osdname; 61918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[5] = "-s"; 62018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[6] = login->systemid_hex; 62118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare argv[7] = NULL; 62218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 62318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); 62418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare /* 62518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare * Disable the upcall mechanism if we're getting an ENOENT or 62618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare * EACCES error. The admin can re-enable it on the fly by using 62718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare * sysfs to set the objlayoutdriver.osd_login_prog module parameter once 62818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare * the problem has been fixed. 62918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare */ 63018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (ret == -ENOENT || ret == -EACCES) { 63118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare printk(KERN_ERR "PNFS-OBJ: %s was not found please set " 63218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare "objlayoutdriver.osd_login_prog kernel parameter!\n", 63318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare osd_login_prog); 63418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare osd_login_prog[0] = '\0'; 63518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare } 63618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare dprintk("%s %s return value: %d\n", __func__, osd_login_prog, ret); 63718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 63818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return ret; 63918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare} 64018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 64118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare/* Assume dest is all zeros */ 64218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamarestatic void __copy_nfsS_and_zero_terminate(struct nfs4_string s, 64318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char *dest, int max_len, 64418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare const char *var_name) 64518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare{ 64618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (!s.len) 64718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return; 64818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 64918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (s.len >= max_len) { 65018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare pr_warn_ratelimited( 65118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare "objlayout_autologin: %s: s.len(%d) >= max_len(%d)", 65218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare var_name, s.len, max_len); 65318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare s.len = max_len - 1; /* space for null terminator */ 65418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare } 65518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 65618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare memcpy(dest, s.data, s.len); 65718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare} 65818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 65918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare/* Assume sysid is all zeros */ 66018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamarestatic void _sysid_2_hex(struct nfs4_string s, 66118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char sysid[OBJLAYOUT_MAX_SYSID_HEX_LEN]) 66218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare{ 66318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare int i; 66418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare char *cur; 66518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 66618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (!s.len) 66718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return; 66818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 66918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (s.len != OSD_SYSTEMID_LEN) { 67018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare pr_warn_ratelimited( 67118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare "objlayout_autologin: systemid_len(%d) != OSD_SYSTEMID_LEN", 67218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare s.len); 67318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (s.len > OSD_SYSTEMID_LEN) 67418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare s.len = OSD_SYSTEMID_LEN; 67518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare } 67618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 67718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare cur = sysid; 67818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare for (i = 0; i < s.len; i++) 67918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare cur = hex_byte_pack(cur, s.data[i]); 68018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare} 68118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 68218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamareint objlayout_autologin(struct pnfs_osd_deviceaddr *deviceaddr) 68318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare{ 68418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare int rc; 68518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare struct __auto_login login; 68618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 68718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (!deviceaddr->oda_targetaddr.ota_netaddr.r_addr.len) 68818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return -ENODEV; 68918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 69018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare memset(&login, 0, sizeof(login)); 69118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare __copy_nfsS_and_zero_terminate( 69218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare deviceaddr->oda_targetaddr.ota_netaddr.r_addr, 69318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare login.uri, sizeof(login.uri), "URI"); 69418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 69518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare __copy_nfsS_and_zero_terminate( 69618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare deviceaddr->oda_osdname, 69718d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare login.osdname, sizeof(login.osdname), "OSDNAME"); 69818d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 69918d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare _sysid_2_hex(deviceaddr->oda_systemid, login.systemid_hex); 70018d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 70118d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare rc = __objlayout_upcall(&login); 70218d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare if (rc > 0) /* script returns positive values */ 70318d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare rc = -ENODEV; 70418d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare 70518d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare return rc; 70618d98f6c04991dd3c12acf6f39cea40e9510640aSachin Bhamare} 707