Print this page
8634 epoll fails to wake on certain edge-triggered conditions
8635 epoll should not emit POLLNVAL
8636 recursive epoll should emit EPOLLRDNORM
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
@@ -19,11 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 1984, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015, Joyent, Inc.
+ * Copyright 2017 Joyent, Inc.
* Copyright (c) 2016 by Delphix. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -2099,15 +2099,11 @@
return (ufs_iaccess(ip, mode, cr, 0));
}
/*ARGSUSED4*/
static int
-ufs_setattr(
- struct vnode *vp,
- struct vattr *vap,
- int flags,
- struct cred *cr,
+ufs_setattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr,
caller_context_t *ct)
{
struct inode *ip = VTOI(vp);
struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
struct fs *fs;
@@ -2615,12 +2611,11 @@
return (error);
}
/* ARGSUSED */
static int
-ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr,
- caller_context_t *ct)
+ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr, caller_context_t *ct)
{
struct inode *ip = VTOI(vp);
struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
struct ulockfs *ulp;
int error;
@@ -3191,12 +3186,12 @@
}
extern int ufs_idle_max;
/*ARGSUSED*/
static int
-ufs_remove(struct vnode *vp, char *nm, struct cred *cr,
- caller_context_t *ct, int flags)
+ufs_remove(struct vnode *vp, char *nm, struct cred *cr, caller_context_t *ct,
+ int flags)
{
struct inode *ip = VTOI(vp);
struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
struct ulockfs *ulp;
vnode_t *rmvp = NULL; /* Vnode corresponding to name being removed */
@@ -3353,18 +3348,12 @@
* can do is always guarantee that the TARGET exists.
*/
/*ARGSUSED*/
static int
-ufs_rename(
- struct vnode *sdvp, /* old (source) parent vnode */
- char *snm, /* old (source) entry name */
- struct vnode *tdvp, /* new (target) parent vnode */
- char *tnm, /* new (target) entry name */
- struct cred *cr,
- caller_context_t *ct,
- int flags)
+ufs_rename(struct vnode *sdvp, char *snm, struct vnode *tdvp, char *tnm,
+ struct cred *cr, caller_context_t *ct, int flags)
{
struct inode *sip = NULL; /* source inode */
struct inode *ip = NULL; /* check inode */
struct inode *sdp; /* old (source) parent inode */
struct inode *tdp; /* new (target) parent inode */
@@ -3899,17 +3888,12 @@
return (error);
}
/* ARGSUSED */
static int
-ufs_readdir(
- struct vnode *vp,
- struct uio *uiop,
- struct cred *cr,
- int *eofp,
- caller_context_t *ct,
- int flags)
+ufs_readdir(struct vnode *vp, struct uio *uiop, struct cred *cr, int *eofp,
+ caller_context_t *ct, int flags)
{
struct iovec *iovp;
struct inode *ip;
struct direct *idp;
struct dirent64 *odp;
@@ -4108,18 +4092,12 @@
return (error);
}
/*ARGSUSED*/
static int
-ufs_symlink(
- struct vnode *dvp, /* ptr to parent dir vnode */
- char *linkname, /* name of symbolic link */
- struct vattr *vap, /* attributes */
- char *target, /* target path */
- struct cred *cr, /* user credentials */
- caller_context_t *ct,
- int flags)
+ufs_symlink(struct vnode *dvp, char *linkname, struct vattr *vap, char *target,
+ struct cred *cr, caller_context_t *ct, int flags)
{
struct inode *ip, *dip = VTOI(dvp);
struct ufsvfs *ufsvfsp = dip->i_ufsvfs;
struct ulockfs *ulp;
int error;
@@ -4431,12 +4409,11 @@
rw_exit(&ip->i_rwlock);
}
/* ARGSUSED */
static int
-ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp,
- caller_context_t *ct)
+ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
{
return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
}
/* ARGSUSED */
@@ -5189,15 +5166,11 @@
* len == MAXBSIZE (from segmap_release actions), and len == PAGESIZE
* (from pageout).
*/
/*ARGSUSED*/
static int
-ufs_putpages(
- struct vnode *vp,
- offset_t off,
- size_t len,
- int flags,
+ufs_putpages(struct vnode *vp, offset_t off, size_t len, int flags,
struct cred *cr)
{
u_offset_t io_off;
u_offset_t eoff;
struct inode *ip = VTOI(vp);
@@ -5364,17 +5337,12 @@
*
* LMXXX - bsize < pagesize not done.
*/
/*ARGSUSED*/
int
-ufs_putapage(
- struct vnode *vp,
- page_t *pp,
- u_offset_t *offp,
- size_t *lenp, /* return values */
- int flags,
- struct cred *cr)
+ufs_putapage(struct vnode *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
+ int flags, struct cred *cr)
{
u_offset_t io_off;
u_offset_t off;
struct inode *ip = VTOI(vp);
struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
@@ -5601,19 +5569,12 @@
uint64_t ufs_map_alock_retry_cnt;
uint64_t ufs_map_lockfs_retry_cnt;
/* ARGSUSED */
static int
-ufs_map(struct vnode *vp,
- offset_t off,
- struct as *as,
- caddr_t *addrp,
- size_t len,
- uchar_t prot,
- uchar_t maxprot,
- uint_t flags,
- struct cred *cr,
+ufs_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr,
caller_context_t *ct)
{
struct segvn_crargs vn_a;
struct ufsvfs *ufsvfsp = VTOI(vp)->i_ufsvfs;
struct ulockfs *ulp;
@@ -5726,20 +5687,13 @@
return (error);
}
/* ARGSUSED */
static int
-ufs_addmap(struct vnode *vp,
- offset_t off,
- struct as *as,
- caddr_t addr,
- size_t len,
- uchar_t prot,
- uchar_t maxprot,
- uint_t flags,
- struct cred *cr,
- caller_context_t *ct)
+ufs_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
+ struct cred *cr, caller_context_t *ct)
{
struct inode *ip = VTOI(vp);
if (vp->v_flag & VNOMAP) {
return (ENOSYS);
@@ -5752,12 +5706,12 @@
}
/*ARGSUSED*/
static int
ufs_delmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
- size_t len, uint_t prot, uint_t maxprot, uint_t flags,
- struct cred *cr, caller_context_t *ct)
+ size_t len, uint_t prot, uint_t maxprot, uint_t flags, struct cred *cr,
+ caller_context_t *ct)
{
struct inode *ip = VTOI(vp);
if (vp->v_flag & VNOMAP) {
return (ENOSYS);
@@ -5779,10 +5733,18 @@
ufs_poll(vnode_t *vp, short ev, int any, short *revp, struct pollhead **phpp,
caller_context_t *ct)
{
struct ufsvfs *ufsvfsp;
+ /*
+ * Regular files reject edge-triggered pollers.
+ * See the comment in fs_poll() for a more detailed explanation.
+ */
+ if (ev & POLLET) {
+ return (EPERM);
+ }
+
*revp = 0;
ufsvfsp = VTOI(vp)->i_ufsvfs;
if (!ufsvfsp) {
*revp = POLLHUP;
@@ -5813,11 +5775,13 @@
}
if ((ev & POLLPRI) && (*revp & (POLLERR|POLLHUP)))
*revp |= POLLPRI;
out:
- *phpp = !any && !*revp ? &ufs_pollhd : (struct pollhead *)NULL;
+ if (*revp == 0 && ! any) {
+ *phpp = &ufs_pollhd;
+ }
return (0);
}
/* ARGSUSED */