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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/ufs/ufs_vnops.c
          +++ new/usr/src/uts/common/fs/ufs/ufs_vnops.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1984, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2015, Joyent, Inc.
       24 + * Copyright 2017 Joyent, Inc.
  25   25   * Copyright (c) 2016 by Delphix. All rights reserved.
  26   26   */
  27   27  
  28   28  /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
  29   29  /*        All Rights Reserved   */
  30   30  
  31   31  /*
  32   32   * Portions of this source code were derived from Berkeley 4.3 BSD
  33   33   * under license from the Regents of the University of California.
  34   34   */
↓ open down ↓ 233 lines elided ↑ open up ↑
 268  268  /* ARGSUSED */
 269  269  static int
 270  270  ufs_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *ct)
 271  271  {
 272  272          return (0);
 273  273  }
 274  274  
 275  275  /*ARGSUSED*/
 276  276  static int
 277  277  ufs_close(struct vnode *vp, int flag, int count, offset_t offset,
 278      -        struct cred *cr, caller_context_t *ct)
      278 +    struct cred *cr, caller_context_t *ct)
 279  279  {
 280  280          cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
 281  281          cleanshares(vp, ttoproc(curthread)->p_pid);
 282  282  
 283  283          /*
 284  284           * Push partially filled cluster at last close.
 285  285           * ``last close'' is approximated because the dnlc
 286  286           * may have a hold on the vnode.
 287  287           * Checking for VBAD here will also act as a forced umount check.
 288  288           */
↓ open down ↓ 6 lines elided ↑ open up ↑
 295  295                          ip->i_delaylen = 0;
 296  296                  }
 297  297          }
 298  298  
 299  299          return (0);
 300  300  }
 301  301  
 302  302  /*ARGSUSED*/
 303  303  static int
 304  304  ufs_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr,
 305      -        struct caller_context *ct)
      305 +    struct caller_context *ct)
 306  306  {
 307  307          struct inode *ip = VTOI(vp);
 308  308          struct ufsvfs *ufsvfsp;
 309  309          struct ulockfs *ulp = NULL;
 310  310          int error = 0;
 311  311          int intrans = 0;
 312  312  
 313  313          ASSERT(RW_READ_HELD(&ip->i_rwlock));
 314  314  
 315  315          /*
↓ open down ↓ 109 lines elided ↑ open up ↑
 425  425              (uiop->uio_loffset >= (offset_t)0) &&
 426  426              (uiop->uio_loffset < ip->i_size) && (uiop->uio_resid > 0) &&
 427  427              ((ip->i_size - uiop->uio_loffset) >= uiop->uio_resid) &&
 428  428              !(ioflag & FSYNC) && !bmap_has_holes(ip) &&
 429  429              shared_write);
 430  430  }
 431  431  
 432  432  /*ARGSUSED*/
 433  433  static int
 434  434  ufs_write(struct vnode *vp, struct uio *uiop, int ioflag, cred_t *cr,
 435      -        caller_context_t *ct)
      435 +    caller_context_t *ct)
 436  436  {
 437  437          struct inode *ip = VTOI(vp);
 438  438          struct ufsvfs *ufsvfsp;
 439  439          struct ulockfs *ulp;
 440  440          int retry = 1;
 441  441          int error, resv, resid = 0;
 442  442          int directio_status;
 443  443          int exclusive;
 444  444          int rewriteflg;
 445  445          long start_resid = uiop->uio_resid;
↓ open down ↓ 1540 lines elided ↑ open up ↑
1986 1986  
1987 1987                  default:
1988 1988                          return (ENOTTY);
1989 1989          }
1990 1990  }
1991 1991  
1992 1992  
1993 1993  /* ARGSUSED */
1994 1994  static int
1995 1995  ufs_getattr(struct vnode *vp, struct vattr *vap, int flags,
1996      -        struct cred *cr, caller_context_t *ct)
     1996 +    struct cred *cr, caller_context_t *ct)
1997 1997  {
1998 1998          struct inode *ip = VTOI(vp);
1999 1999          struct ufsvfs *ufsvfsp;
2000 2000          int err;
2001 2001  
2002 2002          if (vap->va_mask == AT_SIZE) {
2003 2003                  /*
2004 2004                   * for performance, if only the size is requested don't bother
2005 2005                   * with anything else.
2006 2006                   */
↓ open down ↓ 87 lines elided ↑ open up ↑
2094 2094  static int
2095 2095  ufs_priv_access(void *vip, int mode, struct cred *cr)
2096 2096  {
2097 2097          struct inode *ip = vip;
2098 2098  
2099 2099          return (ufs_iaccess(ip, mode, cr, 0));
2100 2100  }
2101 2101  
2102 2102  /*ARGSUSED4*/
2103 2103  static int
2104      -ufs_setattr(
2105      -        struct vnode *vp,
2106      -        struct vattr *vap,
2107      -        int flags,
2108      -        struct cred *cr,
2109      -        caller_context_t *ct)
     2104 +ufs_setattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cr,
     2105 +    caller_context_t *ct)
2110 2106  {
2111 2107          struct inode *ip = VTOI(vp);
2112 2108          struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
2113 2109          struct fs *fs;
2114 2110          struct ulockfs *ulp;
2115 2111          char *errmsg1;
2116 2112          char *errmsg2;
2117 2113          long blocks;
2118 2114          long int mask = vap->va_mask;
2119 2115          size_t len1, len2;
↓ open down ↓ 311 lines elided ↑ open up ↑
2431 2427          if (errmsg2 != NULL) {
2432 2428                  uprintf(errmsg2);
2433 2429                  kmem_free(errmsg2, len2);
2434 2430          }
2435 2431          return (error);
2436 2432  }
2437 2433  
2438 2434  /*ARGSUSED*/
2439 2435  static int
2440 2436  ufs_access(struct vnode *vp, int mode, int flags, struct cred *cr,
2441      -        caller_context_t *ct)
     2437 +    caller_context_t *ct)
2442 2438  {
2443 2439          struct inode *ip = VTOI(vp);
2444 2440  
2445 2441          if (ip->i_ufsvfs == NULL)
2446 2442                  return (EIO);
2447 2443  
2448 2444          /*
2449 2445           * The ufs_iaccess function wants to be called with
2450 2446           * mode bits expressed as "ufs specific" bits.
2451 2447           * I.e., VWRITE|VREAD|VEXEC do not make sense to
↓ open down ↓ 3 lines elided ↑ open up ↑
2455 2451           */
2456 2452  #if IWRITE != VWRITE || IREAD != VREAD || IEXEC != VEXEC
2457 2453  #error "ufs_access needs to map Vmodes to Imodes"
2458 2454  #endif
2459 2455          return (ufs_iaccess(ip, mode, cr, 1));
2460 2456  }
2461 2457  
2462 2458  /* ARGSUSED */
2463 2459  static int
2464 2460  ufs_readlink(struct vnode *vp, struct uio *uiop, struct cred *cr,
2465      -        caller_context_t *ct)
     2461 +    caller_context_t *ct)
2466 2462  {
2467 2463          struct inode *ip = VTOI(vp);
2468 2464          struct ufsvfs *ufsvfsp;
2469 2465          struct ulockfs *ulp;
2470 2466          int error;
2471 2467          int fastsymlink;
2472 2468  
2473 2469          if (vp->v_type != VLNK) {
2474 2470                  error = EINVAL;
2475 2471                  goto nolockout;
↓ open down ↓ 134 lines elided ↑ open up ↑
2610 2606  out:
2611 2607          if (ulp) {
2612 2608                  ufs_lockfs_end(ulp);
2613 2609          }
2614 2610  nolockout:
2615 2611          return (error);
2616 2612  }
2617 2613  
2618 2614  /* ARGSUSED */
2619 2615  static int
2620      -ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr,
2621      -        caller_context_t *ct)
     2616 +ufs_fsync(struct vnode *vp, int syncflag, struct cred *cr, caller_context_t *ct)
2622 2617  {
2623 2618          struct inode *ip = VTOI(vp);
2624 2619          struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
2625 2620          struct ulockfs *ulp;
2626 2621          int error;
2627 2622  
2628 2623          error = ufs_lockfs_begin(ufsvfsp, &ulp, ULOCKFS_FSYNC_MASK);
2629 2624          if (error)
2630 2625                  return (error);
2631 2626  
↓ open down ↓ 84 lines elided ↑ open up ↑
2716 2711          ufs_iinactive(VTOI(vp));
2717 2712  }
2718 2713  
2719 2714  /*
2720 2715   * Unix file system operations having to do with directory manipulation.
2721 2716   */
2722 2717  int ufs_lookup_idle_count = 2;  /* Number of inodes to idle each time */
2723 2718  /* ARGSUSED */
2724 2719  static int
2725 2720  ufs_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
2726      -        struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr,
2727      -        caller_context_t *ct, int *direntflags, pathname_t *realpnp)
     2721 +    struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cr,
     2722 +    caller_context_t *ct, int *direntflags, pathname_t *realpnp)
2728 2723  {
2729 2724          struct inode *ip;
2730 2725          struct inode *sip;
2731 2726          struct inode *xip;
2732 2727          struct ufsvfs *ufsvfsp;
2733 2728          struct ulockfs *ulp;
2734 2729          struct vnode *vp;
2735 2730          int error;
2736 2731  
2737 2732          /*
↓ open down ↓ 163 lines elided ↑ open up ↑
2901 2896          if (error == EAGAIN)
2902 2897                  goto retry_lookup;
2903 2898  
2904 2899  out:
2905 2900          return (error);
2906 2901  }
2907 2902  
2908 2903  /*ARGSUSED*/
2909 2904  static int
2910 2905  ufs_create(struct vnode *dvp, char *name, struct vattr *vap, enum vcexcl excl,
2911      -        int mode, struct vnode **vpp, struct cred *cr, int flag,
2912      -        caller_context_t *ct, vsecattr_t *vsecp)
     2906 +    int mode, struct vnode **vpp, struct cred *cr, int flag,
     2907 +    caller_context_t *ct, vsecattr_t *vsecp)
2913 2908  {
2914 2909          struct inode *ip;
2915 2910          struct inode *xip;
2916 2911          struct inode *dip;
2917 2912          struct vnode *xvp;
2918 2913          struct ufsvfs *ufsvfsp;
2919 2914          struct ulockfs *ulp;
2920 2915          int error;
2921 2916          int issync;
2922 2917          int truncflag;
↓ open down ↓ 263 lines elided ↑ open up ↑
3186 3181                  goto again;
3187 3182          }
3188 3183  
3189 3184  out:
3190 3185          return (error);
3191 3186  }
3192 3187  
3193 3188  extern int ufs_idle_max;
3194 3189  /*ARGSUSED*/
3195 3190  static int
3196      -ufs_remove(struct vnode *vp, char *nm, struct cred *cr,
3197      -        caller_context_t *ct, int flags)
     3191 +ufs_remove(struct vnode *vp, char *nm, struct cred *cr, caller_context_t *ct,
     3192 +    int flags)
3198 3193  {
3199 3194          struct inode *ip = VTOI(vp);
3200 3195          struct ufsvfs *ufsvfsp  = ip->i_ufsvfs;
3201 3196          struct ulockfs *ulp;
3202 3197          vnode_t *rmvp = NULL;   /* Vnode corresponding to name being removed */
3203 3198          int indeadlock;
3204 3199          int error;
3205 3200          int issync;
3206 3201          int trans_size;
3207 3202  
↓ open down ↓ 45 lines elided ↑ open up ↑
3253 3248          return (error);
3254 3249  }
3255 3250  
3256 3251  /*
3257 3252   * Link a file or a directory.  Only privileged processes are allowed to
3258 3253   * make links to directories.
3259 3254   */
3260 3255  /*ARGSUSED*/
3261 3256  static int
3262 3257  ufs_link(struct vnode *tdvp, struct vnode *svp, char *tnm, struct cred *cr,
3263      -        caller_context_t *ct, int flags)
     3258 +    caller_context_t *ct, int flags)
3264 3259  {
3265 3260          struct inode *sip;
3266 3261          struct inode *tdp = VTOI(tdvp);
3267 3262          struct ufsvfs *ufsvfsp = tdp->i_ufsvfs;
3268 3263          struct ulockfs *ulp;
3269 3264          struct vnode *realvp;
3270 3265          int error;
3271 3266          int issync;
3272 3267          int trans_size;
3273 3268          int isdev;
↓ open down ↓ 74 lines elided ↑ open up ↑
3348 3343   *      unlink(target);
3349 3344   *      link(source, target);
3350 3345   *      unlink(source);
3351 3346   * but "atomically".  Can't do full commit without saving state in
3352 3347   * the inode on disk, which isn't feasible at this time.  Best we
3353 3348   * can do is always guarantee that the TARGET exists.
3354 3349   */
3355 3350  
3356 3351  /*ARGSUSED*/
3357 3352  static int
3358      -ufs_rename(
3359      -        struct vnode *sdvp,             /* old (source) parent vnode */
3360      -        char *snm,                      /* old (source) entry name */
3361      -        struct vnode *tdvp,             /* new (target) parent vnode */
3362      -        char *tnm,                      /* new (target) entry name */
3363      -        struct cred *cr,
3364      -        caller_context_t *ct,
3365      -        int flags)
     3353 +ufs_rename(struct vnode *sdvp, char *snm, struct vnode *tdvp, char *tnm,
     3354 +    struct cred *cr, caller_context_t *ct, int flags)
3366 3355  {
3367 3356          struct inode *sip = NULL;       /* source inode */
3368 3357          struct inode *ip = NULL;        /* check inode */
3369 3358          struct inode *sdp;              /* old (source) parent inode */
3370 3359          struct inode *tdp;              /* new (target) parent inode */
3371 3360          struct vnode *svp = NULL;       /* source vnode */
3372 3361          struct vnode *tvp = NULL;       /* target vnode, if it exists */
3373 3362          struct vnode *realvp;
3374 3363          struct ufsvfs *ufsvfsp;
3375 3364          struct ulockfs *ulp = NULL;
↓ open down ↓ 378 lines elided ↑ open up ↑
3754 3743                  TRANS_END_CSYNC(ufsvfsp, error, issync, TOP_RENAME, trans_size);
3755 3744                  ufs_lockfs_end(ulp);
3756 3745          }
3757 3746  
3758 3747          return (error);
3759 3748  }
3760 3749  
3761 3750  /*ARGSUSED*/
3762 3751  static int
3763 3752  ufs_mkdir(struct vnode *dvp, char *dirname, struct vattr *vap,
3764      -        struct vnode **vpp, struct cred *cr, caller_context_t *ct, int flags,
3765      -        vsecattr_t *vsecp)
     3753 +    struct vnode **vpp, struct cred *cr, caller_context_t *ct, int flags,
     3754 +    vsecattr_t *vsecp)
3766 3755  {
3767 3756          struct inode *ip;
3768 3757          struct inode *xip;
3769 3758          struct ufsvfs *ufsvfsp;
3770 3759          struct ulockfs *ulp;
3771 3760          int error;
3772 3761          int issync;
3773 3762          int trans_size;
3774 3763          int indeadlock;
3775 3764          int retry = 1;
↓ open down ↓ 56 lines elided ↑ open up ↑
3832 3821                  retry = 0;
3833 3822                  goto again;
3834 3823          }
3835 3824  
3836 3825          return (error);
3837 3826  }
3838 3827  
3839 3828  /*ARGSUSED*/
3840 3829  static int
3841 3830  ufs_rmdir(struct vnode *vp, char *nm, struct vnode *cdir, struct cred *cr,
3842      -        caller_context_t *ct, int flags)
     3831 +    caller_context_t *ct, int flags)
3843 3832  {
3844 3833          struct inode *ip = VTOI(vp);
3845 3834          struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
3846 3835          struct ulockfs *ulp;
3847 3836          vnode_t *rmvp = NULL;   /* Vnode of removed directory */
3848 3837          int error;
3849 3838          int issync;
3850 3839          int trans_size;
3851 3840          int indeadlock;
3852 3841  
↓ open down ↓ 41 lines elided ↑ open up ↑
3894 3883                      trans_size);
3895 3884                  ufs_lockfs_end(ulp);
3896 3885          }
3897 3886  
3898 3887  out:
3899 3888          return (error);
3900 3889  }
3901 3890  
3902 3891  /* ARGSUSED */
3903 3892  static int
3904      -ufs_readdir(
3905      -        struct vnode *vp,
3906      -        struct uio *uiop,
3907      -        struct cred *cr,
3908      -        int *eofp,
3909      -        caller_context_t *ct,
3910      -        int flags)
     3893 +ufs_readdir(struct vnode *vp, struct uio *uiop, struct cred *cr, int *eofp,
     3894 +    caller_context_t *ct, int flags)
3911 3895  {
3912 3896          struct iovec *iovp;
3913 3897          struct inode *ip;
3914 3898          struct direct *idp;
3915 3899          struct dirent64 *odp;
3916 3900          struct fbuf *fbp;
3917 3901          struct ufsvfs *ufsvfsp;
3918 3902          struct ulockfs *ulp;
3919 3903          caddr_t outbuf;
3920 3904          size_t bufsize;
↓ open down ↓ 182 lines elided ↑ open up ↑
4103 4087  unlock:
4104 4088          if (ulp) {
4105 4089                  ufs_lockfs_end(ulp);
4106 4090          }
4107 4091  out:
4108 4092          return (error);
4109 4093  }
4110 4094  
4111 4095  /*ARGSUSED*/
4112 4096  static int
4113      -ufs_symlink(
4114      -        struct vnode *dvp,              /* ptr to parent dir vnode */
4115      -        char *linkname,                 /* name of symbolic link */
4116      -        struct vattr *vap,              /* attributes */
4117      -        char *target,                   /* target path */
4118      -        struct cred *cr,                /* user credentials */
4119      -        caller_context_t *ct,
4120      -        int flags)
     4097 +ufs_symlink(struct vnode *dvp, char *linkname, struct vattr *vap, char *target,
     4098 +    struct cred *cr, caller_context_t *ct, int flags)
4121 4099  {
4122 4100          struct inode *ip, *dip = VTOI(dvp);
4123 4101          struct ufsvfs *ufsvfsp = dip->i_ufsvfs;
4124 4102          struct ulockfs *ulp;
4125 4103          int error;
4126 4104          int issync;
4127 4105          int trans_size;
4128 4106          int residual;
4129 4107          int ioflag;
4130 4108          int retry = 1;
↓ open down ↓ 162 lines elided ↑ open up ↑
4293 4271  
4294 4272  out:
4295 4273          return (error);
4296 4274  }
4297 4275  
4298 4276  /*
4299 4277   * Ufs specific routine used to do ufs io.
4300 4278   */
4301 4279  int
4302 4280  ufs_rdwri(enum uio_rw rw, int ioflag, struct inode *ip, caddr_t base,
4303      -        ssize_t len, offset_t offset, enum uio_seg seg, int *aresid,
4304      -        struct cred *cr)
     4281 +    ssize_t len, offset_t offset, enum uio_seg seg, int *aresid,
     4282 +    struct cred *cr)
4305 4283  {
4306 4284          struct uio auio;
4307 4285          struct iovec aiov;
4308 4286          int error;
4309 4287  
4310 4288          ASSERT(RW_LOCK_HELD(&ip->i_contents));
4311 4289  
4312 4290          bzero((caddr_t)&auio, sizeof (uio_t));
4313 4291          bzero((caddr_t)&aiov, sizeof (iovec_t));
4314 4292  
↓ open down ↓ 111 lines elided ↑ open up ↑
4426 4404  static void
4427 4405  ufs_rwunlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
4428 4406  {
4429 4407          struct inode    *ip = VTOI(vp);
4430 4408  
4431 4409          rw_exit(&ip->i_rwlock);
4432 4410  }
4433 4411  
4434 4412  /* ARGSUSED */
4435 4413  static int
4436      -ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp,
4437      -        caller_context_t *ct)
     4414 +ufs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
4438 4415  {
4439 4416          return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
4440 4417  }
4441 4418  
4442 4419  /* ARGSUSED */
4443 4420  static int
4444 4421  ufs_frlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
4445      -        offset_t offset, struct flk_callback *flk_cbp, struct cred *cr,
4446      -        caller_context_t *ct)
     4422 +    offset_t offset, struct flk_callback *flk_cbp, struct cred *cr,
     4423 +    caller_context_t *ct)
4447 4424  {
4448 4425          struct inode *ip = VTOI(vp);
4449 4426  
4450 4427          if (ip->i_ufsvfs == NULL)
4451 4428                  return (EIO);
4452 4429  
4453 4430          /*
4454 4431           * If file is being mapped, disallow frlock.
4455 4432           * XXX I am not holding tlock while checking i_mapcnt because the
4456 4433           * current locking strategy drops all locks before calling fs_frlock.
↓ open down ↓ 1 lines elided ↑ open up ↑
4458 4435           * meaningless to have held tlock in the first place.
4459 4436           */
4460 4437          if (ip->i_mapcnt > 0 && MANDLOCK(vp, ip->i_mode))
4461 4438                  return (EAGAIN);
4462 4439          return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct));
4463 4440  }
4464 4441  
4465 4442  /* ARGSUSED */
4466 4443  static int
4467 4444  ufs_space(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
4468      -        offset_t offset, cred_t *cr, caller_context_t *ct)
     4445 +    offset_t offset, cred_t *cr, caller_context_t *ct)
4469 4446  {
4470 4447          struct ufsvfs *ufsvfsp = VTOI(vp)->i_ufsvfs;
4471 4448          struct ulockfs *ulp;
4472 4449          int error;
4473 4450  
4474 4451          if ((error = convoff(vp, bfp, 0, offset)) == 0) {
4475 4452                  if (cmd == F_FREESP) {
4476 4453                          error = ufs_lockfs_begin(ufsvfsp, &ulp,
4477 4454                              ULOCKFS_SPACE_MASK);
4478 4455                          if (error)
↓ open down ↓ 41 lines elided ↑ open up ↑
4520 4497   *       protected by any mutex. The read ahead will act wild if
4521 4498   *       multiple processes will access the file concurrently and
4522 4499   *       some of them in sequential mode. One particulary bad case
4523 4500   *       is if another thread will change the value of i_nextrio between
4524 4501   *       the time this thread tests the i_nextrio value and then reads it
4525 4502   *       again to use it as the offset for the read ahead.
4526 4503   */
4527 4504  /*ARGSUSED*/
4528 4505  static int
4529 4506  ufs_getpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp,
4530      -        page_t *plarr[], size_t plsz, struct seg *seg, caddr_t addr,
4531      -        enum seg_rw rw, struct cred *cr, caller_context_t *ct)
     4507 +    page_t *plarr[], size_t plsz, struct seg *seg, caddr_t addr,
     4508 +    enum seg_rw rw, struct cred *cr, caller_context_t *ct)
4532 4509  {
4533 4510          u_offset_t      uoff = (u_offset_t)off; /* type conversion */
4534 4511          u_offset_t      pgoff;
4535 4512          u_offset_t      eoff;
4536 4513          struct inode    *ip = VTOI(vp);
4537 4514          struct ufsvfs   *ufsvfsp = ip->i_ufsvfs;
4538 4515          struct fs       *fs;
4539 4516          struct ulockfs  *ulp;
4540 4517          page_t          **pl;
4541 4518          caddr_t         pgaddr;
↓ open down ↓ 342 lines elided ↑ open up ↑
4884 4861  
4885 4862  /*
4886 4863   * ufs_getpage_miss is called when ufs_getpage missed the page in the page
4887 4864   * cache. The page is either read from the disk, or it's created.
4888 4865   * A page is created (without disk read) if rw == S_CREATE, or if
4889 4866   * the page is not backed with a real disk block (UFS hole).
4890 4867   */
4891 4868  /* ARGSUSED */
4892 4869  static int
4893 4870  ufs_getpage_miss(struct vnode *vp, u_offset_t off, size_t len, struct seg *seg,
4894      -        caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw, int seq)
     4871 +    caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw, int seq)
4895 4872  {
4896 4873          struct inode    *ip = VTOI(vp);
4897 4874          page_t          *pp;
4898 4875          daddr_t         bn;
4899 4876          size_t          io_len;
4900 4877          int             crpage = 0;
4901 4878          int             err;
4902 4879          int             contig;
4903 4880          int             bsize = ip->i_fs->fs_bsize;
4904 4881  
↓ open down ↓ 197 lines elided ↑ open up ↑
5102 5079  /*
5103 5080   * Flags are composed of {B_INVAL, B_FREE, B_DONTNEED, B_FORCE, B_ASYNC}
5104 5081   *
5105 5082   * LMXXX - the inode really ought to contain a pointer to one of these
5106 5083   * async args.  Stuff gunk in there and just hand the whole mess off.
5107 5084   * This would replace i_delaylen, i_delayoff.
5108 5085   */
5109 5086  /*ARGSUSED*/
5110 5087  static int
5111 5088  ufs_putpage(struct vnode *vp, offset_t off, size_t len, int flags,
5112      -        struct cred *cr, caller_context_t *ct)
     5089 +    struct cred *cr, caller_context_t *ct)
5113 5090  {
5114 5091          struct inode *ip = VTOI(vp);
5115 5092          int err = 0;
5116 5093  
5117 5094          if (vp->v_count == 0) {
5118 5095                  return (ufs_fault(vp, "ufs_putpage: bad v_count == 0"));
5119 5096          }
5120 5097  
5121 5098          /*
5122 5099           * XXX - Why should this check be made here?
↓ open down ↓ 61 lines elided ↑ open up ↑
5184 5161  
5185 5162  /*
5186 5163   * If len == 0, do from off to EOF.
5187 5164   *
5188 5165   * The normal cases should be len == 0 & off == 0 (entire vp list),
5189 5166   * len == MAXBSIZE (from segmap_release actions), and len == PAGESIZE
5190 5167   * (from pageout).
5191 5168   */
5192 5169  /*ARGSUSED*/
5193 5170  static int
5194      -ufs_putpages(
5195      -        struct vnode *vp,
5196      -        offset_t off,
5197      -        size_t len,
5198      -        int flags,
5199      -        struct cred *cr)
     5171 +ufs_putpages(struct vnode *vp, offset_t off, size_t len, int flags,
     5172 +    struct cred *cr)
5200 5173  {
5201 5174          u_offset_t io_off;
5202 5175          u_offset_t eoff;
5203 5176          struct inode *ip = VTOI(vp);
5204 5177          page_t *pp;
5205 5178          size_t io_len;
5206 5179          int err = 0;
5207 5180          int dolock;
5208 5181  
5209 5182          if (vp->v_count == 0)
↓ open down ↓ 149 lines elided ↑ open up ↑
5359 5332  }
5360 5333  
5361 5334  /*
5362 5335   * Write out a single page, possibly klustering adjacent
5363 5336   * dirty pages.  The inode lock must be held.
5364 5337   *
5365 5338   * LMXXX - bsize < pagesize not done.
5366 5339   */
5367 5340  /*ARGSUSED*/
5368 5341  int
5369      -ufs_putapage(
5370      -        struct vnode *vp,
5371      -        page_t *pp,
5372      -        u_offset_t *offp,
5373      -        size_t *lenp,           /* return values */
5374      -        int flags,
5375      -        struct cred *cr)
     5342 +ufs_putapage(struct vnode *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
     5343 +    int flags, struct cred *cr)
5376 5344  {
5377 5345          u_offset_t io_off;
5378 5346          u_offset_t off;
5379 5347          struct inode *ip = VTOI(vp);
5380 5348          struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
5381 5349          struct fs *fs;
5382 5350          struct buf *bp;
5383 5351          size_t io_len;
5384 5352          daddr_t bn;
5385 5353          int err;
↓ open down ↓ 210 lines elided ↑ open up ↑
5596 5564                  *lenp = io_len;
5597 5565  out_trace:
5598 5566          return (err);
5599 5567  }
5600 5568  
5601 5569  uint64_t ufs_map_alock_retry_cnt;
5602 5570  uint64_t ufs_map_lockfs_retry_cnt;
5603 5571  
5604 5572  /* ARGSUSED */
5605 5573  static int
5606      -ufs_map(struct vnode *vp,
5607      -        offset_t off,
5608      -        struct as *as,
5609      -        caddr_t *addrp,
5610      -        size_t len,
5611      -        uchar_t prot,
5612      -        uchar_t maxprot,
5613      -        uint_t flags,
5614      -        struct cred *cr,
5615      -        caller_context_t *ct)
     5574 +ufs_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
     5575 +    size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, struct cred *cr,
     5576 +    caller_context_t *ct)
5616 5577  {
5617 5578          struct segvn_crargs vn_a;
5618 5579          struct ufsvfs *ufsvfsp = VTOI(vp)->i_ufsvfs;
5619 5580          struct ulockfs *ulp;
5620 5581          int error, sig;
5621 5582          k_sigset_t smask;
5622 5583          caddr_t hint = *addrp;
5623 5584  
5624 5585          if (vp->v_flag & VNOMAP) {
5625 5586                  error = ENOSYS;
↓ open down ↓ 95 lines elided ↑ open up ↑
5721 5682          error = as_map_locked(as, *addrp, len, segvn_create, &vn_a);
5722 5683          if (ulp)
5723 5684                  ufs_lockfs_end(ulp);
5724 5685          as_rangeunlock(as);
5725 5686  out:
5726 5687          return (error);
5727 5688  }
5728 5689  
5729 5690  /* ARGSUSED */
5730 5691  static int
5731      -ufs_addmap(struct vnode *vp,
5732      -        offset_t off,
5733      -        struct as *as,
5734      -        caddr_t addr,
5735      -        size_t  len,
5736      -        uchar_t  prot,
5737      -        uchar_t  maxprot,
5738      -        uint_t    flags,
5739      -        struct cred *cr,
5740      -        caller_context_t *ct)
     5692 +ufs_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
     5693 +    size_t len, uchar_t  prot, uchar_t  maxprot, uint_t    flags,
     5694 +    struct cred *cr, caller_context_t *ct)
5741 5695  {
5742 5696          struct inode *ip = VTOI(vp);
5743 5697  
5744 5698          if (vp->v_flag & VNOMAP) {
5745 5699                  return (ENOSYS);
5746 5700          }
5747 5701  
5748 5702          mutex_enter(&ip->i_tlock);
5749 5703          ip->i_mapcnt += btopr(len);
5750 5704          mutex_exit(&ip->i_tlock);
5751 5705          return (0);
5752 5706  }
5753 5707  
5754 5708  /*ARGSUSED*/
5755 5709  static int
5756 5710  ufs_delmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
5757      -        size_t len, uint_t prot,  uint_t maxprot,  uint_t flags,
5758      -        struct cred *cr, caller_context_t *ct)
     5711 +    size_t len, uint_t prot,  uint_t maxprot,  uint_t flags, struct cred *cr,
     5712 +    caller_context_t *ct)
5759 5713  {
5760 5714          struct inode *ip = VTOI(vp);
5761 5715  
5762 5716          if (vp->v_flag & VNOMAP) {
5763 5717                  return (ENOSYS);
5764 5718          }
5765 5719  
5766 5720          mutex_enter(&ip->i_tlock);
5767 5721          ip->i_mapcnt -= btopr(len);     /* Count released mappings */
5768 5722          ASSERT(ip->i_mapcnt >= 0);
↓ open down ↓ 1 lines elided ↑ open up ↑
5770 5724          return (0);
5771 5725  }
5772 5726  /*
5773 5727   * Return the answer requested to poll() for non-device files
5774 5728   */
5775 5729  struct pollhead ufs_pollhd;
5776 5730  
5777 5731  /* ARGSUSED */
5778 5732  int
5779 5733  ufs_poll(vnode_t *vp, short ev, int any, short *revp, struct pollhead **phpp,
5780      -        caller_context_t *ct)
     5734 +    caller_context_t *ct)
5781 5735  {
5782 5736          struct ufsvfs   *ufsvfsp;
5783 5737  
     5738 +        /*
     5739 +         * Regular files reject edge-triggered pollers.
     5740 +         * See the comment in fs_poll() for a more detailed explanation.
     5741 +         */
     5742 +        if (ev & POLLET) {
     5743 +                return (EPERM);
     5744 +        }
     5745 +
5784 5746          *revp = 0;
5785 5747          ufsvfsp = VTOI(vp)->i_ufsvfs;
5786 5748  
5787 5749          if (!ufsvfsp) {
5788 5750                  *revp = POLLHUP;
5789 5751                  goto out;
5790 5752          }
5791 5753  
5792 5754          if (ULOCKFS_IS_HLOCK(&ufsvfsp->vfs_ulockfs) ||
5793 5755              ULOCKFS_IS_ELOCK(&ufsvfsp->vfs_ulockfs)) {
↓ open down ↓ 14 lines elided ↑ open up ↑
5808 5770                  if (ev & POLLRDNORM)
5809 5771                          *revp |= POLLRDNORM;
5810 5772  
5811 5773                  if (ev & POLLRDBAND)
5812 5774                          *revp |= POLLRDBAND;
5813 5775          }
5814 5776  
5815 5777          if ((ev & POLLPRI) && (*revp & (POLLERR|POLLHUP)))
5816 5778                  *revp |= POLLPRI;
5817 5779  out:
5818      -        *phpp = !any && !*revp ? &ufs_pollhd : (struct pollhead *)NULL;
     5780 +        if (*revp == 0 && ! any) {
     5781 +                *phpp = &ufs_pollhd;
     5782 +        }
5819 5783  
5820 5784          return (0);
5821 5785  }
5822 5786  
5823 5787  /* ARGSUSED */
5824 5788  static int
5825 5789  ufs_l_pathconf(struct vnode *vp, int cmd, ulong_t *valp, struct cred *cr,
5826      -        caller_context_t *ct)
     5790 +    caller_context_t *ct)
5827 5791  {
5828 5792          struct ufsvfs   *ufsvfsp = VTOI(vp)->i_ufsvfs;
5829 5793          struct ulockfs  *ulp = NULL;
5830 5794          struct inode    *sip = NULL;
5831 5795          int             error;
5832 5796          struct inode    *ip = VTOI(vp);
5833 5797          int             issync;
5834 5798  
5835 5799          error = ufs_lockfs_begin(ufsvfsp, &ulp, ULOCKFS_PATHCONF_MASK);
5836 5800          if (error)
↓ open down ↓ 93 lines elided ↑ open up ↑
5930 5894                  ufs_lockfs_end(ulp);
5931 5895          }
5932 5896          return (error);
5933 5897  }
5934 5898  
5935 5899  int ufs_pageio_writes, ufs_pageio_reads;
5936 5900  
5937 5901  /*ARGSUSED*/
5938 5902  static int
5939 5903  ufs_pageio(struct vnode *vp, page_t *pp, u_offset_t io_off, size_t io_len,
5940      -        int flags, struct cred *cr, caller_context_t *ct)
     5904 +    int flags, struct cred *cr, caller_context_t *ct)
5941 5905  {
5942 5906          struct inode *ip = VTOI(vp);
5943 5907          struct ufsvfs *ufsvfsp;
5944 5908          page_t *npp = NULL, *opp = NULL, *cpp = pp;
5945 5909          struct buf *bp;
5946 5910          daddr_t bn;
5947 5911          size_t done_len = 0, cur_len = 0;
5948 5912          int err = 0;
5949 5913          int contig = 0;
5950 5914          int dolock;
↓ open down ↓ 460 lines elided ↑ open up ↑
6411 6375  
6412 6376                  if (storeblk == NULL)
6413 6377                          return (NULL);
6414 6378          }
6415 6379          return (storeblk);
6416 6380  }
6417 6381  
6418 6382  /* ARGSUSED */
6419 6383  static int
6420 6384  ufs_getsecattr(struct vnode *vp, vsecattr_t *vsap, int flag,
6421      -        struct cred *cr, caller_context_t *ct)
     6385 +    struct cred *cr, caller_context_t *ct)
6422 6386  {
6423 6387          struct inode    *ip = VTOI(vp);
6424 6388          struct ulockfs  *ulp;
6425 6389          struct ufsvfs   *ufsvfsp = ip->i_ufsvfs;
6426 6390          ulong_t         vsa_mask = vsap->vsa_mask;
6427 6391          int             err = EINVAL;
6428 6392  
6429 6393          vsa_mask &= (VSA_ACL | VSA_ACLCNT | VSA_DFACL | VSA_DFACLCNT);
6430 6394  
6431 6395          /*
↓ open down ↓ 11 lines elided ↑ open up ↑
6443 6407  
6444 6408                  if (ulp)
6445 6409                          ufs_lockfs_end(ulp);
6446 6410          }
6447 6411          return (err);
6448 6412  }
6449 6413  
6450 6414  /* ARGSUSED */
6451 6415  static int
6452 6416  ufs_setsecattr(struct vnode *vp, vsecattr_t *vsap, int flag, struct cred *cr,
6453      -        caller_context_t *ct)
     6417 +    caller_context_t *ct)
6454 6418  {
6455 6419          struct inode    *ip = VTOI(vp);
6456 6420          struct ulockfs  *ulp = NULL;
6457 6421          struct ufsvfs   *ufsvfsp = VTOI(vp)->i_ufsvfs;
6458 6422          ulong_t         vsa_mask = vsap->vsa_mask;
6459 6423          int             err;
6460 6424          int             haverwlock = 1;
6461 6425          int             trans_size;
6462 6426          int             donetrans = 0;
6463 6427          int             retry = 1;
↓ open down ↓ 202 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX