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/8.1/sys/fs/nfsclient/nfs_clcomsubs.c 191783 2009-05-04 15:23:58Z 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, 3, "Open", 4, },
   69         { NFSV4OP_CREATE, 3, "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;
  130         else if (NFSHASNFSV3(nmp))
  131                 nd->nd_flag = ND_NFSV3;
  132         else
  133                 nd->nd_flag = ND_NFSV2;
  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                                 NFSWCCATTR_ATTRBIT(&attrbits);
  171                                 (void) nfsrv_putattrbit(nd, &attrbits);
  172                                 nd->nd_flag |= ND_V4WCCATTR;
  173                         }
  174                         NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  175                 }
  176                 *tl = txdr_unsigned(nfsv4_opmap[procnum].op);
  177         } else {
  178                 (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
  179         }
  180         NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]);
  181 }
  182 
  183 #ifndef APPLE
  184 /*
  185  * copies a uio scatter/gather list to an mbuf chain.
  186  * NOTE: can ony handle iovcnt == 1
  187  */
  188 APPLESTATIC void
  189 nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
  190 {
  191         char *uiocp;
  192         struct mbuf *mp, *mp2;
  193         int xfer, left, mlen;
  194         int uiosiz, clflg, rem;
  195         char *cp, *tcp;
  196 
  197 #ifdef DIAGNOSTIC
  198         if (uiop->uio_iovcnt != 1)
  199                 panic("nfsm_uiotombuf: iovcnt != 1");
  200 #endif
  201 
  202         if (siz > ncl_mbuf_mlen)        /* or should it >= MCLBYTES ?? */
  203                 clflg = 1;
  204         else
  205                 clflg = 0;
  206         rem = NFSM_RNDUP(siz) - siz;
  207         mp = mp2 = nd->nd_mb;
  208         while (siz > 0) {
  209                 left = uiop->uio_iov->iov_len;
  210                 uiocp = uiop->uio_iov->iov_base;
  211                 if (left > siz)
  212                         left = siz;
  213                 uiosiz = left;
  214                 while (left > 0) {
  215                         mlen = M_TRAILINGSPACE(mp);
  216                         if (mlen == 0) {
  217                                 if (clflg)
  218                                         NFSMCLGET(mp, M_WAIT);
  219                                 else
  220                                         NFSMGET(mp);
  221                                 mbuf_setlen(mp, 0);
  222                                 mbuf_setnext(mp2, mp);
  223                                 mp2 = mp;
  224                                 mlen = M_TRAILINGSPACE(mp);
  225                         }
  226                         xfer = (left > mlen) ? mlen : left;
  227 #ifdef notdef
  228                         /* Not Yet.. */
  229                         if (uiop->uio_iov->iov_op != NULL)
  230                                 (*(uiop->uio_iov->iov_op))
  231                                 (uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  232                                     xfer);
  233                         else
  234 #endif
  235                         if (uiop->uio_segflg == UIO_SYSSPACE)
  236                             NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
  237                                 xfer);
  238                         else
  239                             copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
  240                                 + mbuf_len(mp), xfer);
  241                         mbuf_setlen(mp, mbuf_len(mp) + xfer);
  242                         left -= xfer;
  243                         uiocp += xfer;
  244                         uiop->uio_offset += xfer;
  245                         uiop->uio_resid -= xfer;
  246                 }
  247                 tcp = (char *)uiop->uio_iov->iov_base;
  248                 tcp += uiosiz;
  249                 uiop->uio_iov->iov_base = (void *)tcp;
  250                 uiop->uio_iov->iov_len -= uiosiz;
  251                 siz -= uiosiz;
  252         }
  253         if (rem > 0) {
  254                 if (rem > M_TRAILINGSPACE(mp)) {
  255                         NFSMGET(mp);
  256                         mbuf_setlen(mp, 0);
  257                         mbuf_setnext(mp2, mp);
  258                 }
  259                 cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  260                 for (left = 0; left < rem; left++)
  261                         *cp++ = '\0';
  262                 mbuf_setlen(mp, mbuf_len(mp) + rem);
  263                 nd->nd_bpos = cp;
  264         } else
  265                 nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
  266         nd->nd_mb = mp;
  267 }
  268 #endif  /* !APPLE */
  269 
  270 /*
  271  * Load vnode attributes from the xdr file attributes.
  272  * Returns EBADRPC if they can't be parsed, 0 otherwise.
  273  */
  274 APPLESTATIC int
  275 nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
  276 {
  277         struct nfs_fattr *fp;
  278         int error = 0;
  279 
  280         if (nd->nd_flag & ND_NFSV4) {
  281                 error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
  282                     NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL);
  283         } else if (nd->nd_flag & ND_NFSV3) {
  284                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
  285                 nap->na_type = nfsv34tov_type(fp->fa_type);
  286                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  287                 nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
  288                         fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
  289                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  290                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  291                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  292                 nap->na_size = fxdr_hyper(&fp->fa3_size);
  293                 nap->na_blocksize = NFS_FABLKSIZE;
  294                 nap->na_bytes = fxdr_hyper(&fp->fa3_used);
  295                 nap->na_fileid = fxdr_unsigned(int32_t,
  296                     fp->fa3_fileid.nfsuquad[1]);
  297                 fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime);
  298                 fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime);
  299                 fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime);
  300                 nap->na_flags = 0;
  301                 nap->na_filerev = 0;
  302         } else {
  303                 NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V2FATTR);
  304                 nap->na_type = nfsv2tov_type(fp->fa_type);
  305                 nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
  306                 if (nap->na_type == VNON || nap->na_type == VREG)
  307                         nap->na_type = IFTOVT(nap->na_mode);
  308                 nap->na_rdev = fxdr_unsigned(dev_t, fp->fa2_rdev);
  309 
  310                 /*
  311                  * Really ugly NFSv2 kludge.
  312                  */
  313                 if (nap->na_type == VCHR && nap->na_rdev == ((dev_t)-1))
  314                         nap->na_type = VFIFO;
  315                 nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
  316                 nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
  317                 nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
  318                 nap->na_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
  319                 nap->na_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
  320                 nap->na_bytes =
  321                     (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
  322                     NFS_FABLKSIZE;
  323                 nap->na_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid);
  324                 fxdr_nfsv2time(&fp->fa2_atime, &nap->na_atime);
  325                 fxdr_nfsv2time(&fp->fa2_mtime, &nap->na_mtime);
  326                 nap->na_flags = 0;
  327                 nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t,
  328                     fp->fa2_ctime.nfsv2_sec);
  329                 nap->na_ctime.tv_nsec = 0;
  330                 nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
  331                 nap->na_filerev = 0;
  332         }
  333 nfsmout:
  334         return (error);
  335 }
  336 
  337 /*
  338  * This function finds the directory cookie that corresponds to the
  339  * logical byte offset given.
  340  */
  341 APPLESTATIC nfsuint64 *
  342 nfscl_getcookie(struct nfsnode *np, off_t off, int add)
  343 {
  344         struct nfsdmap *dp, *dp2;
  345         int pos;
  346 
  347         pos = off / NFS_DIRBLKSIZ;
  348         if (pos == 0) {
  349 #ifdef DIAGNOSTIC
  350                 if (add)
  351                         panic("nfs getcookie add at 0");
  352 #endif
  353                 return (&nfs_nullcookie);
  354         }
  355         pos--;
  356         dp = LIST_FIRST(&np->n_cookies);
  357         if (!dp) {
  358                 if (add) {
  359                         MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
  360                                 M_NFSDIROFF, M_WAITOK);
  361                         dp->ndm_eocookie = 0;
  362                         LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
  363                 } else
  364                         return (NULL);
  365         }
  366         while (pos >= NFSNUMCOOKIES) {
  367                 pos -= NFSNUMCOOKIES;
  368                 if (LIST_NEXT(dp, ndm_list) != NULL) {
  369                         if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
  370                                 pos >= dp->ndm_eocookie)
  371                                 return (NULL);
  372                         dp = LIST_NEXT(dp, ndm_list);
  373                 } else if (add) {
  374                         MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
  375                                 M_NFSDIROFF, M_WAITOK);
  376                         dp2->ndm_eocookie = 0;
  377                         LIST_INSERT_AFTER(dp, dp2, ndm_list);
  378                         dp = dp2;
  379                 } else
  380                         return (NULL);
  381         }
  382         if (pos >= dp->ndm_eocookie) {
  383                 if (add)
  384                         dp->ndm_eocookie = pos + 1;
  385                 else
  386                         return (NULL);
  387         }
  388         return (&dp->ndm_cookies[pos]);
  389 }
  390 
  391 /*
  392  * Gets a file handle out of an nfs reply sent to the client and returns
  393  * the file handle and the file's attributes.
  394  * For V4, it assumes that Getfh and Getattr Op's results are here.
  395  */
  396 APPLESTATIC int
  397 nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh **nfhpp,
  398     struct nfsvattr *nap, int *attrflagp)
  399 {
  400         u_int32_t *tl;
  401         int error = 0, flag = 1;
  402 
  403         *nfhpp = NULL;
  404         *attrflagp = 0;
  405         /*
  406          * First get the file handle and vnode.
  407          */
  408         if (nd->nd_flag & ND_NFSV3) {
  409                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  410                 flag = fxdr_unsigned(int, *tl);
  411         } else if (nd->nd_flag & ND_NFSV4) {
  412                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  413         }
  414         if (flag) {
  415                 error = nfsm_getfh(nd, nfhpp);
  416                 if (error)
  417                         return (error);
  418         }
  419 
  420         /*
  421          * Now, get the attributes.
  422          */
  423         if (nd->nd_flag & ND_NFSV4) {
  424                 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  425         } else if (nd->nd_flag & ND_NFSV3) {
  426                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  427                 if (flag) {
  428                         flag = fxdr_unsigned(int, *tl);
  429                 } else if (fxdr_unsigned(int, *tl)) {
  430                         error = nfsm_advance(nd, NFSX_V3FATTR, -1);
  431                         if (error)
  432                                 return (error);
  433                 }
  434         }
  435         if (flag) {
  436                 error = nfsm_loadattr(nd, nap);
  437                 if (!error)
  438                         *attrflagp = 1;
  439         }
  440 nfsmout:
  441         return (error);
  442 }
  443 
  444 /*
  445  * Put a state Id in the mbuf list.
  446  */
  447 APPLESTATIC void
  448 nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag)
  449 {
  450         nfsv4stateid_t *st;
  451 
  452         NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID);
  453         if (flag == NFSSTATEID_PUTALLZERO) {
  454                 st->seqid = 0;
  455                 st->other[0] = 0;
  456                 st->other[1] = 0;
  457                 st->other[2] = 0;
  458         } else if (flag == NFSSTATEID_PUTALLONE) {
  459                 st->seqid = 0xffffffff;
  460                 st->other[0] = 0xffffffff;
  461                 st->other[1] = 0xffffffff;
  462                 st->other[2] = 0xffffffff;
  463         } else {
  464                 st->seqid = stateidp->seqid;
  465                 st->other[0] = stateidp->other[0];
  466                 st->other[1] = stateidp->other[1];
  467                 st->other[2] = stateidp->other[2];
  468         }
  469 }
  470 
  471 /*
  472  * Initialize the owner/delegation sleep lock.
  473  */
  474 APPLESTATIC void
  475 nfscl_lockinit(struct nfsv4lock *lckp)
  476 {
  477 
  478         lckp->nfslock_usecnt = 0;
  479         lckp->nfslock_lock = 0;
  480 }
  481 
  482 /*
  483  * Get an exclusive lock. (Not needed for OpenBSD4, since there is only one
  484  * thread for each posix process in the kernel.)
  485  */
  486 APPLESTATIC void
  487 nfscl_lockexcl(struct nfsv4lock *lckp, void *mutex)
  488 {
  489         int igotlock;
  490 
  491         do {
  492                 igotlock = nfsv4_lock(lckp, 1, NULL, mutex);
  493         } while (!igotlock);
  494 }
  495 
  496 /*
  497  * Release an exclusive lock.
  498  */
  499 APPLESTATIC void
  500 nfscl_lockunlock(struct nfsv4lock *lckp)
  501 {
  502 
  503         nfsv4_unlock(lckp, 0);
  504 }
  505 
  506 /*
  507  * Called to derefernce a lock on a stateid (delegation or open owner).
  508  */
  509 APPLESTATIC void
  510 nfscl_lockderef(struct nfsv4lock *lckp)
  511 {
  512 
  513         NFSLOCKCLSTATE();
  514         lckp->nfslock_usecnt--;
  515         if (lckp->nfslock_usecnt == 0 && (lckp->nfslock_lock & NFSV4LOCK_WANTED)) {
  516                 lckp->nfslock_lock &= ~NFSV4LOCK_WANTED;
  517                 wakeup((caddr_t)lckp);
  518         }
  519         NFSUNLOCKCLSTATE();
  520 }
  521 

Cache object: c597b5914146d8e45078bcbf5bc7a8d2


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