Print this page
onc plus-be-gone


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* ONC_PLUS EXTRACT START */
  23 /*
  24  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  25  * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
  26  */
  27 
  28 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  29 /*        All Rights Reserved   */
  30 
  31 /*
  32  * Portions of this source code were derived from Berkeley 4.3 BSD
  33  * under license from the Regents of the University of California.
  34  */
  35 
  36 
  37 /* ONC_PLUS EXTRACT END */
  38 
  39 #include <sys/param.h>
  40 #include <sys/isa_defs.h>
  41 #include <sys/types.h>
  42 #include <sys/sysmacros.h>
  43 #include <sys/systm.h>
  44 #include <sys/errno.h>
  45 #include <sys/fcntl.h>
  46 /* ONC_PLUS EXTRACT START */
  47 #include <sys/flock.h>
  48 /* ONC_PLUS EXTRACT END */
  49 #include <sys/vnode.h>
  50 #include <sys/file.h>
  51 #include <sys/mode.h>
  52 #include <sys/proc.h>
  53 #include <sys/filio.h>
  54 #include <sys/share.h>
  55 #include <sys/debug.h>
  56 #include <sys/rctl.h>
  57 #include <sys/nbmlock.h>
  58 
  59 #include <sys/cmn_err.h>
  60 
  61 /* ONC_PLUS EXTRACT START */
  62 static int flock_check(vnode_t *, flock64_t *, offset_t, offset_t);
  63 static int flock_get_start(vnode_t *, flock64_t *, offset_t, u_offset_t *);
  64 static void fd_too_big(proc_t *);
  65 
  66 /*
  67  * File control.
  68  */
  69 int
  70 fcntl(int fdes, int cmd, intptr_t arg)
  71 {
  72         int iarg;
  73         int error = 0;
  74         int retval;
  75         proc_t *p;
  76         file_t *fp;
  77         vnode_t *vp;
  78         u_offset_t offset;
  79         u_offset_t start;
  80         struct vattr vattr;
  81         int in_crit;


 133                 }
 134                 goto out;
 135 
 136         case F_BADFD:
 137                 if ((error = f_badfd(fdes, &fdres, (int)arg)) == 0)
 138                         retval = fdres;
 139                 goto out;
 140         }
 141 
 142         /*
 143          * Second, for speed, deal with the subset of cases that
 144          * require getf() / releasef() but do not require copyin.
 145          */
 146         if ((fp = getf(fdes)) == NULL) {
 147                 error = EBADF;
 148                 goto out;
 149         }
 150         iarg = (int)arg;
 151 
 152         switch (cmd) {
 153 /* ONC_PLUS EXTRACT END */
 154 
 155         case F_DUPFD:
 156         case F_DUPFD_CLOEXEC:
 157                 p = curproc;
 158                 if ((uint_t)iarg >= p->p_fno_ctl) {
 159                         if (iarg >= 0)
 160                                 fd_too_big(p);
 161                         error = EINVAL;
 162                         goto done;
 163                 }
 164                 /*
 165                  * We need to increment the f_count reference counter
 166                  * before allocating a new file descriptor.
 167                  * Doing it other way round opens a window for race condition
 168                  * with closeandsetf() on the target file descriptor which can
 169                  * close the file still referenced by the original
 170                  * file descriptor.
 171                  */
 172                 mutex_enter(&fp->f_tlock);
 173                 fp->f_count++;
 174                 mutex_exit(&fp->f_tlock);


 258                 goto done;
 259         }
 260 
 261         /*
 262          * Finally, deal with the expensive cases.
 263          */
 264         retval = 0;
 265         in_crit = 0;
 266         maxoffset = MAXOFF_T;
 267         datamodel = DATAMODEL_NATIVE;
 268 #if defined(_SYSCALL32_IMPL)
 269         if ((datamodel = get_udatamodel()) == DATAMODEL_ILP32)
 270                 maxoffset = MAXOFF32_T;
 271 #endif
 272 
 273         vp = fp->f_vnode;
 274         flag = fp->f_flag;
 275         offset = fp->f_offset;
 276 
 277         switch (cmd) {
 278 /* ONC_PLUS EXTRACT START */
 279         /*
 280          * The file system and vnode layers understand and implement
 281          * locking with flock64 structures. So here once we pass through
 282          * the test for compatibility as defined by LFS API, (for F_SETLK,
 283          * F_SETLKW, F_GETLK, F_GETLKW, F_FREESP) we transform
 284          * the flock structure to a flock64 structure and send it to the
 285          * lower layers. Similarly in case of GETLK the returned flock64
 286          * structure is transformed to a flock structure if everything fits
 287          * in nicely, otherwise we return EOVERFLOW.
 288          */
 289 
 290         case F_GETLK:
 291         case F_O_GETLK:
 292         case F_SETLK:
 293         case F_SETLKW:
 294         case F_SETLK_NBMAND:
 295 
 296                 /*
 297                  * Copy in input fields only.
 298                  */


 433                                 if (bf.l_start > MAXOFF32_T ||
 434                                     bf.l_len > MAXOFF32_T) {
 435                                         error = EOVERFLOW;
 436                                         break;
 437                                 }
 438                                 for (i = 0; i < 4; i++)
 439                                         sbf32.l_pad[i] = 0;
 440                                 sbf32.l_type = (int16_t)bf.l_type;
 441                                 sbf32.l_whence = (int16_t)bf.l_whence;
 442                                 sbf32.l_start = (off32_t)bf.l_start;
 443                                 sbf32.l_len = (off32_t)bf.l_len;
 444                                 sbf32.l_sysid = (int32_t)bf.l_sysid;
 445                                 sbf32.l_pid = (pid32_t)bf.l_pid;
 446                                 if (copyout(&sbf32,
 447                                     (void *)arg, sizeof (sbf32)))
 448                                         error = EFAULT;
 449                         }
 450 #endif
 451                 }
 452                 break;
 453 /* ONC_PLUS EXTRACT END */
 454 
 455         case F_CHKFL:
 456                 /*
 457                  * This is for internal use only, to allow the vnode layer
 458                  * to validate a flags setting before applying it.  User
 459                  * programs can't issue it.
 460                  */
 461                 error = EINVAL;
 462                 break;
 463 
 464         case F_ALLOCSP:
 465         case F_FREESP:
 466         case F_ALLOCSP64:
 467         case F_FREESP64:
 468                 /*
 469                  * Test for not-a-regular-file (and returning EINVAL)
 470                  * before testing for open-for-writing (and returning EBADF).
 471                  * This is relied upon by posix_fallocate() in libc.
 472                  */
 473                 if (vp->v_type != VREG) {


 580                         begin = start > vattr.va_size ? vattr.va_size : start;
 581                         length = vattr.va_size > start ? vattr.va_size - start :
 582                             start - vattr.va_size;
 583                         if (nbl_conflict(vp, NBL_WRITE, begin, length, 0,
 584                             NULL)) {
 585                                 error = EACCES;
 586                                 break;
 587                         }
 588                 }
 589 
 590                 if (cmd == F_ALLOCSP64)
 591                         cmd = F_ALLOCSP;
 592                 else if (cmd == F_FREESP64)
 593                         cmd = F_FREESP;
 594 
 595                 error = VOP_SPACE(vp, cmd, &bf, flag, offset, fp->f_cred, NULL);
 596 
 597                 break;
 598 
 599 #if !defined(_LP64) || defined(_SYSCALL32_IMPL)
 600 /* ONC_PLUS EXTRACT START */
 601         case F_GETLK64:
 602         case F_SETLK64:
 603         case F_SETLKW64:
 604         case F_SETLK64_NBMAND:
 605                 /*
 606                  * Large Files: Here we set cmd as *LK and send it to
 607                  * lower layers. *LK64 is only for the user land.
 608                  * Most of the comments described above for F_SETLK
 609                  * applies here too.
 610                  * Large File support is only needed for ILP32 apps!
 611                  */
 612                 if (datamodel != DATAMODEL_ILP32) {
 613                         error = EINVAL;
 614                         break;
 615                 }
 616 
 617                 if (cmd == F_GETLK64)
 618                         cmd = F_GETLK;
 619                 else if (cmd == F_SETLK64)
 620                         cmd = F_SETLK;


 663 
 664                         /*
 665                          * We do not want to assume that the flock64 structure
 666                          * is laid out in the same in ILP32 and LP64
 667                          * environments, so we will copy out the ILP32 version
 668                          * of flock64 explicitly after copying the native
 669                          * flock64 structure to it.
 670                          */
 671                         for (i = 0; i < 4; i++)
 672                                 bf64_32.l_pad[i] = 0;
 673                         bf64_32.l_type = (int16_t)bf.l_type;
 674                         bf64_32.l_whence = (int16_t)bf.l_whence;
 675                         bf64_32.l_start = bf.l_start;
 676                         bf64_32.l_len = bf.l_len;
 677                         bf64_32.l_sysid = (int32_t)bf.l_sysid;
 678                         bf64_32.l_pid = (pid32_t)bf.l_pid;
 679                         if (copyout(&bf64_32, (void *)arg, sizeof (bf64_32)))
 680                                 error = EFAULT;
 681                 }
 682                 break;
 683 /* ONC_PLUS EXTRACT END */
 684 #endif /* !defined(_LP64) || defined(_SYSCALL32_IMPL) */
 685 
 686 /* ONC_PLUS EXTRACT START */
 687         case F_SHARE:
 688         case F_SHARE_NBMAND:
 689         case F_UNSHARE:
 690 
 691                 /*
 692                  * Copy in input fields only.
 693                  */
 694                 if (copyin((void *)arg, &fsh, sizeof (fsh))) {
 695                         error = EFAULT;
 696                         break;
 697                 }
 698 
 699                 /*
 700                  * Local share reservations always have this simple form
 701                  */
 702                 shr.s_access = fsh.f_access;
 703                 shr.s_deny = fsh.f_deny;
 704                 shr.s_sysid = 0;
 705                 shr.s_pid = ttoproc(curthread)->p_pid;
 706                 shr_own.sl_pid = shr.s_pid;
 707                 shr_own.sl_id = fsh.f_id;
 708                 shr.s_own_len = sizeof (shr_own);
 709                 shr.s_owner = (caddr_t)&shr_own;
 710                 error = VOP_SHRLOCK(vp, cmd, &shr, flag, fp->f_cred, NULL);
 711 /* ONC_PLUS EXTRACT END */
 712                 break;
 713 
 714         default:
 715                 error = EINVAL;
 716                 break;
 717         }
 718 
 719         if (in_crit)
 720                 nbl_end_crit(vp);
 721 
 722 done:
 723         releasef(fdes);
 724 out:
 725         if (error)
 726                 return (set_errno(error));
 727         return (retval);
 728 }
 729 
 730 /* ONC_PLUS EXTRACT START */
 731 int
 732 flock_check(vnode_t *vp, flock64_t *flp, offset_t offset, offset_t max)
 733 {
 734         struct vattr    vattr;
 735         int     error;
 736         u_offset_t start, end;
 737 
 738         /*
 739          * Determine the starting point of the request
 740          */
 741         switch (flp->l_whence) {
 742         case 0:         /* SEEK_SET */
 743                 start = (u_offset_t)flp->l_start;
 744                 if (start > max)
 745                         return (EINVAL);
 746                 break;
 747         case 1:         /* SEEK_CUR */
 748                 if (flp->l_start > (max - offset))
 749                         return (EOVERFLOW);
 750                 start = (u_offset_t)(flp->l_start + offset);


 822                 *start = (u_offset_t)(flp->l_start + (offset_t)vattr.va_size);
 823                 break;
 824         default:
 825                 return (EINVAL);
 826         }
 827 
 828         return (0);
 829 }
 830 
 831 /*
 832  * Take rctl action when the requested file descriptor is too big.
 833  */
 834 static void
 835 fd_too_big(proc_t *p)
 836 {
 837         mutex_enter(&p->p_lock);
 838         (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE],
 839             p->p_rctls, p, RCA_SAFE);
 840         mutex_exit(&p->p_lock);
 841 }
 842 /* ONC_PLUS EXTRACT END */


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 

  22 /*
  23  * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
  25  */
  26 
  27 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * Portions of this source code were derived from Berkeley 4.3 BSD
  32  * under license from the Regents of the University of California.
  33  */
  34 
  35 


  36 #include <sys/param.h>
  37 #include <sys/isa_defs.h>
  38 #include <sys/types.h>
  39 #include <sys/sysmacros.h>
  40 #include <sys/systm.h>
  41 #include <sys/errno.h>
  42 #include <sys/fcntl.h>

  43 #include <sys/flock.h>

  44 #include <sys/vnode.h>
  45 #include <sys/file.h>
  46 #include <sys/mode.h>
  47 #include <sys/proc.h>
  48 #include <sys/filio.h>
  49 #include <sys/share.h>
  50 #include <sys/debug.h>
  51 #include <sys/rctl.h>
  52 #include <sys/nbmlock.h>
  53 
  54 #include <sys/cmn_err.h>
  55 

  56 static int flock_check(vnode_t *, flock64_t *, offset_t, offset_t);
  57 static int flock_get_start(vnode_t *, flock64_t *, offset_t, u_offset_t *);
  58 static void fd_too_big(proc_t *);
  59 
  60 /*
  61  * File control.
  62  */
  63 int
  64 fcntl(int fdes, int cmd, intptr_t arg)
  65 {
  66         int iarg;
  67         int error = 0;
  68         int retval;
  69         proc_t *p;
  70         file_t *fp;
  71         vnode_t *vp;
  72         u_offset_t offset;
  73         u_offset_t start;
  74         struct vattr vattr;
  75         int in_crit;


 127                 }
 128                 goto out;
 129 
 130         case F_BADFD:
 131                 if ((error = f_badfd(fdes, &fdres, (int)arg)) == 0)
 132                         retval = fdres;
 133                 goto out;
 134         }
 135 
 136         /*
 137          * Second, for speed, deal with the subset of cases that
 138          * require getf() / releasef() but do not require copyin.
 139          */
 140         if ((fp = getf(fdes)) == NULL) {
 141                 error = EBADF;
 142                 goto out;
 143         }
 144         iarg = (int)arg;
 145 
 146         switch (cmd) {


 147         case F_DUPFD:
 148         case F_DUPFD_CLOEXEC:
 149                 p = curproc;
 150                 if ((uint_t)iarg >= p->p_fno_ctl) {
 151                         if (iarg >= 0)
 152                                 fd_too_big(p);
 153                         error = EINVAL;
 154                         goto done;
 155                 }
 156                 /*
 157                  * We need to increment the f_count reference counter
 158                  * before allocating a new file descriptor.
 159                  * Doing it other way round opens a window for race condition
 160                  * with closeandsetf() on the target file descriptor which can
 161                  * close the file still referenced by the original
 162                  * file descriptor.
 163                  */
 164                 mutex_enter(&fp->f_tlock);
 165                 fp->f_count++;
 166                 mutex_exit(&fp->f_tlock);


 250                 goto done;
 251         }
 252 
 253         /*
 254          * Finally, deal with the expensive cases.
 255          */
 256         retval = 0;
 257         in_crit = 0;
 258         maxoffset = MAXOFF_T;
 259         datamodel = DATAMODEL_NATIVE;
 260 #if defined(_SYSCALL32_IMPL)
 261         if ((datamodel = get_udatamodel()) == DATAMODEL_ILP32)
 262                 maxoffset = MAXOFF32_T;
 263 #endif
 264 
 265         vp = fp->f_vnode;
 266         flag = fp->f_flag;
 267         offset = fp->f_offset;
 268 
 269         switch (cmd) {

 270         /*
 271          * The file system and vnode layers understand and implement
 272          * locking with flock64 structures. So here once we pass through
 273          * the test for compatibility as defined by LFS API, (for F_SETLK,
 274          * F_SETLKW, F_GETLK, F_GETLKW, F_FREESP) we transform
 275          * the flock structure to a flock64 structure and send it to the
 276          * lower layers. Similarly in case of GETLK the returned flock64
 277          * structure is transformed to a flock structure if everything fits
 278          * in nicely, otherwise we return EOVERFLOW.
 279          */
 280 
 281         case F_GETLK:
 282         case F_O_GETLK:
 283         case F_SETLK:
 284         case F_SETLKW:
 285         case F_SETLK_NBMAND:
 286 
 287                 /*
 288                  * Copy in input fields only.
 289                  */


 424                                 if (bf.l_start > MAXOFF32_T ||
 425                                     bf.l_len > MAXOFF32_T) {
 426                                         error = EOVERFLOW;
 427                                         break;
 428                                 }
 429                                 for (i = 0; i < 4; i++)
 430                                         sbf32.l_pad[i] = 0;
 431                                 sbf32.l_type = (int16_t)bf.l_type;
 432                                 sbf32.l_whence = (int16_t)bf.l_whence;
 433                                 sbf32.l_start = (off32_t)bf.l_start;
 434                                 sbf32.l_len = (off32_t)bf.l_len;
 435                                 sbf32.l_sysid = (int32_t)bf.l_sysid;
 436                                 sbf32.l_pid = (pid32_t)bf.l_pid;
 437                                 if (copyout(&sbf32,
 438                                     (void *)arg, sizeof (sbf32)))
 439                                         error = EFAULT;
 440                         }
 441 #endif
 442                 }
 443                 break;

 444 
 445         case F_CHKFL:
 446                 /*
 447                  * This is for internal use only, to allow the vnode layer
 448                  * to validate a flags setting before applying it.  User
 449                  * programs can't issue it.
 450                  */
 451                 error = EINVAL;
 452                 break;
 453 
 454         case F_ALLOCSP:
 455         case F_FREESP:
 456         case F_ALLOCSP64:
 457         case F_FREESP64:
 458                 /*
 459                  * Test for not-a-regular-file (and returning EINVAL)
 460                  * before testing for open-for-writing (and returning EBADF).
 461                  * This is relied upon by posix_fallocate() in libc.
 462                  */
 463                 if (vp->v_type != VREG) {


 570                         begin = start > vattr.va_size ? vattr.va_size : start;
 571                         length = vattr.va_size > start ? vattr.va_size - start :
 572                             start - vattr.va_size;
 573                         if (nbl_conflict(vp, NBL_WRITE, begin, length, 0,
 574                             NULL)) {
 575                                 error = EACCES;
 576                                 break;
 577                         }
 578                 }
 579 
 580                 if (cmd == F_ALLOCSP64)
 581                         cmd = F_ALLOCSP;
 582                 else if (cmd == F_FREESP64)
 583                         cmd = F_FREESP;
 584 
 585                 error = VOP_SPACE(vp, cmd, &bf, flag, offset, fp->f_cred, NULL);
 586 
 587                 break;
 588 
 589 #if !defined(_LP64) || defined(_SYSCALL32_IMPL)

 590         case F_GETLK64:
 591         case F_SETLK64:
 592         case F_SETLKW64:
 593         case F_SETLK64_NBMAND:
 594                 /*
 595                  * Large Files: Here we set cmd as *LK and send it to
 596                  * lower layers. *LK64 is only for the user land.
 597                  * Most of the comments described above for F_SETLK
 598                  * applies here too.
 599                  * Large File support is only needed for ILP32 apps!
 600                  */
 601                 if (datamodel != DATAMODEL_ILP32) {
 602                         error = EINVAL;
 603                         break;
 604                 }
 605 
 606                 if (cmd == F_GETLK64)
 607                         cmd = F_GETLK;
 608                 else if (cmd == F_SETLK64)
 609                         cmd = F_SETLK;


 652 
 653                         /*
 654                          * We do not want to assume that the flock64 structure
 655                          * is laid out in the same in ILP32 and LP64
 656                          * environments, so we will copy out the ILP32 version
 657                          * of flock64 explicitly after copying the native
 658                          * flock64 structure to it.
 659                          */
 660                         for (i = 0; i < 4; i++)
 661                                 bf64_32.l_pad[i] = 0;
 662                         bf64_32.l_type = (int16_t)bf.l_type;
 663                         bf64_32.l_whence = (int16_t)bf.l_whence;
 664                         bf64_32.l_start = bf.l_start;
 665                         bf64_32.l_len = bf.l_len;
 666                         bf64_32.l_sysid = (int32_t)bf.l_sysid;
 667                         bf64_32.l_pid = (pid32_t)bf.l_pid;
 668                         if (copyout(&bf64_32, (void *)arg, sizeof (bf64_32)))
 669                                 error = EFAULT;
 670                 }
 671                 break;

 672 #endif /* !defined(_LP64) || defined(_SYSCALL32_IMPL) */
 673 

 674         case F_SHARE:
 675         case F_SHARE_NBMAND:
 676         case F_UNSHARE:
 677 
 678                 /*
 679                  * Copy in input fields only.
 680                  */
 681                 if (copyin((void *)arg, &fsh, sizeof (fsh))) {
 682                         error = EFAULT;
 683                         break;
 684                 }
 685 
 686                 /*
 687                  * Local share reservations always have this simple form
 688                  */
 689                 shr.s_access = fsh.f_access;
 690                 shr.s_deny = fsh.f_deny;
 691                 shr.s_sysid = 0;
 692                 shr.s_pid = ttoproc(curthread)->p_pid;
 693                 shr_own.sl_pid = shr.s_pid;
 694                 shr_own.sl_id = fsh.f_id;
 695                 shr.s_own_len = sizeof (shr_own);
 696                 shr.s_owner = (caddr_t)&shr_own;
 697                 error = VOP_SHRLOCK(vp, cmd, &shr, flag, fp->f_cred, NULL);

 698                 break;
 699 
 700         default:
 701                 error = EINVAL;
 702                 break;
 703         }
 704 
 705         if (in_crit)
 706                 nbl_end_crit(vp);
 707 
 708 done:
 709         releasef(fdes);
 710 out:
 711         if (error)
 712                 return (set_errno(error));
 713         return (retval);
 714 }
 715 

 716 int
 717 flock_check(vnode_t *vp, flock64_t *flp, offset_t offset, offset_t max)
 718 {
 719         struct vattr    vattr;
 720         int     error;
 721         u_offset_t start, end;
 722 
 723         /*
 724          * Determine the starting point of the request
 725          */
 726         switch (flp->l_whence) {
 727         case 0:         /* SEEK_SET */
 728                 start = (u_offset_t)flp->l_start;
 729                 if (start > max)
 730                         return (EINVAL);
 731                 break;
 732         case 1:         /* SEEK_CUR */
 733                 if (flp->l_start > (max - offset))
 734                         return (EOVERFLOW);
 735                 start = (u_offset_t)(flp->l_start + offset);


 807                 *start = (u_offset_t)(flp->l_start + (offset_t)vattr.va_size);
 808                 break;
 809         default:
 810                 return (EINVAL);
 811         }
 812 
 813         return (0);
 814 }
 815 
 816 /*
 817  * Take rctl action when the requested file descriptor is too big.
 818  */
 819 static void
 820 fd_too_big(proc_t *p)
 821 {
 822         mutex_enter(&p->p_lock);
 823         (void) rctl_action(rctlproc_legacy[RLIMIT_NOFILE],
 824             p->p_rctls, p, RCA_SAFE);
 825         mutex_exit(&p->p_lock);
 826 }