From owner-svn-src-projects@freebsd.org Tue Jun 19 20:32:45 2018 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7D5D1100D43F for ; Tue, 19 Jun 2018 20:32:45 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2772874FD0; Tue, 19 Jun 2018 20:32:45 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E2204189A9; Tue, 19 Jun 2018 20:32:44 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w5JKWind010738; Tue, 19 Jun 2018 20:32:44 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w5JKWhOA010730; Tue, 19 Jun 2018 20:32:43 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201806192032.w5JKWhOA010730@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Tue, 19 Jun 2018 20:32:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r335385 - in projects/pnfs-planb-server/sys/fs: nfs nfsclient X-SVN-Group: projects X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: in projects/pnfs-planb-server/sys/fs: nfs nfsclient X-SVN-Commit-Revision: 335385 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jun 2018 20:32:45 -0000 Author: rmacklem Date: Tue Jun 19 20:32:43 2018 New Revision: 335385 URL: https://svnweb.freebsd.org/changeset/base/335385 Log: Bring kernel up to date. Mostly changes already in head so that an nfsd.ko will load without "options NFSCL" specified for the kernel config. The changes also include the most recent client code for handling "soft" RPCs to the DSs. This code is still under test, so it hasn't been committed to head yet. Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs.h projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h projects/pnfs-planb-server/sys/fs/nfs/nfsport.h projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clcomsubs.c projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clstate.c projects/pnfs-planb-server/sys/fs/nfsclient/nfsmount.h Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs.h ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs.h Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs.h Tue Jun 19 20:32:43 2018 (r335385) @@ -681,6 +681,7 @@ struct nfsrv_descript { #define ND_DSSERVER 0x40000000 #define ND_CURSTATEID 0x80000000 #define ND_SAVEDCURSTATEID 0x100000000 +#define ND_HASSLOTID 0x200000000 /* * ND_GSS should be the "or" of all GSS type authentications. Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c Tue Jun 19 20:32:43 2018 (r335385) @@ -510,7 +510,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmo uint32_t retseq, retval, slotseq, *tl; time_t waituntil; int i = 0, j = 0, opcnt, set_sigset = 0, slot; - int error = 0, usegssname = 0, secflavour = AUTH_SYS, trycnt; + int error = 0, usegssname = 0, secflavour = AUTH_SYS; int freeslot, maxslot, reterr, slotpos, timeo; u_int16_t procnum; u_int trylater_delay = 1; @@ -719,7 +719,6 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmo } #endif } - trycnt = 0; freeslot = -1; /* Set to slot that needs to be free'd */ tryagain: slot = -1; /* Slot that needs a sequence# increment. */ @@ -810,55 +809,31 @@ tryagain: error = EINTR; } else if (stat == RPC_CANTSEND || stat == RPC_CANTRECV || stat == RPC_SYSTEMERROR) { - if ((nd->nd_flag & ND_NFSV41) != 0 && nmp != NULL && + /* Check for a session slot that needs to be free'd. */ + if ((nd->nd_flag & (ND_NFSV41 | ND_HASSLOTID)) == + (ND_NFSV41 | ND_HASSLOTID) && nmp != NULL && nd->nd_procnum != NFSPROC_NULL) { /* - * The nfsess_defunct field is protected by - * the NFSLOCKMNT()/nm_mtx lock and not the - * nfsess_mtx lock to simplify its handling, - * for the MDS session. This lock is also - * sufficient for nfsess_sessionid, since it - * never changes in the structure. + * This should only occur when either the MDS or + * a client has an RPC against a DS fail. + * This happens because these cases use "soft" + * connections that can time out and fail. + * The slot used for this RPC is now in a + * non-deterministic state, but if the slot isn't + * free'd, threads can get stuck waiting for a slot. */ - NFSLOCKCLSTATE(); - NFSLOCKMNT(nmp); - /* The session must be marked defunct. */ - if (dssep == NULL) { - /* - * This is either an MDS proxy operation or - * a client mount with "soft,retrans=N" options. - * Mark the MDS session defunct and initiate - * recovery, as required. - */ - NFSCL_DEBUG(1, "Failed soft proxy RPC\n"); - sep = NFSMNT_MDSSESSION(nmp); - if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, - NFSX_V4SESSIONID) == 0) { - /* Initiate recovery. */ - sep->nfsess_defunct = 1; - NFSCL_DEBUG(1, "Marked defunct\n"); - if (nmp->nm_clp != NULL) { - nmp->nm_clp->nfsc_flags |= - NFSCLFLAGS_RECOVER; - wakeup(nmp->nm_clp); - } - } - } else { - /* - * This is a client side DS RPC. Just mark - * the session defunct. A subsequent LayoutGet - * should get a new session. - */ - NFSCL_DEBUG(1, "Failed client DS RPC\n"); - if (bcmp(dssep->nfsess_sessionid, - nd->nd_sequence, NFSX_V4SESSIONID) == 0) { - /* Mark it defunct. */ - dssep->nfsess_defunct = 1; - NFSCL_DEBUG(1, "Marked defunct\n"); - } - } - NFSUNLOCKMNT(nmp); - NFSUNLOCKCLSTATE(); + if (sep == NULL) + sep = nfsmnt_mdssession(nmp); + /* + * Bump the sequence# out of range, so that reuse of + * this slot will result in an NFSERR_SEQMISORDERED + * error and not a bogus cached RPC reply. + */ + mtx_lock(&sep->nfsess_mtx); + sep->nfsess_slotseq[nd->nd_slotid] += 10; + mtx_unlock(&sep->nfsess_mtx); + /* And free the slot. */ + nfsv4_freeslot(sep, nd->nd_slotid); } NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = ENXIO; @@ -1220,6 +1195,30 @@ lookformore: } NFSUNLOCKMNT(nmp); return (0); +} + +/* + * Sinilar to newnfs_nmcancelreqs(), except that it is called for a + * single DS's dsp. + * It also marks the session defunct. + */ +void +newnfs_canceldspreq(struct nfsclds *dsp) +{ + struct __rpc_client *cl; + + NFSLOCKDS(dsp); + if ((dsp->nfsclds_flags & NFSCLDS_CLOSED) == 0 && + dsp->nfsclds_sockp != NULL && + dsp->nfsclds_sockp->nr_client != NULL) { + dsp->nfsclds_flags |= NFSCLDS_CLOSED; + dsp->nfsclds_sess.nfsess_defunct = 1; + cl = dsp->nfsclds_sockp->nr_client; + NFSUNLOCKDS(dsp); + CLNT_CLOSE(cl); + return; + } + NFSUNLOCKDS(dsp); } /* Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs_commonsubs.c Tue Jun 19 20:32:43 2018 (r335385) @@ -79,6 +79,7 @@ extern struct mtx nfsrv_dslock_mtx; extern volatile int nfsrv_devidcnt; extern int nfscl_debuglevel; extern struct nfsdevicehead nfsrv_devidhead; +extern struct nfsstatsv1 nfsstatsv1; SYSCTL_DECL(_vfs_nfs); SYSCTL_INT(_vfs_nfs, OID_AUTO, enable_uidtostring, CTLFLAG_RW, @@ -189,7 +190,7 @@ static struct nfsrv_lughash *nfsgroupnamehash; * marked 0 in this array, the code will still work, just not quite as * efficiently.) */ -int nfs_bigreply[NFSV41_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, +static int nfs_bigreply[NFSV41_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; @@ -204,7 +205,363 @@ static int nfsrv_getrefstr(struct nfsrv_descript *, u_ int *, int *); static void nfsrv_refstrbigenough(int, u_char **, u_char **, int *); +static struct { + int op; + int opcnt; + const u_char *tag; + int taglen; +} nfsv4_opmap[NFSV41_NPROCS] = { + { 0, 1, "Null", 4 }, + { NFSV4OP_GETATTR, 1, "Getattr", 7, }, + { NFSV4OP_SETATTR, 2, "Setattr", 7, }, + { NFSV4OP_LOOKUP, 3, "Lookup", 6, }, + { NFSV4OP_ACCESS, 2, "Access", 6, }, + { NFSV4OP_READLINK, 2, "Readlink", 8, }, + { NFSV4OP_READ, 1, "Read", 4, }, + { NFSV4OP_WRITE, 2, "Write", 5, }, + { NFSV4OP_OPEN, 5, "Open", 4, }, + { NFSV4OP_CREATE, 5, "Create", 6, }, + { NFSV4OP_CREATE, 1, "Create", 6, }, + { NFSV4OP_CREATE, 3, "Create", 6, }, + { NFSV4OP_REMOVE, 1, "Remove", 6, }, + { NFSV4OP_REMOVE, 1, "Remove", 6, }, + { NFSV4OP_SAVEFH, 5, "Rename", 6, }, + { NFSV4OP_SAVEFH, 4, "Link", 4, }, + { NFSV4OP_READDIR, 2, "Readdir", 7, }, + { NFSV4OP_READDIR, 2, "Readdir", 7, }, + { NFSV4OP_GETATTR, 1, "Getattr", 7, }, + { NFSV4OP_GETATTR, 1, "Getattr", 7, }, + { NFSV4OP_GETATTR, 1, "Getattr", 7, }, + { NFSV4OP_COMMIT, 2, "Commit", 6, }, + { NFSV4OP_LOOKUPP, 3, "Lookupp", 7, }, + { NFSV4OP_SETCLIENTID, 1, "SetClientID", 11, }, + { NFSV4OP_SETCLIENTIDCFRM, 1, "SetClientIDConfirm", 18, }, + { NFSV4OP_LOCK, 1, "Lock", 4, }, + { NFSV4OP_LOCKU, 1, "LockU", 5, }, + { NFSV4OP_OPEN, 2, "Open", 4, }, + { NFSV4OP_CLOSE, 1, "Close", 5, }, + { NFSV4OP_OPENCONFIRM, 1, "Openconfirm", 11, }, + { NFSV4OP_LOCKT, 1, "LockT", 5, }, + { NFSV4OP_OPENDOWNGRADE, 1, "Opendowngrade", 13, }, + { NFSV4OP_RENEW, 1, "Renew", 5, }, + { NFSV4OP_PUTROOTFH, 1, "Dirpath", 7, }, + { NFSV4OP_RELEASELCKOWN, 1, "Rellckown", 9, }, + { NFSV4OP_DELEGRETURN, 1, "Delegret", 8, }, + { NFSV4OP_DELEGRETURN, 3, "DelegRemove", 11, }, + { NFSV4OP_DELEGRETURN, 7, "DelegRename1", 12, }, + { NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, }, + { NFSV4OP_GETATTR, 1, "Getacl", 6, }, + { NFSV4OP_SETATTR, 1, "Setacl", 6, }, + { NFSV4OP_EXCHANGEID, 1, "ExchangeID", 10, }, + { NFSV4OP_CREATESESSION, 1, "CreateSession", 13, }, + { NFSV4OP_DESTROYSESSION, 1, "DestroySession", 14, }, + { NFSV4OP_DESTROYCLIENTID, 1, "DestroyClient", 13, }, + { NFSV4OP_FREESTATEID, 1, "FreeStateID", 11, }, + { NFSV4OP_LAYOUTGET, 1, "LayoutGet", 9, }, + { NFSV4OP_GETDEVINFO, 1, "GetDeviceInfo", 13, }, + { NFSV4OP_LAYOUTCOMMIT, 1, "LayoutCommit", 12, }, + { NFSV4OP_LAYOUTRETURN, 1, "LayoutReturn", 12, }, + { NFSV4OP_RECLAIMCOMPL, 1, "ReclaimComplete", 15, }, + { NFSV4OP_WRITE, 1, "WriteDS", 7, }, + { NFSV4OP_READ, 1, "ReadDS", 6, }, + { NFSV4OP_COMMIT, 1, "CommitDS", 8, }, + { NFSV4OP_OPEN, 3, "OpenLayoutGet", 13, }, + { NFSV4OP_OPEN, 8, "CreateLayGet", 12, }, +}; +/* + * NFS RPCS that have large request message size. + */ +static int nfs_bigrequest[NFSV41_NPROCS] = { + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 +}; + +/* + * Start building a request. Mostly just put the first file handle in + * place. + */ +APPLESTATIC void +nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, + u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, + int vers, int minorvers) +{ + struct mbuf *mb; + u_int32_t *tl; + int opcnt; + nfsattrbit_t attrbits; + + /* + * First, fill in some of the fields of nd. + */ + nd->nd_slotseq = NULL; + if (vers == NFS_VER4) { + nd->nd_flag = ND_NFSV4 | ND_NFSCL; + if (minorvers == NFSV41_MINORVERSION) + nd->nd_flag |= ND_NFSV41; + } else if (vers == NFS_VER3) + nd->nd_flag = ND_NFSV3 | ND_NFSCL; + else { + if (NFSHASNFSV4(nmp)) { + nd->nd_flag = ND_NFSV4 | ND_NFSCL; + if (NFSHASNFSV4N(nmp)) + nd->nd_flag |= ND_NFSV41; + } else if (NFSHASNFSV3(nmp)) + nd->nd_flag = ND_NFSV3 | ND_NFSCL; + else + nd->nd_flag = ND_NFSV2 | ND_NFSCL; + } + nd->nd_procnum = procnum; + nd->nd_repstat = 0; + + /* + * Get the first mbuf for the request. + */ + if (nfs_bigrequest[procnum]) + NFSMCLGET(mb, M_WAITOK); + else + NFSMGET(mb); + mbuf_setlen(mb, 0); + nd->nd_mreq = nd->nd_mb = mb; + nd->nd_bpos = NFSMTOD(mb, caddr_t); + + /* + * And fill the first file handle into the request. + */ + if (nd->nd_flag & ND_NFSV4) { + opcnt = nfsv4_opmap[procnum].opcnt + + nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh; + if ((nd->nd_flag & ND_NFSV41) != 0) { + opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq; + if (procnum == NFSPROC_RENEW) + /* + * For the special case of Renew, just do a + * Sequence Op. + */ + opcnt = 1; + else if (procnum == NFSPROC_WRITEDS || + procnum == NFSPROC_COMMITDS) + /* + * For the special case of a Writeor Commit to + * a DS, the opcnt == 3, for Sequence, PutFH, + * Write/Commit. + */ + opcnt = 3; + } + /* + * What should the tag really be? + */ + (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag, + nfsv4_opmap[procnum].taglen); + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + if ((nd->nd_flag & ND_NFSV41) != 0) + *tl++ = txdr_unsigned(NFSV41_MINORVERSION); + else + *tl++ = txdr_unsigned(NFSV4_MINORVERSION); + if (opcntpp != NULL) + *opcntpp = tl; + *tl = txdr_unsigned(opcnt); + if ((nd->nd_flag & ND_NFSV41) != 0 && + nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) { + if (nfsv4_opflag[nfsv4_opmap[procnum].op].loopbadsess > + 0) + nd->nd_flag |= ND_LOOPBADSESS; + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_SEQUENCE); + if (sep == NULL) { + sep = nfsmnt_mdssession(nmp); + nfsv4_setsequence(nmp, nd, sep, + nfs_bigreply[procnum]); + } else + nfsv4_setsequence(nmp, nd, sep, + nfs_bigreply[procnum]); + } + if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_PUTFH); + (void) nfsm_fhtom(nd, nfhp, fhlen, 0); + if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh + == 2 && procnum != NFSPROC_WRITEDS && + procnum != NFSPROC_COMMITDS) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_GETATTR); + /* + * For Lookup Ops, we want all the directory + * attributes, so we can load the name cache. + */ + if (procnum == NFSPROC_LOOKUP || + procnum == NFSPROC_LOOKUPP) + NFSGETATTR_ATTRBIT(&attrbits); + else { + NFSWCCATTR_ATTRBIT(&attrbits); + nd->nd_flag |= ND_V4WCCATTR; + } + (void) nfsrv_putattrbit(nd, &attrbits); + } + } + if (procnum != NFSPROC_RENEW || + (nd->nd_flag & ND_NFSV41) == 0) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(nfsv4_opmap[procnum].op); + } + } else { + (void) nfsm_fhtom(nd, nfhp, fhlen, 0); + } + if (procnum < NFSV41_NPROCS) + NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]); +} + +/* + * Put a state Id in the mbuf list. + */ +APPLESTATIC void +nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag) +{ + nfsv4stateid_t *st; + + NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID); + if (flag == NFSSTATEID_PUTALLZERO) { + st->seqid = 0; + st->other[0] = 0; + st->other[1] = 0; + st->other[2] = 0; + } else if (flag == NFSSTATEID_PUTALLONE) { + st->seqid = 0xffffffff; + st->other[0] = 0xffffffff; + st->other[1] = 0xffffffff; + st->other[2] = 0xffffffff; + } else if (flag == NFSSTATEID_PUTSEQIDZERO) { + st->seqid = 0; + st->other[0] = stateidp->other[0]; + st->other[1] = stateidp->other[1]; + st->other[2] = stateidp->other[2]; + } else { + st->seqid = stateidp->seqid; + st->other[0] = stateidp->other[0]; + st->other[1] = stateidp->other[1]; + st->other[2] = stateidp->other[2]; + } +} + +/* + * Fill in the setable attributes. The full argument indicates whether + * to fill in them all or just mode and time. + */ +void +nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap, + struct vnode *vp, int flags, u_int32_t rdev) +{ + u_int32_t *tl; + struct nfsv2_sattr *sp; + nfsattrbit_t attrbits; + + switch (nd->nd_flag & (ND_NFSV2 | ND_NFSV3 | ND_NFSV4)) { + case ND_NFSV2: + NFSM_BUILD(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + if (vap->va_mode == (mode_t)VNOVAL) + sp->sa_mode = newnfs_xdrneg1; + else + sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); + if (vap->va_uid == (uid_t)VNOVAL) + sp->sa_uid = newnfs_xdrneg1; + else + sp->sa_uid = txdr_unsigned(vap->va_uid); + if (vap->va_gid == (gid_t)VNOVAL) + sp->sa_gid = newnfs_xdrneg1; + else + sp->sa_gid = txdr_unsigned(vap->va_gid); + if (flags & NFSSATTR_SIZE0) + sp->sa_size = 0; + else if (flags & NFSSATTR_SIZENEG1) + sp->sa_size = newnfs_xdrneg1; + else if (flags & NFSSATTR_SIZERDEV) + sp->sa_size = txdr_unsigned(rdev); + else + sp->sa_size = txdr_unsigned(vap->va_size); + txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); + txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); + break; + case ND_NFSV3: + if (vap->va_mode != (mode_t)VNOVAL) { + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = newnfs_true; + *tl = txdr_unsigned(vap->va_mode); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = newnfs_false; + } + if ((flags & NFSSATTR_FULL) && vap->va_uid != (uid_t)VNOVAL) { + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = newnfs_true; + *tl = txdr_unsigned(vap->va_uid); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = newnfs_false; + } + if ((flags & NFSSATTR_FULL) && vap->va_gid != (gid_t)VNOVAL) { + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = newnfs_true; + *tl = txdr_unsigned(vap->va_gid); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = newnfs_false; + } + if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL) { + NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + *tl++ = newnfs_true; + txdr_hyper(vap->va_size, tl); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = newnfs_false; + } + if (vap->va_atime.tv_sec != VNOVAL) { + if ((vap->va_vaflags & VA_UTIMES_NULL) == 0) { + NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&vap->va_atime, tl); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } + if (vap->va_mtime.tv_sec != VNOVAL) { + if ((vap->va_vaflags & VA_UTIMES_NULL) == 0) { + NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&vap->va_mtime, tl); + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } + break; + case ND_NFSV4: + NFSZERO_ATTRBIT(&attrbits); + if (vap->va_mode != (mode_t)VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_MODE); + if ((flags & NFSSATTR_FULL) && vap->va_uid != (uid_t)VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER); + if ((flags & NFSSATTR_FULL) && vap->va_gid != (gid_t)VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNERGROUP); + if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); + if (vap->va_atime.tv_sec != VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET); + if (vap->va_mtime.tv_sec != VNOVAL) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET); + (void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0, + &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL); + break; + } +} + #ifndef APPLE /* * copies mbuf chain to the uio scatter/gather list @@ -4230,6 +4587,8 @@ nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_d tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; nd->nd_slotseq = tl; if (error == 0) { + nd->nd_flag |= ND_HASSLOTID; + nd->nd_slotid = slotpos; *tl++ = txdr_unsigned(slotseq); *tl++ = txdr_unsigned(slotpos); *tl++ = txdr_unsigned(maxslot); Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs_var.h Tue Jun 19 20:32:43 2018 (r335385) @@ -298,6 +298,11 @@ void nfsrvd_delcache(struct nfsrvcache *); void nfsrc_trimcache(uint64_t, uint32_t, int); /* nfs_commonsubs.c */ +void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *, + u_int8_t *, int, u_int32_t **, struct nfsclsession *, int, int); +void nfsm_stateidtom(struct nfsrv_descript *, nfsv4stateid_t *, int); +void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *, + vnode_t, int, u_int32_t); void newnfs_init(void); int nfsaddr_match(int, union nethostaddr *, NFSSOCKADDR_T); int nfsaddr2_match(NFSSOCKADDR_T, NFSSOCKADDR_T); @@ -347,11 +352,7 @@ struct nfsdevice *nfsv4_findmirror(struct nfsmount *); /* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); struct mbuf *nfsm_uiombuflist(struct uio *, int, struct mbuf **, char **); -void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *, - u_int8_t *, int, u_int32_t **, struct nfsclsession *, int, int); nfsuint64 *nfscl_getcookie(struct nfsnode *, off_t off, int); -void nfscl_fillsattr(struct nfsrv_descript *, struct vattr *, - vnode_t, int, u_int32_t); u_int8_t *nfscl_getmyip(struct nfsmount *, struct in6_addr *, int *); int nfsm_getfh(struct nfsrv_descript *, struct nfsfh **); int nfscl_mtofh(struct nfsrv_descript *, struct nfsfh **, @@ -363,7 +364,6 @@ int nfscl_wcc_data(struct nfsrv_descript *, vnode_t, int nfsm_loadattr(struct nfsrv_descript *, struct nfsvattr *); int nfscl_request(struct nfsrv_descript *, vnode_t, NFSPROC_T *, struct ucred *, void *); -void nfsm_stateidtom(struct nfsrv_descript *, nfsv4stateid_t *, int); /* nfs_nfsdsubs.c */ void nfsd_fhtovp(struct nfsrv_descript *, struct nfsrvfh *, int, @@ -601,7 +601,8 @@ int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t NFSPROC_T *); struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int, uint64_t, struct nfsclflayout **, int *); -void nfscl_dserr(uint32_t, struct nfscldevinfo *, struct nfscllayout *); +void nfscl_dserr(uint32_t, struct nfscldevinfo *, struct nfscllayout *, + struct nfsclds *); void nfscl_rellayout(struct nfscllayout *, int); struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *, struct nfscldevinfo *); @@ -717,6 +718,7 @@ int nfsrv_setacl(struct vnode *, NFSACL_T *, struct uc /* nfs_commonkrpc.c */ int newnfs_nmcancelreqs(struct nfsmount *); +void newnfs_canceldspreq(struct nfsclds *); void newnfs_set_sigmask(struct thread *, sigset_t *); void newnfs_restore_sigmask(struct thread *, sigset_t *); int newnfs_msleep(struct thread *, void *, struct mtx *, int, char *, int); Modified: projects/pnfs-planb-server/sys/fs/nfs/nfsport.h ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfsport.h Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfs/nfsport.h Tue Jun 19 20:32:43 2018 (r335385) @@ -1054,6 +1054,27 @@ extern const char nfs_vnode_tag[]; */ #define nfsds_failerr(e) ((e) == ENXIO || (e) == EIO) +/* + * Get a pointer to the MDS session, which is always the first element + * in the list. + * This macro can only be safely used when the NFSLOCKMNT() lock is held. + * The inline function can be used when the lock isn't held. + */ +#define NFSMNT_MDSSESSION(m) (&(TAILQ_FIRST(&((m)->nm_sess))->nfsclds_sess)) + +static __inline struct nfsclsession * +nfsmnt_mdssession(struct nfsmount *nmp) +{ + struct nfsclsession *tsep; + + tsep = NULL; + mtx_lock(&nmp->nm_mtx); + if (TAILQ_FIRST(&nmp->nm_sess) != NULL) + tsep = NFSMNT_MDSSESSION(nmp); + mtx_unlock(&nmp->nm_mtx); + return (tsep); +} + #endif /* _KERNEL */ #endif /* _NFS_NFSPORT_H */ Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clcomsubs.c Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clcomsubs.c Tue Jun 19 20:32:43 2018 (r335385) @@ -49,219 +49,12 @@ extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS]; extern int ncl_mbuf_mlen; extern enum vtype newnv2tov_type[8]; extern enum vtype nv34tov_type[8]; -extern int nfs_bigreply[NFSV41_NPROCS]; NFSCLSTATEMUTEX; #endif /* !APPLEKEXT */ static nfsuint64 nfs_nullcookie = {{ 0, 0 }}; -static struct { - int op; - int opcnt; - const u_char *tag; - int taglen; -} nfsv4_opmap[NFSV41_NPROCS] = { - { 0, 1, "Null", 4 }, - { NFSV4OP_GETATTR, 1, "Getattr", 7, }, - { NFSV4OP_SETATTR, 2, "Setattr", 7, }, - { NFSV4OP_LOOKUP, 3, "Lookup", 6, }, - { NFSV4OP_ACCESS, 2, "Access", 6, }, - { NFSV4OP_READLINK, 2, "Readlink", 8, }, - { NFSV4OP_READ, 1, "Read", 4, }, - { NFSV4OP_WRITE, 2, "Write", 5, }, - { NFSV4OP_OPEN, 5, "Open", 4, }, - { NFSV4OP_CREATE, 5, "Create", 6, }, - { NFSV4OP_CREATE, 1, "Create", 6, }, - { NFSV4OP_CREATE, 3, "Create", 6, }, - { NFSV4OP_REMOVE, 1, "Remove", 6, }, - { NFSV4OP_REMOVE, 1, "Remove", 6, }, - { NFSV4OP_SAVEFH, 5, "Rename", 6, }, - { NFSV4OP_SAVEFH, 4, "Link", 4, }, - { NFSV4OP_READDIR, 2, "Readdir", 7, }, - { NFSV4OP_READDIR, 2, "Readdir", 7, }, - { NFSV4OP_GETATTR, 1, "Getattr", 7, }, - { NFSV4OP_GETATTR, 1, "Getattr", 7, }, - { NFSV4OP_GETATTR, 1, "Getattr", 7, }, - { NFSV4OP_COMMIT, 2, "Commit", 6, }, - { NFSV4OP_LOOKUPP, 3, "Lookupp", 7, }, - { NFSV4OP_SETCLIENTID, 1, "SetClientID", 11, }, - { NFSV4OP_SETCLIENTIDCFRM, 1, "SetClientIDConfirm", 18, }, - { NFSV4OP_LOCK, 1, "Lock", 4, }, - { NFSV4OP_LOCKU, 1, "LockU", 5, }, - { NFSV4OP_OPEN, 2, "Open", 4, }, - { NFSV4OP_CLOSE, 1, "Close", 5, }, - { NFSV4OP_OPENCONFIRM, 1, "Openconfirm", 11, }, - { NFSV4OP_LOCKT, 1, "LockT", 5, }, - { NFSV4OP_OPENDOWNGRADE, 1, "Opendowngrade", 13, }, - { NFSV4OP_RENEW, 1, "Renew", 5, }, - { NFSV4OP_PUTROOTFH, 1, "Dirpath", 7, }, - { NFSV4OP_RELEASELCKOWN, 1, "Rellckown", 9, }, - { NFSV4OP_DELEGRETURN, 1, "Delegret", 8, }, - { NFSV4OP_DELEGRETURN, 3, "DelegRemove", 11, }, - { NFSV4OP_DELEGRETURN, 7, "DelegRename1", 12, }, - { NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, }, - { NFSV4OP_GETATTR, 1, "Getacl", 6, }, - { NFSV4OP_SETATTR, 1, "Setacl", 6, }, - { NFSV4OP_EXCHANGEID, 1, "ExchangeID", 10, }, - { NFSV4OP_CREATESESSION, 1, "CreateSession", 13, }, - { NFSV4OP_DESTROYSESSION, 1, "DestroySession", 14, }, - { NFSV4OP_DESTROYCLIENTID, 1, "DestroyClient", 13, }, - { NFSV4OP_FREESTATEID, 1, "FreeStateID", 11, }, - { NFSV4OP_LAYOUTGET, 1, "LayoutGet", 9, }, - { NFSV4OP_GETDEVINFO, 1, "GetDeviceInfo", 13, }, - { NFSV4OP_LAYOUTCOMMIT, 1, "LayoutCommit", 12, }, - { NFSV4OP_LAYOUTRETURN, 1, "LayoutReturn", 12, }, - { NFSV4OP_RECLAIMCOMPL, 1, "ReclaimComplete", 15, }, - { NFSV4OP_WRITE, 1, "WriteDS", 7, }, - { NFSV4OP_READ, 1, "ReadDS", 6, }, - { NFSV4OP_COMMIT, 1, "CommitDS", 8, }, - { NFSV4OP_OPEN, 3, "OpenLayoutGet", 13, }, - { NFSV4OP_OPEN, 8, "CreateLayGet", 12, }, -}; /* - * NFS RPCS that have large request message size. - */ -static int nfs_bigrequest[NFSV41_NPROCS] = { - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 -}; - -/* - * Start building a request. Mostly just put the first file handle in - * place. - */ -APPLESTATIC void -nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp, - u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep, - int vers, int minorvers) -{ - struct mbuf *mb; - u_int32_t *tl; - int opcnt; - nfsattrbit_t attrbits; - - /* - * First, fill in some of the fields of nd. - */ - nd->nd_slotseq = NULL; - if (vers == NFS_VER4) { - nd->nd_flag = ND_NFSV4 | ND_NFSCL; - if (minorvers == NFSV41_MINORVERSION) - nd->nd_flag |= ND_NFSV41; - } else if (vers == NFS_VER3) - nd->nd_flag = ND_NFSV3 | ND_NFSCL; - else { - if (NFSHASNFSV4(nmp)) { - nd->nd_flag = ND_NFSV4 | ND_NFSCL; - if (NFSHASNFSV4N(nmp)) - nd->nd_flag |= ND_NFSV41; - } else if (NFSHASNFSV3(nmp)) - nd->nd_flag = ND_NFSV3 | ND_NFSCL; - else - nd->nd_flag = ND_NFSV2 | ND_NFSCL; - } - nd->nd_procnum = procnum; - nd->nd_repstat = 0; - - /* - * Get the first mbuf for the request. - */ - if (nfs_bigrequest[procnum]) - NFSMCLGET(mb, M_WAITOK); - else - NFSMGET(mb); - mbuf_setlen(mb, 0); - nd->nd_mreq = nd->nd_mb = mb; - nd->nd_bpos = NFSMTOD(mb, caddr_t); - - /* - * And fill the first file handle into the request. - */ - if (nd->nd_flag & ND_NFSV4) { - opcnt = nfsv4_opmap[procnum].opcnt + - nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh; - if ((nd->nd_flag & ND_NFSV41) != 0) { - opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq; - if (procnum == NFSPROC_RENEW) - /* - * For the special case of Renew, just do a - * Sequence Op. - */ - opcnt = 1; - else if (procnum == NFSPROC_WRITEDS || - procnum == NFSPROC_COMMITDS) - /* - * For the special case of a Writeor Commit to - * a DS, the opcnt == 3, for Sequence, PutFH, - * Write/Commit. - */ - opcnt = 3; - } - /* - * What should the tag really be? - */ - (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag, - nfsv4_opmap[procnum].taglen); - NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if ((nd->nd_flag & ND_NFSV41) != 0) - *tl++ = txdr_unsigned(NFSV41_MINORVERSION); - else - *tl++ = txdr_unsigned(NFSV4_MINORVERSION); - if (opcntpp != NULL) - *opcntpp = tl; - *tl = txdr_unsigned(opcnt); - if ((nd->nd_flag & ND_NFSV41) != 0 && - nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) { - if (nfsv4_opflag[nfsv4_opmap[procnum].op].loopbadsess > - 0) - nd->nd_flag |= ND_LOOPBADSESS; - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV4OP_SEQUENCE); - if (sep == NULL) { - sep = nfsmnt_mdssession(nmp); - nfsv4_setsequence(nmp, nd, sep, - nfs_bigreply[procnum]); - } else - nfsv4_setsequence(nmp, nd, sep, - nfs_bigreply[procnum]); - } - if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV4OP_PUTFH); - (void) nfsm_fhtom(nd, nfhp, fhlen, 0); - if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh - == 2 && procnum != NFSPROC_WRITEDS && - procnum != NFSPROC_COMMITDS) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV4OP_GETATTR); - /* - * For Lookup Ops, we want all the directory - * attributes, so we can load the name cache. - */ - if (procnum == NFSPROC_LOOKUP || - procnum == NFSPROC_LOOKUPP) - NFSGETATTR_ATTRBIT(&attrbits); - else { - NFSWCCATTR_ATTRBIT(&attrbits); - nd->nd_flag |= ND_V4WCCATTR; - } - (void) nfsrv_putattrbit(nd, &attrbits); - } - } - if (procnum != NFSPROC_RENEW || - (nd->nd_flag & ND_NFSV41) == 0) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(nfsv4_opmap[procnum].op); - } - } else { - (void) nfsm_fhtom(nd, nfhp, fhlen, 0); - } - if (procnum < NFSV41_NPROCS) - NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]); -} - -/* * copies a uio scatter/gather list to an mbuf chain. * NOTE: can ony handle iovcnt == 1 */ @@ -591,38 +384,6 @@ nfscl_mtofh(struct nfsrv_descript *nd, struct nfsfh ** } nfsmout: return (error); -} - -/* - * Put a state Id in the mbuf list. - */ -APPLESTATIC void -nfsm_stateidtom(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, int flag) -{ - nfsv4stateid_t *st; - - NFSM_BUILD(st, nfsv4stateid_t *, NFSX_STATEID); - if (flag == NFSSTATEID_PUTALLZERO) { - st->seqid = 0; - st->other[0] = 0; - st->other[1] = 0; - st->other[2] = 0; - } else if (flag == NFSSTATEID_PUTALLONE) { - st->seqid = 0xffffffff; - st->other[0] = 0xffffffff; - st->other[1] = 0xffffffff; - st->other[2] = 0xffffffff; - } else if (flag == NFSSTATEID_PUTSEQIDZERO) { - st->seqid = 0; - st->other[0] = stateidp->other[0]; - st->other[1] = stateidp->other[1]; - st->other[2] = stateidp->other[2]; - } else { - st->seqid = stateidp->seqid; - st->other[0] = stateidp->other[0]; - st->other[1] = stateidp->other[1]; - st->other[2] = stateidp->other[2]; - } } /* Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c Tue Jun 19 20:02:03 2018 (r335384) +++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clport.c Tue Jun 19 20:32:43 2018 (r335385) @@ -819,124 +819,6 @@ nfsmout: } /* - * Fill in the setable attributes. The full argument indicates whether - * to fill in them all or just mode and time. - */ -void -nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap, - struct vnode *vp, int flags, u_int32_t rdev) -{ - u_int32_t *tl; - struct nfsv2_sattr *sp; - nfsattrbit_t attrbits; - - switch (nd->nd_flag & (ND_NFSV2 | ND_NFSV3 | ND_NFSV4)) { - case ND_NFSV2: - NFSM_BUILD(sp, struct nfsv2_sattr *, NFSX_V2SATTR); - if (vap->va_mode == (mode_t)VNOVAL) - sp->sa_mode = newnfs_xdrneg1; - else - sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); - if (vap->va_uid == (uid_t)VNOVAL) - sp->sa_uid = newnfs_xdrneg1; - else - sp->sa_uid = txdr_unsigned(vap->va_uid); - if (vap->va_gid == (gid_t)VNOVAL) - sp->sa_gid = newnfs_xdrneg1; - else - sp->sa_gid = txdr_unsigned(vap->va_gid); - if (flags & NFSSATTR_SIZE0) - sp->sa_size = 0; - else if (flags & NFSSATTR_SIZENEG1) - sp->sa_size = newnfs_xdrneg1; - else if (flags & NFSSATTR_SIZERDEV) - sp->sa_size = txdr_unsigned(rdev); - else - sp->sa_size = txdr_unsigned(vap->va_size); - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - break; - case ND_NFSV3: - if (vap->va_mode != (mode_t)VNOVAL) { - NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = newnfs_true; - *tl = txdr_unsigned(vap->va_mode); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = newnfs_false; - } - if ((flags & NFSSATTR_FULL) && vap->va_uid != (uid_t)VNOVAL) { - NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = newnfs_true; - *tl = txdr_unsigned(vap->va_uid); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = newnfs_false; - } - if ((flags & NFSSATTR_FULL) && vap->va_gid != (gid_t)VNOVAL) { - NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = newnfs_true; - *tl = txdr_unsigned(vap->va_gid); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = newnfs_false; - } - if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL) { - NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = newnfs_true; - txdr_hyper(vap->va_size, tl); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = newnfs_false; - } - if (vap->va_atime.tv_sec != VNOVAL) { - if ((vap->va_vaflags & VA_UTIMES_NULL) == 0) { - NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&vap->va_atime, tl); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } - if (vap->va_mtime.tv_sec != VNOVAL) { - if ((vap->va_vaflags & VA_UTIMES_NULL) == 0) { - NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&vap->va_mtime, tl); - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } - break; - case ND_NFSV4: - NFSZERO_ATTRBIT(&attrbits); - if (vap->va_mode != (mode_t)VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_MODE); - if ((flags & NFSSATTR_FULL) && vap->va_uid != (uid_t)VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER); - if ((flags & NFSSATTR_FULL) && vap->va_gid != (gid_t)VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNERGROUP); - if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); - if (vap->va_atime.tv_sec != VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET); - if (vap->va_mtime.tv_sec != VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET); - (void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0, - &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL); - break; - } -} - -/* * nfscl_request() - mostly a wrapper for newnfs_request(). */ int *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***