X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=libsysio%2Fsrc%2Freconcile.c;fp=libsysio%2Fsrc%2Freconcile.c;h=0000000000000000000000000000000000000000;hb=cdfbc722f4d63d3ed3740cbb549062f712010d90;hp=8fa01fdf38e5f5ec3d2d2a1ff914025890e83844;hpb=fc75c4b4f597f095fc16d6119427f17f0d8e2a85;p=fs%2Flustre-release.git diff --git a/libsysio/src/reconcile.c b/libsysio/src/reconcile.c deleted file mode 100644 index 8fa01fd..0000000 --- a/libsysio/src/reconcile.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * This Cplant(TM) source code is the property of Sandia National - * Laboratories. - * - * This Cplant(TM) source code is copyrighted by Sandia National - * Laboratories. - * - * The redistribution of this Cplant(TM) source code is subject to the - * terms of the GNU Lesser General Public License - * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) - * - * Cplant(TM) Copyright 1998-2004 Sandia Corporation. - * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive - * license for use of this work by or on behalf of the US Government. - * Export of this program may require a license from the United States - * Government. - */ - -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Questions or comments about this library should be sent to: - * - * Lee Ward - * Sandia National Laboratories, New Mexico - * P.O. Box 5800 - * Albuquerque, NM 87185-1110 - * - * lee@sandia.gov - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysio.h" -#include "xtio.h" - -/* - * Extent-vector IO support. - */ - -/* - * Arguments to IO vector enumerator callback when used by _sysio_doio(). - */ -struct doio_helper_args { - ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, void *); /* base func */ - void *arg; /* caller arg */ -}; - -/* - * General help validating strided-IO vectors. - * - * A driver may call this to make sure underflow/overflow of an off_t can't - * occur and overflow of a ssize_t can't occur when writing. The sum - * of the reconciled transfer length is returned or some appropriate - * error depending on underflow/overflow. - * - * The following algorithm assumes: - * - * a) sizeof(size_t) >= sizeof(ssize_t) - * b) 2's complement arithmetic - * c) The compiler won't optimize away code because it's developers - * believed that something with an undefined result in `C' can't happen. - */ -ssize_t -_sysio_validx(const struct intnl_xtvec *xtv, size_t xtvlen, - const struct iovec *iov, size_t iovlen, - _SYSIO_OFF_T limit) -{ - ssize_t acc, cc; - struct iovec iovec; - struct intnl_xtvec xtvec; - _SYSIO_OFF_T off; - - if (!(xtvlen && iovlen)) - return -EINVAL; - - acc = 0; - xtvec.xtv_len = iovec.iov_len = 0; - do { - while (!xtvec.xtv_len) { - if (!xtvlen--) - break; - if (!xtv->xtv_len) { - xtv++; - continue; - } - xtvec = *xtv++; - if (xtvec.xtv_off < 0) - return -EINVAL; - } - if (!xtvec.xtv_len) - break; - do { - while (!iovec.iov_len) { - if (!iovlen--) - break; - if (!iov->iov_len) { - iov++; - continue; - } - iovec = *iov++; - } - if (!iovec.iov_len) - break; - cc = iovec.iov_len; - if (cc < 0) - return -EINVAL; - if ((size_t )cc > xtvec.xtv_len) - cc = xtvec.xtv_len; - xtvec.xtv_len -= cc; - iovec.iov_len -= cc; - off = xtvec.xtv_off + cc; - if (xtvec.xtv_off && off <= xtvec.xtv_off) - return off < 0 ? -EINVAL : -EOVERFLOW; - if (off > limit) - return -EFBIG; - xtvec.xtv_off = off; - cc += acc; - if (acc && (cc <= acc)) - return -EINVAL; - acc = cc; - } while (xtvec.xtv_len && iovlen); - } while ((xtvlen || xtvec.xtv_len) && iovlen); - return acc; -} - -/* - */ -ssize_t -_sysio_enumerate_extents(const struct intnl_xtvec *xtv, size_t xtvlen, - const struct iovec *iov, size_t iovlen, - ssize_t (*f)(const struct iovec *, int, - _SYSIO_OFF_T, - ssize_t, - void *), - void *arg) -{ - ssize_t acc, tmp, cc; - struct iovec iovec; - struct intnl_xtvec xtvec; - const struct iovec *start; - _SYSIO_OFF_T off; - size_t n; - size_t remain; - - acc = 0; - iovec.iov_len = 0; - while (xtvlen) { - /* - * Coalesce contiguous extent vector entries. - */ - off = xtvec.xtv_off = xtv->xtv_off; - off += xtvec.xtv_len = xtv->xtv_len; - while (++xtv, --xtvlen) { - if (off != xtv->xtv_off) { - /* - * Not contiguous. - */ - break; - } - if (!xtv->xtv_len) { - /* - * Zero length. - */ - continue; - } - off += xtv->xtv_len; - xtvec.xtv_len += xtv->xtv_len; - } - while (xtvec.xtv_len) { - if (iovec.iov_len) { - tmp = iovec.iov_len; - if (iovec.iov_len > xtvec.xtv_len) - iovec.iov_len = xtvec.xtv_len; - cc = - (*f)(&iovec, 1, - xtvec.xtv_off, - xtvec.xtv_len, - arg); - if (cc <= 0) { - if (acc) - return acc; - return cc; - } - iovec.iov_base = (char *)iovec.iov_base + cc; - iovec.iov_len = tmp - cc; - tmp = cc + acc; - if (acc && tmp <= acc) - abort(); /* paranoia */ - acc = tmp; - } else if (iovlen) { - start = iov; - n = xtvec.xtv_len; - do { - if (iov->iov_len > n) { - /* - * That'll do. - */ - break; - } - n -= iov->iov_len; - iov++; - } while (--iovlen); - if (iov == start) { - iovec = *iov++; - iovlen--; - continue; - } - remain = xtvec.xtv_len - n; - cc = - (*f)(start, iov - start, - xtvec.xtv_off, - remain, - arg); - if (cc <= 0) { - if (acc) - return acc; - return cc; - } - - tmp = cc + acc; - if (acc && tmp <= acc) - abort(); /* paranoia */ - acc = tmp; - - remain -= cc; - if (remain) - return acc; /* short */ - } else - return acc; /* short out */ - xtvec.xtv_off += cc; - xtvec.xtv_len -= cc; - } - } - return acc; -} - -ssize_t -_sysio_enumerate_iovec(const struct iovec *iov, size_t count, - _SYSIO_OFF_T off, - ssize_t limit, - ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, void *), - void *arg) -{ - ssize_t acc, cc; - size_t n; - unsigned indx; - size_t remain; - - if (!count) - return -EINVAL; - assert(limit >= 0); - acc = 0; - n = limit; - for (indx = 0; n && indx < count; indx++) { - if (iov[indx].iov_len < n) { - cc = (ssize_t )iov[indx].iov_len; - if (cc < 0) - return -EINVAL; - } else - cc = (ssize_t )n; - if (!cc) - continue; - n -= cc; - cc += acc; - if (acc && cc <= acc) - return -EINVAL; - acc = cc; - } - if (!acc) - return 0; - acc = 0; - do { - if (!iov->iov_len) { - iov++; - continue; - } - n = - iov->iov_len < (size_t )limit - ? iov->iov_len - : (size_t )limit; - cc = (*f)(iov->iov_base, n, off, arg); - if (cc <= 0) { - if (acc) - return acc; - return cc; - } - off += cc; - limit -= cc; - remain = iov->iov_len - cc; - cc += acc; - if (acc && cc <= acc) - abort(); /* bad driver! */ - acc = cc; - if (remain || !limit) - break; /* short/limited read */ - iov++; - } while (--count); - return acc; -} - -static ssize_t -_sysio_doio_helper(const struct iovec *iov, int count, - _SYSIO_OFF_T off, - ssize_t limit, - struct doio_helper_args *args) -{ - - return _sysio_enumerate_iovec(iov, count, - off, limit, - args->f, - args->arg); -} - -/* - * A meta-driver for the whole strided-io process. Appropriate when - * the driver can't handle anything but simple p{read,write}-like - * interface. - */ -ssize_t -_sysio_doio(const struct intnl_xtvec *xtv, size_t xtvlen, - const struct iovec *iov, size_t iovlen, - ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, void *), - void *arg) -{ - struct doio_helper_args arguments; - - arguments.f = f; - arguments.arg = arg; - return _sysio_enumerate_extents(xtv, xtvlen, - iov, iovlen, - (ssize_t (*)(const struct iovec *, int, - _SYSIO_OFF_T, - ssize_t, - void *))_sysio_doio_helper, - &arguments); -}