summaryrefslogtreecommitdiffstats
path: root/lib/libstand/lseek.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2000-09-05 09:52:50 +0000
committermsmith <msmith@FreeBSD.org>2000-09-05 09:52:50 +0000
commit6ff92c14b7a65f64dea4e0d4e8d19b2dcf3f57b3 (patch)
treeded2222e22c2d532e900757ec03c1d5306a3e570 /lib/libstand/lseek.c
parent75c63c707d89253e9bd44217d8975ec16bec5aa5 (diff)
downloadFreeBSD-src-6ff92c14b7a65f64dea4e0d4e8d19b2dcf3f57b3.zip
FreeBSD-src-6ff92c14b7a65f64dea4e0d4e8d19b2dcf3f57b3.tar.gz
Implement readahead buffering for non-raw files. This drastically improves
the efficiency of byte-by-byte read operations on filesystems not already supported by the block cache (especially NFS). This should be a welcome change for users booting via PXE, as the loader now reads its startup files almost instantly, instead of taking tens of seconds.
Diffstat (limited to 'lib/libstand/lseek.c')
-rw-r--r--lib/libstand/lseek.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/lib/libstand/lseek.c b/lib/libstand/lseek.c
index 0894912..91f8612 100644
--- a/lib/libstand/lseek.c
+++ b/lib/libstand/lseek.c
@@ -1,3 +1,4 @@
+/* $FreeBSD$ */
/* $NetBSD: lseek.c,v 1.4 1997/01/22 00:38:10 cgd Exp $ */
/*-
@@ -67,36 +68,46 @@
#include "stand.h"
off_t
-lseek(fd, offset, where)
- int fd;
- off_t offset;
- int where;
+lseek(int fd, off_t offset, int where)
{
- register struct open_file *f = &files[fd];
+ struct open_file *f = &files[fd];
- if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
- errno = EBADF;
- return (-1);
- }
+ if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
+ }
- if (f->f_flags & F_RAW) {
- /*
- * On RAW devices, update internal offset.
- */
- switch (where) {
- case SEEK_SET:
- f->f_offset = offset;
- break;
- case SEEK_CUR:
- f->f_offset += offset;
- break;
- case SEEK_END:
- default:
- errno = EOFFSET;
- return (-1);
- }
- return (f->f_offset);
+ if (f->f_flags & F_RAW) {
+ /*
+ * On RAW devices, update internal offset.
+ */
+ switch (where) {
+ case SEEK_SET:
+ f->f_offset = offset;
+ break;
+ case SEEK_CUR:
+ f->f_offset += offset;
+ break;
+ case SEEK_END:
+ default:
+ errno = EOFFSET;
+ return (-1);
}
+ return (f->f_offset);
+ }
+
+ /*
+ * If this is a relative seek, we need to correct the offset for
+ * bytes that we have already read but the caller doesn't know
+ * about.
+ */
+ if (where == SEEK_CUR)
+ offset -= f->f_ralen;
+
+ /*
+ * Invalidate the readahead buffer.
+ */
+ f->f_ralen = 0;
- return (f->f_ops->fo_seek)(f, offset, where);
+ return (f->f_ops->fo_seek)(f, offset, where);
}
OpenPOWER on IntegriCloud