The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/nfs4client/nfs4_socket.c

Version: -  FREEBSD  -  FREEBSD11  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD$ */
    2 /* $Id: nfs_socket.c,v 1.12 2003/11/05 14:59:01 rees Exp $ */
    3 
    4 /*-
    5  * copyright (c) 2003
    6  * the regents of the university of michigan
    7  * all rights reserved
    8  * 
    9  * permission is granted to use, copy, create derivative works and redistribute
   10  * this software and such derivative works for any purpose, so long as the name
   11  * of the university of michigan is not used in any advertising or publicity
   12  * pertaining to the use or distribution of this software without specific,
   13  * written prior authorization.  if the above copyright notice or any other
   14  * identification of the university of michigan is included in any copy of any
   15  * portion of this software, then the disclaimer below must also be included.
   16  * 
   17  * this software is provided as is, without representation from the university
   18  * of michigan as to its fitness for any purpose, and without warranty by the
   19  * university of michigan of any kind, either express or implied, including
   20  * without limitation the implied warranties of merchantability and fitness for
   21  * a particular purpose. the regents of the university of michigan shall not be
   22  * liable for any damages, including special, indirect, incidental, or
   23  * consequential damages, with respect to any claim arising out of or in
   24  * connection with the use of the software, even if it has been or is hereafter
   25  * advised of the possibility of such damages.
   26  */
   27 
   28 /*-
   29  * Copyright (c) 1989, 1991, 1993, 1995
   30  *      The Regents of the University of California.  All rights reserved.
   31  *
   32  * This code is derived from software contributed to Berkeley by
   33  * Rick Macklem at The University of Guelph.
   34  *
   35  * Redistribution and use in source and binary forms, with or without
   36  * modification, are permitted provided that the following conditions
   37  * are met:
   38  * 1. Redistributions of source code must retain the above copyright
   39  *    notice, this list of conditions and the following disclaimer.
   40  * 2. Redistributions in binary form must reproduce the above copyright
   41  *    notice, this list of conditions and the following disclaimer in the
   42  *    documentation and/or other materials provided with the distribution.
   43  * 4. Neither the name of the University nor the names of its contributors
   44  *    may be used to endorse or promote products derived from this software
   45  *    without specific prior written permission.
   46  *
   47  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   48  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   50  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   51  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   55  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   56  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   57  * SUCH DAMAGE.
   58  *
   59  *      @(#)nfs_socket.c        8.5 (Berkeley) 3/30/95
   60  */
   61 
   62 #include <sys/cdefs.h>
   63 __FBSDID("$FreeBSD$");
   64 
   65 /*
   66  * Socket operations for use by nfs
   67  */
   68 
   69 #include "opt_inet6.h"
   70 
   71 #include <sys/param.h>
   72 #include <sys/systm.h>
   73 #include <sys/kernel.h>
   74 #include <sys/lock.h>
   75 #include <sys/malloc.h>
   76 #include <sys/mbuf.h>
   77 #include <sys/mount.h>
   78 #include <sys/mutex.h>
   79 #include <sys/proc.h>
   80 #include <sys/protosw.h>
   81 #include <sys/signalvar.h>
   82 #include <sys/socket.h>
   83 #include <sys/socketvar.h>
   84 #include <sys/syslog.h>
   85 #include <sys/vnode.h>
   86 
   87 #include <netinet/in.h>
   88 #include <netinet/tcp.h>
   89 
   90 #include <rpc/rpcclnt.h>
   91 
   92 #include <nfs/rpcv2.h>
   93 #include <nfs/nfsproto.h>
   94 #include <nfsclient/nfs.h>
   95 #include <nfs4client/nfs4.h>
   96 #include <nfs/xdr_subs.h>
   97 #include <nfsclient/nfsm_subs.h>
   98 #include <nfsclient/nfsmount.h>
   99 
  100 #ifdef NFS4_USE_RPCCLNT
  101 #include <rpc/rpcclnt.h>
  102 #include <rpc/rpcm_subs.h>
  103 #endif
  104 
  105 #ifdef NFS4_USE_RPCCLNT
  106 static struct rpc_program nfs_program = {
  107   NFS_PROG, NFS_VER4, "NFSv4"
  108 };
  109 #endif
  110 
  111 
  112 static struct {
  113         short   nfserr;
  114         short   syserr;
  115 } nfs_errtbl[] = {
  116         { NFS_OK,               0 },
  117         { NFSERR_PERM,          EPERM },
  118         { NFSERR_NOENT,         ENOENT },
  119         { NFSERR_IO,            EIO },
  120         { NFSERR_NXIO,          ENXIO },
  121         { NFSERR_ACCES,         EACCES },
  122         { NFSERR_EXIST,         EEXIST },
  123         { NFSERR_XDEV,          EXDEV },
  124         { NFSERR_MLINK,         EMLINK },
  125         { NFSERR_NODEV,         ENODEV },
  126         { NFSERR_NOTDIR,        ENOTDIR },
  127         { NFSERR_ISDIR,         EISDIR },
  128         { NFSERR_INVAL,         EINVAL },
  129         { NFSERR_FBIG,          EFBIG },
  130         { NFSERR_NOSPC,         ENOSPC },
  131         { NFSERR_ROFS,          EROFS },
  132         { NFSERR_MLINK,         EMLINK },
  133         { NFSERR_NAMETOL,       ENAMETOOLONG },
  134         { NFSERR_NOTEMPTY,      ENOTEMPTY },
  135         { NFSERR_NOTSUPP,       EOPNOTSUPP },
  136 #ifdef EDQUOT
  137         { NFSERR_DQUOT,         EDQUOT },
  138 #endif
  139         { NFSERR_STALE,         ESTALE },
  140         { NFSERR_DENIED,        EAGAIN },
  141         { NFSERR_SYMLINK,       ELOOP },
  142         { NFSERR_BADXDR,        EBADRPC },
  143         { NFSERR_WRONGSEC,      EPERM },
  144         { -1,                   EIO }
  145 };
  146 
  147 static int
  148 nfs4_nfserr_to_syserr(int nfserr)
  149 {
  150         int i, syserr;
  151         
  152         /* XXX : not the optimal algorithm, but will do for now! */
  153         for (i = 0; nfs_errtbl[i].nfserr != -1; i++) {
  154                 if (nfs_errtbl[i].nfserr == nfserr)
  155                         break;
  156         }
  157 #ifdef NFS4_MAP_UNKNOWN_ERR
  158         syserr = nfs_errtbl[i].syserr;
  159 #else
  160         if (nfs_errtbl[i].nfserr != -1)
  161                 syserr = nfs_errtbl[i].syserr;
  162         else
  163                 syserr = nfserr;
  164 #endif
  165         return syserr;
  166 }
  167 
  168 int
  169 nfs4_connect(struct nfsmount *nmp)
  170 {
  171         struct rpcclnt * rpc = &nmp->nm_rpcclnt;
  172         struct rpc_auth * auth;
  173         int flag = 0;
  174         int error;
  175 
  176         /* XXX hack! */
  177 #ifdef __OpenBSD__
  178         struct proc * td = curproc;
  179 #else
  180         struct thread * td = curthread;
  181 #endif
  182 
  183         MALLOC(auth, struct rpc_auth *, sizeof(struct rpc_auth), M_TEMP, M_WAITOK);
  184         auth->auth_type  = RPCAUTH_UNIX;
  185 
  186         /* translate nfs flags -> rpcclnt flags */
  187         if (nmp->nm_flag & NFSMNT_SOFT)
  188                 flag |= RPCCLNT_SOFT;
  189 
  190         if (nmp->nm_flag & NFSMNT_INT)
  191                 flag |= RPCCLNT_INT;
  192 
  193         if (nmp->nm_flag & NFSMNT_NOCONN)
  194                 flag |= RPCCLNT_NOCONN;
  195 
  196         if (nmp->nm_flag & NFSMNT_DUMBTIMR)
  197                 flag |= RPCCLNT_DUMBTIMR;
  198 
  199         /* rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname; */
  200                                   
  201         error = rpcclnt_setup(rpc, &nfs_program, nmp->nm_nam, nmp->nm_sotype,
  202                               nmp->nm_soproto, auth, 
  203                               /* XXX: check nmp->nm_flag to make sure these are set */
  204                               (nmp->nm_rsize > nmp->nm_readdirsize) ? nmp->nm_rsize : nmp->nm_readdirsize,
  205                               nmp->nm_wsize, flag);
  206 
  207         /* set deadthresh, timeo, retry */
  208         rpc->rc_deadthresh = nmp->nm_deadthresh;
  209         rpc->rc_timeo = nmp->nm_timeo;
  210         rpc->rc_retry = nmp->nm_retry;
  211 
  212 
  213         if (error)
  214                 return error;
  215 
  216         return rpcclnt_connect(rpc, td);
  217 }
  218 
  219 /*
  220  * NFS disconnect. Clean up and unlink.
  221  */
  222 void
  223 nfs4_disconnect(struct nfsmount *nmp)
  224 {
  225         rpcclnt_disconnect(&nmp->nm_rpcclnt);
  226 }
  227 
  228 void
  229 nfs4_safedisconnect(struct nfsmount *nmp)
  230 {
  231         rpcclnt_safedisconnect(&nmp->nm_rpcclnt);
  232 }
  233 
  234 /*
  235  * nfs_request - goes something like this
  236  *      - fill in request struct
  237  *      - links it into list
  238  *      - calls nfs_send() for first transmit
  239  *      - calls nfs_receive() to get reply
  240  *      - break down rpc header and return with nfs reply pointed to
  241  *        by mrep or error
  242  * nb: always frees up mreq mbuf list
  243  */
  244 /* XXX overloaded before */
  245 #define NQ_TRYLATERDEL  15      /* Initial try later delay (sec) */
  246 
  247 int
  248 nfs4_request(struct vnode *vp, struct mbuf *mrest, int procnum,
  249     struct thread *td, struct ucred *cred, struct mbuf **mrp,
  250     struct mbuf **mdp, caddr_t *dposp)
  251 {
  252         int error;
  253 
  254         error = nfs4_request_mnt(VFSTONFS(vp->v_mount), mrest, procnum,
  255                                  td, cred, mrp, mdp, dposp);
  256 
  257         /*
  258          ** If the File Handle was stale, invalidate the
  259          ** lookup cache, just in case.
  260          **/
  261         if (error == ESTALE)
  262                 cache_purge(vp);
  263 
  264         return (error);
  265 }
  266 
  267 
  268 int
  269 nfs4_request_mnt(struct nfsmount *nmp, struct mbuf *mrest, int procnum,
  270     struct thread *td, struct ucred *cred, struct mbuf **mrp,
  271     struct mbuf **mdp, caddr_t *dposp)
  272 {
  273         int error;
  274         u_int32_t *tl;
  275         struct rpcclnt * clnt = &nmp->nm_rpcclnt;
  276         struct mbuf *md, *mrep;
  277         caddr_t dpos;
  278         struct rpc_reply reply;
  279 
  280         if ((error = rpcclnt_request(clnt, mrest, procnum, td, cred,
  281             &reply)) != 0) {
  282                 goto out;
  283         }
  284 
  285         /* XXX: don't free mrest if an error occured, to allow caller to retry*/
  286         m_freem(mrest);
  287         mrep = reply.mrep;
  288         md = reply.result_md;
  289         dpos = reply.result_dpos;
  290 
  291         tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
  292         if (*tl != 0) {
  293                 error = fxdr_unsigned(int, *tl);
  294 #if 0
  295                 if ((nmp->nm_flag & NFSMNT_NFSV3) &&
  296                     error == NFSERR_TRYLATER) {
  297                         m_freem(mrep);
  298                         error = 0;
  299                         waituntil = time_second + trylater_delay;
  300                         while (time_second < waituntil)
  301                                 (void) tsleep(&lbolt, PSOCK, "nqnfstry", 0);
  302                         trylater_delay *= nfs_backoff[trylater_cnt];
  303                         if (trylater_cnt < NFS_NBACKOFF - 1)
  304                                 trylater_cnt++;
  305                         goto tryagain;
  306                 }
  307 #endif
  308                 goto out;
  309         }
  310 
  311         *mrp = mrep;
  312         *mdp = md;
  313         *dposp = dpos;
  314         return (0);
  315 nfsmout:
  316 out:
  317         m_freem(reply.mrep);
  318         *mrp = NULL;
  319         *mdp = NULL;
  320         return (nfs4_nfserr_to_syserr(error));
  321 }
  322 
  323 
  324 /*
  325  * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
  326  * wait for all requests to complete. This is used by forced unmounts
  327  * to terminate any outstanding RPCs.
  328  */
  329 int
  330 nfs4_nmcancelreqs(nmp)
  331         struct nfsmount *nmp;
  332 {
  333         return rpcclnt_cancelreqs(&nmp->nm_rpcclnt);
  334 }
  335 
  336 /*
  337  * Test for a termination condition pending on the process.
  338  * This is used for NFSMNT_INT mounts.
  339  */
  340 int
  341 nfs4_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
  342 {
  343         if (rep != NULL) {
  344                 printf("nfs_sigintr: attempting to use nfsreq != NULL\n");
  345                 return EINTR;
  346         }
  347         return rpcclnt_sigintr(&nmp->nm_rpcclnt, NULL, td);
  348 }

Cache object: 02db93c98e6cdd4bcc3a751d79cae05e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.