14a5d661aSToomas Soome /* $NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $ */
24a5d661aSToomas Soome
34a5d661aSToomas Soome /*-
44a5d661aSToomas Soome * Copyright (c) 1993
54a5d661aSToomas Soome * The Regents of the University of California. All rights reserved.
64a5d661aSToomas Soome *
74a5d661aSToomas Soome * This code is derived from software contributed to Berkeley by
84a5d661aSToomas Soome * The Mach Operating System project at Carnegie-Mellon University.
94a5d661aSToomas Soome *
104a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
114a5d661aSToomas Soome * modification, are permitted provided that the following conditions
124a5d661aSToomas Soome * are met:
134a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
144a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
154a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
164a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
174a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
184a5d661aSToomas Soome * 4. Neither the name of the University nor the names of its contributors
194a5d661aSToomas Soome * may be used to endorse or promote products derived from this software
204a5d661aSToomas Soome * without specific prior written permission.
214a5d661aSToomas Soome *
224a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
234a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
244a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
254a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
264a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
274a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
284a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
294a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
304a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
314a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
324a5d661aSToomas Soome * SUCH DAMAGE.
334a5d661aSToomas Soome *
344a5d661aSToomas Soome * @(#)read.c 8.1 (Berkeley) 6/11/93
354a5d661aSToomas Soome *
364a5d661aSToomas Soome *
374a5d661aSToomas Soome * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
384a5d661aSToomas Soome * All Rights Reserved.
394a5d661aSToomas Soome *
404a5d661aSToomas Soome * Author: Alessandro Forin
414a5d661aSToomas Soome *
424a5d661aSToomas Soome * Permission to use, copy, modify and distribute this software and its
434a5d661aSToomas Soome * documentation is hereby granted, provided that both the copyright
444a5d661aSToomas Soome * notice and this permission notice appear in all copies of the
454a5d661aSToomas Soome * software, derivative works or modified versions, and any portions
464a5d661aSToomas Soome * thereof, and that both notices appear in supporting documentation.
474a5d661aSToomas Soome *
484a5d661aSToomas Soome * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
494a5d661aSToomas Soome * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
504a5d661aSToomas Soome * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
514a5d661aSToomas Soome *
524a5d661aSToomas Soome * Carnegie Mellon requests users of this software to return to
534a5d661aSToomas Soome *
544a5d661aSToomas Soome * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
554a5d661aSToomas Soome * School of Computer Science
564a5d661aSToomas Soome * Carnegie Mellon University
574a5d661aSToomas Soome * Pittsburgh PA 15213-3890
584a5d661aSToomas Soome *
594a5d661aSToomas Soome * any improvements or extensions that they make and grant Carnegie the
604a5d661aSToomas Soome * rights to redistribute these changes.
614a5d661aSToomas Soome */
624a5d661aSToomas Soome
634a5d661aSToomas Soome #include <sys/cdefs.h>
644a5d661aSToomas Soome __FBSDID("$FreeBSD$");
654a5d661aSToomas Soome
664a5d661aSToomas Soome #include <sys/param.h>
674a5d661aSToomas Soome #include "stand.h"
684a5d661aSToomas Soome
694a5d661aSToomas Soome ssize_t
read(int fd,void * dest,size_t bcount)704a5d661aSToomas Soome read(int fd, void *dest, size_t bcount)
714a5d661aSToomas Soome {
724a5d661aSToomas Soome struct open_file *f = &files[fd];
734a5d661aSToomas Soome size_t resid;
744a5d661aSToomas Soome
754a5d661aSToomas Soome if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
764a5d661aSToomas Soome errno = EBADF;
774a5d661aSToomas Soome return (-1);
784a5d661aSToomas Soome }
794a5d661aSToomas Soome if (f->f_flags & F_RAW) {
804a5d661aSToomas Soome twiddle(8);
814a5d661aSToomas Soome errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
82*976852c7SToomas Soome btodb(f->f_offset), bcount, dest, &resid);
834a5d661aSToomas Soome if (errno)
844a5d661aSToomas Soome return (-1);
854a5d661aSToomas Soome f->f_offset += resid;
864a5d661aSToomas Soome return (resid);
874a5d661aSToomas Soome }
884a5d661aSToomas Soome
894a5d661aSToomas Soome /*
904a5d661aSToomas Soome * Optimise reads from regular files using a readahead buffer.
914a5d661aSToomas Soome * If the request can't be satisfied from the current buffer contents,
924a5d661aSToomas Soome * check to see if it should be bypassed, or refill the buffer and complete
934a5d661aSToomas Soome * the request.
944a5d661aSToomas Soome */
954a5d661aSToomas Soome resid = bcount;
964a5d661aSToomas Soome for (;;) {
974a5d661aSToomas Soome size_t ccount, cresid;
984a5d661aSToomas Soome /* how much can we supply? */
994a5d661aSToomas Soome ccount = imin(f->f_ralen, resid);
1004a5d661aSToomas Soome if (ccount > 0) {
1014a5d661aSToomas Soome bcopy(f->f_rabuf + f->f_raoffset, dest, ccount);
1024a5d661aSToomas Soome f->f_raoffset += ccount;
1034a5d661aSToomas Soome f->f_ralen -= ccount;
1044a5d661aSToomas Soome resid -= ccount;
1054a5d661aSToomas Soome if (resid == 0)
1064a5d661aSToomas Soome return(bcount);
1074a5d661aSToomas Soome dest = (char *)dest + ccount;
1084a5d661aSToomas Soome }
1094a5d661aSToomas Soome
1104a5d661aSToomas Soome /* will filling the readahead buffer again not help? */
1114a5d661aSToomas Soome if (resid >= SOPEN_RASIZE) {
1124a5d661aSToomas Soome /* bypass the rest of the request and leave the buffer empty */
1134a5d661aSToomas Soome if ((errno = (f->f_ops->fo_read)(f, dest, resid, &cresid)))
1144a5d661aSToomas Soome return (-1);
1154a5d661aSToomas Soome return(bcount - cresid);
1164a5d661aSToomas Soome }
1174a5d661aSToomas Soome
1184a5d661aSToomas Soome /* fetch more data */
1194a5d661aSToomas Soome if ((errno = (f->f_ops->fo_read)(f, f->f_rabuf, SOPEN_RASIZE, &cresid)))
1204a5d661aSToomas Soome return (-1);
1214a5d661aSToomas Soome f->f_raoffset = 0;
1224a5d661aSToomas Soome f->f_ralen = SOPEN_RASIZE - cresid;
1234a5d661aSToomas Soome /* no more data, return what we had */
1244a5d661aSToomas Soome if (f->f_ralen == 0)
1254a5d661aSToomas Soome return(bcount - resid);
1264a5d661aSToomas Soome }
1274a5d661aSToomas Soome }
128