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

Cache object: 6246b6eb191c7b820bd00fe790821f23


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