예제 #1
0
/*
 * Called for write. Hand off to DEVOP_IO.
 */
static
int
dev_write(struct vnode *v, struct uio *uio)
{
	struct device *d = v->vn_data;
	int result;

	result = dev_tryseek(d, uio->uio_offset);
	if (result) {
		return result;
	}

	KASSERT(uio->uio_rw == UIO_WRITE);
	return DEVOP_IO(d, uio);
}
예제 #2
0
/*
 * Read or write a block, retrying I/O errors.
 */
static
int
sfs_rwblock(struct sfs_fs *sfs, struct uio *uio)
{
	int result;
	int tries=0;

	DEBUG(DB_SFS, "sfs: %s %llu\n",
	      uio->uio_rw == UIO_READ ? "read" : "write",
	      uio->uio_offset / SFS_BLOCKSIZE);

 retry:
	result = DEVOP_IO(sfs->sfs_device, uio);
	if (result == EINVAL) {
		/*
		 * This means the sector we requested was out of range,
		 * or the seek address we gave wasn't sector-aligned,
		 * or a couple of other things that are our fault.
		 */
		panic("sfs: DEVOP_IO returned EINVAL\n");
	}
	if (result == EIO) {
		if (tries == 0) {
			tries++;
			kprintf("sfs: block %llu I/O error, retrying\n",
				uio->uio_offset / SFS_BLOCKSIZE);
			goto retry;
		}
		else if (tries < 10) {
			tries++;
			goto retry;
		}
		else {
			kprintf("sfs: block %llu I/O error, giving up after "
				"%d retries\n",
				uio->uio_offset / SFS_BLOCKSIZE, tries);
		}
	}
	return result;
}