Print this page
re #13613 rb4516 Tunables needs volatile keyword


   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  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 /*
  27  *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
  28  *      All rights reserved.
  29  */
  30 
  31 /*
  32  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  33  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  34  */
  35 
  36 #include <sys/param.h>
  37 #include <sys/types.h>
  38 #include <sys/systm.h>
  39 #include <sys/cred.h>
  40 #include <sys/time.h>
  41 #include <sys/vnode.h>
  42 #include <sys/vfs.h>
  43 #include <sys/vfs_opreg.h>
  44 #include <sys/file.h>


1647                          * with the new cred.
1648                          */
1649                         if (ncr != NULL) {
1650                                 cred = ncr;
1651                                 ncr = NULL;
1652                                 goto tryagain;
1653                         }
1654                         error = EACCES;
1655                 }
1656         } else {
1657                 nfs3_cache_post_op_attr(vp, &res.resfail.obj_attributes, t, cr);
1658                 PURGE_STALE_FH(error, vp, cr);
1659         }
1660 
1661         if (ncrfree != NULL)
1662                 crfree(ncrfree);
1663 
1664         return (error);
1665 }
1666 
1667 static int nfs3_do_symlink_cache = 1;
1668 
1669 /* ARGSUSED */
1670 static int
1671 nfs3_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct)
1672 {
1673         int error;
1674         READLINK3args args;
1675         READLINK3res res;
1676         nfspath3 resdata_backup;
1677         rnode_t *rp;
1678         int douprintf;
1679         int len;
1680         failinfo_t fi;
1681         hrtime_t t;
1682 
1683         /*
1684          * Can't readlink anything other than a symbolic link.
1685          */
1686         if (vp->v_type != VLNK)
1687                 return (EINVAL);


1976         error = nfs3lookup(dvp, nm, vpp, pnp, flags, rdir, cr, 0);
1977 
1978         nfs_rw_exit(&drp->r_rwlock);
1979 
1980         /*
1981          * If vnode is a device, create special vnode.
1982          */
1983         if (!error && IS_DEVVP(*vpp)) {
1984                 vp = *vpp;
1985                 *vpp = specvp(vp, vp->v_rdev, vp->v_type, cr);
1986                 VN_RELE(vp);
1987         }
1988 
1989 out:
1990         if (avp != NULL)
1991                 VN_RELE(avp);
1992 
1993         return (error);
1994 }
1995 
1996 static int nfs3_lookup_neg_cache = 1;
1997 
1998 #ifdef DEBUG
1999 static int nfs3_lookup_dnlc_hits = 0;
2000 static int nfs3_lookup_dnlc_misses = 0;
2001 static int nfs3_lookup_dnlc_neg_hits = 0;
2002 static int nfs3_lookup_dnlc_disappears = 0;
2003 static int nfs3_lookup_dnlc_lookups = 0;
2004 #endif
2005 
2006 /* ARGSUSED */
2007 int
2008 nfs3lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
2009         int flags, vnode_t *rdir, cred_t *cr, int rfscall_flags)
2010 {
2011         int error;
2012         rnode_t *drp;
2013 
2014         ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
2015         /*
2016          * If lookup is for "", just return dvp.  Don't need


3682                 if (error == EOPNOTSUPP) {
3683                         mutex_enter(&mi->mi_lock);
3684                         mi->mi_flags &= ~MI_SYMLINK;
3685                         mutex_exit(&mi->mi_lock);
3686                 }
3687         }
3688 
3689         nfs_rw_exit(&drp->r_rwlock);
3690 
3691         return (error);
3692 }
3693 
3694 #ifdef DEBUG
3695 static int nfs3_readdir_cache_hits = 0;
3696 static int nfs3_readdir_cache_shorts = 0;
3697 static int nfs3_readdir_cache_waits = 0;
3698 static int nfs3_readdir_cache_misses = 0;
3699 static int nfs3_readdir_readahead = 0;
3700 #endif
3701 
3702 static int nfs3_shrinkreaddir = 0;
3703 
3704 /*
3705  * Read directory entries.
3706  * There are some weird things to look out for here.  The uio_loffset
3707  * field is either 0 or it is the offset returned from a previous
3708  * readdir.  It is an opaque value used by the server to find the
3709  * correct directory block to read. The count field is the number
3710  * of blocks to read on the server.  This is advisory only, the server
3711  * may return only one block's worth of entries.  Entries may be compressed
3712  * on the server.
3713  */
3714 /* ARGSUSED */
3715 static int
3716 nfs3_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp,
3717         caller_context_t *ct, int flags)
3718 {
3719         int error;
3720         size_t count;
3721         rnode_t *rp;
3722         rddir_cache *rdc;


4501 /* ARGSUSED */
4502 static int
4503 nfs3_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
4504 {
4505 
4506         /*
4507          * Because we stuff the readdir cookie into the offset field
4508          * someone may attempt to do an lseek with the cookie which
4509          * we want to succeed.
4510          */
4511         if (vp->v_type == VDIR)
4512                 return (0);
4513         if (*noffp < 0)
4514                 return (EINVAL);
4515         return (0);
4516 }
4517 
4518 /*
4519  * number of nfs3_bsize blocks to read ahead.
4520  */
4521 static int nfs3_nra = 4;
4522 
4523 #ifdef DEBUG
4524 static int nfs3_lostpage = 0;   /* number of times we lost original page */
4525 #endif
4526 
4527 /*
4528  * Return all the pages from [off..off+len) in file
4529  */
4530 /* ARGSUSED */
4531 static int
4532 nfs3_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
4533         page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
4534         enum seg_rw rw, cred_t *cr, caller_context_t *ct)
4535 {
4536         rnode_t *rp;
4537         int error;
4538         mntinfo_t *mi;
4539 
4540         if (vp->v_flag & VNOMAP)
4541                 return (ENOSYS);


5689                         error = nfs3_putpage_commit(dmapp->vp, dmapp->off,
5690                             dmapp->len, dmapp->cr);
5691                 if (!error) {
5692                         mutex_enter(&rp->r_statelock);
5693                         error = rp->r_error;
5694                         rp->r_error = 0;
5695                         mutex_exit(&rp->r_statelock);
5696                 }
5697         } else
5698                 error = 0;
5699 
5700         if ((rp->r_flags & RDIRECTIO) || (mi->mi_flags & MI_DIRECTIO))
5701                 (void) nfs3_putpage(dmapp->vp, dmapp->off, dmapp->len,
5702                     B_INVAL, dmapp->cr, NULL);
5703 
5704         dmapp->caller->error = error;
5705         (void) as_delete_callback(as, arg);
5706         kmem_free(dmapp, sizeof (nfs_delmap_args_t));
5707 }
5708 
5709 static int nfs3_pathconf_disable_cache = 0;
5710 
5711 #ifdef DEBUG
5712 static int nfs3_pathconf_cache_hits = 0;
5713 static int nfs3_pathconf_cache_misses = 0;
5714 #endif
5715 
5716 /* ARGSUSED */
5717 static int
5718 nfs3_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
5719         caller_context_t *ct)
5720 {
5721         int error;
5722         PATHCONF3args args;
5723         PATHCONF3res res;
5724         int douprintf;
5725         failinfo_t fi;
5726         rnode_t *rp;
5727         hrtime_t t;
5728 
5729         if (nfs_zone() != VTOMI(vp)->mi_zone)




   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  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
  31  *      All rights reserved.
  32  */
  33 
  34 /*
  35  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  36  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  37  */
  38 
  39 #include <sys/param.h>
  40 #include <sys/types.h>
  41 #include <sys/systm.h>
  42 #include <sys/cred.h>
  43 #include <sys/time.h>
  44 #include <sys/vnode.h>
  45 #include <sys/vfs.h>
  46 #include <sys/vfs_opreg.h>
  47 #include <sys/file.h>


1650                          * with the new cred.
1651                          */
1652                         if (ncr != NULL) {
1653                                 cred = ncr;
1654                                 ncr = NULL;
1655                                 goto tryagain;
1656                         }
1657                         error = EACCES;
1658                 }
1659         } else {
1660                 nfs3_cache_post_op_attr(vp, &res.resfail.obj_attributes, t, cr);
1661                 PURGE_STALE_FH(error, vp, cr);
1662         }
1663 
1664         if (ncrfree != NULL)
1665                 crfree(ncrfree);
1666 
1667         return (error);
1668 }
1669 
1670 volatile int nfs3_do_symlink_cache = 1;
1671 
1672 /* ARGSUSED */
1673 static int
1674 nfs3_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct)
1675 {
1676         int error;
1677         READLINK3args args;
1678         READLINK3res res;
1679         nfspath3 resdata_backup;
1680         rnode_t *rp;
1681         int douprintf;
1682         int len;
1683         failinfo_t fi;
1684         hrtime_t t;
1685 
1686         /*
1687          * Can't readlink anything other than a symbolic link.
1688          */
1689         if (vp->v_type != VLNK)
1690                 return (EINVAL);


1979         error = nfs3lookup(dvp, nm, vpp, pnp, flags, rdir, cr, 0);
1980 
1981         nfs_rw_exit(&drp->r_rwlock);
1982 
1983         /*
1984          * If vnode is a device, create special vnode.
1985          */
1986         if (!error && IS_DEVVP(*vpp)) {
1987                 vp = *vpp;
1988                 *vpp = specvp(vp, vp->v_rdev, vp->v_type, cr);
1989                 VN_RELE(vp);
1990         }
1991 
1992 out:
1993         if (avp != NULL)
1994                 VN_RELE(avp);
1995 
1996         return (error);
1997 }
1998 
1999 volatile int nfs3_lookup_neg_cache = 1;
2000 
2001 #ifdef DEBUG
2002 static int nfs3_lookup_dnlc_hits = 0;
2003 static int nfs3_lookup_dnlc_misses = 0;
2004 static int nfs3_lookup_dnlc_neg_hits = 0;
2005 static int nfs3_lookup_dnlc_disappears = 0;
2006 static int nfs3_lookup_dnlc_lookups = 0;
2007 #endif
2008 
2009 /* ARGSUSED */
2010 int
2011 nfs3lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
2012         int flags, vnode_t *rdir, cred_t *cr, int rfscall_flags)
2013 {
2014         int error;
2015         rnode_t *drp;
2016 
2017         ASSERT(nfs_zone() == VTOMI(dvp)->mi_zone);
2018         /*
2019          * If lookup is for "", just return dvp.  Don't need


3685                 if (error == EOPNOTSUPP) {
3686                         mutex_enter(&mi->mi_lock);
3687                         mi->mi_flags &= ~MI_SYMLINK;
3688                         mutex_exit(&mi->mi_lock);
3689                 }
3690         }
3691 
3692         nfs_rw_exit(&drp->r_rwlock);
3693 
3694         return (error);
3695 }
3696 
3697 #ifdef DEBUG
3698 static int nfs3_readdir_cache_hits = 0;
3699 static int nfs3_readdir_cache_shorts = 0;
3700 static int nfs3_readdir_cache_waits = 0;
3701 static int nfs3_readdir_cache_misses = 0;
3702 static int nfs3_readdir_readahead = 0;
3703 #endif
3704 
3705 volatile int nfs3_shrinkreaddir = 0;
3706 
3707 /*
3708  * Read directory entries.
3709  * There are some weird things to look out for here.  The uio_loffset
3710  * field is either 0 or it is the offset returned from a previous
3711  * readdir.  It is an opaque value used by the server to find the
3712  * correct directory block to read. The count field is the number
3713  * of blocks to read on the server.  This is advisory only, the server
3714  * may return only one block's worth of entries.  Entries may be compressed
3715  * on the server.
3716  */
3717 /* ARGSUSED */
3718 static int
3719 nfs3_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp,
3720         caller_context_t *ct, int flags)
3721 {
3722         int error;
3723         size_t count;
3724         rnode_t *rp;
3725         rddir_cache *rdc;


4504 /* ARGSUSED */
4505 static int
4506 nfs3_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
4507 {
4508 
4509         /*
4510          * Because we stuff the readdir cookie into the offset field
4511          * someone may attempt to do an lseek with the cookie which
4512          * we want to succeed.
4513          */
4514         if (vp->v_type == VDIR)
4515                 return (0);
4516         if (*noffp < 0)
4517                 return (EINVAL);
4518         return (0);
4519 }
4520 
4521 /*
4522  * number of nfs3_bsize blocks to read ahead.
4523  */
4524 volatile int nfs3_nra = 4;
4525 
4526 #ifdef DEBUG
4527 static int nfs3_lostpage = 0;   /* number of times we lost original page */
4528 #endif
4529 
4530 /*
4531  * Return all the pages from [off..off+len) in file
4532  */
4533 /* ARGSUSED */
4534 static int
4535 nfs3_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
4536         page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
4537         enum seg_rw rw, cred_t *cr, caller_context_t *ct)
4538 {
4539         rnode_t *rp;
4540         int error;
4541         mntinfo_t *mi;
4542 
4543         if (vp->v_flag & VNOMAP)
4544                 return (ENOSYS);


5692                         error = nfs3_putpage_commit(dmapp->vp, dmapp->off,
5693                             dmapp->len, dmapp->cr);
5694                 if (!error) {
5695                         mutex_enter(&rp->r_statelock);
5696                         error = rp->r_error;
5697                         rp->r_error = 0;
5698                         mutex_exit(&rp->r_statelock);
5699                 }
5700         } else
5701                 error = 0;
5702 
5703         if ((rp->r_flags & RDIRECTIO) || (mi->mi_flags & MI_DIRECTIO))
5704                 (void) nfs3_putpage(dmapp->vp, dmapp->off, dmapp->len,
5705                     B_INVAL, dmapp->cr, NULL);
5706 
5707         dmapp->caller->error = error;
5708         (void) as_delete_callback(as, arg);
5709         kmem_free(dmapp, sizeof (nfs_delmap_args_t));
5710 }
5711 
5712 volatile int nfs3_pathconf_disable_cache = 0;
5713 
5714 #ifdef DEBUG
5715 static int nfs3_pathconf_cache_hits = 0;
5716 static int nfs3_pathconf_cache_misses = 0;
5717 #endif
5718 
5719 /* ARGSUSED */
5720 static int
5721 nfs3_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
5722         caller_context_t *ct)
5723 {
5724         int error;
5725         PATHCONF3args args;
5726         PATHCONF3res res;
5727         int douprintf;
5728         failinfo_t fi;
5729         rnode_t *rp;
5730         hrtime_t t;
5731 
5732         if (nfs_zone() != VTOMI(vp)->mi_zone)