summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/fio.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/fio.c')
-rw-r--r--usr/src/uts/common/os/fio.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/usr/src/uts/common/os/fio.c b/usr/src/uts/common/os/fio.c
index 76eddd4e50..41e7e63d2b 100644
--- a/usr/src/uts/common/os/fio.c
+++ b/usr/src/uts/common/os/fio.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015, Joyent Inc.
+ * Copyright 2017, Joyent Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -386,6 +386,7 @@ flist_grow(int maxfd)
dst->uf_flag = src->uf_flag;
dst->uf_busy = src->uf_busy;
dst->uf_portfd = src->uf_portfd;
+ dst->uf_gen = src->uf_gen;
}
/*
@@ -487,7 +488,7 @@ free_afd(afd_t *afd) /* called below and from thread_free() */
afd->a_fd[i] = -1;
}
-static void
+void
set_active_fd(int fd)
{
afd_t *afd = &curthread->t_activefd;
@@ -575,13 +576,12 @@ is_active_fd(kthread_t *t, int fd)
}
/*
- * Convert a user supplied file descriptor into a pointer to a file
- * structure. Only task is to check range of the descriptor (soft
- * resource limit was enforced at open time and shouldn't be checked
- * here).
+ * Convert a user supplied file descriptor into a pointer to a file structure.
+ * Only task is to check range of the descriptor (soft resource limit was
+ * enforced at open time and shouldn't be checked here).
*/
file_t *
-getf(int fd)
+getf_gen(int fd, uf_entry_gen_t *genp)
{
uf_info_t *fip = P_FINFO(curproc);
uf_entry_t *ufp;
@@ -607,6 +607,9 @@ getf(int fd)
return (NULL);
}
ufp->uf_refcnt++;
+ if (genp != NULL) {
+ *genp = ufp->uf_gen;
+ }
set_active_fd(fd); /* record the active file descriptor */
@@ -615,6 +618,12 @@ getf(int fd)
return (fp);
}
+file_t *
+getf(int fd)
+{
+ return (getf_gen(fd, NULL));
+}
+
/*
* Close whatever file currently occupies the file descriptor slot
* and install the new file, usually NULL, in the file descriptor slot.
@@ -667,6 +676,7 @@ closeandsetf(int fd, file_t *newfp)
ASSERT(ufp->uf_flag == 0);
fd_reserve(fip, fd, 1);
ufp->uf_file = newfp;
+ ufp->uf_gen++;
UF_EXIT(ufp);
mutex_exit(&fip->fi_lock);
return (0);
@@ -852,7 +862,8 @@ flist_fork(uf_info_t *pfip, uf_info_t *cfip)
*/
cfip->fi_nfiles = nfiles = flist_minsize(pfip);
- cfip->fi_list = kmem_zalloc(nfiles * sizeof (uf_entry_t), KM_SLEEP);
+ cfip->fi_list = nfiles == 0 ? NULL :
+ kmem_zalloc(nfiles * sizeof (uf_entry_t), KM_SLEEP);
for (fd = 0, pufp = pfip->fi_list, cufp = cfip->fi_list; fd < nfiles;
fd++, pufp++, cufp++) {
@@ -860,6 +871,7 @@ flist_fork(uf_info_t *pfip, uf_info_t *cfip)
cufp->uf_alloc = pufp->uf_alloc;
cufp->uf_flag = pufp->uf_flag;
cufp->uf_busy = pufp->uf_busy;
+ cufp->uf_gen = pufp->uf_gen;
if (pufp->uf_file == NULL) {
ASSERT(pufp->uf_flag == 0);
if (pufp->uf_busy) {
@@ -1028,6 +1040,9 @@ ufalloc_file(int start, file_t *fp)
fd_reserve(fip, fd, 1);
ASSERT(ufp->uf_file == NULL);
ufp->uf_file = fp;
+ if (fp != NULL) {
+ ufp->uf_gen++;
+ }
UF_EXIT(ufp);
mutex_exit(&fip->fi_lock);
return (fd);
@@ -1183,6 +1198,7 @@ setf(int fd, file_t *fp)
} else {
UF_ENTER(ufp, fip, fd);
ASSERT(ufp->uf_busy);
+ ufp->uf_gen++;
}
ASSERT(ufp->uf_fpollinfo == NULL);
ASSERT(ufp->uf_flag == 0);
@@ -1212,8 +1228,7 @@ f_getfl(int fd, int *flagp)
error = EBADF;
else {
vnode_t *vp = fp->f_vnode;
- int flag = fp->f_flag |
- ((fp->f_flag2 & ~FEPOLLED) << 16);
+ int flag = fp->f_flag | (fp->f_flag2 << 16);
/*
* BSD fcntl() FASYNC compatibility.