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: stable/9/sys/fs/nfsclient/nfs_clcomsubs.c 265389 2014-05-05 20:48:36Z 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[NFSV4OP_NOPS];
   47 extern int ncl_mbuf_mlen;
   48 extern enum vtype newnv2tov_type[8];
   49 extern enum vtype nv34tov_type[8];
   50 NFSCLSTATEMUTEX;
   51 #endif  /* !APPLEKEXT */
   52 
   53 static nfsuint64 nfs_nullcookie = {{ 0, 0 }};
   54 static struct {
   55         int     op;
   56         int     opcnt;
   57         const u_char *tag;
   58         int     taglen;
   59 } nfsv4_opmap[NFS_NPROCS] = {
   60         { 0, 1, "Null", 4 },
   61         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   62         { NFSV4OP_SETATTR, 2, "Setattr", 7, },
   63         { NFSV4OP_LOOKUP, 3, "Lookup", 6, },
   64         { NFSV4OP_ACCESS, 2, "Access", 6, },
   65         { NFSV4OP_READLINK, 2, "Readlink", 8, },
   66         { NFSV4OP_READ, 1, "Read", 4, },
   67         { NFSV4OP_WRITE, 2, "Write", 5, },
   68         { NFSV4OP_OPEN, 5, "Open", 4, },
   69         { NFSV4OP_CREATE, 5, "Create", 6, },
   70         { NFSV4OP_CREATE, 1, "Create", 6, },
   71         { NFSV4OP_CREATE, 3, "Create", 6, },
   72         { NFSV4OP_REMOVE, 1, "Remove", 6, },
   73         { NFSV4OP_REMOVE, 1, "Remove", 6, },
   74         { NFSV4OP_SAVEFH, 5, "Rename", 6, },
   75         { NFSV4OP_SAVEFH, 4, "Link", 4, },
   76         { NFSV4OP_READDIR, 2, "Readdir", 7, },
   77         { NFSV4OP_READDIR, 2, "Readdir", 7, },
   78         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   79         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   80         { NFSV4OP_GETATTR, 1, "Getattr", 7, },
   81         { NFSV4OP_COMMIT, 2, "Commit", 6, },
   82         { NFSV4OP_LOOKUPP, 3, "Lookupp", 7, },
   83         { NFSV4OP_SETCLIENTID, 1, "SetClientID", 11, },
   84         { NFSV4OP_SETCLIENTIDCFRM, 1, "SetClientIDConfirm", 18, },
   85         { NFSV4OP_LOCK, 1, "Lock", 4, },
   86         { NFSV4OP_LOCKU, 1, "LockU", 5, },
   87         { NFSV4OP_OPEN, 2, "Open", 4, },
   88         { NFSV4OP_CLOSE, 1, "Close", 5, },
   89         { NFSV4OP_OPENCONFIRM, 1, "Openconfirm", 11, },
   90         { NFSV4OP_LOCKT, 1, "LockT", 5, },
   91         { NFSV4OP_OPENDOWNGRADE, 1, "Opendowngrade", 13, },
   92         { NFSV4OP_RENEW, 1, "Renew", 5, },
   93         { NFSV4OP_PUTROOTFH, 1, "Dirpath", 7, },
   94         { NFSV4OP_RELEASELCKOWN, 1, "Rellckown", 9, },
   95         { NFSV4OP_DELEGRETURN, 1, "Delegret", 8, },
   96         { NFSV4OP_DELEGRETURN, 3, "DelegRemove", 11, },
   97         { NFSV4OP_DELEGRETURN, 7, "DelegRename1", 12, },
   98         { NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, },
   99         { NFSV4OP_GETATTR, 1, "Getacl", 6, },
  100         { NFSV4OP_SETATTR, 1, "Setacl", 6, },
  101 };
  102 
  103 
  104 /*
  105  * NFS RPCS that have large request message size.
  106  */
  107 static int nfs_bigrequest[NFS_NPROCS] = {
  108         0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  109         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  110 };
  111 
  112 /*
  113  * Start building a request. Mostly just put the first file handle in
  114  * place.
  115  */
  116 APPLESTATIC void
  117 nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
  118     u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp)
  119 {
  120         struct mbuf *mb;
  121         u_int32_t *tl;
  122         int opcnt;
  123         nfsattrbit_t attrbits;
  124 
  125         /*
  126          * First, fill in some of the fields of nd.
  127          */
  128         if (NFSHASNFSV4(nmp))
  129                 nd->nd_flag = ND_NFSV4 | ND_NFSCL;
  130         else if (NFSHASNFSV3(nmp))
  131                 nd->nd_flag = ND_NFSV3 | ND_NFSCL;
  132         else
  133                 nd->nd_flag = ND_NFSV2 | ND_NFSCL;
  134         nd->nd_procnum = procnum;
  135         nd->nd_repstat = 0;
  136 
  137         /*
  138          * Get the first mbuf for the request.
  139          */
  140         if (nfs_bigrequest[procnum])
  141                 NFSMCLGET(mb, M_WAIT);
  142         else
  143                 NFSMGET(mb);
  144         mbuf_setlen(mb, 0);
  145         nd->nd_mreq = nd->nd_mb = mb;
  146         nd->nd_bpos = NFSMTOD(mb, caddr_t);
  147         
  148         /*
  149          * And fill the first file handle into the request.
  150          */
  151         if (nd->nd_flag & ND_NFSV4) {
  152                 opcnt = nfsv4_opmap[procnum].opcnt +
  153                     nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh;
  154                 /*
  155                  * What should the tag really be?
  156                  */
  157                 (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag,
  158                         nfsv4_opmap[procnum].taglen);
  159                 NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
  160                 *tl++ = txdr_unsigned(NFSV4_MINORVERSION);
  161                 if (opcntpp != NULL)
  162                         *opcntpp = tl;
  163                 *tl++ = txdr_unsigned(opcnt);
  164                 if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
  165                         *tl = txdr_unsigned(NFSV4OP_PUTFH);
  166                         (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  167                         if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh==2){
  168                                 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  169                                 *tl = txdr_unsigned(NFSV4OP_GETATTR);
  170                                 /*
  171                                  * For Lookup Ops, we want all the directory
  172                                  * attributes, so we can load the name cache.
  173                                  */
  174                                 if (procnum == NFSPROC_LOOKUP ||
  175                                     procnum == NFSPROC_LOOKUPP)
  176                                         NFSGETATTR_ATTRBIT(&attrbits);
  177                                 else {
  178                                         NFSWCCATTR_ATTRBIT(&attrbits);
  179                                         nd->nd_flag |= ND_V4WCCATTR;
  180                                 }
  181                                 (void) nfsrv_putattrbit(nd, &attrbits);
  182                         }
  183                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  184                 }
  185                 *tl = txdr_unsigned(nfsv4_opmap[procnum].op);
  186         } else {
  187                 (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  188         }
  189         NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]);
  190 }
  191 
  192 #ifndef APPLE
  193 /*
  194  * copies a uio scatter/gather list to an mbuf chain.
  195  * NOTE: can ony handle iovcnt == 1
  196  */
  197 APPLESTATIC void
  198 nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
  199 {
  200         char *uiocp;
  201         struct mbuf *mp, *mp2;
  202         int xfer, left, mlen;
  203         int uiosiz, clflg, rem;
  204         char *cp, *tcp;
  205 
  206         KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
  207 
  208         if (siz > ncl_mbuf_mlen)        /* or should it >= MCLBYTES ?? */
  209                 clflg = 1;
  210         else
  211                 clflg = 0;
  212         rem = NFSM_RNDUP(siz) - siz;
  213         mp = mp2 = nd->nd_mb;
  214         while (siz > 0) {
  215                 left = uiop->uio_iov->iov_len;
  216                 uiocp = uiop->uio_iov->iov_base;
  217                 if (left > siz)
  218                         left = siz;
  219                 uiosiz = left;
  220                 while (left > 0) {
  221                         mlen = M_TRAILINGSPACE(mp);
  222                         if (mlen == 0) {
  223                                 if (clflg)
  224                                         NFSMCLGET(mp, M_WAIT);
  225                                 else
  226                                         NFSMGET(mp);
  227                                 mbuf_setlen(mp, 0);
  228                                 mbuf_setnext(mp2, mp);
  229                                 mp2 = mp;
  230                                 mlen = M_TRAILINGSPACE(mp);
  231                         }
  232                         xfer = (left > mlen) ? mlen : left;
  233 #ifdef notdef
  234                         /* Not Yet.. */
  235                         if (uiop->uio_iov->iov_op != NULL)
  236                                 (*(uiop->uio_iov->iov_op))
  237                                 (uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  238                                     xfer);
  239                         else
  240 #endif
  241                         if (uiop->uio_segflg == UIO_SYSSPACE)
  242                             NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  243                                 xfer);
  244                         else
  245                             copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
  246                                 + mbuf_len(mp), xfer);
  247                         mbuf_setlen(mp, mbuf_len(mp) + xfer);
  248                         left -= xfer;
  249                         uiocp += xfer;
  250                         uiop->uio_offset += xfer;
  251                         uiop->uio_resid -= xfer;
  252                 }
  253                 tcp = (char *)uiop->uio_iov->iov_base;
  254                 tcp += uiosiz;
  255                 uiop->uio_iov->iov_base = (void *)tcp;
  256                 uiop->uio_iov->iov_len -= uiosiz;
  257                 siz -= uiosiz;
  258         }
  259         if (rem > 0) {
  260                 if (rem > M_TRAILINGSPACE(mp)) {
  261                         NFSMGET(mp);
  262                         mbuf_setlen(mp, 0);
  263                         mbuf_setnext(mp2, mp);
  264                 }
  265                 cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  266                 for (left = 0; left < rem; left++)
  267                         *cp++ = '\0';
  268                 mbuf_setlen(mp, mbuf_len(mp) + rem);
  269                 nd->nd_bpos = cp;
  270         } else
  271                 nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  272         nd->nd_mb = mp;
  273 }
  274 #endif  /* !APPLE */
  275 
  276 /*
  277  * Load vnode attributes from the xdr file attributes.
  278  * Returns EBADRPC if they can't be parsed, 0 otherwise.
  279  */
  280 APPLESTATIC int
  281 nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
  282 {
  283         struct nfs_fattr *fp;
  284         int error = 0;
  285 
  286         if (nd->nd_flag & ND_NFSV4) {
  287                 error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
  288                     NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL);
  289         } else if (nd->nd_flag & ND_NFSV3) {
  290                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
  291                 nap->na_type = nfsv34tov_type(fp->fa_type);
  292                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  293                 nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
  294                         fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
  295                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  296                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  297                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  298                 nap->na_size = fxdr_hyper(&fp->fa3_size);
  299                 nap->na_blocksize = NFS_FABLKSIZE;
  300                 nap->na_bytes = fxdr_hyper(&fp->fa3_used);
  301                 nap->na_fileid = fxdr_hyper(&fp->fa3_fileid);
  302                 fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime);
  303                 fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime);
  304                 fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime);
  305                 nap->na_flags = 0;
  306                 nap->na_filerev = 0;
  307         } else {
  308                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V2FATTR);
  309                 nap->na_type = nfsv2tov_type(fp->fa_type);
  310                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  311                 if (nap->na_type == VNON || nap->na_type == VREG)
  312                         nap->na_type = IFTOVT(nap->na_mode);
  313                 nap->na_rdev = fxdr_unsigned(dev_t, fp->fa2_rdev);
  314 
  315                 /*
  316                  * Really ugly NFSv2 kludge.
  317                  */
  318                 if (nap->na_type == VCHR && nap->na_rdev == ((dev_t)-1))
  319                         nap->na_type = VFIFO;
  320                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  321                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  322                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  323                 nap->na_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
  324                 nap->na_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
  325                 nap->na_bytes =
  326                     (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
  327                     NFS_FABLKSIZE;
  328                 nap->na_fileid = fxdr_unsigned(uint64_t, fp->fa2_fileid);
  329                 fxdr_nfsv2time(&fp->fa2_atime, &nap->na_atime);
  330                 fxdr_nfsv2time(&fp->fa2_mtime, &nap->na_mtime);
  331                 nap->na_flags = 0;
  332                 nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t,
  333                     fp->fa2_ctime.nfsv2_sec);
  334                 nap->na_ctime.tv_nsec = 0;
  335                 nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
  336                 nap->na_filerev = 0;
  337         }
  338 nfsmout:
  339         return (error);
  340 }
  341 
  342 /*
  343  * This function finds the directory cookie that corresponds to the
  344  * logical byte offset given.
  345  */
  346 APPLESTATIC nfsuint64 *
  347 nfscl_getcookie(struct nfsnode *np, off_t off, int add)
  348 {
  349         struct nfsdmap *dp, *dp2;
  350         int pos;
  351 
  352         pos = off / NFS_DIRBLKSIZ;
  353         if (pos == 0) {
  354                 KASSERT(!add, ("nfs getcookie add at 0"));
  355                 return (&nfs_nullcookie);
  356         }
  357         pos--;
  358         dp = LIST_FIRST(&np->n_cookies);
  359         if (!dp) {
  360                 if (add) {
  361                         MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
  362                                 M_NFSDIROFF, M_WAITOK);
  363                         dp->ndm_eocookie = 0;
  364                         LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
  365                 } else
  366                         return (NULL);
  367         }
  368         while (pos >= NFSNUMCOOKIES) {
  369                 pos -= NFSNUMCOOKIES;
  370                 if (LIST_NEXT(dp, ndm_list) != NULL) {
  371                         if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
  372                                 pos >= dp->ndm_eocookie)
  373                                 return (NULL);
  374                         dp = LIST_NEXT(dp, ndm_list);
  375                 } else if (add) {
  376                         MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
  377                                 M_NFSDIROFF, M_WAITOK);
  378                         dp2->ndm_eocookie = 0;
  379                         LIST_INSERT_AFTER(dp, dp2, ndm_list);
  380                         dp = dp2;
  381                 } else
  382                         return (NULL);
  383         }
  384         if (pos >= dp->ndm_eocookie) {
  385                 if (add)
  386                         dp->ndm_eocookie = pos + 1;
  387                 else
  388                         return (NULL);
  389         }
  390         return (&dp->ndm_cookies[pos]);
  391 }
  392 
  393 /*
  394  * Gets a file handle out of an nfs reply sent to the client and returns
  395  * the file handle and the file's attributes.
  396  * For V4, it assumes that Getfh and Getattr Op's results are here.
  397  */
  398 APPLESTATIC int
  399 nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh **nfhpp,
  400     struct nfsvattr *nap, int *attrflagp)
  401 {
  402         u_int32_t *tl;
  403         int error = 0, flag = 1;
  404 
  405         *nfhpp = NULL;
  406         *attrflagp = 0;
  407         /*
  408          * First get the file handle and vnode.
  409          */
  410         if (nd->nd_flag & ND_NFSV3) {
  411                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  412                 flag = fxdr_unsigned(int, *tl);
  413         } else if (nd->nd_flag & ND_NFSV4) {
  414                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  415         }
  416         if (flag) {
  417                 error = nfsm_getfh(nd, nfhpp);
  418                 if (error)
  419                         return (error);
  420         }
  421 
  422         /*
  423          * Now, get the attributes.
  424          */
  425         if (nd->nd_flag & ND_NFSV4) {
  426                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  427         } else if (nd->nd_flag & ND_NFSV3) {
  428                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  429                 if (flag) {
  430                         flag = fxdr_unsigned(int, *tl);
  431                 } else if (fxdr_unsigned(int, *tl)) {
  432                         error = nfsm_advance(nd, NFSX_V3FATTR, -1);
  433                         if (error)
  434                                 return (error);
  435                 }
  436         }
  437         if (flag) {
  438                 error = nfsm_loadattr(nd, nap);
  439                 if (!error)
  440                         *attrflagp = 1;
  441         }
  442 nfsmout:
  443         return (error);
  444 }
  445 
  446 /*
  447  * Put a state Id in the mbuf list.
  448  */
  449 APPLESTATIC void
  450 nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag)
  451 {
  452         nfsv4stateid_t *st;
  453 
  454         NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID);
  455         if (flag == NFSSTATEID_PUTALLZERO) {
  456                 st->seqid = 0;
  457                 st->other[0] = 0;
  458                 st->other[1] = 0;
  459                 st->other[2] = 0;
  460         } else if (flag == NFSSTATEID_PUTALLONE) {
  461                 st->seqid = 0xffffffff;
  462                 st->other[0] = 0xffffffff;
  463                 st->other[1] = 0xffffffff;
  464                 st->other[2] = 0xffffffff;
  465         } else {
  466                 st->seqid = stateidp->seqid;
  467                 st->other[0] = stateidp->other[0];
  468                 st->other[1] = stateidp->other[1];
  469                 st->other[2] = stateidp->other[2];
  470         }
  471 }
  472 
  473 /*
  474  * Initialize the owner/delegation sleep lock.
  475  */
  476 APPLESTATIC void
  477 nfscl_lockinit(struct nfsv4lock *lckp)
  478 {
  479 
  480         lckp->nfslock_usecnt = 0;
  481         lckp->nfslock_lock = 0;
  482 }
  483 
  484 /*
  485  * Get an exclusive lock. (Not needed for OpenBSD4, since there is only one
  486  * thread for each posix process in the kernel.)
  487  */
  488 APPLESTATIC void
  489 nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
  490 {
  491         int igotlock;
  492 
  493         do {
  494                 igotlock = nfsv4_lock(lckp, 1, NULL, mutex, NULL);
  495         } while (!igotlock);
  496 }
  497 
  498 /*
  499  * Release an exclusive lock.
  500  */
  501 APPLESTATIC void
  502 nfscl_lockunlock(struct nfsv4lock *lckp)
  503 {
  504 
  505         nfsv4_unlock(lckp, 0);
  506 }
  507 
  508 /*
  509  * Called to derefernce a lock on a stateid (delegation or open owner).
  510  */
  511 APPLESTATIC void
  512 nfscl_lockderef(struct nfsv4lock *lckp)
  513 {
  514 
  515         NFSLOCKCLSTATE();
  516         lckp->nfslock_usecnt--;
  517         if (lckp->nfslock_usecnt == 0 && (lckp->nfslock_lock & NFSV4LOCK_WANTED)) {
  518                 lckp->nfslock_lock &= ~NFSV4LOCK_WANTED;
  519                 wakeup((caddr_t)lckp);
  520         }
  521         NFSUNLOCKCLSTATE();
  522 }
  523 

Cache object: d838e136b08101cbd0792deeaeb8c9c4


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