[BACK]Return to nfs_clcomsubs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / nfs / client

Annotation of src/sys/fs/nfs/client/nfs_clcomsubs.c, Revision 1.4

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

CVSweb <webmaster@jp.NetBSD.org>