/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <types.h>30#include <kern/errno.h>31#include <lib.h>32#include <uio.h>33#include <vfs.h>34#include <device.h>35#include <sfs.h>3637////////////////////////////////////////////////////////////38//39// Basic block-level I/O routines40//41// Note: sfs_rblock is used to read the superblock42// early in mount, before sfs is fully (or even mostly)43// initialized, and so may not use anything from sfs44// except sfs_device.4546int47sfs_rwblock(struct sfs_fs *sfs, struct uio *uio)48{49int result;50int tries=0;5152KASSERT(vfs_biglock_do_i_hold());5354DEBUG(DB_SFS, "sfs: %s %llu\n",55uio->uio_rw == UIO_READ ? "read" : "write",56uio->uio_offset / SFS_BLOCKSIZE);5758retry:59result = sfs->sfs_device->d_io(sfs->sfs_device, uio);60if (result == EINVAL) {61/*62* This means the sector we requested was out of range,63* or the seek address we gave wasn't sector-aligned,64* or a couple of other things that are our fault.65*/66panic("sfs: d_io returned EINVAL\n");67}68if (result == EIO) {69if (tries == 0) {70tries++;71kprintf("sfs: block %llu I/O error, retrying\n",72uio->uio_offset / SFS_BLOCKSIZE);73goto retry;74}75else if (tries < 10) {76tries++;77goto retry;78}79else {80kprintf("sfs: block %llu I/O error, giving up after "81"%d retries\n",82uio->uio_offset / SFS_BLOCKSIZE, tries);83}84}85return result;86}8788int89sfs_rblock(struct sfs_fs *sfs, void *data, uint32_t block)90{91struct iovec iov;92struct uio ku;9394SFSUIO(&iov, &ku, data, block, UIO_READ);95return sfs_rwblock(sfs, &ku);96}9798int99sfs_wblock(struct sfs_fs *sfs, void *data, uint32_t block)100{101struct iovec iov;102struct uio ku;103104SFSUIO(&iov, &ku, data, block, UIO_WRITE);105return sfs_rwblock(sfs, &ku);106}107108109