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/fs/nfsclient/nfs_clcomsubs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 4. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   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  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: releng/11.2/sys/fs/nfsclient/nfs_clcomsubs.c 331722 2018-03-29 02:50:57Z eadler $");
   36 
   37 /*
   38  * These functions support the macros and help fiddle mbuf chains for
   39  * the nfs op functions. They do things like create the rpc header and
   40  * copy data between mbuf chains and uio lists.
   41  */
   42 #ifndef APPLEKEXT
   43 #include <fs/nfs/nfsport.h>
   44 
   45 extern struct nfsstatsv1 nfsstatsv1;
   46 extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
   47 extern int ncl_mbuf_mlen;
   48 extern enum vtype newnv2tov_type[8];
   49 extern enum vtype nv34tov_type[8];
   50 extern int      nfs_bigreply[NFSV41_NPROCS];
   51 NFSCLSTATEMUTEX;
   52 #endif  /* !APPLEKEXT */
   53 
   54 static nfsuint64 nfs_nullcookie = {{ 0, 0 }};
   55 static struct {
   56         int     op;
   57         int     opcnt;
   58         const u_char *tag;
   59         int     taglen;
   60 } nfsv4_opmap[NFSV41_NPROCS] = {
   61         { 0, 1, "Null", 4 },
   62         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   63         { NFSV4OP_SETATTR, 2, "Setattr", 7, },
   64         { NFSV4OP_LOOKUP, 3, "Lookup", 6, },
   65         { NFSV4OP_ACCESS, 2, "Access", 6, },
   66         { NFSV4OP_READLINK, 2, "Readlink", 8, },
   67         { NFSV4OP_READ, 1, "Read", 4, },
   68         { NFSV4OP_WRITE, 2, "Write", 5, },
   69         { NFSV4OP_OPEN, 5, "Open", 4, },
   70         { NFSV4OP_CREATE, 5, "Create", 6, },
   71         { NFSV4OP_CREATE, 1, "Create", 6, },
   72         { NFSV4OP_CREATE, 3, "Create", 6, },
   73         { NFSV4OP_REMOVE, 1, "Remove", 6, },
   74         { NFSV4OP_REMOVE, 1, "Remove", 6, },
   75         { NFSV4OP_SAVEFH, 5, "Rename", 6, },
   76         { NFSV4OP_SAVEFH, 4, "Link", 4, },
   77         { NFSV4OP_READDIR, 2, "Readdir", 7, },
   78         { NFSV4OP_READDIR, 2, "Readdir", 7, },
   79         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   80         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   81         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   82         { NFSV4OP_COMMIT, 2, "Commit", 6, },
   83         { NFSV4OP_LOOKUPP, 3, "Lookupp", 7, },
   84         { NFSV4OP_SETCLIENTID, 1, "SetClientID", 11, },
   85         { NFSV4OP_SETCLIENTIDCFRM, 1, "SetClientIDConfirm", 18, },
   86         { NFSV4OP_LOCK, 1, "Lock", 4, },
   87         { NFSV4OP_LOCKU, 1, "LockU", 5, },
   88         { NFSV4OP_OPEN, 2, "Open", 4, },
   89         { NFSV4OP_CLOSE, 1, "Close", 5, },
   90         { NFSV4OP_OPENCONFIRM, 1, "Openconfirm", 11, },
   91         { NFSV4OP_LOCKT, 1, "LockT", 5, },
   92         { NFSV4OP_OPENDOWNGRADE, 1, "Opendowngrade", 13, },
   93         { NFSV4OP_RENEW, 1, "Renew", 5, },
   94         { NFSV4OP_PUTROOTFH, 1, "Dirpath", 7, },
   95         { NFSV4OP_RELEASELCKOWN, 1, "Rellckown", 9, },
   96         { NFSV4OP_DELEGRETURN, 1, "Delegret", 8, },
   97         { NFSV4OP_DELEGRETURN, 3, "DelegRemove", 11, },
   98         { NFSV4OP_DELEGRETURN, 7, "DelegRename1", 12, },
   99         { NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, },
  100         { NFSV4OP_GETATTR, 1, "Getacl", 6, },
  101         { NFSV4OP_SETATTR, 1, "Setacl", 6, },
  102         { NFSV4OP_EXCHANGEID, 1, "ExchangeID", 10, },
  103         { NFSV4OP_CREATESESSION, 1, "CreateSession", 13, },
  104         { NFSV4OP_DESTROYSESSION, 1, "DestroySession", 14, },
  105         { NFSV4OP_DESTROYCLIENTID, 1, "DestroyClient", 13, },
  106         { NFSV4OP_FREESTATEID, 1, "FreeStateID", 11, },
  107         { NFSV4OP_LAYOUTGET, 1, "LayoutGet", 9, },
  108         { NFSV4OP_GETDEVINFO, 1, "GetDeviceInfo", 13, },
  109         { NFSV4OP_LAYOUTCOMMIT, 1, "LayoutCommit", 12, },
  110         { NFSV4OP_LAYOUTRETURN, 1, "LayoutReturn", 12, },
  111         { NFSV4OP_RECLAIMCOMPL, 1, "ReclaimComplete", 15, },
  112         { NFSV4OP_WRITE, 1, "WriteDS", 7, },
  113         { NFSV4OP_READ, 1, "ReadDS", 6, },
  114         { NFSV4OP_COMMIT, 1, "CommitDS", 8, },
  115         { NFSV4OP_OPEN, 3, "OpenLayoutGet", 13, },
  116         { NFSV4OP_OPEN, 8, "CreateLayGet", 12, },
  117 };
  118 
  119 /*
  120  * NFS RPCS that have large request message size.
  121  */
  122 static int nfs_bigrequest[NFSV41_NPROCS] = {
  123         0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  124         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  125         0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
  126 };
  127 
  128 /*
  129  * Start building a request. Mostly just put the first file handle in
  130  * place.
  131  */
  132 APPLESTATIC void
  133 nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
  134     u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep)
  135 {
  136         struct mbuf *mb;
  137         u_int32_t *tl;
  138         int opcnt;
  139         nfsattrbit_t attrbits;
  140 
  141         /*
  142          * First, fill in some of the fields of nd.
  143          */
  144         nd->nd_slotseq = NULL;
  145         if (NFSHASNFSV4(nmp)) {
  146                 nd->nd_flag = ND_NFSV4 | ND_NFSCL;
  147                 if (NFSHASNFSV4N(nmp))
  148                         nd->nd_flag |= ND_NFSV41;
  149         } else if (NFSHASNFSV3(nmp))
  150                 nd->nd_flag = ND_NFSV3 | ND_NFSCL;
  151         else
  152                 nd->nd_flag = ND_NFSV2 | ND_NFSCL;
  153         nd->nd_procnum = procnum;
  154         nd->nd_repstat = 0;
  155 
  156         /*
  157          * Get the first mbuf for the request.
  158          */
  159         if (nfs_bigrequest[procnum])
  160                 NFSMCLGET(mb, M_WAITOK);
  161         else
  162                 NFSMGET(mb);
  163         mbuf_setlen(mb, 0);
  164         nd->nd_mreq = nd->nd_mb = mb;
  165         nd->nd_bpos = NFSMTOD(mb, caddr_t);
  166         
  167         /*
  168          * And fill the first file handle into the request.
  169          */
  170         if (nd->nd_flag & ND_NFSV4) {
  171                 opcnt = nfsv4_opmap[procnum].opcnt +
  172                     nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh;
  173                 if ((nd->nd_flag & ND_NFSV41) != 0) {
  174                         opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq;
  175                         if (procnum == NFSPROC_RENEW)
  176                                 /*
  177                                  * For the special case of Renew, just do a
  178                                  * Sequence Op.
  179                                  */
  180                                 opcnt = 1;
  181                         else if (procnum == NFSPROC_WRITEDS ||
  182                             procnum == NFSPROC_COMMITDS)
  183                                 /*
  184                                  * For the special case of a Writeor Commit to
  185                                  * a DS, the opcnt == 3, for Sequence, PutFH,
  186                                  * Write/Commit.
  187                                  */
  188                                 opcnt = 3;
  189                 }
  190                 /*
  191                  * What should the tag really be?
  192                  */
  193                 (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag,
  194                         nfsv4_opmap[procnum].taglen);
  195                 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  196                 if ((nd->nd_flag & ND_NFSV41) != 0)
  197                         *tl++ = txdr_unsigned(NFSV41_MINORVERSION);
  198                 else
  199                         *tl++ = txdr_unsigned(NFSV4_MINORVERSION);
  200                 if (opcntpp != NULL)
  201                         *opcntpp = tl;
  202                 *tl = txdr_unsigned(opcnt);
  203                 if ((nd->nd_flag & ND_NFSV41) != 0 &&
  204                     nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) {
  205                         if (nfsv4_opflag[nfsv4_opmap[procnum].op].loopbadsess >
  206                             0)
  207                                 nd->nd_flag |= ND_LOOPBADSESS;
  208                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  209                         *tl = txdr_unsigned(NFSV4OP_SEQUENCE);
  210                         if (sep == NULL) {
  211                                 sep = nfsmnt_mdssession(nmp);
  212                                 nfsv4_setsequence(nmp, nd, sep,
  213                                     nfs_bigreply[procnum]);
  214                         } else
  215                                 nfsv4_setsequence(nmp, nd, sep,
  216                                     nfs_bigreply[procnum]);
  217                 }
  218                 if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
  219                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  220                         *tl = txdr_unsigned(NFSV4OP_PUTFH);
  221                         (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  222                         if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh
  223                             == 2 && procnum != NFSPROC_WRITEDS &&
  224                             procnum != NFSPROC_COMMITDS) {
  225                                 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  226                                 *tl = txdr_unsigned(NFSV4OP_GETATTR);
  227                                 /*
  228                                  * For Lookup Ops, we want all the directory
  229                                  * attributes, so we can load the name cache.
  230                                  */
  231                                 if (procnum == NFSPROC_LOOKUP ||
  232                                     procnum == NFSPROC_LOOKUPP)
  233                                         NFSGETATTR_ATTRBIT(&attrbits);
  234                                 else {
  235                                         NFSWCCATTR_ATTRBIT(&attrbits);
  236                                         nd->nd_flag |= ND_V4WCCATTR;
  237                                 }
  238                                 (void) nfsrv_putattrbit(nd, &attrbits);
  239                         }
  240                 }
  241                 if (procnum != NFSPROC_RENEW ||
  242                     (nd->nd_flag & ND_NFSV41) == 0) {
  243                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  244                         *tl = txdr_unsigned(nfsv4_opmap[procnum].op);
  245                 }
  246         } else {
  247                 (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  248         }
  249         if (procnum < NFSV41_NPROCS)
  250                 NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]);
  251 }
  252 
  253 #ifndef APPLE
  254 /*
  255  * copies a uio scatter/gather list to an mbuf chain.
  256  * NOTE: can ony handle iovcnt == 1
  257  */
  258 APPLESTATIC void
  259 nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
  260 {
  261         char *uiocp;
  262         struct mbuf *mp, *mp2;
  263         int xfer, left, mlen;
  264         int uiosiz, clflg, rem;
  265         char *cp, *tcp;
  266 
  267         KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
  268 
  269         if (siz > ncl_mbuf_mlen)        /* or should it >= MCLBYTES ?? */
  270                 clflg = 1;
  271         else
  272                 clflg = 0;
  273         rem = NFSM_RNDUP(siz) - siz;
  274         mp = mp2 = nd->nd_mb;
  275         while (siz > 0) {
  276                 left = uiop->uio_iov->iov_len;
  277                 uiocp = uiop->uio_iov->iov_base;
  278                 if (left > siz)
  279                         left = siz;
  280                 uiosiz = left;
  281                 while (left > 0) {
  282                         mlen = M_TRAILINGSPACE(mp);
  283                         if (mlen == 0) {
  284                                 if (clflg)
  285                                         NFSMCLGET(mp, M_WAITOK);
  286                                 else
  287                                         NFSMGET(mp);
  288                                 mbuf_setlen(mp, 0);
  289                                 mbuf_setnext(mp2, mp);
  290                                 mp2 = mp;
  291                                 mlen = M_TRAILINGSPACE(mp);
  292                         }
  293                         xfer = (left > mlen) ? mlen : left;
  294 #ifdef notdef
  295                         /* Not Yet.. */
  296                         if (uiop->uio_iov->iov_op != NULL)
  297                                 (*(uiop->uio_iov->iov_op))
  298                                 (uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  299                                     xfer);
  300                         else
  301 #endif
  302                         if (uiop->uio_segflg == UIO_SYSSPACE)
  303                             NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  304                                 xfer);
  305                         else
  306                             copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
  307                                 + mbuf_len(mp), xfer);
  308                         mbuf_setlen(mp, mbuf_len(mp) + xfer);
  309                         left -= xfer;
  310                         uiocp += xfer;
  311                         uiop->uio_offset += xfer;
  312                         uiop->uio_resid -= xfer;
  313                 }
  314                 tcp = (char *)uiop->uio_iov->iov_base;
  315                 tcp += uiosiz;
  316                 uiop->uio_iov->iov_base = (void *)tcp;
  317                 uiop->uio_iov->iov_len -= uiosiz;
  318                 siz -= uiosiz;
  319         }
  320         if (rem > 0) {
  321                 if (rem > M_TRAILINGSPACE(mp)) {
  322                         NFSMGET(mp);
  323                         mbuf_setlen(mp, 0);
  324                         mbuf_setnext(mp2, mp);
  325                 }
  326                 cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  327                 for (left = 0; left < rem; left++)
  328                         *cp++ = '\0';
  329                 mbuf_setlen(mp, mbuf_len(mp) + rem);
  330                 nd->nd_bpos = cp;
  331         } else
  332                 nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  333         nd->nd_mb = mp;
  334 }
  335 #endif  /* !APPLE */
  336 
  337 /*
  338  * Load vnode attributes from the xdr file attributes.
  339  * Returns EBADRPC if they can't be parsed, 0 otherwise.
  340  */
  341 APPLESTATIC int
  342 nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
  343 {
  344         struct nfs_fattr *fp;
  345         int error = 0;
  346 
  347         if (nd->nd_flag & ND_NFSV4) {
  348                 error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
  349                     NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL);
  350         } else if (nd->nd_flag & ND_NFSV3) {
  351                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
  352                 nap->na_type = nfsv34tov_type(fp->fa_type);
  353                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  354                 nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
  355                         fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
  356                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  357                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  358                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  359                 nap->na_size = fxdr_hyper(&fp->fa3_size);
  360                 nap->na_blocksize = NFS_FABLKSIZE;
  361                 nap->na_bytes = fxdr_hyper(&fp->fa3_used);
  362                 nap->na_fileid = fxdr_hyper(&fp->fa3_fileid);
  363                 fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime);
  364                 fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime);
  365                 fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime);
  366                 nap->na_flags = 0;
  367                 nap->na_filerev = 0;
  368         } else {
  369                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V2FATTR);
  370                 nap->na_type = nfsv2tov_type(fp->fa_type);
  371                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  372                 if (nap->na_type == VNON || nap->na_type == VREG)
  373                         nap->na_type = IFTOVT(nap->na_mode);
  374                 nap->na_rdev = fxdr_unsigned(dev_t, fp->fa2_rdev);
  375 
  376                 /*
  377                  * Really ugly NFSv2 kludge.
  378                  */
  379                 if (nap->na_type == VCHR && nap->na_rdev == ((dev_t)-1))
  380                         nap->na_type = VFIFO;
  381                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  382                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  383                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  384                 nap->na_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
  385                 nap->na_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
  386                 nap->na_bytes =
  387                     (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
  388                     NFS_FABLKSIZE;
  389                 nap->na_fileid = fxdr_unsigned(uint64_t, fp->fa2_fileid);
  390                 fxdr_nfsv2time(&fp->fa2_atime, &nap->na_atime);
  391                 fxdr_nfsv2time(&fp->fa2_mtime, &nap->na_mtime);
  392                 nap->na_flags = 0;
  393                 nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t,
  394                     fp->fa2_ctime.nfsv2_sec);
  395                 nap->na_ctime.tv_nsec = 0;
  396                 nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
  397                 nap->na_filerev = 0;
  398         }
  399 nfsmout:
  400         return (error);
  401 }
  402 
  403 /*
  404  * This function finds the directory cookie that corresponds to the
  405  * logical byte offset given.
  406  */
  407 APPLESTATIC nfsuint64 *
  408 nfscl_getcookie(struct nfsnode *np, off_t off, int add)
  409 {
  410         struct nfsdmap *dp, *dp2;
  411         int pos;
  412 
  413         pos = off / NFS_DIRBLKSIZ;
  414         if (pos == 0) {
  415                 KASSERT(!add, ("nfs getcookie add at 0"));
  416                 return (&nfs_nullcookie);
  417         }
  418         pos--;
  419         dp = LIST_FIRST(&np->n_cookies);
  420         if (!dp) {
  421                 if (add) {
  422                         MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
  423                                 M_NFSDIROFF, M_WAITOK);
  424                         dp->ndm_eocookie = 0;
  425                         LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
  426                 } else
  427                         return (NULL);
  428         }
  429         while (pos >= NFSNUMCOOKIES) {
  430                 pos -= NFSNUMCOOKIES;
  431                 if (LIST_NEXT(dp, ndm_list) != NULL) {
  432                         if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
  433                                 pos >= dp->ndm_eocookie)
  434                                 return (NULL);
  435                         dp = LIST_NEXT(dp, ndm_list);
  436                 } else if (add) {
  437                         MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
  438                                 M_NFSDIROFF, M_WAITOK);
  439                         dp2->ndm_eocookie = 0;
  440                         LIST_INSERT_AFTER(dp, dp2, ndm_list);
  441                         dp = dp2;
  442                 } else
  443                         return (NULL);
  444         }
  445         if (pos >= dp->ndm_eocookie) {
  446                 if (add)
  447                         dp->ndm_eocookie = pos + 1;
  448                 else
  449                         return (NULL);
  450         }
  451         return (&dp->ndm_cookies[pos]);
  452 }
  453 
  454 /*
  455  * Gets a file handle out of an nfs reply sent to the client and returns
  456  * the file handle and the file's attributes.
  457  * For V4, it assumes that Getfh and Getattr Op's results are here.
  458  */
  459 APPLESTATIC int
  460 nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh **nfhpp,
  461     struct nfsvattr *nap, int *attrflagp)
  462 {
  463         u_int32_t *tl;
  464         int error = 0, flag = 1;
  465 
  466         *nfhpp = NULL;
  467         *attrflagp = 0;
  468         /*
  469          * First get the file handle and vnode.
  470          */
  471         if (nd->nd_flag & ND_NFSV3) {
  472                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  473                 flag = fxdr_unsigned(int, *tl);
  474         } else if (nd->nd_flag & ND_NFSV4) {
  475                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  476                 /* If the GetFH failed, clear flag. */
  477                 if (*++tl != 0) {
  478                         nd->nd_flag |= ND_NOMOREDATA;
  479                         flag = 0;
  480                         error = ENXIO;  /* Return ENXIO so *nfhpp isn't used. */
  481                 }
  482         }
  483         if (flag) {
  484                 error = nfsm_getfh(nd, nfhpp);
  485                 if (error)
  486                         return (error);
  487         }
  488 
  489         /*
  490          * Now, get the attributes.
  491          */
  492         if (flag != 0 && (nd->nd_flag & ND_NFSV4) != 0) {
  493                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  494                 if (*++tl != 0) {
  495                         nd->nd_flag |= ND_NOMOREDATA;
  496                         flag = 0;
  497                 }
  498         } else if (nd->nd_flag & ND_NFSV3) {
  499                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  500                 if (flag) {
  501                         flag = fxdr_unsigned(int, *tl);
  502                 } else if (fxdr_unsigned(int, *tl)) {
  503                         error = nfsm_advance(nd, NFSX_V3FATTR, -1);
  504                         if (error)
  505                                 return (error);
  506                 }
  507         }
  508         if (flag) {
  509                 error = nfsm_loadattr(nd, nap);
  510                 if (!error)
  511                         *attrflagp = 1;
  512         }
  513 nfsmout:
  514         return (error);
  515 }
  516 
  517 /*
  518  * Put a state Id in the mbuf list.
  519  */
  520 APPLESTATIC void
  521 nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag)
  522 {
  523         nfsv4stateid_t *st;
  524 
  525         NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID);
  526         if (flag == NFSSTATEID_PUTALLZERO) {
  527                 st->seqid = 0;
  528                 st->other[0] = 0;
  529                 st->other[1] = 0;
  530                 st->other[2] = 0;
  531         } else if (flag == NFSSTATEID_PUTALLONE) {
  532                 st->seqid = 0xffffffff;
  533                 st->other[0] = 0xffffffff;
  534                 st->other[1] = 0xffffffff;
  535                 st->other[2] = 0xffffffff;
  536         } else if (flag == NFSSTATEID_PUTSEQIDZERO) {
  537                 st->seqid = 0;
  538                 st->other[0] = stateidp->other[0];
  539                 st->other[1] = stateidp->other[1];
  540                 st->other[2] = stateidp->other[2];
  541         } else {
  542                 st->seqid = stateidp->seqid;
  543                 st->other[0] = stateidp->other[0];
  544                 st->other[1] = stateidp->other[1];
  545                 st->other[2] = stateidp->other[2];
  546         }
  547 }
  548 
  549 /*
  550  * Initialize the owner/delegation sleep lock.
  551  */
  552 APPLESTATIC void
  553 nfscl_lockinit(struct nfsv4lock *lckp)
  554 {
  555 
  556         lckp->nfslock_usecnt = 0;
  557         lckp->nfslock_lock = 0;
  558 }
  559 
  560 /*
  561  * Get an exclusive lock. (Not needed for OpenBSD4, since there is only one
  562  * thread for each posix process in the kernel.)
  563  */
  564 APPLESTATIC void
  565 nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
  566 {
  567         int igotlock;
  568 
  569         do {
  570                 igotlock = nfsv4_lock(lckp, 1, NULL, mutex, NULL);
  571         } while (!igotlock);
  572 }
  573 
  574 /*
  575  * Release an exclusive lock.
  576  */
  577 APPLESTATIC void
  578 nfscl_lockunlock(struct nfsv4lock *lckp)
  579 {
  580 
  581         nfsv4_unlock(lckp, 0);
  582 }
  583 
  584 /*
  585  * Called to derefernce a lock on a stateid (delegation or open owner).
  586  */
  587 APPLESTATIC void
  588 nfscl_lockderef(struct nfsv4lock *lckp)
  589 {
  590 
  591         NFSLOCKCLSTATE();
  592         lckp->nfslock_usecnt--;
  593         if (lckp->nfslock_usecnt == 0 && (lckp->nfslock_lock & NFSV4LOCK_WANTED)) {
  594                 lckp->nfslock_lock &= ~NFSV4LOCK_WANTED;
  595                 wakeup((caddr_t)lckp);
  596         }
  597         NFSUNLOCKCLSTATE();
  598 }
  599 

Cache object: bb670473bc8f1cf9657942892eb5f7fa


[ 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.