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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  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 /*-
    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/10.0/sys/fs/nfsclient/nfs_clcomsubs.c 244042 2012-12-08 22:52:39Z rmacklem $");
   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 nfsstats newnfsstats;
   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, 3, "Open", 4, },
   70         { NFSV4OP_CREATE, 3, "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 };
  116 
  117 /*
  118  * NFS RPCS that have large request message size.
  119  */
  120 static int nfs_bigrequest[NFSV41_NPROCS] = {
  121         0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  122         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  123         0, 0, 0, 0, 0, 0, 1, 0, 0
  124 };
  125 
  126 /*
  127  * Start building a request. Mostly just put the first file handle in
  128  * place.
  129  */
  130 APPLESTATIC void
  131 nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
  132     u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep)
  133 {
  134         struct mbuf *mb;
  135         u_int32_t *tl;
  136         int opcnt;
  137         nfsattrbit_t attrbits;
  138 
  139         /*
  140          * First, fill in some of the fields of nd.
  141          */
  142         nd->nd_slotseq = NULL;
  143         if (NFSHASNFSV4(nmp)) {
  144                 nd->nd_flag = ND_NFSV4 | ND_NFSCL;
  145                 if (NFSHASNFSV4N(nmp))
  146                         nd->nd_flag |= ND_NFSV41;
  147         } else if (NFSHASNFSV3(nmp))
  148                 nd->nd_flag = ND_NFSV3 | ND_NFSCL;
  149         else
  150                 nd->nd_flag = ND_NFSV2 | ND_NFSCL;
  151         nd->nd_procnum = procnum;
  152         nd->nd_repstat = 0;
  153 
  154         /*
  155          * Get the first mbuf for the request.
  156          */
  157         if (nfs_bigrequest[procnum])
  158                 NFSMCLGET(mb, M_WAITOK);
  159         else
  160                 NFSMGET(mb);
  161         mbuf_setlen(mb, 0);
  162         nd->nd_mreq = nd->nd_mb = mb;
  163         nd->nd_bpos = NFSMTOD(mb, caddr_t);
  164         
  165         /*
  166          * And fill the first file handle into the request.
  167          */
  168         if (nd->nd_flag & ND_NFSV4) {
  169                 opcnt = nfsv4_opmap[procnum].opcnt +
  170                     nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh;
  171                 if ((nd->nd_flag & ND_NFSV41) != 0) {
  172                         opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq;
  173                         if (procnum == NFSPROC_RENEW)
  174                                 /*
  175                                  * For the special case of Renew, just do a
  176                                  * Sequence Op.
  177                                  */
  178                                 opcnt = 1;
  179                         else if (procnum == NFSPROC_WRITEDS ||
  180                             procnum == NFSPROC_COMMITDS)
  181                                 /*
  182                                  * For the special case of a Writeor Commit to
  183                                  * a DS, the opcnt == 3, for Sequence, PutFH,
  184                                  * Write/Commit.
  185                                  */
  186                                 opcnt = 3;
  187                 }
  188                 /*
  189                  * What should the tag really be?
  190                  */
  191                 (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag,
  192                         nfsv4_opmap[procnum].taglen);
  193                 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  194                 if ((nd->nd_flag & ND_NFSV41) != 0)
  195                         *tl++ = txdr_unsigned(NFSV41_MINORVERSION);
  196                 else
  197                         *tl++ = txdr_unsigned(NFSV4_MINORVERSION);
  198                 if (opcntpp != NULL)
  199                         *opcntpp = tl;
  200                 *tl = txdr_unsigned(opcnt);
  201                 if ((nd->nd_flag & ND_NFSV41) != 0 &&
  202                     nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) {
  203                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  204                         *tl = txdr_unsigned(NFSV4OP_SEQUENCE);
  205                         if (sep == NULL)
  206                                 nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp),
  207                                     nfs_bigreply[procnum]);
  208                         else
  209                                 nfsv4_setsequence(nd, sep,
  210                                     nfs_bigreply[procnum]);
  211                 }
  212                 if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
  213                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  214                         *tl = txdr_unsigned(NFSV4OP_PUTFH);
  215                         (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  216                         if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh
  217                             == 2 && procnum != NFSPROC_WRITEDS &&
  218                             procnum != NFSPROC_COMMITDS) {
  219                                 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  220                                 *tl = txdr_unsigned(NFSV4OP_GETATTR);
  221                                 NFSWCCATTR_ATTRBIT(&attrbits);
  222                                 (void) nfsrv_putattrbit(nd, &attrbits);
  223                                 nd->nd_flag |= ND_V4WCCATTR;
  224                         }
  225                 }
  226                 if (procnum != NFSPROC_RENEW ||
  227                     (nd->nd_flag & ND_NFSV41) == 0) {
  228                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  229                         *tl = txdr_unsigned(nfsv4_opmap[procnum].op);
  230                 }
  231         } else {
  232                 (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  233         }
  234         if (procnum < NFSV4_NPROCS)
  235                 NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]);
  236 }
  237 
  238 #ifndef APPLE
  239 /*
  240  * copies a uio scatter/gather list to an mbuf chain.
  241  * NOTE: can ony handle iovcnt == 1
  242  */
  243 APPLESTATIC void
  244 nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
  245 {
  246         char *uiocp;
  247         struct mbuf *mp, *mp2;
  248         int xfer, left, mlen;
  249         int uiosiz, clflg, rem;
  250         char *cp, *tcp;
  251 
  252         KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
  253 
  254         if (siz > ncl_mbuf_mlen)        /* or should it >= MCLBYTES ?? */
  255                 clflg = 1;
  256         else
  257                 clflg = 0;
  258         rem = NFSM_RNDUP(siz) - siz;
  259         mp = mp2 = nd->nd_mb;
  260         while (siz > 0) {
  261                 left = uiop->uio_iov->iov_len;
  262                 uiocp = uiop->uio_iov->iov_base;
  263                 if (left > siz)
  264                         left = siz;
  265                 uiosiz = left;
  266                 while (left > 0) {
  267                         mlen = M_TRAILINGSPACE(mp);
  268                         if (mlen == 0) {
  269                                 if (clflg)
  270                                         NFSMCLGET(mp, M_WAITOK);
  271                                 else
  272                                         NFSMGET(mp);
  273                                 mbuf_setlen(mp, 0);
  274                                 mbuf_setnext(mp2, mp);
  275                                 mp2 = mp;
  276                                 mlen = M_TRAILINGSPACE(mp);
  277                         }
  278                         xfer = (left > mlen) ? mlen : left;
  279 #ifdef notdef
  280                         /* Not Yet.. */
  281                         if (uiop->uio_iov->iov_op != NULL)
  282                                 (*(uiop->uio_iov->iov_op))
  283                                 (uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  284                                     xfer);
  285                         else
  286 #endif
  287                         if (uiop->uio_segflg == UIO_SYSSPACE)
  288                             NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  289                                 xfer);
  290                         else
  291                             copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
  292                                 + mbuf_len(mp), xfer);
  293                         mbuf_setlen(mp, mbuf_len(mp) + xfer);
  294                         left -= xfer;
  295                         uiocp += xfer;
  296                         uiop->uio_offset += xfer;
  297                         uiop->uio_resid -= xfer;
  298                 }
  299                 tcp = (char *)uiop->uio_iov->iov_base;
  300                 tcp += uiosiz;
  301                 uiop->uio_iov->iov_base = (void *)tcp;
  302                 uiop->uio_iov->iov_len -= uiosiz;
  303                 siz -= uiosiz;
  304         }
  305         if (rem > 0) {
  306                 if (rem > M_TRAILINGSPACE(mp)) {
  307                         NFSMGET(mp);
  308                         mbuf_setlen(mp, 0);
  309                         mbuf_setnext(mp2, mp);
  310                 }
  311                 cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  312                 for (left = 0; left < rem; left++)
  313                         *cp++ = '\0';
  314                 mbuf_setlen(mp, mbuf_len(mp) + rem);
  315                 nd->nd_bpos = cp;
  316         } else
  317                 nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  318         nd->nd_mb = mp;
  319 }
  320 #endif  /* !APPLE */
  321 
  322 /*
  323  * Load vnode attributes from the xdr file attributes.
  324  * Returns EBADRPC if they can't be parsed, 0 otherwise.
  325  */
  326 APPLESTATIC int
  327 nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
  328 {
  329         struct nfs_fattr *fp;
  330         int error = 0;
  331 
  332         if (nd->nd_flag & ND_NFSV4) {
  333                 error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
  334                     NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL);
  335         } else if (nd->nd_flag & ND_NFSV3) {
  336                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
  337                 nap->na_type = nfsv34tov_type(fp->fa_type);
  338                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  339                 nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
  340                         fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
  341                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  342                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  343                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  344                 nap->na_size = fxdr_hyper(&fp->fa3_size);
  345                 nap->na_blocksize = NFS_FABLKSIZE;
  346                 nap->na_bytes = fxdr_hyper(&fp->fa3_used);
  347                 nap->na_fileid = fxdr_hyper(&fp->fa3_fileid);
  348                 fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime);
  349                 fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime);
  350                 fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime);
  351                 nap->na_flags = 0;
  352                 nap->na_filerev = 0;
  353         } else {
  354                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V2FATTR);
  355                 nap->na_type = nfsv2tov_type(fp->fa_type);
  356                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  357                 if (nap->na_type == VNON || nap->na_type == VREG)
  358                         nap->na_type = IFTOVT(nap->na_mode);
  359                 nap->na_rdev = fxdr_unsigned(dev_t, fp->fa2_rdev);
  360 
  361                 /*
  362                  * Really ugly NFSv2 kludge.
  363                  */
  364                 if (nap->na_type == VCHR && nap->na_rdev == ((dev_t)-1))
  365                         nap->na_type = VFIFO;
  366                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  367                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  368                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  369                 nap->na_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
  370                 nap->na_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
  371                 nap->na_bytes =
  372                     (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
  373                     NFS_FABLKSIZE;
  374                 nap->na_fileid = fxdr_unsigned(uint64_t, fp->fa2_fileid);
  375                 fxdr_nfsv2time(&fp->fa2_atime, &nap->na_atime);
  376                 fxdr_nfsv2time(&fp->fa2_mtime, &nap->na_mtime);
  377                 nap->na_flags = 0;
  378                 nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t,
  379                     fp->fa2_ctime.nfsv2_sec);
  380                 nap->na_ctime.tv_nsec = 0;
  381                 nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
  382                 nap->na_filerev = 0;
  383         }
  384 nfsmout:
  385         return (error);
  386 }
  387 
  388 /*
  389  * This function finds the directory cookie that corresponds to the
  390  * logical byte offset given.
  391  */
  392 APPLESTATIC nfsuint64 *
  393 nfscl_getcookie(struct nfsnode *np, off_t off, int add)
  394 {
  395         struct nfsdmap *dp, *dp2;
  396         int pos;
  397 
  398         pos = off / NFS_DIRBLKSIZ;
  399         if (pos == 0) {
  400                 KASSERT(!add, ("nfs getcookie add at 0"));
  401                 return (&nfs_nullcookie);
  402         }
  403         pos--;
  404         dp = LIST_FIRST(&np->n_cookies);
  405         if (!dp) {
  406                 if (add) {
  407                         MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
  408                                 M_NFSDIROFF, M_WAITOK);
  409                         dp->ndm_eocookie = 0;
  410                         LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
  411                 } else
  412                         return (NULL);
  413         }
  414         while (pos >= NFSNUMCOOKIES) {
  415                 pos -= NFSNUMCOOKIES;
  416                 if (LIST_NEXT(dp, ndm_list) != NULL) {
  417                         if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
  418                                 pos >= dp->ndm_eocookie)
  419                                 return (NULL);
  420                         dp = LIST_NEXT(dp, ndm_list);
  421                 } else if (add) {
  422                         MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
  423                                 M_NFSDIROFF, M_WAITOK);
  424                         dp2->ndm_eocookie = 0;
  425                         LIST_INSERT_AFTER(dp, dp2, ndm_list);
  426                         dp = dp2;
  427                 } else
  428                         return (NULL);
  429         }
  430         if (pos >= dp->ndm_eocookie) {
  431                 if (add)
  432                         dp->ndm_eocookie = pos + 1;
  433                 else
  434                         return (NULL);
  435         }
  436         return (&dp->ndm_cookies[pos]);
  437 }
  438 
  439 /*
  440  * Gets a file handle out of an nfs reply sent to the client and returns
  441  * the file handle and the file's attributes.
  442  * For V4, it assumes that Getfh and Getattr Op's results are here.
  443  */
  444 APPLESTATIC int
  445 nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh **nfhpp,
  446     struct nfsvattr *nap, int *attrflagp)
  447 {
  448         u_int32_t *tl;
  449         int error = 0, flag = 1;
  450 
  451         *nfhpp = NULL;
  452         *attrflagp = 0;
  453         /*
  454          * First get the file handle and vnode.
  455          */
  456         if (nd->nd_flag & ND_NFSV3) {
  457                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  458                 flag = fxdr_unsigned(int, *tl);
  459         } else if (nd->nd_flag & ND_NFSV4) {
  460                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  461         }
  462         if (flag) {
  463                 error = nfsm_getfh(nd, nfhpp);
  464                 if (error)
  465                         return (error);
  466         }
  467 
  468         /*
  469          * Now, get the attributes.
  470          */
  471         if (nd->nd_flag & ND_NFSV4) {
  472                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  473         } else if (nd->nd_flag & ND_NFSV3) {
  474                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  475                 if (flag) {
  476                         flag = fxdr_unsigned(int, *tl);
  477                 } else if (fxdr_unsigned(int, *tl)) {
  478                         error = nfsm_advance(nd, NFSX_V3FATTR, -1);
  479                         if (error)
  480                                 return (error);
  481                 }
  482         }
  483         if (flag) {
  484                 error = nfsm_loadattr(nd, nap);
  485                 if (!error)
  486                         *attrflagp = 1;
  487         }
  488 nfsmout:
  489         return (error);
  490 }
  491 
  492 /*
  493  * Put a state Id in the mbuf list.
  494  */
  495 APPLESTATIC void
  496 nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag)
  497 {
  498         nfsv4stateid_t *st;
  499 
  500         NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID);
  501         if (flag == NFSSTATEID_PUTALLZERO) {
  502                 st->seqid = 0;
  503                 st->other[0] = 0;
  504                 st->other[1] = 0;
  505                 st->other[2] = 0;
  506         } else if (flag == NFSSTATEID_PUTALLONE) {
  507                 st->seqid = 0xffffffff;
  508                 st->other[0] = 0xffffffff;
  509                 st->other[1] = 0xffffffff;
  510                 st->other[2] = 0xffffffff;
  511         } else if (flag == NFSSTATEID_PUTSEQIDZERO) {
  512                 st->seqid = 0;
  513                 st->other[0] = stateidp->other[0];
  514                 st->other[1] = stateidp->other[1];
  515                 st->other[2] = stateidp->other[2];
  516         } else {
  517                 st->seqid = stateidp->seqid;
  518                 st->other[0] = stateidp->other[0];
  519                 st->other[1] = stateidp->other[1];
  520                 st->other[2] = stateidp->other[2];
  521         }
  522 }
  523 
  524 /*
  525  * Initialize the owner/delegation sleep lock.
  526  */
  527 APPLESTATIC void
  528 nfscl_lockinit(struct nfsv4lock *lckp)
  529 {
  530 
  531         lckp->nfslock_usecnt = 0;
  532         lckp->nfslock_lock = 0;
  533 }
  534 
  535 /*
  536  * Get an exclusive lock. (Not needed for OpenBSD4, since there is only one
  537  * thread for each posix process in the kernel.)
  538  */
  539 APPLESTATIC void
  540 nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
  541 {
  542         int igotlock;
  543 
  544         do {
  545                 igotlock = nfsv4_lock(lckp, 1, NULL, mutex, NULL);
  546         } while (!igotlock);
  547 }
  548 
  549 /*
  550  * Release an exclusive lock.
  551  */
  552 APPLESTATIC void
  553 nfscl_lockunlock(struct nfsv4lock *lckp)
  554 {
  555 
  556         nfsv4_unlock(lckp, 0);
  557 }
  558 
  559 /*
  560  * Called to derefernce a lock on a stateid (delegation or open owner).
  561  */
  562 APPLESTATIC void
  563 nfscl_lockderef(struct nfsv4lock *lckp)
  564 {
  565 
  566         NFSLOCKCLSTATE();
  567         lckp->nfslock_usecnt--;
  568         if (lckp->nfslock_usecnt == 0 && (lckp->nfslock_lock & NFSV4LOCK_WANTED)) {
  569                 lckp->nfslock_lock &= ~NFSV4LOCK_WANTED;
  570                 wakeup((caddr_t)lckp);
  571         }
  572         NFSUNLOCKCLSTATE();
  573 }
  574 

Cache object: 4a247052ae391db46c41f8bcdeb1922a


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