os161-1.99
 All Data Structures
sfs_io.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 #include <types.h>
00031 #include <kern/errno.h>
00032 #include <lib.h>
00033 #include <uio.h>
00034 #include <vfs.h>
00035 #include <device.h>
00036 #include <sfs.h>
00037 
00038 ////////////////////////////////////////////////////////////
00039 //
00040 // Basic block-level I/O routines
00041 //
00042 // Note: sfs_rblock is used to read the superblock
00043 // early in mount, before sfs is fully (or even mostly)
00044 // initialized, and so may not use anything from sfs
00045 // except sfs_device.
00046 
00047 int
00048 sfs_rwblock(struct sfs_fs *sfs, struct uio *uio)
00049 {
00050         int result;
00051         int tries=0;
00052 
00053         KASSERT(vfs_biglock_do_i_hold());
00054 
00055         DEBUG(DB_SFS, "sfs: %s %llu\n", 
00056               uio->uio_rw == UIO_READ ? "read" : "write",
00057               uio->uio_offset / SFS_BLOCKSIZE);
00058 
00059  retry:
00060         result = sfs->sfs_device->d_io(sfs->sfs_device, uio);
00061         if (result == EINVAL) {
00062                 /*
00063                  * This means the sector we requested was out of range,
00064                  * or the seek address we gave wasn't sector-aligned,
00065                  * or a couple of other things that are our fault.
00066                  */
00067                 panic("sfs: d_io returned EINVAL\n");
00068         }
00069         if (result == EIO) {
00070                 if (tries == 0) {
00071                         tries++;
00072                         kprintf("sfs: block %llu I/O error, retrying\n",
00073                                 uio->uio_offset / SFS_BLOCKSIZE);
00074                         goto retry;
00075                 }
00076                 else if (tries < 10) {
00077                         tries++;
00078                         goto retry;
00079                 }
00080                 else {
00081                         kprintf("sfs: block %llu I/O error, giving up after "
00082                                 "%d retries\n",
00083                                 uio->uio_offset / SFS_BLOCKSIZE, tries);
00084                 }
00085         }
00086         return result;
00087 }
00088 
00089 int
00090 sfs_rblock(struct sfs_fs *sfs, void *data, uint32_t block)
00091 {
00092         struct iovec iov;
00093         struct uio ku;
00094 
00095         SFSUIO(&iov, &ku, data, block, UIO_READ);
00096         return sfs_rwblock(sfs, &ku);
00097 }
00098 
00099 int
00100 sfs_wblock(struct sfs_fs *sfs, void *data, uint32_t block)
00101 {
00102         struct iovec iov;
00103         struct uio ku;
00104 
00105         SFSUIO(&iov, &ku, data, block, UIO_WRITE);
00106         return sfs_rwblock(sfs, &ku);
00107 }
 All Data Structures