fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cred.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/uio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sdt.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define __NSC_GEN__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_dev.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "nsc_disk.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "../nsctl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_def_t _nsc_disk_def[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "UserRead", (uintptr_t)nsc_ioerr, _I(uread),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "UserWrite", (uintptr_t)nsc_ioerr, _I(uwrite),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PartSize", (uintptr_t)nsc_null, _I(partsize),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "MaxFbas", (uintptr_t)nsc_null, _I(maxfbas),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Control", (uintptr_t)nsc_ioerr, _I(control),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern nsc_mem_t *_nsc_local_mem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_uread(dev_t, uio_t *, cred_t *, nsc_fd_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_uwrite(dev_t, uio_t *, cred_t *, nsc_fd_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_rw_uio(nsc_fd_t *, uio_t *, uio_rw_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_free_dhandle(nsc_dbuf_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_alloc_dbuf(blind_t, nsc_off_t, nsc_size_t, int, nsc_dbuf_t **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_free_dbuf(nsc_dbuf_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _nsc_wait_dbuf(nsc_dbuf_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_read_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_write_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_zero_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _nsc_dbuf_io(int (*)(), nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_dbuf_t *_nsc_alloc_dhandle(void (*)(), void (*)(), void (*)());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _nsc_add_disk (nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add disk interface functions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Calling/Exit State:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Updates the I/O module with the appropriate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * interface routines.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add functions to the I/O module to provide a disk
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or cache interface as appropriate.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_add_disk(nsc_io_t *io)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((io->alloc_buf != nsc_ioerr && io->free_buf != nsc_fatal) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (io->flag & NSC_FILTER)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->uread == nsc_ioerr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->uread = _nsc_uread;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->uwrite == nsc_ioerr &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (io->write != nsc_fatal || (io->flag & NSC_FILTER)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->uwrite = _nsc_uwrite;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->alloc_h != (nsc_buf_t *(*)())nsc_null ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->free_h != nsc_fatal || io->alloc_buf != nsc_ioerr ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->free_buf != nsc_fatal || io->read != nsc_fatal ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->write != nsc_fatal || io->zero != nsc_fatal)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (io->uread == nsc_ioerr && io->uwrite == nsc_ioerr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Layer the generic nsc_buf_t provider onto a uio_t provider.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->alloc_h = (nsc_buf_t *(*)())_nsc_alloc_dhandle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->free_h = _nsc_free_dhandle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->alloc_buf = _nsc_alloc_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->free_buf = _nsc_free_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->read = _nsc_read_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->write = _nsc_write_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->zero = _nsc_zero_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte io->provide |= NSC_ANON;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_uread(nsc_fd_t *fd, void *uiop, void *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (*fd->sf_aio->uread)(fd->sf_cd, uiop, crp, fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_uwrite(nsc_fd_t *fd, void *uiop, void *crp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd->sf_avail & NSC_WRITE) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (*fd->sf_aio->uwrite)(fd->sf_cd, uiop, crp, fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_partsize(nsc_fd_t *fd, nsc_size_t *valp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *valp = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (*fd->sf_aio->partsize)(fd->sf_cd, valp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_maxfbas(nsc_fd_t *fd, int flag, nsc_size_t *valp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *valp = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (*fd->sf_aio->maxfbas)(fd->sf_cd, flag, valp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortensc_control(nsc_fd_t *fd, int command, void *argp, int argl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (*fd->sf_aio->control)(fd->sf_cd, command, argp, argl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_uread(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_rw_uio(fd, uiop, UIO_READ));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_uwrite(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_rw_uio(fd, uiop, UIO_WRITE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_rw_uio(nsc_fd_t *fd, uio_t *uiop, uio_rw_t rw)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t buflen, len, limit, chunk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t pos, off;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_buf_t *buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_vec_t *vec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pos = FPOS_TO_FBA(uiop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off = FPOS_TO_OFF(uiop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = FBA_LEN(uiop->uio_resid + off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE3(_nsc_rw_uio_io,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, off,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* prevent non-FBA bounded I/O - this is a disk driver! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (off != 0 || FBA_OFF(uiop->uio_resid) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_partsize(fd, &limit)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_maxfbas(fd, 0, &chunk)) != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE2(_nsc_rw_uio_limit,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, limit,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t, chunk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (limit && pos >= limit) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pos > limit || rw == UIO_WRITE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (limit && pos + len > limit)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = limit - pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (len > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflen = min(len, chunk);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf = NULL; /* always use a temporary buffer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = nsc_alloc_buf(fd, pos, buflen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rw == UIO_READ) ? NSC_RDBUF : NSC_WRBUF, &buf)) > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vec = buf->sb_vec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !rc && uiop->uio_resid && vec->sv_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vec++, off = 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = min(vec->sv_len - off, uiop->uio_resid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = uiomove((char *)vec->sv_addr + off,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n, rw, uiop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rw == UIO_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_uncommit(buf, pos, buflen, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((rc = nsc_write(buf, pos, buflen, 0)) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) nsc_free_buf(buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len -= buflen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pos += buflen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic nsc_dbuf_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_dhandle(void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dbuf_t *h;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((h = nsc_kmem_zalloc(sizeof (nsc_dbuf_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, _nsc_local_mem)) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_disc = d_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_flag = NSC_HALLOCATED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_dhandle(nsc_dbuf_t *h)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(h, sizeof (*h));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_alloc_dbuf(blind_t cd, nsc_off_t pos, nsc_size_t len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag, nsc_dbuf_t **hp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dbuf_t *h = *hp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == NSC_ANON_CD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag &= ~(NSC_READ | NSC_WRITE | NSC_RDAHEAD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_maxfbas == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_maxfbas(h->db_fd, 0, &h->db_maxfbas);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (h->db_maxfbas == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len > h->db_maxfbas)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOSPC);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & NSC_NODATA) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!(flag & NSC_RDBUF));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_addr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_disc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*h->db_disc)(h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(h->db_addr = nsc_kmem_alloc(FBA_SIZE(len), KM_SLEEP, 0)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_pos = pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_len = len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_error = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_flag |= flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & NSC_NODATA) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_vec = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_vec = &h->db_bvec[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[0].sv_len = FBA_SIZE(len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[0].sv_addr = (void *)h->db_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[0].sv_vme = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[1].sv_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[1].sv_addr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_bvec[1].sv_vme = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((flag & NSC_RDAHEAD) || (cd == NSC_ANON_CD))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NSC_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nsc_wait_dbuf(h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & NSC_RDBUF) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rc = _nsc_dbuf_io(nsc_uread, h, pos, len, flag)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _nsc_free_dbuf(h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NSC_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_wait_dbuf(nsc_dbuf_t *h)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev = h->db_fd->sf_iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*fn)() = h->db_disc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dbuf_t *hp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_next = iodev->si_active;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev->si_active = h;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (hp = h->db_next; hp; hp = hp->db_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_pos + h->db_len > hp->db_pos &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_pos < hp->db_pos + hp->db_len) break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!hp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*fn)(h), fn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&iodev->si_cv, &iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_free_dbuf(nsc_dbuf_t *h)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_dbuf_t **hpp, *hp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_iodev_t *iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int wake = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_fd && !(h->db_flag & NSC_ABUF)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iodev = h->db_fd->sf_iodev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hpp = (nsc_dbuf_t **)&iodev->si_active;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; *hpp; hpp = &hp->db_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((hp = *hpp) == h) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *hpp = h->db_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_pos + h->db_len > hp->db_pos &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_pos < hp->db_pos + hp->db_len) wake = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wake)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&iodev->si_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iodev->si_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(h->db_flag & NSC_NODATA) && h->db_addr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(h->db_addr, FBA_SIZE(h->db_len));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_addr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_flag &= NSC_HALLOCATED; /* clear flags, preserve NSC_HALLOCATED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((h->db_flag & NSC_HALLOCATED) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) _nsc_free_dhandle(h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_read_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_dbuf_io(nsc_uread, h, pos, len, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_write_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_dbuf_io(nsc_uwrite, h, pos, len, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_zero_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (_nsc_dbuf_io(NULL, h, pos, len, flag));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_nsc_dbuf_io(int (*fn)(), nsc_dbuf_t *h, nsc_off_t pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t len, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_vec_t *vp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred_t *crp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iovec_t *iovp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t thisio; /* bytes in this io */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t todo; /* anticipated bytes to go */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t truedo; /* actual bytes to go */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t xpos; /* offset of this io */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int destidx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t firstentryfix; /* value used for first entry */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*iofn)();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!h->db_vec || (h->db_flag & NSC_ABUF))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pos < h->db_pos || pos + len > h->db_pos + h->db_len)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!len)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fn == nsc_uread && (flag & NSC_RDAHEAD))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (h->db_disc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*h->db_disc)(h);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte crp = ddi_get_cred();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&h->db_uio, sizeof (uio_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&h->db_iov[0], (_NSC_DBUF_NVEC * sizeof (iovec_t)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte todo = FBA_SIZE(len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * determine where in the vector array we should start.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp = h->db_vec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xpos = pos - h->db_pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; xpos >= FBA_NUM(vp->sv_len); vp++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xpos -= FBA_NUM(vp->sv_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte firstentryfix = FBA_SIZE(xpos);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xpos = pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loop performing i/o to the underlying driver.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (todo) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte destidx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thisio = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iofn = fn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy up to _NSC_DBUF_NVEC vector entries from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nsc_vec_t into the iovec_t so that the number of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * i/o operations is minimised.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (destidx < _NSC_DBUF_NVEC && todo) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iovp = &h->db_iov[destidx];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(FBA_LEN(vp->sv_len) == FBA_NUM(vp->sv_len));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((vp->sv_len - firstentryfix) && vp->sv_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte truedo = min(vp->sv_len - firstentryfix, todo);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iovp->iov_base = (caddr_t)vp->sv_addr + firstentryfix;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte firstentryfix = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iovp->iov_len = (size_t)truedo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iofn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(iovp->iov_base, iovp->iov_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thisio += truedo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte todo -= truedo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte destidx++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_uio.uio_iovcnt = destidx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_uio.uio_iov = &h->db_iov[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_uio.uio_segflg = UIO_SYSSPACE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte h->db_uio.uio_resid = (size_t)thisio;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SET_FPOS(&h->db_uio, xpos);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iofn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iofn = nsc_uwrite;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = (*iofn)(h->db_fd, &h->db_uio, crp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(FBA_LEN(thisio) == FBA_NUM(thisio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xpos += FBA_LEN(thisio);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}