Deleted Added
full compact
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 ---