svn commit: r324025 - in projects/pnfs-planb-server-stable11/sys/fs: nfs nfsclient nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Tue Sep 26 20:26:51 UTC 2017
Author: rmacklem
Date: Tue Sep 26 20:26:48 2017
New Revision: 324025
URL: https://svnweb.freebsd.org/changeset/base/324025
Log:
Add support for Flex File Layout to the client.
This patch does not change the pNFS server, but adds Flex File Layout support
to the NFSv4.1 client. I have done this to the stable/11 branch so that others
can test more easily. This patch will go into head/current as a bunch of
smaller commits. As such, it will eventually be merged from head into
pnfs-planb-server.
Modified:
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs.h
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_commonsubs.c
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_var.h
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfscl.h
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsclstate.h
projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsport.h
projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clcomsubs.c
projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clrpcops.c
projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clstate.c
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdport.c
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs.h
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs.h Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs.h Tue Sep 26 20:26:48 2017 (r324025)
@@ -192,9 +192,11 @@ struct nfsd_nfsd_args {
* (To support more than 1000 DSs on an MDS, this needs to be increased.)
* NFSDEV_MAXMIRRORS - Maximum # of mirrors for a DS.
* (Most will only have a single mirror, but this setting allows up to 3.)
+ * NFSDEV_MAXVERS - maximum number of NFS versions supported by Flex File.
*/
#define NFSDEV_MIRRORSTR 3
#define NFSDEV_MAXMIRRORS 4
+#define NFSDEV_MAXVERS 4
/* Old version. */
struct nfsd_nfsd_oargs {
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_commonsubs.c Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_commonsubs.c Tue Sep 26 20:26:48 2017 (r324025)
@@ -4025,14 +4025,13 @@ newnfs_sndunlock(int *flagp)
}
APPLESTATIC int
-nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_storage *sa,
- int *isudp)
+nfsv4_getipaddr(struct nfsrv_descript *nd, struct sockaddr_in *sin,
+ struct sockaddr_in6 *sin6, sa_family_t *saf, int *isudp)
{
- struct sockaddr_in *sad;
- struct sockaddr_in6 *sad6;
struct in_addr saddr;
uint32_t portnum, *tl;
- int af = 0, i, j, k;
+ int i, j, k;
+ sa_family_t af = AF_UNSPEC;
char addr[64], protocol[5], *cp;
int cantparse = 0, error = 0;
uint16_t portv;
@@ -4110,20 +4109,20 @@ nfsv4_getipaddr(struct nfsrv_descript *nd, struct sock
cantparse = 1;
if (cantparse == 0) {
if (af == AF_INET) {
- sad = (struct sockaddr_in *)sa;
- if (inet_pton(af, addr, &sad->sin_addr) == 1) {
- sad->sin_len = sizeof(*sad);
- sad->sin_family = AF_INET;
- sad->sin_port = htons(portv);
+ if (inet_pton(af, addr, &sin->sin_addr) == 1) {
+ sin->sin_len = sizeof(*sin);
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons(portv);
+ *saf = af;
return (0);
}
} else {
- sad6 = (struct sockaddr_in6 *)sa;
- if (inet_pton(af, addr, &sad6->sin6_addr)
+ if (inet_pton(af, addr, &sin6->sin6_addr)
== 1) {
- sad6->sin6_len = sizeof(*sad6);
- sad6->sin6_family = AF_INET6;
- sad6->sin6_port = htons(portv);
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons(portv);
+ *saf = af;
return (0);
}
}
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_var.h Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfs_var.h Tue Sep 26 20:26:48 2017 (r324025)
@@ -311,8 +311,8 @@ void nfsrv_cleanusergroup(void);
int nfsrv_checkutf8(u_int8_t *, int);
int newnfs_sndlock(int *);
void newnfs_sndunlock(int *);
-int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_storage *,
- int *);
+int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_in *,
+ struct sockaddr_in6 *, sa_family_t *, int *);
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
struct mbuf **, uint16_t);
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
@@ -325,8 +325,9 @@ struct ucred *nfsrv_getgrpscred(struct ucred *);
/* 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 *);
+ 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);
@@ -502,17 +503,14 @@ int nfsrpc_destroysession(struct nfsmount *, struct nf
struct ucred *, NFSPROC_T *);
int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *,
struct ucred *, NFSPROC_T *);
-int nfsrpc_layoutget(struct nfsmount *, uint8_t *, int, int, uint64_t, uint64_t,
- uint64_t, int, nfsv4stateid_t *, int *, struct nfsclflayouthead *,
- struct ucred *, NFSPROC_T *, void *);
int nfsrpc_getdeviceinfo(struct nfsmount *, uint8_t *, int, uint32_t *,
struct nfscldevinfo **, struct ucred *, NFSPROC_T *);
int nfsrpc_layoutcommit(struct nfsmount *, uint8_t *, int, int,
- uint64_t, uint64_t, uint64_t, nfsv4stateid_t *, int, int, uint8_t *,
- struct ucred *, NFSPROC_T *, void *);
-int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t,
- int, uint64_t, uint64_t, nfsv4stateid_t *, int, uint32_t *, struct ucred *,
+ uint64_t, uint64_t, uint64_t, nfsv4stateid_t *, int, struct ucred *,
NFSPROC_T *, void *);
+int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t,
+ int, uint64_t, uint64_t, nfsv4stateid_t *, struct ucred *, NFSPROC_T *,
+ void *);
int nfsrpc_reclaimcomplete(struct nfsmount *, struct ucred *, NFSPROC_T *);
int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, int,
struct ucred *, NFSPROC_T *);
@@ -581,7 +579,7 @@ int nfscl_tryclose(struct nfsclopen *, struct ucred *,
struct nfsmount *, NFSPROC_T *);
void nfscl_cleanup(NFSPROC_T *);
int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t *, int, nfsv4stateid_t *,
- int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *,
+ int, int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *,
NFSPROC_T *);
struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int,
uint64_t, struct nfsclflayout **, int *);
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfscl.h
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfscl.h Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfscl.h Tue Sep 26 20:26:48 2017 (r324025)
@@ -49,7 +49,8 @@ struct nfsv4node {
*/
#define NFSCL_REQSTART(n, p, v) \
nfscl_reqstart((n), (p), VFSTONFS((v)->v_mount), \
- VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL, NULL)
+ VTONFS(v)->n_fhp->nfh_fh, VTONFS(v)->n_fhp->nfh_len, NULL, \
+ NULL, 0, 0)
/*
* These two macros convert between a lease duration and renew interval.
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsclstate.h
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsclstate.h Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsclstate.h Tue Sep 26 20:26:48 2017 (r324025)
@@ -258,9 +258,24 @@ struct nfscllayout {
#define NFSLY_RECALLALL 0x0040
#define NFSLY_RETONCLOSE 0x0080
#define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */
+#define NFSLY_FLEXFILE 0x0200
/*
- * MALLOC'd to the correct length to accommodate the file handle list.
+ * Flex file layout mirror specific stuff for nfsclflayout.
+ */
+struct nfsffm {
+ nfsv4stateid_t st;
+ char dev[NFSX_V4DEVICEID];
+ uint32_t eff;
+ uid_t user;
+ gid_t group;
+ struct nfsfh *fh[NFSDEV_MAXVERS];
+ uint16_t fhcnt;
+};
+
+/*
+ * MALLOC'd to the correct length to accommodate the file handle list for File
+ * layout and the list of mirrors for the Flex File Layout.
* These hang off of nfsly_flayread and nfsly_flayrw, sorted in increasing
* offset order.
* The nfsly_flayread list holds the ones with iomode == NFSLAYOUTIOMODE_READ,
@@ -268,23 +283,49 @@ struct nfscllayout {
*/
struct nfsclflayout {
LIST_ENTRY(nfsclflayout) nfsfl_list;
- uint8_t nfsfl_dev[NFSX_V4DEVICEID];
uint64_t nfsfl_off;
uint64_t nfsfl_end;
- uint64_t nfsfl_patoff;
- struct nfscldevinfo *nfsfl_devp;
uint32_t nfsfl_iomode;
- uint32_t nfsfl_util;
- uint32_t nfsfl_stripe1;
+ struct nfscldevinfo *nfsfl_devp;
uint16_t nfsfl_flags;
- uint16_t nfsfl_fhcnt;
- struct nfsfh *nfsfl_fh[1]; /* FH list for DS */
+ union {
+ struct {
+ uint64_t patoff;
+ uint32_t util;
+ uint32_t stripe1;
+ uint8_t dev[NFSX_V4DEVICEID];
+ uint16_t fhcnt;
+ } fl;
+ struct {
+ uint64_t stripeunit;
+ uint32_t fflags;
+ uint32_t statshint;
+ uint16_t mirrorcnt;
+ } ff;
+ } nfsfl_un;
+ union {
+ struct nfsfh *fh[0]; /* FH list for DS File layout */
+ struct nfsffm ffm[0]; /* Mirror list for Flex File */
+ } nfsfl_un2; /* Must be last. Malloc'd to correct array length */
};
+#define nfsfl_patoff nfsfl_un.fl.patoff
+#define nfsfl_util nfsfl_un.fl.util
+#define nfsfl_stripe1 nfsfl_un.fl.stripe1
+#define nfsfl_dev nfsfl_un.fl.dev
+#define nfsfl_fhcnt nfsfl_un.fl.fhcnt
+#define nfsfl_stripeunit nfsfl_un.ff.stripeunit
+#define nfsfl_fflags nfsfl_un.ff.fflags
+#define nfsfl_statshint nfsfl_un.ff.statshint
+#define nfsfl_mirrorcnt nfsfl_un.ff.mirrorcnt
+#define nfsfl_fh nfsfl_un2.fh
+#define nfsfl_ffm nfsfl_un2.ffm
/*
* Flags for nfsfl_flags.
*/
#define NFSFL_RECALL 0x0001 /* File layout has been recalled */
+#define NFSFL_FILE 0x0002 /* File layout */
+#define NFSFL_FLEXFILE 0x0004 /* Flex File layout */
/*
* Structure that is used to store a LAYOUTRECALL.
@@ -306,6 +347,7 @@ struct nfsclrecalllayout {
* - stripe indices, each stored as one byte, since there can be many
* of them. (This implies a limit of 256 on nfsdi_addrcnt, since the
* indices select which address.)
+ * For Flex File, the addrcnt is always one and no stripe indices exist.
*/
struct nfscldevinfo {
LIST_ENTRY(nfscldevinfo) nfsdi_list;
@@ -313,10 +355,33 @@ struct nfscldevinfo {
struct nfsclclient *nfsdi_clp;
uint32_t nfsdi_refcnt;
uint32_t nfsdi_layoutrefs;
- uint16_t nfsdi_stripecnt;
+ union {
+ struct {
+ uint16_t stripecnt;
+ } fl;
+ struct {
+ int versindex;
+ uint32_t vers;
+ uint32_t minorvers;
+ uint32_t rsize;
+ uint32_t wsize;
+ } ff;
+ } nfsdi_un;
uint16_t nfsdi_addrcnt;
+ uint16_t nfsdi_flags;
struct nfsclds *nfsdi_data[0];
};
+#define nfsdi_stripecnt nfsdi_un.fl.stripecnt
+#define nfsdi_versindex nfsdi_un.ff.versindex
+#define nfsdi_vers nfsdi_un.ff.vers
+#define nfsdi_minorvers nfsdi_un.ff.minorvers
+#define nfsdi_rsize nfsdi_un.ff.rsize
+#define nfsdi_wsize nfsdi_un.ff.wsize
+
+/* Flags for nfsdi_flags. */
+#define NFSDI_FILELAYOUT 0x0001
+#define NFSDI_FLEXFILE 0x0002
+#define NFSDI_TIGHTCOUPLED 0X0004
/* These inline functions return values from nfsdi_data[]. */
/*
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsport.h Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfs/nfsport.h Tue Sep 26 20:26:48 2017 (r324025)
@@ -921,6 +921,7 @@ int newnfs_realign(struct mbuf **, int);
#define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier */
#define NFSSTA_GOTFSINFO 0x00100000 /* Got the fsinfo */
#define NFSSTA_OPENMODE 0x00200000 /* Must use correct open mode */
+#define NFSSTA_FLEXFILE 0x00800000 /* Use Flex File Layout */
#define NFSSTA_NOLAYOUTCOMMIT 0x04000000 /* Don't do LayoutCommit */
#define NFSSTA_SESSPERSIST 0x08000000 /* Has a persistent session */
#define NFSSTA_TIMEO 0x10000000 /* Experiencing a timeout */
@@ -951,6 +952,7 @@ int newnfs_realign(struct mbuf **, int);
#define NFSHASNOLAYOUTCOMMIT(n) ((n)->nm_state & NFSSTA_NOLAYOUTCOMMIT)
#define NFSHASSESSPERSIST(n) ((n)->nm_state & NFSSTA_SESSPERSIST)
#define NFSHASPNFS(n) ((n)->nm_state & NFSSTA_PNFS)
+#define NFSHASFLEXFILE(n) ((n)->nm_state & NFSSTA_FLEXFILE)
#define NFSHASOPENMODE(n) ((n)->nm_state & NFSSTA_OPENMODE)
#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
(n)->nm_minorvers > 0)
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clcomsubs.c Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clcomsubs.c Tue Sep 26 20:26:48 2017 (r324025)
@@ -131,7 +131,8 @@ static int nfs_bigrequest[NFSV41_NPROCS] = {
*/
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)
+ u_int8_t *nfhp, int fhlen, u_int32_t **opcntpp, struct nfsclsession *sep,
+ int vers, int minorvers)
{
struct mbuf *mb;
u_int32_t *tl;
@@ -142,14 +143,22 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum,
* First, fill in some of the fields of nd.
*/
nd->nd_slotseq = NULL;
- if (NFSHASNFSV4(nmp)) {
+ if (vers == NFS_VER4) {
nd->nd_flag = ND_NFSV4 | ND_NFSCL;
- if (NFSHASNFSV4N(nmp))
+ if (minorvers == NFSV41_MINORVERSION)
nd->nd_flag |= ND_NFSV41;
- } else if (NFSHASNFSV3(nmp))
+ } else if (vers == NFS_VER3)
nd->nd_flag = ND_NFSV3 | ND_NFSCL;
- else
- nd->nd_flag = ND_NFSV2 | 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;
@@ -333,6 +342,77 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *ui
nd->nd_mb = mp;
}
#endif /* !APPLE */
+
+/*
+ * copies a uio scatter/gather list to an mbuf chain.
+ * This version returns the mbuf list and does not use "nd".
+ * NOTE: can ony handle iovcnt == 1
+ */
+struct mbuf *
+nfsm_uiombuflist(struct uio *uiop, int siz, struct mbuf **mbp, char **cpp)
+{
+ char *uiocp;
+ struct mbuf *mp, *mp2, *firstmp;
+ int xfer, left, mlen;
+ int uiosiz, clflg, rem;
+ char *tcp;
+
+ KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
+
+ if (siz > ncl_mbuf_mlen) /* or should it >= MCLBYTES ?? */
+ clflg = 1;
+ else
+ clflg = 0;
+ rem = NFSM_RNDUP(siz) - siz;
+ if (clflg != 0)
+ NFSMCLGET(mp, M_WAITOK);
+ else
+ NFSMGET(mp);
+ mbuf_setlen(mp, 0);
+ firstmp = mp2 = mp;
+ while (siz > 0) {
+ left = uiop->uio_iov->iov_len;
+ uiocp = uiop->uio_iov->iov_base;
+ if (left > siz)
+ left = siz;
+ uiosiz = left;
+ while (left > 0) {
+ mlen = M_TRAILINGSPACE(mp);
+ if (mlen == 0) {
+ if (clflg)
+ NFSMCLGET(mp, M_WAITOK);
+ else
+ NFSMGET(mp);
+ mbuf_setlen(mp, 0);
+ mbuf_setnext(mp2, mp);
+ mp2 = mp;
+ mlen = M_TRAILINGSPACE(mp);
+ }
+ xfer = (left > mlen) ? mlen : left;
+ if (uiop->uio_segflg == UIO_SYSSPACE)
+ NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) +
+ mbuf_len(mp), xfer);
+ else
+ copyin(uiocp, NFSMTOD(mp, caddr_t) +
+ mbuf_len(mp), xfer);
+ mbuf_setlen(mp, mbuf_len(mp) + xfer);
+ left -= xfer;
+ uiocp += xfer;
+ uiop->uio_offset += xfer;
+ uiop->uio_resid -= xfer;
+ }
+ tcp = (char *)uiop->uio_iov->iov_base;
+ tcp += uiosiz;
+ uiop->uio_iov->iov_base = (void *)tcp;
+ uiop->uio_iov->iov_len -= uiosiz;
+ siz -= uiosiz;
+ }
+ if (cpp != NULL)
+ *cpp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
+ if (mbp != NULL)
+ *mbp = mp;
+ return (firstmp);
+}
/*
* Load vnode attributes from the xdr file attributes.
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clrpcops.c Tue Sep 26 20:23:09 2017 (r324024)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfsclient/nfs_clrpcops.c Tue Sep 26 20:26:48 2017 (r324025)
@@ -109,25 +109,35 @@ static int nfsrpc_setaclrpc(vnode_t, struct ucred *, N
static int nfsrpc_getlayout(struct nfsmount *, vnode_t, struct nfsfh *, int,
uint32_t *, nfsv4stateid_t *, uint64_t, struct nfscllayout **,
struct ucred *, NFSPROC_T *);
-static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_storage *,
- struct nfsclds **, NFSPROC_T *);
+static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_in *,
+ struct sockaddr_in6 *, sa_family_t, int, struct nfsclds **, NFSPROC_T *);
static void nfscl_initsessionslots(struct nfsclsession *);
static int nfscl_doflayoutio(vnode_t, struct uio *, int *, int *, int *,
nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *,
struct nfsclflayout *, uint64_t, uint64_t, int, struct ucred *,
NFSPROC_T *);
+static int nfscl_dofflayoutio(vnode_t, struct uio *, int *, int *, int *,
+ nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *,
+ struct nfsclflayout *, uint64_t, uint64_t, int, int, struct mbuf *,
+ struct ucred *, NFSPROC_T *);
+static struct mbuf *nfsm_copym(struct mbuf *, int, int);
static int nfsrpc_readds(vnode_t, struct uio *, nfsv4stateid_t *, int *,
- struct nfsclds *, uint64_t, int, struct nfsfh *, struct ucred *,
- NFSPROC_T *);
+ struct nfsclds *, uint64_t, int, struct nfsfh *, int, int, int,
+ struct ucred *, NFSPROC_T *);
static int nfsrpc_writeds(vnode_t, struct uio *, int *, int *,
nfsv4stateid_t *, struct nfsclds *, uint64_t, int,
- struct nfsfh *, int, struct ucred *, NFSPROC_T *);
+ struct nfsfh *, int, int, int, int, struct ucred *, NFSPROC_T *);
+static int nfsrpc_writedsmir(vnode_t, int *, int *, nfsv4stateid_t *,
+ struct nfsclds *, uint64_t, int, struct nfsfh *, struct mbuf *, int, int,
+ struct ucred *, NFSPROC_T *);
static enum nfsclds_state nfscl_getsameserver(struct nfsmount *,
struct nfsclds *, struct nfsclds **);
static int nfsrpc_commitds(vnode_t, uint64_t, int, struct nfsclds *,
- struct nfsfh *, struct ucred *, NFSPROC_T *);
+ struct nfsfh *, int, int, struct ucred *, NFSPROC_T *);
static void nfsrv_setuplayoutget(struct nfsrv_descript *, int, uint64_t,
- uint64_t, uint64_t, nfsv4stateid_t *, int, int);
+ uint64_t, uint64_t, nfsv4stateid_t *, int, int, int);
+static int nfsrv_parseug(struct nfsrv_descript *, int, uid_t *, gid_t *,
+ NFSPROC_T *);
static int nfsrv_parselayoutget(struct nfsrv_descript *, nfsv4stateid_t *,
int *, struct nfsclflayouthead *);
static int nfsrpc_getopenlayout(struct nfsmount *, vnode_t, u_int8_t *,
@@ -139,16 +149,19 @@ static int nfsrpc_getcreatelayout(vnode_t, char *, int
struct nfsfh **, int *, int *, void *, int *);
static int nfsrpc_openlayoutrpc(struct nfsmount *, vnode_t, u_int8_t *,
int, uint8_t *, int, uint32_t, struct nfsclopen *, uint8_t *, int,
- struct nfscldeleg **, nfsv4stateid_t *, int, int, int *,
+ struct nfscldeleg **, nfsv4stateid_t *, int, int, int, int *,
struct nfsclflayouthead *, int *, struct ucred *, NFSPROC_T *);
static int nfsrpc_createlayout(vnode_t, char *, int, struct vattr *,
nfsquad_t, int, struct nfsclowner *, struct nfscldeleg **,
struct ucred *, NFSPROC_T *, struct nfsvattr *, struct nfsvattr *,
struct nfsfh **, int *, int *, void *, int *, nfsv4stateid_t *,
- int, int, int *, struct nfsclflayouthead *, int *);
+ int, int, int, int *, struct nfsclflayouthead *, int *);
+static int nfsrpc_layoutget(struct nfsmount *, uint8_t *, int, int, uint64_t,
+ uint64_t, uint64_t, int, int, nfsv4stateid_t *, int *,
+ struct nfsclflayouthead *, struct ucred *, NFSPROC_T *, void *);
static int nfsrpc_layoutgetres(struct nfsmount *, vnode_t, uint8_t *,
int, nfsv4stateid_t *, int, uint32_t *, struct nfscllayout **,
- struct nfsclflayouthead *, int, int *, struct ucred *, NFSPROC_T *);
+ struct nfsclflayouthead *, int, int, int *, struct ucred *, NFSPROC_T *);
/*
* nfs null call from vfs.
@@ -426,7 +439,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int
dp = *dpp;
*dpp = NULL;
- nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_OPEN, nmp, nfhp, fhlen, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid);
*tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH);
@@ -782,7 +795,7 @@ nfsrpc_closerpc(struct nfsrv_descript *nd, struct nfsm
int error;
nfscl_reqstart(nd, NFSPROC_CLOSE, nmp, op->nfso_fh,
- op->nfso_fhlen, NULL, NULL);
+ op->nfso_fhlen, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID);
*tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid);
if (NFSHASNFSV4N(nmp))
@@ -824,7 +837,8 @@ nfsrpc_openconfirm(vnode_t vp, u_int8_t *nfhp, int fhl
nmp = VFSTONFS(vnode_mount(vp));
if (NFSHASNFSV4N(nmp))
return (0); /* No confirmation for NFSv4.1. */
- nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, nmp, nfhp, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, nmp, nfhp, fhlen, NULL, NULL,
+ 0, 0);
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID);
*tl++ = op->nfso_stateid.seqid;
*tl++ = op->nfso_stateid.other[0];
@@ -938,7 +952,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli
tsep = NFSMNT_MDSSESSION(nmp);
NFSUNLOCKMNT(nmp);
- nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_SETCLIENTID, nmp, NULL, 0, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(nfsboottime.tv_sec);
*tl = txdr_unsigned(clp->nfsc_rev);
@@ -1008,7 +1022,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli
* and confirm it.
*/
nfscl_reqstart(nd, NFSPROC_SETCLIENTIDCFRM, nmp, NULL, 0, NULL,
- NULL);
+ NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
*tl++ = tsep->nfsess_clientid.lval[0];
*tl++ = tsep->nfsess_clientid.lval[1];
@@ -1023,7 +1037,7 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli
nd->nd_mrep = NULL;
if (nd->nd_repstat == 0) {
nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, nmp->nm_fh,
- nmp->nm_fhsize, NULL, NULL);
+ nmp->nm_fhsize, NULL, NULL, 0, 0);
NFSZERO_ATTRBIT(&attrbits);
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_LEASETIME);
(void) nfsrv_putattrbit(nd, &attrbits);
@@ -1090,7 +1104,7 @@ nfsrpc_getattrnovp(struct nfsmount *nmp, u_int8_t *fhp
int error, vers = NFS_VER2;
nfsattrbit_t attrbits;
- nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_GETATTR, nmp, fhp, fhlen, NULL, NULL, 0, 0);
if (nd->nd_flag & ND_NFSV4) {
vers = NFS_VER4;
NFSGETATTR_ATTRBIT(&attrbits);
@@ -3996,7 +4010,7 @@ nfsrpc_locku(struct nfsrv_descript *nd, struct nfsmoun
int error;
nfscl_reqstart(nd, NFSPROC_LOCKU, nmp, lp->nfsl_open->nfso_fh,
- lp->nfsl_open->nfso_fhlen, NULL, NULL);
+ lp->nfsl_open->nfso_fhlen, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(type);
*tl = txdr_unsigned(lp->nfsl_seqid);
@@ -4048,7 +4062,7 @@ nfsrpc_lock(struct nfsrv_descript *nd, struct nfsmount
uint8_t own[NFSV4CL_LOCKNAMELEN + NFSX_V4FHMAX];
struct nfsclsession *tsep;
- nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_LOCK, nmp, nfhp, fhlen, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED);
if (type == F_RDLCK)
*tl++ = txdr_unsigned(NFSV4LOCKT_READ);
@@ -4321,10 +4335,11 @@ nfsrpc_renew(struct nfsclclient *clp, struct nfsclds *
if (nmp == NULL)
return (0);
if (dsp == NULL)
- nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL, NULL, 0,
+ 0);
else
nfscl_reqstart(nd, NFSPROC_RENEW, nmp, NULL, 0, NULL,
- &dsp->nfsclds_sess);
+ &dsp->nfsclds_sess, 0, 0);
if (!NFSHASNFSV4N(nmp)) {
/* NFSv4.1 just uses a Sequence Op and not a Renew. */
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
@@ -4368,11 +4383,11 @@ nfsrpc_rellockown(struct nfsmount *nmp, struct nfscllo
if (NFSHASNFSV4N(nmp)) {
/* For NFSv4.1, do a FreeStateID. */
nfscl_reqstart(nd, NFSPROC_FREESTATEID, nmp, NULL, 0, NULL,
- NULL);
+ NULL, 0, 0);
nfsm_stateidtom(nd, &lp->nfsl_stateid, NFSSTATEID_PUTSTATEID);
} else {
nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL,
- NULL);
+ NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
tsep = nfsmnt_mdssession(nmp);
*tl++ = tsep->nfsess_clientid.lval[0];
@@ -4405,7 +4420,8 @@ nfsrpc_getdirpath(struct nfsmount *nmp, u_char *dirpat
int error, cnt, len, setnil;
u_int32_t *opcntp;
- nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL);
+ nfscl_reqstart(nd, NFSPROC_PUTROOTFH, nmp, NULL, 0, &opcntp, NULL, 0,
+ 0);
cp = dirpath;
cnt = 0;
do {
@@ -4472,7 +4488,7 @@ nfsrpc_delegreturn(struct nfscldeleg *dp, struct ucred
int error;
nfscl_reqstart(nd, NFSPROC_DELEGRETURN, nmp, dp->nfsdl_fh,
- dp->nfsdl_fhlen, NULL, NULL);
+ dp->nfsdl_fhlen, NULL, NULL, 0, 0);
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID);
if (NFSHASNFSV4N(nmp))
*tl++ = 0;
@@ -4582,7 +4598,7 @@ nfsrpc_exchangeid(struct nfsmount *nmp, struct nfsclcl
int error, len;
*dspp = NULL;
- nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL, 0, 0);
NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(nfsboottime.tv_sec); /* Client owner */
*tl = txdr_unsigned(clp->nfsc_rev);
@@ -4669,7 +4685,8 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsc
nmp->nm_rsize = NFS_MAXBSIZE;
if (nmp->nm_wsize > NFS_MAXBSIZE || nmp->nm_wsize == 0)
nmp->nm_wsize = NFS_MAXBSIZE;
- nfscl_reqstart(nd, NFSPROC_CREATESESSION, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_CREATESESSION, nmp, NULL, 0, NULL, NULL, 0,
+ 0);
NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED);
*tl++ = sep->nfsess_clientid.lval[0];
*tl++ = sep->nfsess_clientid.lval[1];
@@ -4783,7 +4800,8 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfs
int error;
struct nfsclsession *tsep;
- nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0,
+ 0);
NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID);
tsep = nfsmnt_mdssession(nmp);
bcopy(tsep->nfsess_sessionid, tl, NFSX_V4SESSIONID);
@@ -4810,7 +4828,8 @@ nfsrpc_destroyclient(struct nfsmount *nmp, struct nfsc
int error;
struct nfsclsession *tsep;
- nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL, 0,
+ 0);
NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED);
tsep = nfsmnt_mdssession(nmp);
*tl++ = tsep->nfsess_clientid.lval[0];
@@ -4828,18 +4847,20 @@ nfsrpc_destroyclient(struct nfsmount *nmp, struct nfsc
/*
* Do the NFSv4.1 LayoutGet.
*/
-int
+static int
nfsrpc_layoutget(struct nfsmount *nmp, uint8_t *fhp, int fhlen, int iomode,
- uint64_t offset, uint64_t len, uint64_t minlen, int layoutlen,
- nfsv4stateid_t *stateidp, int *retonclosep, struct nfsclflayouthead *flhp,
- struct ucred *cred, NFSPROC_T *p, void *stuff)
+ uint64_t offset, uint64_t len, uint64_t minlen, int layouttype,
+ int layoutlen, nfsv4stateid_t *stateidp, int *retonclosep,
+ struct nfsclflayouthead *flhp, struct ucred *cred, NFSPROC_T *p,
+ void *stuff)
{
struct nfsrv_descript nfsd, *nd = &nfsd;
int error;
- nfscl_reqstart(nd, NFSPROC_LAYOUTGET, nmp, fhp, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_LAYOUTGET, nmp, fhp, fhlen, NULL, NULL, 0,
+ 0);
nfsrv_setuplayoutget(nd, iomode, offset, len, minlen, stateidp,
- layoutlen, 0);
+ layouttype, layoutlen, 0);
nd->nd_flag |= ND_USEGSSNAME;
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
@@ -4862,18 +4883,22 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *de
uint32_t *notifybitsp, struct nfscldevinfo **ndip, struct ucred *cred,
NFSPROC_T *p)
{
- uint32_t cnt, *tl;
+ uint32_t cnt, *tl, vers, minorvers;
struct nfsrv_descript nfsd;
struct nfsrv_descript *nd = &nfsd;
- struct sockaddr_storage ss;
- struct nfsclds *dsp = NULL, **dspp;
+ struct sockaddr_in sin, ssin;
+ struct sockaddr_in6 sin6, ssin6;
+ struct nfsclds *dsp = NULL, **dspp, **gotdspp;
struct nfscldevinfo *ndi;
- int addrcnt, bitcnt, error, i, isudp, j, pos, safilled, stripecnt;
+ int addrcnt = 0, bitcnt, error, gotvers, i, isudp, j, stripecnt;
uint8_t stripeindex;
+ sa_family_t af, safilled;
*ndip = NULL;
ndi = NULL;
- nfscl_reqstart(nd, NFSPROC_GETDEVICEINFO, nmp, NULL, 0, NULL, NULL);
+ gotdspp = NULL;
+ nfscl_reqstart(nd, NFSPROC_GETDEVICEINFO, nmp, NULL, 0, NULL, NULL, 0,
+ 0);
NFSM_BUILD(tl, uint32_t *, NFSX_V4DEVICEID + 3 * NFSX_UNSIGNED);
NFSBCOPY(deviceid, tl, NFSX_V4DEVICEID);
tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
@@ -4891,55 +4916,72 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *de
if (error != 0)
return (error);
if (nd->nd_repstat == 0) {
- NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_UNSIGNED);
- if (layouttype != fxdr_unsigned(int, *tl++))
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ if (layouttype != fxdr_unsigned(int, *tl))
printf("EEK! devinfo layout type not same!\n");
- stripecnt = fxdr_unsigned(int, *++tl);
- NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt);
- if (stripecnt < 1 || stripecnt > 4096) {
- printf("NFS devinfo stripecnt %d: out of range\n",
- stripecnt);
- error = NFSERR_BADXDR;
- goto nfsmout;
- }
- NFSM_DISSECT(tl, uint32_t *, (stripecnt + 1) * NFSX_UNSIGNED);
- addrcnt = fxdr_unsigned(int, *(tl + stripecnt));
- NFSCL_DEBUG(4, "addrcnt=%d\n", addrcnt);
- if (addrcnt < 1 || addrcnt > 128) {
- printf("NFS devinfo addrcnt %d: out of range\n",
- addrcnt);
- error = NFSERR_BADXDR;
- goto nfsmout;
- }
-
- /*
- * Now we know how many stripe indices and addresses, so
- * we can allocate the structure the correct size.
- */
- i = (stripecnt * sizeof(uint8_t)) / sizeof(struct nfsclds *)
- + 1;
- NFSCL_DEBUG(4, "stripeindices=%d\n", i);
- ndi = malloc(sizeof(*ndi) + (addrcnt + i) *
- sizeof(struct nfsclds *), M_NFSDEVINFO, M_WAITOK | M_ZERO);
- NFSBCOPY(deviceid, ndi->nfsdi_deviceid, NFSX_V4DEVICEID);
- ndi->nfsdi_refcnt = 0;
- ndi->nfsdi_stripecnt = stripecnt;
- ndi->nfsdi_addrcnt = addrcnt;
- /* Fill in the stripe indices. */
- for (i = 0; i < stripecnt; i++) {
- stripeindex = fxdr_unsigned(uint8_t, *tl++);
- NFSCL_DEBUG(4, "stripeind=%d\n", stripeindex);
- if (stripeindex >= addrcnt) {
- printf("NFS devinfo stripeindex %d: too big\n",
- (int)stripeindex);
+ if (layouttype == NFSLAYOUT_NFSV4_1_FILES) {
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ stripecnt = fxdr_unsigned(int, *tl);
+ NFSCL_DEBUG(4, "stripecnt=%d\n", stripecnt);
+ if (stripecnt < 1 || stripecnt > 4096) {
+ printf("pNFS File layout devinfo stripecnt %d:"
+ " out of range\n", stripecnt);
error = NFSERR_BADXDR;
goto nfsmout;
}
- nfsfldi_setstripeindex(ndi, i, stripeindex);
+ NFSM_DISSECT(tl, uint32_t *, (stripecnt + 1) *
+ NFSX_UNSIGNED);
+ addrcnt = fxdr_unsigned(int, *(tl + stripecnt));
+ NFSCL_DEBUG(4, "addrcnt=%d\n", addrcnt);
+ if (addrcnt < 1 || addrcnt > 128) {
+ printf("NFS devinfo addrcnt %d: out of range\n",
+ addrcnt);
+ error = NFSERR_BADXDR;
+ goto nfsmout;
+ }
+
+ /*
+ * Now we know how many stripe indices and addresses, so
+ * we can allocate the structure the correct size.
+ */
+ i = (stripecnt * sizeof(uint8_t)) /
+ sizeof(struct nfsclds *) + 1;
+ NFSCL_DEBUG(4, "stripeindices=%d\n", i);
+ ndi = malloc(sizeof(*ndi) + (addrcnt + i) *
+ sizeof(struct nfsclds *), M_NFSDEVINFO, M_WAITOK |
+ M_ZERO);
+ NFSBCOPY(deviceid, ndi->nfsdi_deviceid,
+ NFSX_V4DEVICEID);
+ ndi->nfsdi_refcnt = 0;
+ ndi->nfsdi_flags = NFSDI_FILELAYOUT;
+ ndi->nfsdi_stripecnt = stripecnt;
+ ndi->nfsdi_addrcnt = addrcnt;
+ /* Fill in the stripe indices. */
+ for (i = 0; i < stripecnt; i++) {
+ stripeindex = fxdr_unsigned(uint8_t, *tl++);
+ NFSCL_DEBUG(4, "stripeind=%d\n", stripeindex);
+ if (stripeindex >= addrcnt) {
+ printf("pNFS File Layout devinfo"
+ " stripeindex %d: too big\n",
+ (int)stripeindex);
+ error = NFSERR_BADXDR;
+ goto nfsmout;
+ }
+ nfsfldi_setstripeindex(ndi, i, stripeindex);
+ }
+ } else if (layouttype == NFSLAYOUT_FLEXFILE) {
+ /* For Flex File, we only get one address list. */
+ ndi = malloc(sizeof(*ndi) + sizeof(struct nfsclds *),
+ M_NFSDEVINFO, M_WAITOK | M_ZERO);
+ NFSBCOPY(deviceid, ndi->nfsdi_deviceid,
+ NFSX_V4DEVICEID);
+ ndi->nfsdi_refcnt = 0;
+ ndi->nfsdi_flags = NFSDI_FLEXFILE;
+ addrcnt = ndi->nfsdi_addrcnt = 1;
}
/* Now, dissect the server address(es). */
- safilled = 0;
+ safilled = AF_UNSPEC;
for (i = 0; i < addrcnt; i++) {
NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
cnt = fxdr_unsigned(uint32_t, *tl);
@@ -4949,63 +4991,107 @@ nfsrpc_getdeviceinfo(struct nfsmount *nmp, uint8_t *de
goto nfsmout;
}
dspp = nfsfldi_addr(ndi, i);
- pos = arc4random() % cnt; /* Choose one. */
- safilled = 0;
+ safilled = AF_UNSPEC;
for (j = 0; j < cnt; j++) {
- error = nfsv4_getipaddr(nd, &ss, &isudp);
+ error = nfsv4_getipaddr(nd, &sin, &sin6, &af,
+ &isudp);
if (error != 0 && error != EPERM) {
error = NFSERR_BADXDR;
goto nfsmout;
}
if (error == 0 && isudp == 0) {
/*
- * The algorithm is:
- * - use "pos" entry if it is of the
- * same af_family or none of them
- * is of the same af_family
- * else
- * - use the first one of the same
- * af_family.
+ * The priority is:
+ * - Same address family.
+ * Save the address and dspp, so that
+ * the connection can be done after
+ * parsing is complete.
*/
- if ((safilled == 0 && ss.ss_family ==
- nmp->nm_nam->sa_family) ||
- (j == pos &&
- (safilled == 0 || ss.ss_family ==
- nmp->nm_nam->sa_family)) ||
- (safilled == 1 && ss.ss_family ==
- nmp->nm_nam->sa_family)) {
- error = nfsrpc_fillsa(nmp, &ss,
- &dsp, p);
- if (error == 0) {
- *dspp = dsp;
- if (ss.ss_family ==
- nmp->nm_nam->sa_family)
- safilled = 2;
- else
- safilled = 1;
- }
+ if (safilled == AF_UNSPEC ||
+ (af == nmp->nm_nam->sa_family &&
+ safilled != nmp->nm_nam->sa_family)
+ ) {
+ if (af == AF_INET)
+ ssin = sin;
+ else
+ ssin6 = sin6;
+ safilled = af;
+ gotdspp = dspp;
}
}
}
- if (safilled == 0)
- break;
}
+ gotvers = NFS_VER4; /* Always NFSv4 for File Layout. */
+ /* For Flex File, we will take one of the versions to use. */
+ if (layouttype == NFSLAYOUT_FLEXFILE) {
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ j = fxdr_unsigned(int, *tl);
+ if (j < 1 || j > NFSDEV_MAXVERS) {
+ printf("pNFS: too many versions\n");
+ error = NFSERR_BADXDR;
+ goto nfsmout;
+ }
+ gotvers = 0;
+ for (i = 0; i < j; i++) {
+ NFSM_DISSECT(tl, uint32_t *, 5 * NFSX_UNSIGNED);
+ vers = fxdr_unsigned(uint32_t, *tl++);
+ minorvers = fxdr_unsigned(uint32_t, *tl++);
+ if ((vers == NFS_VER4 && minorvers ==
+ NFSV41_MINORVERSION) || (vers == NFS_VER3 &&
+ gotvers == 0)) {
+ gotvers = vers;
+ /* We'll take this one. */
+ ndi->nfsdi_versindex = i;
+ ndi->nfsdi_vers = vers;
+ ndi->nfsdi_minorvers = minorvers;
+ ndi->nfsdi_rsize = fxdr_unsigned(
+ uint32_t, *tl++);
+ ndi->nfsdi_wsize = fxdr_unsigned(
+ uint32_t, *tl++);
+ if (*tl == newnfs_true)
+ ndi->nfsdi_flags |=
+ NFSDI_TIGHTCOUPLED;
+ else
+ ndi->nfsdi_flags &=
+ ~NFSDI_TIGHTCOUPLED;
+ }
+ }
+ if (gotvers == 0) {
+ printf("pNFS: no NFSv3 or NFSv4.1\n");
+ error = NFSERR_BADXDR;
+ goto nfsmout;
+ }
+ }
+
/* And the notify bits. */
NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
- if (safilled != 0) {
- bitcnt = fxdr_unsigned(int, *tl);
- if (bitcnt > 0) {
- NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
- if (notifybitsp != NULL)
- *notifybitsp =
- fxdr_unsigned(uint32_t, *tl);
- }
+ bitcnt = fxdr_unsigned(int, *tl);
+ if (bitcnt > 0) {
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ if (notifybitsp != NULL)
+ *notifybitsp =
+ fxdr_unsigned(uint32_t, *tl);
+ }
+ if (safilled != AF_UNSPEC) {
+ KASSERT(ndi != NULL, ("ndi is NULL"));
*ndip = ndi;
} else
error = EPERM;
+ if (error == 0) {
+ /*
+ * Now we can do a TCP connection for the correct
+ * NFS version and IP address.
+ */
+ error = nfsrpc_fillsa(nmp, &ssin, &ssin6, safilled,
+ gotvers, &dsp, p);
+ }
+ if (error == 0) {
+ KASSERT(gotdspp != NULL, ("gotdspp is NULL"));
+ *gotdspp = dsp;
+ }
}
- if (nd->nd_repstat != 0)
+ if (nd->nd_repstat != 0 && error == 0)
error = nd->nd_repstat;
nfsmout:
if (error != 0 && ndi != NULL)
@@ -5020,15 +5106,14 @@ nfsmout:
int
nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim,
uint64_t off, uint64_t len, uint64_t lastbyte, nfsv4stateid_t *stateidp,
- int layouttype, int layoutupdatecnt, uint8_t *layp, struct ucred *cred,
- NFSPROC_T *p, void *stuff)
+ int layouttype, struct ucred *cred, NFSPROC_T *p, void *stuff)
{
uint32_t *tl;
struct nfsrv_descript nfsd, *nd = &nfsd;
- int error, outcnt, i;
- uint8_t *cp;
+ int error;
- nfscl_reqstart(nd, NFSPROC_LAYOUTCOMMIT, nmp, fh, fhlen, NULL, NULL);
+ nfscl_reqstart(nd, NFSPROC_LAYOUTCOMMIT, nmp, fh, fhlen, NULL, NULL,
+ 0, 0);
NFSM_BUILD(tl, uint32_t *, 5 * NFSX_UNSIGNED + 3 * NFSX_HYPER +
NFSX_STATEID);
txdr_hyper(off, tl);
@@ -5052,17 +5137,13 @@ nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh,
tl += 2;
*tl++ = newnfs_false;
*tl++ = txdr_unsigned(layouttype);
- *tl = txdr_unsigned(layoutupdatecnt);
- if (layoutupdatecnt > 0) {
- KASSERT(layouttype != NFSLAYOUT_NFSV4_1_FILES,
- ("Must be nil for Files Layout"));
- outcnt = NFSM_RNDUP(layoutupdatecnt);
- NFSM_BUILD(cp, uint8_t *, outcnt);
- NFSBCOPY(layp, cp, layoutupdatecnt);
- cp += layoutupdatecnt;
- for (i = 0; i < (outcnt - layoutupdatecnt); i++)
- *cp++ = 0x0;
- }
+ /* All supported layouts appear to be 0 length for now. */
+ if (layouttype == NFSLAYOUT_NFSV4_1_FILES)
+ *tl = txdr_unsigned(0);
+ else if (layouttype == NFSLAYOUT_FLEXFILE)
+ *tl = txdr_unsigned(0);
+ else
+ *tl = txdr_unsigned(0);
nd->nd_flag |= ND_USEGSSNAME;
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
@@ -5079,15 +5160,15 @@ nfsrpc_layoutcommit(struct nfsmount *nmp, uint8_t *fh,
int
nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim,
int layouttype, uint32_t iomode, int layoutreturn, uint64_t offset,
- uint64_t len, nfsv4stateid_t *stateidp, int layoutcnt, uint32_t *layp,
- struct ucred *cred, NFSPROC_T *p, void *stuff)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list