svn commit: r319833 - projects/pnfs-planb-server-stable11/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sun Jun 11 20:27:40 UTC 2017
Author: rmacklem
Date: Sun Jun 11 20:27:38 2017
New Revision: 319833
URL: https://svnweb.freebsd.org/changeset/base/319833
Log:
Update some NFS server files with the pNFS code.
Modified:
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdserv.c
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdsocket.c
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdstate.c
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdsubs.c
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdserv.c Sun Jun 11 20:18:18 2017 (r319832)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdserv.c Sun Jun 11 20:27:38 2017 (r319833)
@@ -54,6 +54,11 @@ extern struct timeval nfsboottime;
extern int nfs_rootfhset;
extern int nfsrv_enable_crossmntpt;
extern int nfsrv_statehashsize;
+extern int nfsrv_layouthashsize;
+extern time_t nfsdev_time;
+extern struct nfsdevicehead nfsrv_devidhead;
+extern int nfsd_debuglevel;
+extern u_long sb_max_adj;
#endif /* !APPLEKEXT */
static int nfs_async = 0;
@@ -151,7 +156,7 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int
}
nfsmode &= supported;
if (nd->nd_flag & ND_NFSV3) {
- getret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
nfsrv_postopattr(nd, getret, &nva);
}
vput(vp);
@@ -235,14 +240,14 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
}
}
if (!nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, &attrbits);
if (!nd->nd_repstat) {
if (nd->nd_flag & ND_NFSV4) {
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_FILEHANDLE))
nd->nd_repstat = nfsvno_getfh(vp, &fh, p);
if (!nd->nd_repstat)
nd->nd_repstat = nfsrv_checkgetattr(nd, vp,
- &nva, &attrbits, nd->nd_cred, p);
+ &nva, &attrbits, p);
if (nd->nd_repstat == 0) {
supports_nfsv4acls = nfs_supportsnfsv4acls(vp);
mp = vp->v_mount;
@@ -307,6 +312,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int
struct nfsvattr nva, nva2;
u_int32_t *tl;
int preat_ret = 1, postat_ret = 1, gcheck = 0, error = 0;
+ int gotproxystateid;
struct timespec guard = { 0, 0 };
nfsattrbit_t attrbits, retbits;
nfsv4stateid_t stateid;
@@ -320,19 +326,32 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int
aclp = acl_alloc(M_WAITOK);
aclp->acl_cnt = 0;
#endif
+ gotproxystateid = 0;
NFSVNO_ATTRINIT(&nva);
- NFSZERO_ATTRBIT(&retbits);
if (nd->nd_flag & ND_NFSV4) {
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID);
stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
- NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER);
+ stateid.other[0] = *tl++;
+ stateid.other[1] = *tl++;
+ stateid.other[2] = *tl;
+ if (stateid.other[0] == 0x55555555 &&
+ stateid.other[1] == 0x55555555 &&
+ stateid.other[2] == 0x55555555 &&
+ stateid.seqid == 0xffffffff)
+ gotproxystateid = 1;
}
error = nfsrv_sattr(nd, vp, &nva, &attrbits, aclp, p);
if (error)
goto nfsmout;
- preat_ret = nfsvno_getattr(vp, &nva2, nd->nd_cred, p, 1);
+
+ /* For NFSv4, only va_uid is used from nva2. */
+ NFSZERO_ATTRBIT(&retbits);
+ NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_OWNER);
+ preat_ret = nfsvno_getattr(vp, &nva2, nd, p, 1, &retbits);
if (!nd->nd_repstat)
nd->nd_repstat = preat_ret;
+
+ NFSZERO_ATTRBIT(&retbits);
if (nd->nd_flag & ND_NFSV3) {
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
gcheck = fxdr_unsigned(int, *tl);
@@ -376,7 +395,12 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int
NFSACCCHK_VPISLOCKED, NULL);
}
}
- if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4))
+ /*
+ * Proxy operations from the MDS are allowed via the all 0s special
+ * stateid.
+ */
+ if (nd->nd_repstat == 0 && (nd->nd_flag & ND_NFSV4) != 0 &&
+ gotproxystateid == 0)
nd->nd_repstat = nfsrv_checksetattr(vp, nd, &stateid,
&nva, &attrbits, exp, p);
@@ -450,7 +474,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int
exp);
}
if (nd->nd_flag & (ND_NFSV2 | ND_NFSV3)) {
- postat_ret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ postat_ret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (!nd->nd_repstat)
nd->nd_repstat = postat_ret;
}
@@ -534,8 +558,8 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int
if (nd->nd_repstat) {
if (dirp) {
if (nd->nd_flag & ND_NFSV3)
- dattr_ret = nfsvno_getattr(dirp, &dattr,
- nd->nd_cred, p, 0);
+ dattr_ret = nfsvno_getattr(dirp, &dattr, nd, p,
+ 0, NULL);
vrele(dirp);
}
if (nd->nd_flag & ND_NFSV3)
@@ -556,15 +580,15 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int
if (nd->nd_repstat == 0)
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (vpp != NULL && nd->nd_repstat == 0)
*vpp = vp;
else
vput(vp);
if (dirp) {
if (nd->nd_flag & ND_NFSV3)
- dattr_ret = nfsvno_getattr(dirp, &dattr, nd->nd_cred,
- p, 0);
+ dattr_ret = nfsvno_getattr(dirp, &dattr, nd, p, 0,
+ NULL);
vrele(dirp);
}
if (nd->nd_repstat) {
@@ -612,7 +636,7 @@ nfsrvd_readlink(struct nfsrv_descript *nd, __unused in
nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, p,
&mp, &mpend, &len);
if (nd->nd_flag & ND_NFSV3)
- getret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
vput(vp);
if (nd->nd_flag & ND_NFSV3)
nfsrv_postopattr(nd, getret, &nva);
@@ -637,7 +661,7 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
vnode_t vp, NFSPROC_T *p, struct nfsexstuff *exp)
{
u_int32_t *tl;
- int error = 0, cnt, getret = 1, reqlen, eof = 0;
+ int error = 0, cnt, getret = 1, gotproxystateid, reqlen, eof = 0;
mbuf_t m2, m3;
struct nfsvattr nva;
off_t off = 0x0;
@@ -669,6 +693,7 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
error = EBADRPC;
goto nfsmout;
}
+ gotproxystateid = 0;
if (nd->nd_flag & ND_NFSV4) {
stp->ls_flags = (NFSLCK_CHECK | NFSLCK_READACCESS);
lop->lo_flags = NFSLCK_READ;
@@ -690,6 +715,24 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
nd->nd_clientid.qval = clientid.qval;
}
stp->ls_stateid.other[2] = *tl++;
+ /*
+ * Don't allow the client to use a special stateid for a DS op.
+ */
+ if ((nd->nd_flag & ND_DSSERVER) != 0 &&
+ ((stp->ls_stateid.other[0] == 0x0 &&
+ stp->ls_stateid.other[1] == 0x0 &&
+ stp->ls_stateid.other[2] == 0x0) ||
+ (stp->ls_stateid.other[0] == 0xffffffff &&
+ stp->ls_stateid.other[1] == 0xffffffff &&
+ stp->ls_stateid.other[2] == 0xffffffff) ||
+ stp->ls_stateid.seqid != 0))
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ /* However, allow the proxy stateid. */
+ if (stp->ls_stateid.seqid == 0xffffffff &&
+ stp->ls_stateid.other[0] == 0x55555555 &&
+ stp->ls_stateid.other[1] == 0x55555555 &&
+ stp->ls_stateid.other[2] == 0x55555555)
+ gotproxystateid = 1;
off = fxdr_hyper(tl);
lop->lo_first = off;
tl += 2;
@@ -707,7 +750,7 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
nd->nd_repstat = (vnode_vtype(vp) == VDIR) ? EISDIR :
EINVAL;
}
- getret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (!nd->nd_repstat)
nd->nd_repstat = getret;
if (!nd->nd_repstat &&
@@ -721,7 +764,12 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER,
NFSACCCHK_VPISLOCKED, NULL);
}
- if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
+ /*
+ * DS reads are marked by ND_DSSERVER or use the proxy special
+ * stateid.
+ */
+ if (nd->nd_repstat == 0 && (nd->nd_flag & (ND_NFSV4 | ND_DSSERVER)) ==
+ ND_NFSV4 && gotproxystateid == 0)
nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid,
&stateid, exp, nd, p);
if (nd->nd_repstat) {
@@ -745,7 +793,7 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int is
nd->nd_repstat = nfsvno_read(vp, off, cnt, nd->nd_cred, p,
&m3, &m2);
if (!(nd->nd_flag & ND_NFSV4)) {
- getret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (!nd->nd_repstat)
nd->nd_repstat = getret;
}
@@ -802,17 +850,19 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
mbuf_t mp;
struct nfsvattr nva, forat;
int aftat_ret = 1, retlen, len, error = 0, forat_ret = 1;
- int stable = NFSWRITE_FILESYNC;
+ int gotproxystateid, stable = NFSWRITE_FILESYNC;
off_t off;
struct nfsstate st, *stp = &st;
struct nfslock lo, *lop = &lo;
nfsv4stateid_t stateid;
nfsquad_t clientid;
+ nfsattrbit_t attrbits;
if (nd->nd_repstat) {
nfsrv_wcc(nd, forat_ret, &forat, aftat_ret, &nva);
goto out;
}
+ gotproxystateid = 0;
if (nd->nd_flag & ND_NFSV2) {
NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
@@ -846,6 +896,24 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
nd->nd_clientid.qval = clientid.qval;
}
stp->ls_stateid.other[2] = *tl++;
+ /*
+ * Don't allow the client to use a special stateid for a DS op.
+ */
+ if ((nd->nd_flag & ND_DSSERVER) != 0 &&
+ ((stp->ls_stateid.other[0] == 0x0 &&
+ stp->ls_stateid.other[1] == 0x0 &&
+ stp->ls_stateid.other[2] == 0x0) ||
+ (stp->ls_stateid.other[0] == 0xffffffff &&
+ stp->ls_stateid.other[1] == 0xffffffff &&
+ stp->ls_stateid.other[2] == 0xffffffff) ||
+ stp->ls_stateid.seqid != 0))
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ /* However, allow the proxy stateid. */
+ if (stp->ls_stateid.seqid == 0xffffffff &&
+ stp->ls_stateid.other[0] == 0x55555555 &&
+ stp->ls_stateid.other[1] == 0x55555555 &&
+ stp->ls_stateid.other[2] == 0x55555555)
+ gotproxystateid = 1;
off = fxdr_hyper(tl);
lop->lo_first = off;
tl += 2;
@@ -891,7 +959,9 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
nd->nd_repstat = (vnode_vtype(vp) == VDIR) ? EISDIR :
EINVAL;
}
- forat_ret = nfsvno_getattr(vp, &forat, nd->nd_cred, p, 1);
+ NFSZERO_ATTRBIT(&attrbits);
+ NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER);
+ forat_ret = nfsvno_getattr(vp, &forat, nd, p, 1, &attrbits);
if (!nd->nd_repstat)
nd->nd_repstat = forat_ret;
if (!nd->nd_repstat &&
@@ -900,10 +970,14 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
nd->nd_repstat = nfsvno_accchk(vp, VWRITE,
nd->nd_cred, exp, p,
NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL);
- if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) {
+ /*
+ * DS reads are marked by ND_DSSERVER or use the proxy special
+ * stateid.
+ */
+ if (nd->nd_repstat == 0 && (nd->nd_flag & (ND_NFSV4 | ND_DSSERVER)) ==
+ ND_NFSV4 && gotproxystateid == 0)
nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid,
&stateid, exp, nd, p);
- }
if (nd->nd_repstat) {
vput(vp);
if (nd->nd_flag & ND_NFSV3)
@@ -917,7 +991,7 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
* which is to return ok so long as there are no permission problems.
*/
if (retlen > 0) {
- nd->nd_repstat = nfsvno_write(vp, off, retlen, cnt, stable,
+ nd->nd_repstat = nfsvno_write(vp, off, retlen, cnt, &stable,
nd->nd_md, nd->nd_dpos, nd->nd_cred, p);
error = nfsm_advance(nd, NFSM_RNDUP(retlen), -1);
if (error)
@@ -926,7 +1000,7 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
if (nd->nd_flag & ND_NFSV4)
aftat_ret = 0;
else
- aftat_ret = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ aftat_ret = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
vput(vp);
if (!nd->nd_repstat)
nd->nd_repstat = aftat_ret;
@@ -1048,8 +1122,8 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int
if (nd->nd_repstat) {
nfsvno_relpathbuf(&named);
if (nd->nd_flag & ND_NFSV3) {
- dirfor_ret = nfsvno_getattr(dp, &dirfor, nd->nd_cred,
- p, 1);
+ dirfor_ret = nfsvno_getattr(dp, &dirfor, nd, p, 1,
+ NULL);
nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret,
&diraft);
}
@@ -1063,8 +1137,8 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int
vrele(dirp);
dirp = NULL;
} else {
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred,
- p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0,
+ NULL);
}
}
if (nd->nd_repstat) {
@@ -1102,8 +1176,8 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int
if (!nd->nd_repstat) {
nd->nd_repstat = nfsvno_getfh(vp, &fh, p);
if (!nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred,
- p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1,
+ NULL);
vput(vp);
if (!nd->nd_repstat) {
tverf[0] = nva.na_atime.tv_sec;
@@ -1119,7 +1193,7 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int
if (exclusive_flag && !nd->nd_repstat && (cverf[0] != tverf[0]
|| cverf[1] != tverf[1]))
nd->nd_repstat = EEXIST;
- diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
+ diraft_ret = nfsvno_getattr(dirp, &diraft, nd, p, 0, NULL);
vrele(dirp);
if (!nd->nd_repstat) {
(void) nfsm_fhtom(nd, (u_int8_t *)&fh, 0, 1);
@@ -1229,7 +1303,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
}
}
- dirfor_ret = nfsvno_getattr(dp, &dirfor, nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dp, &dirfor, nd, p, 0, NULL);
if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4)) {
if (!dirfor_ret && NFSVNO_ISSETGID(&nva) &&
dirfor.na_gid == nva.na_gid)
@@ -1267,8 +1341,8 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
if (nd->nd_repstat) {
if (dirp) {
if (nd->nd_flag & ND_NFSV3)
- dirfor_ret = nfsvno_getattr(dirp, &dirfor,
- nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd,
+ p, 0, NULL);
vrele(dirp);
}
#ifdef NFS4_ACL_EXTATTR_NAME
@@ -1280,7 +1354,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
goto out;
}
if (dirp)
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL);
if ((nd->nd_flag & ND_NFSV4) && (vtyp == VDIR || vtyp == VLNK)) {
if (vtyp == VDIR) {
@@ -1309,8 +1383,8 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp);
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred,
- p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1,
+ NULL);
if (vpp != NULL && nd->nd_repstat == 0) {
NFSVOPUNLOCK(vp, 0);
*vpp = vp;
@@ -1318,7 +1392,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
vput(vp);
}
- diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
+ diraft_ret = nfsvno_getattr(dirp, &diraft, nd, p, 0, NULL);
vrele(dirp);
if (!nd->nd_repstat) {
if (nd->nd_flag & ND_NFSV3) {
@@ -1392,8 +1466,8 @@ nfsrvd_remove(struct nfsrv_descript *nd, __unused int
}
if (dirp) {
if (!(nd->nd_flag & ND_NFSV2)) {
- dirfor_ret = nfsvno_getattr(dirp, &dirfor,
- nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0,
+ NULL);
} else {
vrele(dirp);
dirp = NULL;
@@ -1417,8 +1491,8 @@ nfsrvd_remove(struct nfsrv_descript *nd, __unused int
}
if (!(nd->nd_flag & ND_NFSV2)) {
if (dirp) {
- diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred,
- p, 0);
+ diraft_ret = nfsvno_getattr(dirp, &diraft, nd, p, 0,
+ NULL);
vrele(dirp);
}
if (nd->nd_flag & ND_NFSV3) {
@@ -1464,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
goto out;
}
if (!(nd->nd_flag & ND_NFSV2))
- fdirfor_ret = nfsvno_getattr(dp, &fdirfor, nd->nd_cred, p, 1);
+ fdirfor_ret = nfsvno_getattr(dp, &fdirfor, nd, p, 1, NULL);
tond.ni_cnd.cn_nameiop = 0;
tond.ni_startdir = NULL;
NFSNAMEICNDSET(&fromnd.ni_cnd, nd->nd_cred, DELETE, WANTPARENT | SAVESTART);
@@ -1487,11 +1561,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
tnes = *toexp;
if (dp != tdp) {
NFSVOPUNLOCK(dp, 0);
- tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
- p, 0); /* Might lock tdp. */
+ /* Might lock tdp. */
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 0,
+ NULL);
} else {
- tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
- p, 1);
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 1,
+ NULL);
NFSVOPUNLOCK(dp, 0);
}
} else {
@@ -1512,8 +1587,8 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
VREF(dp);
tdp = dp;
tnes = *exp;
- tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
- p, 1);
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 1,
+ NULL);
NFSVOPUNLOCK(dp, 0);
} else {
NFSVOPUNLOCK(dp, 0);
@@ -1521,8 +1596,8 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL,
0, p); /* Locks tdp. */
if (tdp) {
- tdirfor_ret = nfsvno_getattr(tdp, &tdirfor,
- nd->nd_cred, p, 1);
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd,
+ p, 1, NULL);
NFSVOPUNLOCK(tdp, 0);
}
}
@@ -1579,11 +1654,9 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
nd->nd_repstat = nfsvno_rename(&fromnd, &tond, nd->nd_repstat,
nd->nd_flag, nd->nd_cred, p);
if (fdirp)
- fdiraft_ret = nfsvno_getattr(fdirp, &fdiraft, nd->nd_cred, p,
- 0);
+ fdiraft_ret = nfsvno_getattr(fdirp, &fdiraft, nd, p, 0, NULL);
if (tdirp)
- tdiraft_ret = nfsvno_getattr(tdirp, &tdiraft, nd->nd_cred, p,
- 0);
+ tdiraft_ret = nfsvno_getattr(tdirp, &tdiraft, nd, p, 0, NULL);
if (fdirp)
vrele(fdirp);
if (tdirp)
@@ -1684,16 +1757,16 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
vrele(dirp);
dirp = NULL;
} else {
- dirfor_ret = nfsvno_getattr(dirp, &dirfor,
- nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0,
+ NULL);
}
}
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_link(&named, vp, nd->nd_cred, p, exp);
if (nd->nd_flag & ND_NFSV3)
- getret = nfsvno_getattr(vp, &at, nd->nd_cred, p, 0);
+ getret = nfsvno_getattr(vp, &at, nd, p, 0, NULL);
if (dirp) {
- diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
+ diraft_ret = nfsvno_getattr(dirp, &diraft, nd, p, 0, NULL);
vrele(dirp);
}
vrele(vp);
@@ -1763,13 +1836,13 @@ nfsrvd_symlink(struct nfsrv_descript *nd, __unused int
*/
if (!nd->nd_repstat) {
if (dirp != NULL)
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred,
- p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0,
+ NULL);
nfsrvd_symlinksub(nd, &named, &nva, fhp, vpp, dirp,
&dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp,
pathcp, pathlen);
} else if (dirp != NULL) {
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL);
vrele(dirp);
}
if (pathcp)
@@ -1809,7 +1882,7 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct na
nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p);
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_getattr(ndp->ni_vp,
- nvap, nd->nd_cred, p, 1);
+ nvap, nd, p, 1, NULL);
}
if (vpp != NULL && nd->nd_repstat == 0) {
NFSVOPUNLOCK(ndp->ni_vp, 0);
@@ -1818,7 +1891,7 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct na
vput(ndp->ni_vp);
}
if (dirp) {
- *diraft_retp = nfsvno_getattr(dirp, diraftp, nd->nd_cred, p, 0);
+ *diraft_retp = nfsvno_getattr(dirp, diraftp, nd, p, 0, NULL);
vrele(dirp);
}
if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) {
@@ -1882,8 +1955,8 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int i
}
if (nd->nd_repstat) {
if (dirp != NULL) {
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred,
- p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0,
+ NULL);
vrele(dirp);
}
if (nd->nd_flag & ND_NFSV3)
@@ -1892,7 +1965,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int i
goto out;
}
if (dirp != NULL)
- dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd->nd_cred, p, 0);
+ dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL);
/*
* Call nfsrvd_mkdirsub() for the code common to V4 as well.
@@ -1942,8 +2015,8 @@ nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct name
nfsrv_fixattr(nd, vp, nvap, aclp, p, attrbitp, exp);
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(vp, nvap, nd->nd_cred,
- p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, nvap, nd, p, 1,
+ NULL);
if (vpp && !nd->nd_repstat) {
NFSVOPUNLOCK(vp, 0);
*vpp = vp;
@@ -1952,7 +2025,7 @@ nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct name
}
}
if (dirp) {
- *diraft_retp = nfsvno_getattr(dirp, diraftp, nd->nd_cred, p, 0);
+ *diraft_retp = nfsvno_getattr(dirp, diraftp, nd, p, 0, NULL);
vrele(dirp);
}
if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) {
@@ -2002,10 +2075,10 @@ nfsrvd_commit(struct nfsrv_descript *nd, __unused int
tl += 2;
cnt = fxdr_unsigned(int, *tl);
if (nd->nd_flag & ND_NFSV3)
- for_ret = nfsvno_getattr(vp, &bfor, nd->nd_cred, p, 1);
+ for_ret = nfsvno_getattr(vp, &bfor, nd, p, 1, NULL);
nd->nd_repstat = nfsvno_fsync(vp, off, cnt, nd->nd_cred, p);
if (nd->nd_flag & ND_NFSV3) {
- aft_ret = nfsvno_getattr(vp, &aft, nd->nd_cred, p, 1);
+ aft_ret = nfsvno_getattr(vp, &aft, nd, p, 1, NULL);
nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft);
}
vput(vp);
@@ -2044,7 +2117,7 @@ nfsrvd_statfs(struct nfsrv_descript *nd, __unused int
}
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
nd->nd_repstat = nfsvno_statfs(vp, sf);
- getret = nfsvno_getattr(vp, &at, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL);
vput(vp);
if (nd->nd_flag & ND_NFSV3)
nfsrv_postopattr(nd, getret, &at);
@@ -2099,7 +2172,7 @@ nfsrvd_fsinfo(struct nfsrv_descript *nd, int isdgram,
nfsrv_postopattr(nd, getret, &at);
goto out;
}
- getret = nfsvno_getattr(vp, &at, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL);
nfsvno_getfs(&fs, isdgram);
vput(vp);
nfsrv_postopattr(nd, getret, &at);
@@ -2149,7 +2222,7 @@ nfsrvd_pathconf(struct nfsrv_descript *nd, __unused in
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_pathconf(vp, _PC_NO_TRUNC, ¬runc,
nd->nd_cred, p);
- getret = nfsvno_getattr(vp, &at, nd->nd_cred, p, 1);
+ getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL);
vput(vp);
nfsrv_postopattr(nd, getret, &at);
if (!nd->nd_repstat) {
@@ -2232,6 +2305,25 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int is
NFSBCOPY((caddr_t)tl, (caddr_t)stp->ls_stateid.other,
NFSX_STATEIDOTHER);
tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set
+ * the stateid to the current stateid, if it is set.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0 &&
+ stp->ls_stateid.seqid == 1 &&
+ stp->ls_stateid.other[0] == 0 &&
+ stp->ls_stateid.other[1] == 0 &&
+ stp->ls_stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0) {
+ stp->ls_stateid = nd->nd_curstateid;
+ stp->ls_stateid.seqid = 0;
+ } else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
stp->ls_opentolockseq = fxdr_unsigned(int, *tl++);
clientid.lval[0] = *tl++;
clientid.lval[1] = *tl++;
@@ -2259,6 +2351,25 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int is
NFSBCOPY((caddr_t)tl, (caddr_t)stp->ls_stateid.other,
NFSX_STATEIDOTHER);
tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set
+ * the stateid to the current stateid, if it is set.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0 &&
+ stp->ls_stateid.seqid == 1 &&
+ stp->ls_stateid.other[0] == 0 &&
+ stp->ls_stateid.other[1] == 0 &&
+ stp->ls_stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0) {
+ stp->ls_stateid = nd->nd_curstateid;
+ stp->ls_stateid.seqid = 0;
+ } else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
stp->ls_seq = fxdr_unsigned(int, *tl);
clientid.lval[0] = stp->ls_stateid.other[0];
clientid.lval[1] = stp->ls_stateid.other[1];
@@ -2325,6 +2436,11 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int is
if (stp)
FREE((caddr_t)stp, M_NFSDSTATE);
if (!nd->nd_repstat) {
+ /* For NFSv4.1, set the Current StateID. */
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ nd->nd_curstateid = stateid;
+ nd->nd_flag |= ND_CURSTATEID;
+ }
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID);
*tl++ = txdr_unsigned(stateid.seqid);
NFSBCOPY((caddr_t)stateid.other,(caddr_t)tl,NFSX_STATEIDOTHER);
@@ -2518,6 +2634,23 @@ nfsrvd_locku(struct nfsrv_descript *nd, __unused int i
NFSBCOPY((caddr_t)tl, (caddr_t)stp->ls_stateid.other,
NFSX_STATEIDOTHER);
tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set the
+ * stateid to the current stateid, if it is set.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0 && stp->ls_stateid.seqid == 1 &&
+ stp->ls_stateid.other[0] == 0 && stp->ls_stateid.other[1] == 0 &&
+ stp->ls_stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0) {
+ stp->ls_stateid = nd->nd_curstateid;
+ stp->ls_stateid.seqid = 0;
+ } else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
lop->lo_first = fxdr_hyper(tl);
tl += 2;
len = fxdr_hyper(tl);
@@ -2697,7 +2830,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int is
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
create = fxdr_unsigned(int, *tl);
if (!nd->nd_repstat)
- nd->nd_repstat = nfsvno_getattr(dp, &dirfor, nd->nd_cred, p, 0);
+ nd->nd_repstat = nfsvno_getattr(dp, &dirfor, nd, p, 0, NULL);
if (create == NFSV4OPEN_CREATE) {
nva.na_type = VREG;
nva.na_mode = 0;
@@ -2896,7 +3029,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int is
}
if (!nd->nd_repstat) {
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (!nd->nd_repstat) {
tverf[0] = nva.na_atime.tv_sec;
tverf[1] = nva.na_atime.tv_nsec;
@@ -2922,9 +3055,13 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int is
if (stp)
FREE((caddr_t)stp, M_NFSDSTATE);
if (!nd->nd_repstat && dirp)
- nd->nd_repstat = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p,
- 0);
+ nd->nd_repstat = nfsvno_getattr(dirp, &diraft, nd, p, 0, NULL);
if (!nd->nd_repstat) {
+ /* For NFSv4.1, set the Current StateID. */
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ nd->nd_curstateid = stateid;
+ nd->nd_flag |= ND_CURSTATEID;
+ }
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(stateid.seqid);
NFSBCOPY((caddr_t)stateid.other,(caddr_t)tl,NFSX_STATEIDOTHER);
@@ -3024,9 +3161,10 @@ nfsrvd_close(struct nfsrv_descript *nd, __unused int i
{
u_int32_t *tl;
struct nfsstate st, *stp = &st;
- int error = 0;
+ int error = 0, writeacc;
nfsv4stateid_t stateid;
nfsquad_t clientid;
+ struct nfsvattr na;
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID);
stp->ls_seq = fxdr_unsigned(u_int32_t, *tl++);
@@ -3036,6 +3174,22 @@ nfsrvd_close(struct nfsrv_descript *nd, __unused int i
stp->ls_stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
NFSBCOPY((caddr_t)tl, (caddr_t)stp->ls_stateid.other,
NFSX_STATEIDOTHER);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set the
+ * stateid to the current stateid, if it is set.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0 && stp->ls_stateid.seqid == 1 &&
+ stp->ls_stateid.other[0] == 0 && stp->ls_stateid.other[1] == 0 &&
+ stp->ls_stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0)
+ stp->ls_stateid = nd->nd_curstateid;
+ else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
stp->ls_flags = NFSLCK_CLOSE;
clientid.lval[0] = stp->ls_stateid.other[0];
clientid.lval[1] = stp->ls_stateid.other[1];
@@ -3050,9 +3204,22 @@ nfsrvd_close(struct nfsrv_descript *nd, __unused int i
nd->nd_flag |= ND_IMPLIEDCLID;
nd->nd_clientid.qval = clientid.qval;
}
- nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p);
+ nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p,
+ &writeacc);
+ /* For pNFS, update the attributes. */
+ if (writeacc != 0)
+ nfsrv_updatemdsattr(vp, &na, p);
vput(vp);
if (!nd->nd_repstat) {
+ /*
+ * If the stateid that has been closed is the current stateid,
+ * unset it.
+ */
+ if ((nd->nd_flag & ND_CURSTATEID) != 0 &&
+ stateid.other[0] == nd->nd_curstateid.other[0] &&
+ stateid.other[1] == nd->nd_curstateid.other[1] &&
+ stateid.other[2] == nd->nd_curstateid.other[2])
+ nd->nd_flag &= ~ND_CURSTATEID;
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID);
*tl++ = txdr_unsigned(stateid.seqid);
NFSBCOPY((caddr_t)stateid.other,(caddr_t)tl,NFSX_STATEIDOTHER);
@@ -3095,7 +3262,7 @@ nfsrvd_delegpurge(struct nfsrv_descript *nd, __unused
nd->nd_clientid.qval = clientid.qval;
}
nd->nd_repstat = nfsrv_delegupdate(nd, clientid, NULL, NULL,
- NFSV4OP_DELEGPURGE, nd->nd_cred, p);
+ NFSV4OP_DELEGPURGE, nd->nd_cred, p, NULL);
nfsmout:
NFSEXITCODE2(error, nd);
return (error);
@@ -3109,9 +3276,10 @@ nfsrvd_delegreturn(struct nfsrv_descript *nd, __unused
vnode_t vp, NFSPROC_T *p, __unused struct nfsexstuff *exp)
{
u_int32_t *tl;
- int error = 0;
+ int error = 0, writeacc;
nfsv4stateid_t stateid;
nfsquad_t clientid;
+ struct nfsvattr na;
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID);
stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
@@ -3130,7 +3298,10 @@ nfsrvd_delegreturn(struct nfsrv_descript *nd, __unused
nd->nd_clientid.qval = clientid.qval;
}
nd->nd_repstat = nfsrv_delegupdate(nd, clientid, &stateid, vp,
- NFSV4OP_DELEGRETURN, nd->nd_cred, p);
+ NFSV4OP_DELEGRETURN, nd->nd_cred, p, &writeacc);
+ /* For pNFS, update the attributes. */
+ if (writeacc != 0)
+ nfsrv_updatemdsattr(vp, &na, p);
nfsmout:
vput(vp);
NFSEXITCODE2(error, nd);
@@ -3194,7 +3365,8 @@ nfsrvd_openconfirm(struct nfsrv_descript *nd, __unused
nd->nd_flag |= ND_IMPLIEDCLID;
nd->nd_clientid.qval = clientid.qval;
}
- nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p);
+ nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p,
+ NULL);
if (!nd->nd_repstat) {
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID);
*tl++ = txdr_unsigned(stateid.seqid);
@@ -3233,6 +3405,22 @@ nfsrvd_opendowngrade(struct nfsrv_descript *nd, __unus
NFSBCOPY((caddr_t)tl, (caddr_t)stp->ls_stateid.other,
NFSX_STATEIDOTHER);
tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set the
+ * stateid to the current stateid, if it is set.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0 && stp->ls_stateid.seqid == 1 &&
+ stp->ls_stateid.other[0] == 0 && stp->ls_stateid.other[1] == 0 &&
+ stp->ls_stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0)
+ stp->ls_stateid = nd->nd_curstateid;
+ else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
stp->ls_seq = fxdr_unsigned(u_int32_t, *tl++);
i = fxdr_unsigned(int, *tl++);
switch (i) {
@@ -3281,8 +3469,13 @@ nfsrvd_opendowngrade(struct nfsrv_descript *nd, __unus
}
if (!nd->nd_repstat)
nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid,
- nd, p);
+ nd, p, NULL);
if (!nd->nd_repstat) {
+ /* For NFSv4.1, set the Current StateID. */
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ nd->nd_curstateid = stateid;
+ nd->nd_flag |= ND_CURSTATEID;
+ }
NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID);
*tl++ = txdr_unsigned(stateid.seqid);
NFSBCOPY((caddr_t)stateid.other,(caddr_t)tl,NFSX_STATEIDOTHER);
@@ -3609,7 +3802,7 @@ nfsrvd_verify(struct nfsrv_descript *nd, int isdgram,
fhandle_t fh;
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
- nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
+ nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_statfs(vp, sf);
if (!nd->nd_repstat)
@@ -3787,7 +3980,10 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused
confirm.lval[1] = 1;
else
confirm.lval[1] = 0;
- v41flags = NFSV4EXCH_USENONPNFS;
+ if (TAILQ_EMPTY(&nfsrv_devidhead))
+ v41flags = NFSV4EXCH_USENONPNFS | NFSV4EXCH_USEPNFSDS;
+ else
+ v41flags = NFSV4EXCH_USEPNFSMDS;
sp4type = fxdr_unsigned(uint32_t, *tl);
if (sp4type != NFSV4EXCH_SP4NONE) {
nd->nd_repstat = NFSERR_NOTSUPP;
@@ -3878,7 +4074,15 @@ nfsrvd_createsession(struct nfsrv_descript *nd, __unus
NFSM_DISSECT(tl, uint32_t *, 7 * NFSX_UNSIGNED);
tl++; /* Header pad always 0. */
sep->sess_maxreq = fxdr_unsigned(uint32_t, *tl++);
+ if (sep->sess_maxreq > sb_max_adj - NFS_MAXXDR) {
+ sep->sess_maxreq = sb_max_adj - NFS_MAXXDR;
+ printf("Consider increasing kern.ipc.maxsockbuf\n");
+ }
sep->sess_maxresp = fxdr_unsigned(uint32_t, *tl++);
+ if (sep->sess_maxresp > sb_max_adj - NFS_MAXXDR) {
+ sep->sess_maxresp = sb_max_adj - NFS_MAXXDR;
+ printf("Consider increasing kern.ipc.maxsockbuf\n");
+ }
sep->sess_maxrespcached = fxdr_unsigned(uint32_t, *tl++);
sep->sess_maxops = fxdr_unsigned(uint32_t, *tl++);
sep->sess_maxslots = fxdr_unsigned(uint32_t, *tl++);
@@ -4080,7 +4284,361 @@ nfsrvd_freestateid(struct nfsrv_descript *nd, __unused
NFSM_DISSECT(tl, uint32_t *, NFSX_STATEID);
stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
NFSBCOPY(tl, stateid.other, NFSX_STATEIDOTHER);
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set the
+ * stateid to the current stateid, if it is set.
+ */
+ if (stateid.seqid == 1 && stateid.other[0] == 0 &&
+ stateid.other[1] == 0 && stateid.other[2] == 0) {
+ if ((nd->nd_flag & ND_CURSTATEID) != 0) {
+ stateid = nd->nd_curstateid;
+ stateid.seqid = 0;
+ } else {
+ nd->nd_repstat = NFSERR_BADSTATEID;
+ goto nfsmout;
+ }
+ }
+
nd->nd_repstat = nfsrv_freestateid(nd, &stateid, p);
+
+ /* If the current stateid has been free'd, unset it. */
+ if (nd->nd_repstat == 0 && (nd->nd_flag & ND_CURSTATEID) != 0 &&
+ stateid.other[0] == nd->nd_curstateid.other[0] &&
+ stateid.other[1] == nd->nd_curstateid.other[1] &&
+ stateid.other[2] == nd->nd_curstateid.other[2])
+ nd->nd_flag &= ~ND_CURSTATEID;
+nfsmout:
+ NFSEXITCODE2(error, nd);
+ return (error);
+}
+
+/*
+ * nfsv4 layoutget service
+ */
+APPLESTATIC int
+nfsrvd_layoutget(struct nfsrv_descript *nd, __unused int isdgram,
+ vnode_t vp, NFSPROC_T *p, struct nfsexstuff *exp)
+{
+ uint32_t *tl;
+ nfsv4stateid_t stateid;
+ int error = 0, layoutlen, layouttype, iomode, maxcnt, retonclose;
+ uint64_t offset, len, minlen;
+ char *layp = NULL;
+
+ if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+ nd->nd_repstat = NFSERR_WRONGSEC;
+ goto nfsmout;
+ }
+ NFSM_DISSECT(tl, uint32_t *, 4 * NFSX_UNSIGNED + 3 * NFSX_HYPER +
+ NFSX_STATEID);
+ tl++; /* Signal layout available. Ignore for now. */
+ layouttype = fxdr_unsigned(int, *tl++);
+ iomode = fxdr_unsigned(int, *tl++);
+ offset = fxdr_hyper(tl); tl += 2;
+ len = fxdr_hyper(tl); tl += 2;
+ minlen = fxdr_hyper(tl); tl += 2;
+ stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
+ NFSBCOPY(tl, stateid.other, NFSX_STATEIDOTHER);
+ tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
+ maxcnt = fxdr_unsigned(int, tl);
+ NFSD_DEBUG(4, "layoutget ltyp=%d iom=%d off=%ju len=%ju mlen=%ju\n",
+ layouttype, iomode, (uintmax_t)offset, (uintmax_t)len,
+ (uintmax_t)minlen);
+ if (len < minlen ||
+ (minlen != UINT64_MAX && offset + minlen < offset) ||
+ (len != UINT64_MAX && offset + len < offset)) {
+ nd->nd_repstat = NFSERR_INVAL;
+ goto nfsmout;
+ }
+
+ /*
+ * For the special stateid of other all 0s and seqid == 1, set the
+ * stateid to the current stateid, if it is set.
+ */
+ if (stateid.seqid == 1 && stateid.other[0] == 0 &&
+ stateid.other[1] == 0 && stateid.other[2] == 0) {
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list