nfs_srvsubs.c (160881) | nfs_srvsubs.c (164585) |
---|---|
1/*- 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/nfsserver/nfs_srvsubs.c 160881 2006-08-01 16:27:14Z jhb $"); | 36__FBSDID("$FreeBSD: head/sys/nfsserver/nfs_srvsubs.c 164585 2006-11-24 11:53:16Z rwatson $"); |
37 38/* 39 * These functions support the macros and help fiddle mbuf chains for 40 * the nfs op functions. They do things like create the rpc header and 41 * copy data between mbuf chains and uio lists. 42 */ 43 44#include "opt_inet6.h" --- 574 unchanged lines hidden (view full) --- 619 struct uio auio; 620 struct vnode *dp; 621 int error, rdonly, linklen; 622 struct componentname *cnp = &ndp->ni_cnd; 623 int lockleaf = (cnp->cn_flags & LOCKLEAF) != 0; 624 625 NFSD_LOCK_ASSERT(); 626 NFSD_UNLOCK(); | 37 38/* 39 * These functions support the macros and help fiddle mbuf chains for 40 * the nfs op functions. They do things like create the rpc header and 41 * copy data between mbuf chains and uio lists. 42 */ 43 44#include "opt_inet6.h" --- 574 unchanged lines hidden (view full) --- 619 struct uio auio; 620 struct vnode *dp; 621 int error, rdonly, linklen; 622 struct componentname *cnp = &ndp->ni_cnd; 623 int lockleaf = (cnp->cn_flags & LOCKLEAF) != 0; 624 625 NFSD_LOCK_ASSERT(); 626 NFSD_UNLOCK(); |
627 mtx_lock(&Giant); /* VFS */ | |
628 629 *retdirp = NULL; 630 cnp->cn_flags |= NOMACCHECK; 631 cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); 632 633 /* 634 * Copy the name from the mbuf list to ndp->ni_pnbuf 635 * and set the various ndp fields appropriately. 636 */ 637 fromcp = *dposp; 638 tocp = cnp->cn_pnbuf; 639 md = *mdp; 640 rem = mtod(md, caddr_t) + md->m_len - fromcp; 641 for (i = 0; i < len; i++) { 642 while (rem == 0) { 643 md = md->m_next; 644 if (md == NULL) { 645 error = EBADRPC; | 627 628 *retdirp = NULL; 629 cnp->cn_flags |= NOMACCHECK; 630 cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); 631 632 /* 633 * Copy the name from the mbuf list to ndp->ni_pnbuf 634 * and set the various ndp fields appropriately. 635 */ 636 fromcp = *dposp; 637 tocp = cnp->cn_pnbuf; 638 md = *mdp; 639 rem = mtod(md, caddr_t) + md->m_len - fromcp; 640 for (i = 0; i < len; i++) { 641 while (rem == 0) { 642 md = md->m_next; 643 if (md == NULL) { 644 error = EBADRPC; |
646 goto out; | 645 goto out_nogiant; |
647 } 648 fromcp = mtod(md, caddr_t); 649 rem = md->m_len; 650 } 651 if (*fromcp == '\0' || (!pubflag && *fromcp == '/')) { 652 error = EACCES; | 646 } 647 fromcp = mtod(md, caddr_t); 648 rem = md->m_len; 649 } 650 if (*fromcp == '\0' || (!pubflag && *fromcp == '/')) { 651 error = EACCES; |
653 goto out; | 652 goto out_nogiant; |
654 } 655 *tocp++ = *fromcp++; 656 rem--; 657 } 658 *tocp = '\0'; 659 *mdp = md; 660 *dposp = fromcp; 661 len = nfsm_rndup(len)-len; 662 if (len > 0) { 663 if (rem >= len) 664 *dposp += len; 665 else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0) | 653 } 654 *tocp++ = *fromcp++; 655 rem--; 656 } 657 *tocp = '\0'; 658 *mdp = md; 659 *dposp = fromcp; 660 len = nfsm_rndup(len)-len; 661 if (len > 0) { 662 if (rem >= len) 663 *dposp += len; 664 else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0) |
666 goto out; | 665 goto out_nogiant; |
667 } 668 669 /* 670 * Extract and set starting directory. | 666 } 667 668 /* 669 * Extract and set starting directory. |
670 * 671 * XXXRW: For now, acquire Giant unconditionally to avoid tracking it 672 * on multiple vnodes. |
|
671 */ | 673 */ |
672 mtx_unlock(&Giant); /* VFS */ 673 NFSD_LOCK(); | |
674 error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp, 675 nam, &rdonly, pubflag); | 674 error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp, 675 nam, &rdonly, pubflag); |
676 NFSD_UNLOCK(); | |
677 mtx_lock(&Giant); /* VFS */ 678 if (error) 679 goto out; 680 if (dp->v_type != VDIR) { 681 vrele(dp); 682 error = ENOTDIR; 683 goto out; 684 } --- 199 unchanged lines hidden (view full) --- 884 } 885 886 /* 887 * nfs_namei() guarentees that fields will not contain garbage 888 * whether an error occurs or not. This allows the caller to track 889 * cleanup state trivially. 890 */ 891out: | 676 mtx_lock(&Giant); /* VFS */ 677 if (error) 678 goto out; 679 if (dp->v_type != VDIR) { 680 vrele(dp); 681 error = ENOTDIR; 682 goto out; 683 } --- 199 unchanged lines hidden (view full) --- 883 } 884 885 /* 886 * nfs_namei() guarentees that fields will not contain garbage 887 * whether an error occurs or not. This allows the caller to track 888 * cleanup state trivially. 889 */ 890out: |
891 mtx_unlock(&Giant); /* VFS */ 892out_nogiant: |
|
892 if (error) { 893 uma_zfree(namei_zone, cnp->cn_pnbuf); 894 ndp->ni_vp = NULL; 895 ndp->ni_dvp = NULL; 896 ndp->ni_startdir = NULL; 897 cnp->cn_flags &= ~HASBUF; 898 } else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) { 899 ndp->ni_dvp = NULL; 900 } | 893 if (error) { 894 uma_zfree(namei_zone, cnp->cn_pnbuf); 895 ndp->ni_vp = NULL; 896 ndp->ni_dvp = NULL; 897 ndp->ni_startdir = NULL; 898 cnp->cn_flags &= ~HASBUF; 899 } else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) { 900 ndp->ni_dvp = NULL; 901 } |
901 mtx_unlock(&Giant); /* VFS */ | |
902 NFSD_LOCK(); 903 return (error); 904} 905 906/* 907 * A fiddled version of m_adj() that ensures null fill to a long 908 * boundary and only trims off the back end 909 */ --- 149 unchanged lines hidden (view full) --- 1059} 1060 1061/* 1062 * nfsrv_fhtovp() - convert a fh to a vnode ptr (optionally locked) 1063 * - look up fsid in mount list (if not found ret error) 1064 * - get vp and export rights by calling VFS_FHTOVP() 1065 * - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon 1066 * - if not lockflag unlock it with VOP_UNLOCK() | 902 NFSD_LOCK(); 903 return (error); 904} 905 906/* 907 * A fiddled version of m_adj() that ensures null fill to a long 908 * boundary and only trims off the back end 909 */ --- 149 unchanged lines hidden (view full) --- 1059} 1060 1061/* 1062 * nfsrv_fhtovp() - convert a fh to a vnode ptr (optionally locked) 1063 * - look up fsid in mount list (if not found ret error) 1064 * - get vp and export rights by calling VFS_FHTOVP() 1065 * - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon 1066 * - if not lockflag unlock it with VOP_UNLOCK() |
1067 * 1068 * As this routine may acquire Giant and may sleep, it can't be called with 1069 * nfsd_mtx. Caller should invoke nfsrv_fhtovp_locked() if the lock is held 1070 * so that it can be automatically dropped and re-acquired. |
|
1067 */ 1068int 1069nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, 1070 struct ucred *cred, struct nfssvc_sock *slp, struct sockaddr *nam, 1071 int *rdonlyp, int pubflag) 1072{ 1073 struct thread *td = curthread; /* XXX */ 1074 struct mount *mp; 1075 int i; 1076 struct ucred *credanon; 1077 int error, exflags; 1078 int vfslocked; 1079#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */ 1080 struct sockaddr_int *saddr; 1081#endif 1082 | 1071 */ 1072int 1073nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, 1074 struct ucred *cred, struct nfssvc_sock *slp, struct sockaddr *nam, 1075 int *rdonlyp, int pubflag) 1076{ 1077 struct thread *td = curthread; /* XXX */ 1078 struct mount *mp; 1079 int i; 1080 struct ucred *credanon; 1081 int error, exflags; 1082 int vfslocked; 1083#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */ 1084 struct sockaddr_int *saddr; 1085#endif 1086 |
1083 NFSD_LOCK_ASSERT(); | 1087 NFSD_UNLOCK_ASSERT(); |
1084 1085 *vpp = NULL; 1086 1087 if (nfs_ispublicfh(fhp)) { 1088 if (!pubflag || !nfs_pub.np_valid) 1089 return (ESTALE); 1090 fhp = &nfs_pub.np_handle; 1091 } 1092 1093 mp = vfs_getvfs(&fhp->fh_fsid); 1094 if (!mp) 1095 return (ESTALE); | 1088 1089 *vpp = NULL; 1090 1091 if (nfs_ispublicfh(fhp)) { 1092 if (!pubflag || !nfs_pub.np_valid) 1093 return (ESTALE); 1094 fhp = &nfs_pub.np_handle; 1095 } 1096 1097 mp = vfs_getvfs(&fhp->fh_fsid); 1098 if (!mp) 1099 return (ESTALE); |
1096 NFSD_UNLOCK(); | |
1097 vfslocked = VFS_LOCK_GIANT(mp); 1098 error = VFS_CHECKEXP(mp, nam, &exflags, &credanon); 1099 if (error) 1100 goto out; 1101 error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); 1102 if (error) 1103 goto out; 1104#ifdef MNT_EXNORESPORT --- 23 unchanged lines hidden (view full) --- 1128 else 1129 *rdonlyp = 0; 1130 1131 if (!lockflag) 1132 VOP_UNLOCK(*vpp, 0, td); 1133out: 1134 vfs_rel(mp); 1135 VFS_UNLOCK_GIANT(vfslocked); | 1100 vfslocked = VFS_LOCK_GIANT(mp); 1101 error = VFS_CHECKEXP(mp, nam, &exflags, &credanon); 1102 if (error) 1103 goto out; 1104 error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); 1105 if (error) 1106 goto out; 1107#ifdef MNT_EXNORESPORT --- 23 unchanged lines hidden (view full) --- 1131 else 1132 *rdonlyp = 0; 1133 1134 if (!lockflag) 1135 VOP_UNLOCK(*vpp, 0, td); 1136out: 1137 vfs_rel(mp); 1138 VFS_UNLOCK_GIANT(vfslocked); |
1136 NFSD_LOCK(); | |
1137 return (error); 1138} 1139 | 1139 return (error); 1140} 1141 |
1142/* 1143 * Version of nfsrv_fhtovp() that can be called holding nfsd_mtx: it will 1144 * drop and re-acquire the lock for the caller. 1145 */ 1146int 1147nfsrv_fhtovp_locked(fhandle_t *fhp, int lockflag, struct vnode **vpp, 1148 struct ucred *cred, struct nfssvc_sock *slp, struct sockaddr *nam, 1149 int *rdonlyp, int pubflag) 1150{ 1151 int error; |
|
1140 | 1152 |
1153 NFSD_LOCK_ASSERT(); 1154 NFSD_UNLOCK(); 1155 error = nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, 1156 pubflag); 1157 NFSD_LOCK(); 1158 return (error); 1159} 1160 |
|
1141/* 1142 * WebNFS: check if a filehandle is a public filehandle. For v3, this 1143 * means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has 1144 * transformed this to all zeroes in both cases, so check for it. 1145 */ 1146int 1147nfs_ispublicfh(fhandle_t *fhp) 1148{ --- 334 unchanged lines hidden --- | 1161/* 1162 * WebNFS: check if a filehandle is a public filehandle. For v3, this 1163 * means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has 1164 * transformed this to all zeroes in both cases, so check for it. 1165 */ 1166int 1167nfs_ispublicfh(fhandle_t *fhp) 1168{ --- 334 unchanged lines hidden --- |