diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-05-22 12:35:12 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-05-22 12:35:12 +0000 |
commit | ccb17e335aed123268303ae81de1b71c1340a1e7 (patch) | |
tree | d3806d83b9761a1610e63824e4451e9628878f16 /sys/nfs4client/nfs4_subs.c | |
parent | a75d175b4f1d7335efc89a91eac2db17f903ec5e (diff) | |
download | FreeBSD-src-ccb17e335aed123268303ae81de1b71c1340a1e7.zip FreeBSD-src-ccb17e335aed123268303ae81de1b71c1340a1e7.tar.gz |
Remove the unmaintained University of Michigan NFSv4 client from 8.x
prior to 8.0-RELEASE. Rick Macklem's new and more feature-rich NFSv234
client and server are replacing it.
Discussed with: rmacklem
Diffstat (limited to 'sys/nfs4client/nfs4_subs.c')
-rw-r--r-- | sys/nfs4client/nfs4_subs.c | 1367 |
1 files changed, 0 insertions, 1367 deletions
diff --git a/sys/nfs4client/nfs4_subs.c b/sys/nfs4client/nfs4_subs.c deleted file mode 100644 index 21c89c9..0000000 --- a/sys/nfs4client/nfs4_subs.c +++ /dev/null @@ -1,1367 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_subs.c,v 1.52 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#include <sys/cdefs.h> - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/namei.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/malloc.h> -#include <sys/sysent.h> -#include <sys/syscall.h> -#include <sys/sysproto.h> -#include <sys/fcntl.h> - -#include <machine/stdarg.h> - -#include <vm/vm.h> -#include <vm/vm_object.h> -#include <vm/vm_extern.h> -#include <vm/uma.h> - -#include <rpc/rpcclnt.h> - -#include <nfs/rpcv2.h> -#include <nfs/nfsproto.h> -#include <nfsclient/nfs.h> -#include <nfs4client/nfs4.h> -#include <nfsclient/nfsnode.h> -#include <nfsclient/nfsmount.h> -#include <nfs/xdr_subs.h> -#include <nfsclient/nfsm_subs.h> - -#include <nfs4client/nfs4_dev.h> -#include <nfs4client/nfs4_idmap.h> -#include <nfs4client/nfs4m_subs.h> - -#include <netinet/in.h> - -#define NFSM_DISSECT(s) do { \ - tl = nfsm_dissect_xx((s), md, dpos); \ - if (tl == NULL) { \ - printf("NFSM_DISSECT error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \ - return (EBADRPC); \ - } \ -} while (0) - -#define NFSM_ADV(s) do { \ - t1 = nfsm_adv_xx((s), md, dpos); \ - if (t1 != 0) { \ - printf("NFSM_ADV error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \ - return (EBADRPC); \ - } \ -} while (0) - -#define NFSM_MTOTIME(t) do { \ - NFSM_DISSECT(3 * NFSX_UNSIGNED); \ - (t).tv_sec = fxdr_hyper(tl); \ - tl += 2; \ - (t).tv_nsec = fxdr_unsigned(long, *tl++); \ -} while (0) - -static uint32_t __fsinfo_bm[2], __fsattr_bm[2], __getattr_bm[2], __readdir_bm[2]; - -nfsv4bitmap nfsv4_fsinfobm = { 2, __fsinfo_bm }; -nfsv4bitmap nfsv4_fsattrbm = { 2, __fsattr_bm }; -nfsv4bitmap nfsv4_getattrbm = { 2, __getattr_bm }; -nfsv4bitmap nfsv4_readdirbm = { 2, __readdir_bm }; - -/* Helper routines */ -int nfsm_v4build_attrs_xx(struct vattr *, struct mbuf **, caddr_t *); -int nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *, struct mbuf **, caddr_t *); - -void -nfsm_v4init(void) -{ - - /* Set up bitmasks */ - FA4_SET(FA4_FSID, __fsinfo_bm); - FA4_SET(FA4_MAXREAD, __fsinfo_bm); - FA4_SET(FA4_MAXWRITE, __fsinfo_bm); - FA4_SET(FA4_LEASE_TIME, __fsinfo_bm); - - FA4_SET(FA4_FSID, __fsattr_bm); - FA4_SET(FA4_FILES_FREE, __fsattr_bm); - FA4_SET(FA4_FILES_TOTAL, __fsattr_bm); - FA4_SET(FA4_SPACE_AVAIL, __fsattr_bm); - FA4_SET(FA4_SPACE_FREE, __fsattr_bm); - FA4_SET(FA4_SPACE_TOTAL, __fsattr_bm); - - FA4_SET(FA4_TYPE, __getattr_bm); - FA4_SET(FA4_FSID, __getattr_bm); - FA4_SET(FA4_SIZE, __getattr_bm); - FA4_SET(FA4_MODE, __getattr_bm); - FA4_SET(FA4_RAWDEV, __getattr_bm); - FA4_SET(FA4_NUMLINKS, __getattr_bm); - FA4_SET(FA4_OWNER, __getattr_bm); - FA4_SET(FA4_OWNER_GROUP, __getattr_bm); - FA4_SET(FA4_FILEID, __getattr_bm); - FA4_SET(FA4_TIME_ACCESS, __getattr_bm); - FA4_SET(FA4_TIME_CREATE, __getattr_bm); - FA4_SET(FA4_TIME_METADATA, __getattr_bm); - FA4_SET(FA4_TIME_MODIFY, __getattr_bm); - - FA4_SET(FA4_TYPE, __readdir_bm); - FA4_SET(FA4_FSID, __readdir_bm); - FA4_SET(FA4_FILEID, __readdir_bm); - FA4_SET(FA4_RDATTR_ERROR, __readdir_bm); -} - -/* - * Util - */ - -uint32_t -nfs_v4fileid4_to_fileid(uint64_t fid) -{ - return ((uint32_t)((fid >> 32) | fid)); -} - -void -nfs_v4initcompound(struct nfs4_compound *cp) -{ - bzero(cp, sizeof(*cp)); -} - -/* - * Build/dissect XDR buffer with a format string. - * - * u - unsigned - * h - hyper - * s - stringlength, string - * k - skip length (bytes) - * a - arraylength, componentlenght, array - * o - opaque fix length - * O - opaque var length in bytes - */ - -void -nfsm_buildf_xx(struct mbuf **mb, caddr_t *bpos, char *fmt, ...) -{ - uint32_t *tl, t1, len, uval; - uint64_t hval; - va_list args; - char *p, *which; - - va_start(args, fmt); - for (which = fmt; *which != '\0'; which++) - switch (*which) { - case 'u': /* Unsigned */ - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - uval = va_arg(args, uint32_t); - *tl++ = txdr_unsigned(uval); - break; - case 'h': /* Hyper */ - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - hval = va_arg(args, uint64_t); - txdr_hyper(hval, tl); - break; - case 'o': /* Fixed-length opaque */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - tl = nfsm_build_xx(nfsm_rndup(len), mb, bpos); - bcopy(p, tl, len); - break; - case 'O': /* Variable-length opaque */ - case 's': /* String */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - t1 = nfsm_strtom_xx(p, len, len, mb, bpos); - break; - case 'k': /* Skip */ - len = va_arg(args, uint32_t); - nfsm_build_xx(nfsm_rndup(len), mb, bpos); - break; - default: - panic("Invalid buildf string %s[%c]", fmt, *which); - break; - } - va_end(args); -} - -int -nfsm_dissectf_xx(struct mbuf **md, caddr_t *dpos, char *fmt, ...) -{ - uint32_t *tl, t1, len, *uval; - uint64_t *hval; - va_list args; - char *p, *which; - - va_start(args, fmt); - for (which = fmt; *which != '\0'; which++) - switch (*which) { - case 'u': /* Unsigned */ - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - uval = va_arg(args, uint32_t *); - *uval = fxdr_unsigned(uint32_t, *tl++); - break; - case 'h': /* Hyper */ - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - hval = va_arg(args, uint64_t *); - *hval = fxdr_hyper(tl); - break; - case 'o': /* Fixed-length opaque */ - len = va_arg(args, uint32_t); - p = va_arg(args, void *); - tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos); - if (tl == NULL) - return (EBADRPC); - bcopy(tl, p, len); - break; - case 'O': /* Variable-length opaque */ - case 's': /* String */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos); - if (tl == NULL) - return (EBADRPC); - bcopy(tl, p, len); - break; - case 'k': /* Skip bytes */ - len = va_arg(args, uint32_t); - t1 = nfsm_adv_xx(nfsm_rndup(len), md, dpos); - break; - default: - panic("Invalid dissectf string %s[%c]", fmt, *which); - break; - } - va_end(args); - - return (0); -} - -/* - * XXX - There are a few problems with the way the postops are places - * in the code. Ideally, they should be taken care of immediately, as - * to avoid uneceesary waits for mutexes, but then we would be - * introducing even more complexity by having to handle two separate - * cases. Also, since they are placed at the end of the vnops', there - * may be operations which sleep in between, further extending this - * wait. It is conceivable that there is a deadlock condition there, - * too. - * - * Also, for vnops that do multiple operations, it's inconvenient - * since on error, individual decoding will got nfsmout. - */ - -int -nfs_v4postop(struct nfs4_compound *cp, int status) -{ - struct nfs4_fctx *fcp = cp->fcp; - - /* - * XXX does the previous result need to be stores with the - * lockowner? ack, spec is unclear .. - */ - - if (fcp != NULL) - if (cp->seqidused < cp->rep_nops || - (cp->seqidused + 1 == cp->rep_nops && - NFS4_SEQIDMUTATINGERROR(status))) - fcp->lop->lo_seqid++; - - return (status); -} - -int -nfs_v4handlestatus(int status, struct nfs4_compound *cp) -{ - return (status); -} - -/* - * Initial setup of compound. - */ - -int -nfsm_v4build_compound_xx(struct nfs4_compound *cp, char *tag, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1, *tl, siz; - - /* Tag */ - siz = strlen(tag); - t1 = nfsm_rndup(siz) + NFSX_UNSIGNED; - if (t1 <= M_TRAILINGSPACE(*mb)) { - tl = nfsm_build_xx(t1, mb, bpos); - *tl++ = txdr_unsigned(siz); - *(tl + ((t1 >> 2) - 2)) = 0; - bcopy(tag, tl, siz); - } else { - t1 = nfsm_strtmbuf(mb, bpos, (const char *)tag, siz); - if (t1 != 0) - return (t1); - } - - /* Minor version and argarray*/ - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - *tl++ = txdr_unsigned(NFS4_MINOR_VERSION); - /* Save for backfill */ - cp->req_nopsp = tl; - *tl = txdr_unsigned(0); - - cp->curvp = NULL; - cp->savevp = NULL; - - return (0); -} - -/* - * XXX - * - backfill for stateid, and such - */ -int -nfsm_v4build_finalize_xx(struct nfs4_compound *cp, struct mbuf **mb, caddr_t *bpos) -{ - *cp->req_nopsp = txdr_unsigned(cp->req_nops); - - return (0); -} - -int -nfsm_v4build_putfh_xx(struct nfs4_compound *cp, struct vnode *vp, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1; - - /* Op */ - nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_PUTFH); - - /* FH */ - t1 = nfsm_fhtom_xx(vp, 1, mb, bpos); - if (t1 != 0) - return (t1); - - cp->req_nops++; - cp->curvp = vp; - - return (0); -} - -int -nfsm_v4build_putfh_nv_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uuo", - NFSV4OP_PUTFH, - gfh->fh_len, - gfh->fh_len, - &gfh->fh_val); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_simple_xx(struct nfs4_compound *cp, uint32_t op, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "u", op); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga, - struct mbuf **mb, caddr_t *bpos) -{ - int i; - - /* Op + bitmap length + bitmap */ - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_GETATTR, ga->bm->bmlen); - for (i = 0; i < ga->bm->bmlen; i++) - nfsm_buildf_xx(mb, bpos, "u", ga->bm->bmval[i]); - - ga->vp = cp->curvp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setattr_xx(struct nfs4_compound *cp, struct vattr *vap, - struct nfs4_fctx *fcp, struct mbuf **mb, caddr_t *bpos) -{ - int error; - static char zero_stateid[NFSX_V4STATEID]; - - nfsm_buildf_xx(mb, bpos, "uo", - NFSV4OP_SETATTR, - NFSX_V4STATEID, fcp ? fcp->stateid : zero_stateid); - error = nfsm_v4build_attrs_xx(vap, mb, bpos); - if (error == 0) - cp->req_nops++; - - return (error); -} - -int -nfsm_v4build_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_GETFH); - - gfh->vp = cp->curvp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_lookup_xx(struct nfs4_compound *cp, struct nfs4_oparg_lookup *l, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LOOKUP, l->namelen, l->name); - - cp->curvp = l->vp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setclientid_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos) -{ - struct timeval tv; - - microtime(&tv); - - nfsm_buildf_xx(mb, bpos, "uuusussu", - NFSV4OP_SETCLIENTID, - tv.tv_sec, tv.tv_usec, - sci->namelen, sci->name, - sci->cb_prog, - sci->cb_netidlen, sci->cb_netid, - sci->cb_univaddrlen, sci->cb_univaddr, - 0xCA11BACC); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setclientid_confirm_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uho", - NFSV4OP_SETCLIENTID_CONFIRM, - sci->clientid, - sizeof(sci->verf), sci->verf); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **mb, caddr_t *bpos) -{ - int error = 0; - struct nfs4_lowner *lop = op->fcp->lop; - - nfsm_buildf_xx(mb, bpos, "uuuuhuu", - NFSV4OP_OPEN, - lop->lo_seqid, - op->flags & O_ACCMODE, - NFSV4OPENSHARE_DENY_NONE, - cp->nmp->nm_clientid, - 4, lop->lo_id); - - if (op->flags & O_CREAT) { - nfsm_buildf_xx(mb, bpos, "u", OTCREATE); - /* openflag4: mode */ - nfsm_buildf_xx(mb, bpos, "u", CMUNCHECKED); - /* openflag4: createattrs... */ - if (op->vap != NULL) { - if (op->flags & O_TRUNC) - op->vap->va_size = 0; - error = nfsm_v4build_attrs_xx(op->vap, mb, bpos); - if (error != 0) - return (error); - } else - nfsm_buildf_xx(mb, bpos, "uu", 0, 0); - } else - nfsm_buildf_xx(mb, bpos, "u", OTNOCREATE); - - nfsm_buildf_xx(mb, bpos, "us", op->ctype, - op->cnp->cn_namelen, op->cnp->cn_nameptr); - - cp->seqidused = cp->req_nops++; - cp->fcp = op->fcp; - - return (error); -} - -/* - * XXX - * - Wait on recovery - */ -int -nfsm_v4build_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uou", - NFSV4OP_OPEN_CONFIRM, - NFSX_V4STATEID, op->fcp->stateid, - op->fcp->lop->lo_seqid); - - cp->seqidused = cp->req_nops++; - cp->fcp = op->fcp; - - return (0); -} - -/* - * XXX - * - Wait on recovery - */ -int -nfsm_v4build_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp, - struct mbuf **mb, caddr_t *bpos) -{ - struct nfs4_lowner *lop = fcp->lop; - - nfsm_buildf_xx(mb, bpos, "uuo", - NFSV4OP_CLOSE, - lop->lo_seqid, - NFSX_V4STATEID, fcp->stateid); - - cp->seqidused = cp->req_nops++; - cp->fcp = fcp; - - return (0); -} - -int -nfsm_v4build_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_ACCESS, acc->mode); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uohu", - NFSV4OP_READ, - NFSX_V4STATEID, r->fcp->stateid, - r->off, - r->maxcnt); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uohuu", - NFSV4OP_WRITE, - NFSX_V4STATEID, w->fcp->stateid, - w->off, - w->stable, - w->cnt); - cp->req_nops++; - return (nfsm_uiotombuf(w->uiop, mb, w->cnt, bpos)); -} - -int -nfsm_v4build_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uhu", NFSV4OP_COMMIT, c->start, c->len); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_readdir_xx(struct nfs4_compound *cp, struct nfs4_oparg_readdir *r, - struct mbuf **mb, caddr_t *bpos) -{ - int i; - - nfsm_buildf_xx(mb, bpos, "uhouuu", - NFSV4OP_READDIR, - r->cookie, - sizeof(r->verf), r->verf, - r->cnt >> 4, /* meaningless "dircount" field */ - r->cnt, - r->bm->bmlen); - - for (i = 0; i < r->bm->bmlen; i++) - nfsm_buildf_xx(mb, bpos, "u", r->bm->bmval[i]); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_renew_xx(struct nfs4_compound *cp, uint64_t cid, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uh", NFSV4OP_RENEW, cid); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1; - - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_CREATE, c->type); - - if (c->type == NFLNK) - /* XXX strlen */ - nfsm_buildf_xx(mb, bpos, "s", strlen(c->linktext), c->linktext); - else if (c->type == NFCHR || c->type == NFBLK) - nfsm_buildf_xx(mb, bpos, "uu", - major(c->vap->va_rdev), minor(c->vap->va_rdev)); - - /* Name */ - nfsm_buildf_xx(mb, bpos, "s", c->namelen, c->name); - - /* Attributes */ - t1 = nfsm_v4build_attrs_xx(c->vap, mb, bpos); - if (t1 != 0) - return (t1); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_rename_xx(struct nfs4_compound *cp, struct nfs4_oparg_rename *r, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uss", NFSV4OP_RENAME, r->fnamelen, r->fname, - r->tnamelen, r->tname); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_link_xx(struct nfs4_compound *cp, struct nfs4_oparg_link *l, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LINK, l->namelen, l->name); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_remove_xx(struct nfs4_compound *cp, const char *name, u_int namelen, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_REMOVE, namelen, name); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_attrs_xx(struct vattr *vap, struct mbuf **mb, caddr_t *bpos) -{ - uint32_t *tl, *attrlenp, *bmvalp, len; - size_t siz; - - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - - *tl++ = txdr_unsigned(2); /* bitmap length */ - bmvalp = tl; - bzero(bmvalp, 8); - tl += 2; - attrlenp = tl; - - len = 0; - if (vap->va_size != VNOVAL) { - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_SIZE, bmvalp); - txdr_hyper(vap->va_size, tl); tl += 2; - len += 2 * NFSX_UNSIGNED; - } - if (vap->va_mode != (u_short)VNOVAL) { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_MODE, bmvalp); - *tl++ = txdr_unsigned(vap->va_mode); - len += NFSX_UNSIGNED; - } - if (vap->va_uid != VNOVAL) { - int error; - char *name; - error = idmap_uid_to_name(vap->va_uid, &name, &siz); - if (error || name == NULL || siz == 0) { - /* XXX */ - siz = sizeof("nobody") - 1; - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy("nobody", tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy(name, tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } - FA4_SET(FA4_OWNER, bmvalp); - } - if (vap->va_gid != VNOVAL) { - int error; - char *name; - error = idmap_gid_to_name(vap->va_gid, &name, &siz); - if (error || name == NULL || siz == 0) { - /* XXX */ - siz = sizeof("nogroup") - 1; - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy("nogroup", tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy(name, tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } - FA4_SET(FA4_OWNER_GROUP, bmvalp); - } - if (vap->va_atime.tv_sec != VNOVAL) { - uint64_t val = vap->va_atime.tv_sec; - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_TIME_ACCESS_SET, bmvalp); - *tl++ = txdr_unsigned(THCLIENTTIME); - txdr_hyper(val, tl); tl += 2; - *tl++ = txdr_unsigned(vap->va_atime.tv_nsec); - len += 4 * NFSX_UNSIGNED; - } - if (vap->va_mtime.tv_sec != VNOVAL) { - uint64_t val = vap->va_mtime.tv_sec; - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_TIME_MODIFY_SET, bmvalp); - *tl++ = txdr_unsigned(THCLIENTTIME); - txdr_hyper(val, tl); tl += 2; - *tl++ = txdr_unsigned(vap->va_mtime.tv_nsec); - len += 4 * NFSX_UNSIGNED; - } - - bmvalp[0] = txdr_unsigned(bmvalp[0]); - bmvalp[1] = txdr_unsigned(bmvalp[1]); - - *attrlenp = txdr_unsigned(len); - - return (0); -} - -int -nfsm_v4dissect_compound_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos) -{ - uint32_t taglen, t1, *tl; - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - - /* Reply status is handled by the RPC code */ - - taglen = fxdr_unsigned(uint32_t, *tl++); - t1 = nfsm_adv_xx(nfsm_rndup(taglen), md, dpos); - if (t1 != 0) - return (EBADRPC); - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - - cp->rep_nops = fxdr_unsigned(uint32_t, *tl++); - - return (0); -} - -int -nfsm_v4dissect_simple_xx(struct nfs4_compound *cp, uint32_t op, - uint32_t skipbytes, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, dop, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &dop, &status); - if (t1 != 0) - return (t1); - - if (dop != op || status != 0) - return (EBADRPC); - - if (skipbytes > 0) - NFSM_ADV(nfsm_rndup(skipbytes)); - - return (0); -} - -int -nfsm_v4dissect_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETATTR || - *tl++ != 0) - return (EBADRPC); - - return (nfsm_v4dissect_attrs_xx(&ga->fa, md, dpos)); -} - -int -nfsm_v4dissect_setattr_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, op, bmlen, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_SETATTR || status != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "u", &bmlen); - if (t1 != 0) - return (t1); - - return (nfsm_dissectf_xx(md, dpos, "k", bmlen << 2)); -} - -int -nfsm_v4dissect_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, len, xdrlen; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETFH) - return (EBADRPC); - - if (*tl++ != 0) - return (EBADRPC); - - NFSM_DISSECT(NFSX_UNSIGNED); - len = fxdr_unsigned(uint32_t, *tl++); - if (len > NFSX_V4FH) - return (EBADRPC); - - /* XXX integrate this into nfs_mtofh()? */ - - gfh->fh_len = len; - xdrlen = nfsm_rndup(len); - - NFSM_DISSECT(xdrlen); - bcopy(tl, &gfh->fh_val, xdrlen); - - return (0); -} - -int -nfsm_v4dissect_setclientid_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_SETCLIENTID) - return (EBADRPC); - - /* Handle NFS4ERR_CLID_INUSE specially */ - if (*tl++ != 0) - return (EBADRPC); - - NFSM_DISSECT(2 * NFSX_UNSIGNED); - sci->clientid = fxdr_hyper(tl); - - NFSM_DISSECT(nfsm_rndup(NFSX_V4VERF)); - bcopy(tl, sci->verf, NFSX_V4VERF); - - return (0); -} - -int -nfsm_v4dissect_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, t1; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_CLOSE || - *tl++ != 0) - return (EBADRPC); - - /* Copy stateid */ - t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid); - if (t1 != 0) - return (t1); - - return (0); -} - -int -nfsm_v4dissect_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(4 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_ACCESS || - *tl++ != 0) - return (EBADRPC); - - acc->supported = fxdr_unsigned(uint32_t, *tl++); - acc->rmode = fxdr_unsigned(uint32_t, *tl++); - - return (0); -} - -int -nfsm_v4dissect_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, t1, bmlen, delegtype = ODNONE; - int error = 0; - nfsv4changeinfo cinfo; - struct nfs4_fctx *fcp = op->fcp; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN || - *tl++ != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid); - if (t1 != 0) - return (t1); - - error = nfsm_v4dissect_changeinfo_xx(&cinfo, md, dpos); - if (error != 0) - goto nfsmout; - - NFSM_DISSECT(2 * NFSX_UNSIGNED); - - op->rflags = fxdr_unsigned(uint32_t, *tl++); - bmlen = fxdr_unsigned(uint32_t, *tl++); - if (bmlen > 2) { - error = EBADRPC; - goto nfsmout; - } - - /* Skip */ - NFSM_ADV(nfsm_rndup(bmlen << 2)); - - NFSM_DISSECT(NFSX_UNSIGNED); - delegtype = fxdr_unsigned(uint32_t, *tl++); - switch (delegtype) { - case ODREAD: - case ODWRITE: - printf("nfs4: client delegation not yet supported\n"); - error = EOPNOTSUPP; - goto nfsmout; - break; - case ODNONE: - default: - break; - } - - nfsmout: - return (error); -} - -int -nfsm_v4dissect_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN_CONFIRM || - *tl++ != 0) - return (EBADRPC); - - return nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, op->fcp->stateid); -} - -int -nfsm_v4dissect_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t op, status, t1; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_READ || status != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &r->eof, &r->retlen); - if (t1 != 0) - return (t1); - - return (nfsm_mbuftouio(md, r->uiop, r->retlen, dpos)); -} - -int -nfsm_v4dissect_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t op, status, t1; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_WRITE || status != 0) - return (EBADRPC); - - return (nfsm_dissectf_xx(md, dpos, "uuo", &w->retlen, &w->committed, - NFSX_V4VERF, w->wverf)); -} - -int -nfsm_v4dissect_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, op, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_COMMIT || status != 0) - return (EBADRPC); - - return (nfsm_dissectf_xx(md, dpos, "o", NFSX_V4VERF, c->verf)); -} - -int -nfsm_v4dissect_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, op, status, bmlen; - nfsv4changeinfo ci; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_CREATE || status != 0) - return (EBADRPC); - - /* Just throw this away for now */ - t1 = nfsm_v4dissect_changeinfo_xx(&ci, md, dpos); - if (t1 != 0) - return (t1); - - /* Throw this away too */ - NFSM_DISSECT(NFSX_UNSIGNED); - bmlen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(bmlen * NFSX_UNSIGNED); - tl += bmlen; - - return 0; -} - -int -nfsm_v4dissect_readlink_xx(struct nfs4_compound *cp, struct uio *uiop, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, op, status, linklen; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_READLINK || status != 0) - return (EBADRPC); - - /* Do this one manually for careful checking of sizes. */ - NFSM_DISSECT(NFSX_UNSIGNED); - linklen = fxdr_unsigned(uint32_t, *tl++); - if (linklen <= 0) - return (EBADRPC); - - return (nfsm_mbuftouio(md, uiop, MIN(linklen, uiop->uio_resid), dpos)); -} - -int -nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *ci, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - NFSM_DISSECT(5 * NFSX_UNSIGNED); - - ci->ciatomic = fxdr_unsigned(uint32_t, *tl++); - ci->cibefore = fxdr_hyper(tl); tl += 2; - ci->ciafter = fxdr_hyper(tl); tl += 2; - - return (0); -} - -int -nfsm_v4dissect_attrs_xx(struct nfsv4_fattr *fa, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, bmlen, bmval[2], attrlen, len = 0; - - /* Bitmap length + value */ - NFSM_DISSECT(NFSX_UNSIGNED); - - bmlen = fxdr_unsigned(uint32_t, *tl++); - if (bmlen > 2) - return (EBADRPC); - - if (bmlen == 0) - return (0); - - NFSM_DISSECT(nfsm_rndup(bmlen << 2) + NFSX_UNSIGNED); - - bmval[0] = bmlen > 0 ? fxdr_unsigned(uint32_t, *tl++) : 0; - bmval[1] = bmlen > 1 ? fxdr_unsigned(uint32_t, *tl++) : 0; - - /* Attribute length */ - attrlen = fxdr_unsigned(uint32_t, *tl++); - - /* - * XXX check for correct (<=) attributes mask return from - * server. need to pass this in. - */ - - if (FA4_ISSET(FA4_TYPE, bmval)) { - /* overflow check */ - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_type = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_TYPE; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_CHANGE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_changeid = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_CHANGEID; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SIZE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_size = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SIZE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FSID, bmval)) { - NFSM_DISSECT(4 * NFSX_UNSIGNED); - fa->fa4_fsid_major = fxdr_hyper(tl); tl += 2; - fa->fa4_fsid_minor = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SIZE; - len += 4 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_LEASE_TIME, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_lease_time = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_LEASE_TIME; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_RDATTR_ERROR, bmval)) { - /* ignore for now; we only ask for it so the compound won't fail */ - NFSM_DISSECT(NFSX_UNSIGNED); - tl++; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILEID, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_fileid = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FILEID; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILES_FREE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_ffree = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FFREE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILES_TOTAL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_ftotal = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FTOTAL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXFILESIZE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxfilesize = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXFILESIZE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXNAME, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_maxname = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_MAXNAME; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXREAD, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxread = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXREAD; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXWRITE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxwrite = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXWRITE; - len += 2 * NFSX_UNSIGNED; - } - - if (FA4_ISSET(FA4_MODE, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_mode = fxdr_unsigned(mode_t, *tl++); - fa->fa4_valid |= FA4V_MODE; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_NUMLINKS, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_nlink = fxdr_unsigned(nlink_t, *tl++); - fa->fa4_valid |= FA4V_NLINK; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_OWNER, bmval)) { - uint32_t ownerlen; - int error; - - NFSM_DISSECT(NFSX_UNSIGNED); - - ownerlen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(nfsm_rndup(ownerlen)); - error = idmap_name_to_uid((char *)tl, ownerlen, &fa->fa4_uid); - if (error) - fa->fa4_uid = -2; - fa->fa4_valid |= FA4V_UID; - len += NFSX_UNSIGNED + nfsm_rndup(ownerlen); - } - if (FA4_ISSET(FA4_OWNER_GROUP, bmval)) { - uint32_t ownergrouplen; - int error; - - NFSM_DISSECT(NFSX_UNSIGNED); - ownergrouplen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(nfsm_rndup(ownergrouplen)); - error = idmap_name_to_gid((char *)tl, ownergrouplen, &fa->fa4_gid); - if (error) - fa->fa4_gid = -2; - fa->fa4_valid |= FA4V_GID; - len += NFSX_UNSIGNED + nfsm_rndup(ownergrouplen); - } - if (FA4_ISSET(FA4_RAWDEV, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_rdev_major = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_rdev_minor = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_RDEV; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_AVAIL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_savail = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SAVAIL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_FREE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_sfree = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SFREE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_TOTAL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_stotal = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_STOTAL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_USED, bmval)) { - NFSM_ADV(2 * NFSX_UNSIGNED); - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_ACCESS, bmval)) { - NFSM_MTOTIME(fa->fa4_atime); - fa->fa4_valid |= FA4V_ATIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_CREATE, bmval)) { - NFSM_MTOTIME(fa->fa4_btime); - fa->fa4_valid |= FA4V_BTIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_METADATA, bmval)) { - NFSM_MTOTIME(fa->fa4_ctime); - fa->fa4_valid |= FA4V_CTIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_MODIFY, bmval)) { - NFSM_MTOTIME(fa->fa4_mtime); - fa->fa4_valid |= FA4V_MTIME; - len += 3 * NFSX_UNSIGNED; - } - - if (len != attrlen) - return (EBADRPC); - - return (0); -} |