summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2021-07-21 23:32:24 +0300
committerToomas Soome <tsoome@me.com>2021-08-20 20:04:44 +0300
commita2027c5d4c477546faea39a790b019c3480c9b9b (patch)
tree6acaede0abe496e863e86036da0081660115d0db
parentd6bf170859287b7b5b26419e266a7e6fdee7ff4d (diff)
downloadillumos-joyent-a2027c5d4c477546faea39a790b019c3480c9b9b.tar.gz
13965 loader: open file list should be dynamic
Reviewed by: Andy Fiddaman <andy@omnios.org> Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/lib/libstand/close.c33
-rw-r--r--usr/src/boot/lib/libstand/closeall.c59
-rw-r--r--usr/src/boot/lib/libstand/fstat.c5
-rw-r--r--usr/src/boot/lib/libstand/ioctl.c5
-rw-r--r--usr/src/boot/lib/libstand/iodesc.h4
-rw-r--r--usr/src/boot/lib/libstand/lseek.c138
-rw-r--r--usr/src/boot/lib/libstand/net.h4
-rw-r--r--usr/src/boot/lib/libstand/netif.c110
-rw-r--r--usr/src/boot/lib/libstand/open.c65
-rw-r--r--usr/src/boot/lib/libstand/read.c5
-rw-r--r--usr/src/boot/lib/libstand/readdir.c6
-rw-r--r--usr/src/boot/lib/libstand/stand.h8
-rw-r--r--usr/src/boot/lib/libstand/write.c5
14 files changed, 282 insertions, 167 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index ffa5854c66..a45290a429 100644
--- a/usr/src/boot/Makefile.version
+++ b/usr/src/boot/Makefile.version
@@ -34,4 +34,4 @@ LOADER_VERSION = 1.1
# Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes.
# The version is processed from left to right, the version number can only
# be increased.
-BOOT_VERSION = $(LOADER_VERSION)-2021.08.03.1
+BOOT_VERSION = $(LOADER_VERSION)-2021.08.03.2
diff --git a/usr/src/boot/lib/libstand/close.c b/usr/src/boot/lib/libstand/close.c
index 573cef4dbd..546dd98600 100644
--- a/usr/src/boot/lib/libstand/close.c
+++ b/usr/src/boot/lib/libstand/close.c
@@ -67,23 +67,38 @@
int
close(int fd)
{
- struct open_file *f = &files[fd];
+ struct open_file *f, *last;
int err1 = 0, err2 = 0;
- if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ f = fd2open_file(fd);
+ if (f == NULL) {
errno = EBADF;
return (-1);
}
free(f->f_rabuf);
f->f_rabuf = NULL;
- if (!(f->f_flags & F_RAW) && f->f_ops)
- err1 = (f->f_ops->fo_close)(f);
- if (!(f->f_flags & F_NODEV) && f->f_dev)
- err2 = (f->f_dev->dv_close)(f);
- if (f->f_devdata != NULL)
- devclose(f);
- f->f_flags = 0;
+ if (f->f_flags != 0) {
+ if (!(f->f_flags & F_RAW) && f->f_ops)
+ err1 = (f->f_ops->fo_close)(f);
+ if (!(f->f_flags & F_NODEV) && f->f_dev)
+ err2 = (f->f_dev->dv_close)(f);
+ if (f->f_devdata != NULL)
+ devclose(f);
+ f->f_flags = 0;
+ } else {
+ /* Attempt to close already closed file. */
+ err1 = EBADF;
+ }
+
+ /* free unused entries from tail. */
+ TAILQ_FOREACH_REVERSE_SAFE(last, &files, file_list, f_link, f) {
+ if (last->f_flags != 0)
+ break;
+ TAILQ_REMOVE(&files, last, f_link);
+ free(last);
+ }
+
if (err1) {
errno = err1;
return (-1);
diff --git a/usr/src/boot/lib/libstand/closeall.c b/usr/src/boot/lib/libstand/closeall.c
index 13ff905a7e..425cd334b7 100644
--- a/usr/src/boot/lib/libstand/closeall.c
+++ b/usr/src/boot/lib/libstand/closeall.c
@@ -1,11 +1,7 @@
-/* $NetBSD: closeall.c,v 1.1 1996/01/13 22:25:36 leo Exp $ */
-
-/*
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * This code is derived from software contributed to Berkeley by
- * The Mach Operating System project at Carnegie-Mellon University.
+ * Copyright (c) 2021 Toomas Soome <tsoome@me.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -15,14 +11,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -30,34 +23,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * @(#)close.c 8.1 (Berkeley) 6/11/93
- *
- *
- * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Author: Alessandro Forin
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
*/
#include <sys/cdefs.h>
@@ -67,9 +32,15 @@
void
closeall(void)
{
- int i;
+ struct open_file *f;
- for (i = 0; i < SOPEN_MAX; i++)
- if (files[i].f_flags != 0)
- (void) close(i);
+ /*
+ * Pick up last entry and close it, this will also trigger
+ * the removal of this entry, and we end up with empty list.
+ */
+ while ((f = TAILQ_LAST(&files, file_list)) != NULL) {
+ (void) close(f->f_id);
+ }
+ /* reset errno from close() */
+ errno = 0;
}
diff --git a/usr/src/boot/lib/libstand/fstat.c b/usr/src/boot/lib/libstand/fstat.c
index 3c33de0cc3..44030d085e 100644
--- a/usr/src/boot/lib/libstand/fstat.c
+++ b/usr/src/boot/lib/libstand/fstat.c
@@ -38,9 +38,10 @@
int
fstat(int fd, struct stat *sb)
{
- struct open_file *f = &files[fd];
+ struct open_file *f;
- if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ f = fd2open_file(fd);
+ if (f == NULL || f->f_flags == 0) {
errno = EBADF;
return (-1);
}
diff --git a/usr/src/boot/lib/libstand/ioctl.c b/usr/src/boot/lib/libstand/ioctl.c
index 557cddf3ef..67c95c77d6 100644
--- a/usr/src/boot/lib/libstand/ioctl.c
+++ b/usr/src/boot/lib/libstand/ioctl.c
@@ -67,9 +67,10 @@
int
ioctl(int fd, ulong_t cmd, char *arg)
{
- struct open_file *f = &files[fd];
+ struct open_file *f;
- if ((unsigned)fd >= SOPEN_MAX || f->f_flags == 0) {
+ f = fd2open_file(fd);
+ if (f == NULL || f->f_flags == 0) {
errno = EBADF;
return (-1);
}
diff --git a/usr/src/boot/lib/libstand/iodesc.h b/usr/src/boot/lib/libstand/iodesc.h
index 37ae044af9..2086c586d2 100644
--- a/usr/src/boot/lib/libstand/iodesc.h
+++ b/usr/src/boot/lib/libstand/iodesc.h
@@ -1,7 +1,7 @@
/* $NetBSD: iodesc.h,v 1.4 1995/09/23 03:31:50 gwr Exp $ */
/*
- * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1993 Adam Glass
* Copyright (c) 1992 Regents of the University of California.
* All rights reserved.
*
@@ -47,6 +47,8 @@ struct iodesc {
u_long xid; /* transaction identification */
u_char myea[6]; /* my ethernet address */
struct netif *io_netif;
+ int io_id; /* descriptor id */
+ TAILQ_ENTRY(iodesc) io_link; /* next entry in list */
};
#endif /* __SYS_LIBNETBOOT_IODESC_H */
diff --git a/usr/src/boot/lib/libstand/lseek.c b/usr/src/boot/lib/libstand/lseek.c
index bfac8624a6..eb063394a1 100644
--- a/usr/src/boot/lib/libstand/lseek.c
+++ b/usr/src/boot/lib/libstand/lseek.c
@@ -32,30 +32,30 @@
* SUCH DAMAGE.
*
* @(#)lseek.c 8.1 (Berkeley) 6/11/93
- *
+ *
*
* Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Author: Alessandro Forin
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
@@ -66,74 +66,76 @@
off_t
lseek(int fd, off_t offset, int where)
{
- off_t bufpos, filepos, target;
- struct open_file *f = &files[fd];
+ off_t bufpos, filepos, target;
+ struct open_file *f;
- 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;
- default:
- errno = EOFFSET;
- return (-1);
+ f = fd2open_file(fd);
+ if (f == NULL || f->f_flags == 0) {
+ errno = EBADF;
+ return (-1);
}
- return (f->f_offset);
- }
- /*
- * If there is some unconsumed data in the readahead buffer and it
- * contains the desired offset, simply adjust the buffer offset and
- * length. We don't bother with SEEK_END here, since the code to
- * handle it would fail in the same cases where the non-readahead
- * code fails (namely, for streams which cannot seek backward and whose
- * size isn't known in advance).
- */
- if (f->f_ralen != 0 && where != SEEK_END) {
- if ((filepos = (f->f_ops->fo_seek)(f, (off_t)0, SEEK_CUR)) == -1)
- return (-1);
- bufpos = filepos - f->f_ralen;
- switch (where) {
- case SEEK_SET:
- target = offset;
- break;
- case SEEK_CUR:
- target = bufpos + offset;
- break;
- default:
- errno = EINVAL;
- 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;
+ default:
+ errno = EOFFSET;
+ return (-1);
+ }
+ return (f->f_offset);
}
- if (bufpos <= target && target < filepos) {
- f->f_raoffset += target - bufpos;
- f->f_ralen -= target - bufpos;
- return (target);
+
+ /*
+ * If there is some unconsumed data in the readahead buffer and it
+ * contains the desired offset, simply adjust the buffer offset and
+ * length. We don't bother with SEEK_END here, since the code to
+ * handle it would fail in the same cases where the non-readahead
+ * code fails (namely, for streams which cannot seek backward and whose
+ * size isn't known in advance).
+ */
+ if (f->f_ralen != 0 && where != SEEK_END) {
+ filepos = (f->f_ops->fo_seek)(f, 0, SEEK_CUR);
+ if (filepos == -1)
+ return (-1);
+ bufpos = filepos - f->f_ralen;
+ switch (where) {
+ case SEEK_SET:
+ target = offset;
+ break;
+ case SEEK_CUR:
+ target = bufpos + offset;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ if (bufpos <= target && target < filepos) {
+ f->f_raoffset += target - bufpos;
+ f->f_ralen -= target - bufpos;
+ return (target);
+ }
}
- }
- /*
- * 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;
+ /*
+ * 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;
+ /*
+ * 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);
}
diff --git a/usr/src/boot/lib/libstand/net.h b/usr/src/boot/lib/libstand/net.h
index 99081a634a..93ab8d84e7 100644
--- a/usr/src/boot/lib/libstand/net.h
+++ b/usr/src/boot/lib/libstand/net.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1993 Adam Glass
* Copyright (c) 1992 Regents of the University of California.
* All rights reserved.
*
@@ -93,8 +93,6 @@ extern u_int intf_mtu;
extern int debug; /* defined in the machdep sources */
-extern struct iodesc sockets[SOPEN_MAX];
-
/* ARP/RevARP functions: */
u_char *arpwhohas(struct iodesc *, struct in_addr);
void arp_reply(struct iodesc *, void *);
diff --git a/usr/src/boot/lib/libstand/netif.c b/usr/src/boot/lib/libstand/netif.c
index 0e6c71569d..74364e9098 100644
--- a/usr/src/boot/lib/libstand/netif.c
+++ b/usr/src/boot/lib/libstand/netif.c
@@ -46,7 +46,19 @@
#include "net.h"
#include "netif.h"
-struct iodesc sockets[SOPEN_MAX];
+typedef TAILQ_HEAD(socket_list, iodesc) socket_list_t;
+
+/*
+ * Open socket list. The current implementation and assumption is,
+ * we only remove entries from tail and we only add new entries to tail.
+ * This decision is to keep iodesc id management simple - we get list
+ * entries ordered by continiously growing io_id field.
+ * If we do have multiple sockets open and we do close socket not from tail,
+ * this entry will be marked unused. netif_open() will reuse unused entry, or
+ * netif_close() will free all unused tail entries.
+ */
+static socket_list_t sockets = TAILQ_HEAD_INITIALIZER(sockets);
+
#ifdef NETIF_DEBUG
int netif_debug = 0;
#endif
@@ -258,32 +270,67 @@ netif_put(struct iodesc *desc, void *pkt, size_t len)
return (rv);
}
+/*
+ * socktodesc_impl:
+ *
+ * Walk socket list and return pointer to iodesc structure.
+ * if id is < 0, return first unused iodesc.
+ */
+static struct iodesc *
+socktodesc_impl(int socket)
+{
+ struct iodesc *s;
+
+ TAILQ_FOREACH(s, &sockets, io_link) {
+ /* search by socket id */
+ if (socket >= 0) {
+ if (s->io_id == socket)
+ break;
+ continue;
+ }
+ /* search for first unused entry */
+ if (s->io_netif == NULL)
+ break;
+ }
+ return (s);
+}
+
struct iodesc *
socktodesc(int sock)
{
- if (sock >= SOPEN_MAX) {
+ struct iodesc *desc;
+
+ if (sock < 0)
+ desc = NULL;
+ else
+ desc = socktodesc_impl(sock);
+
+ if (desc == NULL)
errno = EBADF;
- return (NULL);
- }
- return (&sockets[sock]);
+
+ return (desc);
}
int
netif_open(void *machdep_hint)
{
- int fd;
struct iodesc *s;
struct netif *nif;
/* find a free socket */
- for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
- if (s->io_netif == (struct netif *)0)
- goto fnd;
- errno = EMFILE;
- return (-1);
-
-fnd:
- bzero(s, sizeof (*s));
+ s = socktodesc_impl(-1);
+ if (s == NULL) {
+ struct iodesc *last;
+
+ s = calloc(1, sizeof (*s));
+ if (s == NULL)
+ return (-1);
+ last = TAILQ_LAST(&sockets, socket_list);
+ if (last != NULL)
+ s->io_id = last->io_id + 1;
+ TAILQ_INSERT_TAIL(&sockets, s, io_link);
+ }
+
netif_init();
nif = netif_select(machdep_hint);
if (!nif)
@@ -296,18 +343,43 @@ fnd:
}
netif_attach(nif, s, machdep_hint);
- return (fd);
+ return (s->io_id);
}
int
netif_close(int sock)
{
- if (sock >= SOPEN_MAX) {
- errno = EBADF;
+ struct iodesc *s, *last;
+ int err;
+
+ err = 0;
+ s = socktodesc_impl(sock);
+ if (s == NULL || sock < 0) {
+ err = EBADF;
+ return (-1);
+ }
+ netif_detach(s->io_netif);
+
+ bzero(&s->destip, sizeof (s->destip));
+ bzero(&s->myip, sizeof (s->myip));
+ s->destport = 0;
+ s->myport = 0;
+ s->xid = 0;
+ bzero(s->myea, sizeof (s->myea));
+ s->io_netif = NULL;
+
+ /* free unused entries from tail. */
+ TAILQ_FOREACH_REVERSE_SAFE(last, &sockets, socket_list, io_link, s) {
+ if (last->io_netif != NULL)
+ break;
+ TAILQ_REMOVE(&sockets, last, io_link);
+ free(last);
+ }
+
+ if (err) {
+ errno = err;
return (-1);
}
- netif_detach(sockets[sock].io_netif);
- sockets[sock].io_netif = (struct netif *)0;
return (0);
}
diff --git a/usr/src/boot/lib/libstand/open.c b/usr/src/boot/lib/libstand/open.c
index 5fd6c2a5fb..6d026f1ca6 100644
--- a/usr/src/boot/lib/libstand/open.c
+++ b/usr/src/boot/lib/libstand/open.c
@@ -66,17 +66,65 @@
struct fs_ops *exclusive_file_system;
-struct open_file files[SOPEN_MAX];
+/*
+ * Open file list. The current implementation and assumption is,
+ * we only remove entries from tail and we only add new entries to tail.
+ * This decision is to keep file id management simple - we get list
+ * entries ordered by continiously growing f_id field.
+ * If we do have multiple files open and we do close file not from tail,
+ * this entry will be marked unused. open() will reuse unused entry, or
+ * close will free all unused tail entries.
+ *
+ * Only case we expect open file list to grow long, is with zfs pools with
+ * many disks.
+ */
+file_list_t files = TAILQ_HEAD_INITIALIZER(files);
+
+/*
+ * Walk file list and return pointer to open_file structure.
+ * if fd is < 0, return first unused open_file.
+ */
+struct open_file *
+fd2open_file(int fd)
+{
+ struct open_file *f;
+
+ TAILQ_FOREACH(f, &files, f_link) {
+ if (fd >= 0) {
+ if (f->f_id == fd)
+ break;
+ continue;
+ }
+ if (f->f_flags == 0)
+ break;
+ }
+ return (f);
+}
static int
-o_gethandle(void)
+o_gethandle(struct open_file **ptr)
{
- int fd;
+ struct open_file *f, *last;
- for (fd = 0; fd < SOPEN_MAX; fd++)
- if (files[fd].f_flags == 0)
- return (fd);
- return (-1);
+ /* Pick up unused entry */
+ f = fd2open_file(-1);
+ if (f != NULL) {
+ *ptr = f;
+ return (f->f_id);
+ }
+
+ /* Add new entry */
+ f = calloc(1, sizeof (*f));
+ if (f == NULL)
+ return (-1);
+
+ last = TAILQ_LAST(&files, file_list);
+ if (last != NULL)
+ f->f_id = last->f_id + 1;
+ TAILQ_INSERT_TAIL(&files, f, f_link);
+
+ *ptr = f;
+ return (f->f_id);
}
static void
@@ -95,12 +143,11 @@ open(const char *fname, int mode)
int fd, i, error, besterror;
const char *file;
- if ((fd = o_gethandle()) == -1) {
+ if ((fd = o_gethandle(&f)) == -1) {
errno = EMFILE;
return (-1);
}
- f = &files[fd];
f->f_flags = mode + 1;
f->f_dev = NULL;
f->f_ops = NULL;
diff --git a/usr/src/boot/lib/libstand/read.c b/usr/src/boot/lib/libstand/read.c
index 41e94a4f8b..ebbc082705 100644
--- a/usr/src/boot/lib/libstand/read.c
+++ b/usr/src/boot/lib/libstand/read.c
@@ -68,10 +68,11 @@
ssize_t
read(int fd, void *dest, size_t bcount)
{
- struct open_file *f = &files[fd];
+ struct open_file *f;
size_t resid;
- if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
+ f = fd2open_file(fd);
+ if (f == NULL || !(f->f_flags & F_READ)) {
errno = EBADF;
return (-1);
}
diff --git a/usr/src/boot/lib/libstand/readdir.c b/usr/src/boot/lib/libstand/readdir.c
index e49d93d15e..6920f5b5fe 100644
--- a/usr/src/boot/lib/libstand/readdir.c
+++ b/usr/src/boot/lib/libstand/readdir.c
@@ -25,7 +25,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include "stand.h"
@@ -34,9 +33,10 @@ struct dirent *
readdirfd(int fd)
{
static struct dirent dir; /* XXX not thread safe */
- struct open_file *f = &files[fd];
+ struct open_file *f;
- if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
+ f = fd2open_file(fd);
+ if (f == NULL || !(f->f_flags & F_READ)) {
errno = EBADF;
return (NULL);
}
diff --git a/usr/src/boot/lib/libstand/stand.h b/usr/src/boot/lib/libstand/stand.h
index 1af513b5fa..408ebd73da 100644
--- a/usr/src/boot/lib/libstand/stand.h
+++ b/usr/src/boot/lib/libstand/stand.h
@@ -65,6 +65,7 @@
#include <sys/cdefs.h>
#include <sys/stat.h>
#include <sys/dirent.h>
+#include <sys/queue.h>
/* this header intentionally exports NULL from <string.h> */
#include <string.h>
@@ -183,11 +184,14 @@ struct open_file {
char *f_rabuf; /* readahead buffer pointer */
size_t f_ralen; /* valid data in readahead buffer */
off_t f_raoffset; /* consumer offset in readahead buffer */
+ int f_id; /* file number */
+ TAILQ_ENTRY(open_file) f_link; /* next entry */
#define SOPEN_RASIZE 512
};
-#define SOPEN_MAX 64
-extern struct open_file files[];
+typedef TAILQ_HEAD(file_list, open_file) file_list_t;
+extern file_list_t files;
+extern struct open_file *fd2open_file(int);
/* f_flags values */
#define F_READ 0x0001 /* file opened for reading */
diff --git a/usr/src/boot/lib/libstand/write.c b/usr/src/boot/lib/libstand/write.c
index 86bc162fe5..3edab25428 100644
--- a/usr/src/boot/lib/libstand/write.c
+++ b/usr/src/boot/lib/libstand/write.c
@@ -68,10 +68,11 @@
ssize_t
write(int fd, const void *dest, size_t bcount)
{
- struct open_file *f = &files[fd];
+ struct open_file *f;
size_t resid;
- if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_WRITE)) {
+ f = fd2open_file(fd);
+ if (f == NULL || !(f->f_flags & F_WRITE)) {
errno = EBADF;
return (-1);
}