svn commit: r266958 - in projects/nfsv4.1-server/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Mon Jun 2 00:14:03 UTC 2014
Author: rmacklem
Date: Mon Jun 2 00:14:02 2014
New Revision: 266958
URL: http://svnweb.freebsd.org/changeset/base/266958
Log:
Add support for the Want Delegation flags on Open to the NFSv4.1
server. Also fix it so that it correctly reports that there is
no backchannel in the Sequence reply.
Modified:
projects/nfsv4.1-server/sys/fs/nfs/nfs.h
projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h
projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdserv.c
projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdstate.c
Modified: projects/nfsv4.1-server/sys/fs/nfs/nfs.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfs.h Sun Jun 1 21:33:02 2014 (r266957)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfs.h Mon Jun 2 00:14:02 2014 (r266958)
@@ -324,6 +324,11 @@ struct nfsreferral {
#define NFSLCK_SETATTR 0x02000000
#define NFSLCK_DELEGPURGE 0x04000000
#define NFSLCK_DELEGRETURN 0x08000000
+#define NFSLCK_WANTWDELEG 0x10000000
+#define NFSLCK_WANTRDELEG 0x20000000
+#define NFSLCK_WANTNODELEG 0x40000000
+#define NFSLCK_WANTBITS \
+ (NFSLCK_WANTWDELEG | NFSLCK_WANTRDELEG | NFSLCK_WANTNODELEG)
/* And bits for nid_flag */
#define NFSID_INITIALIZE 0x0001
Modified: projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h Sun Jun 1 21:33:02 2014 (r266957)
+++ projects/nfsv4.1-server/sys/fs/nfs/nfsproto.h Mon Jun 2 00:14:02 2014 (r266958)
@@ -512,15 +512,21 @@
/*
* Open result flags
- * (The first two are in the spec. The rest are used internally.)
+ * (The first four are in the spec. The rest are used internally.)
*/
#define NFSV4OPEN_RESULTCONFIRM 0x00000002
#define NFSV4OPEN_LOCKTYPEPOSIX 0x00000004
+#define NFSV4OPEN_PRESERVEUNLINKED 0x00000008
+#define NFSV4OPEN_MAYNOTIFYLOCK 0x00000020
#define NFSV4OPEN_RFLAGS \
- (NFSV4OPEN_RESULTCONFIRM | NFSV4OPEN_LOCKTYPEPOSIX)
+ (NFSV4OPEN_RESULTCONFIRM | NFSV4OPEN_LOCKTYPEPOSIX | \
+ NFSV4OPEN_PRESERVEUNLINKED | NFSV4OPEN_MAYNOTIFYLOCK)
#define NFSV4OPEN_RECALL 0x00010000
#define NFSV4OPEN_READDELEGATE 0x00020000
#define NFSV4OPEN_WRITEDELEGATE 0x00040000
+#define NFSV4OPEN_WDRESOURCE 0x00080000
+#define NFSV4OPEN_WDCONTENTION 0x00100000
+#define NFSV4OPEN_WDNOTWANTED 0x00200000
/*
* NFS V4 File Handle types
Modified: projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdserv.c Sun Jun 1 21:33:02 2014 (r266957)
+++ projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdserv.c Mon Jun 2 00:14:02 2014 (r266958)
@@ -2599,15 +2599,38 @@ nfsrvd_open(struct nfsrv_descript *nd, _
stp->ls_uid = nd->nd_cred->cr_uid;
stp->ls_seq = fxdr_unsigned(u_int32_t, *tl++);
i = fxdr_unsigned(int, *tl++);
- retext = -1;
+ retext = 0;
if ((i & (NFSV4OPEN_WANTDELEGMASK | NFSV4OPEN_WANTSIGNALDELEG |
NFSV4OPEN_WANTPUSHDELEG)) != 0 && (nd->nd_flag & ND_NFSV41) != 0) {
- retext = NFSV4OPEN_RESOURCE;
- if ((i & (NFSV4OPEN_WANTDELEGMASK | NFSV4OPEN_WANTSIGNALDELEG |
- NFSV4OPEN_WANTPUSHDELEG)) == NFSV4OPEN_WANTNODELEG)
- retext = NFSV4OPEN_NOTWANTED;
- i &= ~(NFSV4OPEN_WANTDELEGMASK | NFSV4OPEN_WANTSIGNALDELEG |
- NFSV4OPEN_WANTPUSHDELEG);
+ retext = 1;
+ /* For now, ignore these. */
+ i &= ~(NFSV4OPEN_WANTPUSHDELEG | NFSV4OPEN_WANTSIGNALDELEG);
+ switch (i & NFSV4OPEN_WANTDELEGMASK) {
+ case NFSV4OPEN_WANTANYDELEG:
+ stp->ls_flags |= (NFSLCK_WANTRDELEG |
+ NFSLCK_WANTWDELEG);
+ i &= ~NFSV4OPEN_WANTDELEGMASK;
+ break;
+ case NFSV4OPEN_WANTREADDELEG:
+ stp->ls_flags |= NFSLCK_WANTRDELEG;
+ i &= ~NFSV4OPEN_WANTDELEGMASK;
+ break;
+ case NFSV4OPEN_WANTWRITEDELEG:
+ stp->ls_flags |= NFSLCK_WANTWDELEG;
+ i &= ~NFSV4OPEN_WANTDELEGMASK;
+ break;
+ case NFSV4OPEN_WANTNODELEG:
+ stp->ls_flags |= NFSLCK_WANTNODELEG;
+ i &= ~NFSV4OPEN_WANTDELEGMASK;
+ break;
+ case NFSV4OPEN_WANTCANCEL:
+ printf("NFSv4: ignore Open WantCancel\n");
+ i &= ~NFSV4OPEN_WANTDELEGMASK;
+ break;
+ default:
+ /* nd_repstat will be set to NFSERR_INVAL below. */
+ break;
+ };
}
switch (i) {
case NFSV4OPEN_ACCESSREAD:
@@ -2910,16 +2933,19 @@ nfsrvd_open(struct nfsrv_descript *nd, _
*tl = txdr_unsigned(NFSV4OPEN_DELEGATEREAD);
else if (rflags & NFSV4OPEN_WRITEDELEGATE)
*tl = txdr_unsigned(NFSV4OPEN_DELEGATEWRITE);
- else if (retext != -1) {
+ else if (retext != 0) {
*tl = txdr_unsigned(NFSV4OPEN_DELEGATENONEEXT);
- if (retext == NFSV4OPEN_RESOURCE ||
- retext == NFSV4OPEN_CONTENTION) {
+ if ((rflags & NFSV4OPEN_WDCONTENTION) != 0) {
+ NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+ *tl++ = txdr_unsigned(NFSV4OPEN_CONTENTION);
+ *tl = newnfs_false;
+ } else if ((rflags & NFSV4OPEN_WDRESOURCE) != 0) {
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = txdr_unsigned(retext);
+ *tl++ = txdr_unsigned(NFSV4OPEN_RESOURCE);
*tl = newnfs_false;
} else {
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(retext);
+ *tl = txdr_unsigned(NFSV4OPEN_NOTWANTED);
}
} else
*tl = txdr_unsigned(NFSV4OPEN_DELEGATENONE);
Modified: projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdstate.c Sun Jun 1 21:33:02 2014 (r266957)
+++ projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdstate.c Mon Jun 2 00:14:02 2014 (r266958)
@@ -153,7 +153,6 @@ nfsrv_setclient(struct nfsrv_descript *n
/*
* Check for state resource limit exceeded.
*/
-printf("in nfsrv_setcl\n");
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
error = NFSERR_RESOURCE;
goto out;
@@ -211,7 +210,6 @@ printf("in nfsrv_setcl\n");
NFSUNLOCKV4ROOTMUTEX();
confirmp->lval[1] = 0;
error = NFSERR_NOENT;
-printf("reconfirming\n");
goto out;
}
/*
@@ -259,7 +257,6 @@ printf("reconfirming\n");
if (zapit)
nfsrv_zapclient(clp, p);
*new_clpp = NULL;
-printf("new cl\n");
goto out;
}
@@ -375,7 +372,6 @@ printf("new cl\n");
NFSUNLOCKSTATE();
nfsrv_zapclient(clp, p);
*new_clpp = NULL;
-printf("new cl2\n");
goto out;
}
@@ -420,7 +416,6 @@ printf("new cl2\n");
newnfsstats.srvclients++;
nfsrv_openpluslock++;
nfsrv_clients++;
-printf("new cl3\n");
}
NFSLOCKV4ROOTMUTEX();
nfsv4_unlock(&nfsv4rootfs_lock, 1);
@@ -578,18 +573,14 @@ nfsrv_getclient(nfsquad_t clientid, int
clp->lc_flags &= ~(LCL_NEEDSCONFIRM | LCL_DONTCLEAN);
if (clp->lc_program)
clp->lc_flags |= LCL_NEEDSCBNULL;
-printf("prog=%d\n", clp->lc_program);
/* For NFSv4.1, link the session onto the client. */
if (nsep != NULL) {
-printf("nsep not null\n");
/* Hold a reference on the xprt for a backchannel. */
if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN)
!= 0 && clp->lc_req.nr_client == NULL) {
-printf("set backch\n");
clp->lc_req.nr_client = (struct __rpc_client *)
clnt_bck_create(nd->nd_xprt->xp_socket,
cbprogram, NFSV4_CBVERS);
-printf("cbcl=%p\n", clp->lc_req.nr_client);
if (clp->lc_req.nr_client != NULL) {
SVC_ACQUIRE(nd->nd_xprt);
nd->nd_xprt->xp_p2 =
@@ -2896,13 +2887,20 @@ tryagain:
/*
* This is where we can choose to issue a delegation.
*/
- if (delegate && nfsrv_issuedelegs &&
- writedeleg && !NFSVNO_EXRDONLY(exp) &&
- (nfsrv_writedelegifpos || !readonly) &&
- (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) ==
- LCL_CALLBACKSON &&
- !NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) &&
- NFSVNO_DELEGOK(vp)) {
+ if (delegate == 0 || writedeleg == 0 ||
+ NFSVNO_EXRDONLY(exp) || (readonly != 0 &&
+ nfsrv_writedelegifpos == 0) ||
+ !NFSVNO_DELEGOK(vp) ||
+ (new_stp->ls_flags & NFSLCK_WANTRDELEG) != 0 ||
+ (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) !=
+ LCL_CALLBACKSON)
+ *rflagsp |= NFSV4OPEN_WDCONTENTION;
+ else if (nfsrv_issuedelegs == 0 ||
+ NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt))
+ *rflagsp |= NFSV4OPEN_WDRESOURCE;
+ else if ((new_stp->ls_flags & NFSLCK_WANTNODELEG) != 0)
+ *rflagsp |= NFSV4OPEN_WDNOTWANTED;
+ else {
new_deleg->ls_stateid.seqid = delegstateidp->seqid = 1;
new_deleg->ls_stateid.other[0] = delegstateidp->other[0]
= clp->lc_clientid.lval[0];
@@ -2951,12 +2949,17 @@ tryagain:
/*
* This is where we can choose to issue a delegation.
*/
- if (delegate && nfsrv_issuedelegs &&
- (writedeleg || readonly) &&
- (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) ==
- LCL_CALLBACKSON &&
- !NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) &&
- NFSVNO_DELEGOK(vp)) {
+ if (delegate == 0 || (writedeleg == 0 && readonly == 0) ||
+ !NFSVNO_DELEGOK(vp) ||
+ (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) !=
+ LCL_CALLBACKSON)
+ *rflagsp |= NFSV4OPEN_WDCONTENTION;
+ else if (nfsrv_issuedelegs == 0 ||
+ NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt))
+ *rflagsp |= NFSV4OPEN_WDRESOURCE;
+ else if ((new_stp->ls_flags & NFSLCK_WANTNODELEG) != 0)
+ *rflagsp |= NFSV4OPEN_WDNOTWANTED;
+ else {
new_deleg->ls_stateid.seqid = delegstateidp->seqid = 1;
new_deleg->ls_stateid.other[0] = delegstateidp->other[0]
= clp->lc_clientid.lval[0];
@@ -2965,7 +2968,8 @@ tryagain:
new_deleg->ls_stateid.other[2] = delegstateidp->other[2]
= nfsrv_nextstateindex(clp);
if (writedeleg && !NFSVNO_EXRDONLY(exp) &&
- (nfsrv_writedelegifpos || !readonly)) {
+ (nfsrv_writedelegifpos || !readonly) &&
+ (new_stp->ls_flags & NFSLCK_WANTRDELEG) == 0) {
new_deleg->ls_flags = (NFSLCK_DELEGWRITE |
NFSLCK_READACCESS | NFSLCK_WRITEACCESS);
*rflagsp |= NFSV4OPEN_WRITEDELEGATE;
@@ -3012,6 +3016,61 @@ tryagain:
} else if ((nd->nd_flag & ND_NFSV41) != 0) {
/* NFSv4.1 never needs confirmation. */
new_stp->ls_flags = 0;
+
+ /*
+ * This is where we can choose to issue a delegation.
+ */
+ if (delegate && nfsrv_issuedelegs &&
+ (writedeleg || readonly) &&
+ (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) ==
+ LCL_CALLBACKSON &&
+ !NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) &&
+ NFSVNO_DELEGOK(vp) &&
+ ((nd->nd_flag & ND_NFSV41) == 0 ||
+ (new_stp->ls_flags & NFSLCK_WANTNODELEG) == 0)) {
+ new_deleg->ls_stateid.seqid =
+ delegstateidp->seqid = 1;
+ new_deleg->ls_stateid.other[0] =
+ delegstateidp->other[0]
+ = clp->lc_clientid.lval[0];
+ new_deleg->ls_stateid.other[1] =
+ delegstateidp->other[1]
+ = clp->lc_clientid.lval[1];
+ new_deleg->ls_stateid.other[2] =
+ delegstateidp->other[2]
+ = nfsrv_nextstateindex(clp);
+ if (writedeleg && !NFSVNO_EXRDONLY(exp) &&
+ (nfsrv_writedelegifpos || !readonly) &&
+ ((nd->nd_flag & ND_NFSV41) == 0 ||
+ (new_stp->ls_flags & NFSLCK_WANTRDELEG) ==
+ 0)) {
+ new_deleg->ls_flags =
+ (NFSLCK_DELEGWRITE |
+ NFSLCK_READACCESS |
+ NFSLCK_WRITEACCESS);
+ *rflagsp |= NFSV4OPEN_WRITEDELEGATE;
+ } else {
+ new_deleg->ls_flags =
+ (NFSLCK_DELEGREAD |
+ NFSLCK_READACCESS);
+ *rflagsp |= NFSV4OPEN_READDELEGATE;
+ }
+ new_deleg->ls_uid = new_stp->ls_uid;
+ new_deleg->ls_lfp = lfp;
+ new_deleg->ls_clp = clp;
+ new_deleg->ls_filerev = filerev;
+ new_deleg->ls_compref = nd->nd_compref;
+ LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg,
+ ls_file);
+ LIST_INSERT_HEAD(NFSSTATEHASH(clp,
+ new_deleg->ls_stateid), new_deleg, ls_hash);
+ LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg,
+ ls_list);
+ new_deleg = NULL;
+ newnfsstats.srvdelegates++;
+ nfsrv_openpluslock++;
+ nfsrv_delegatecnt++;
+ }
} else {
*rflagsp |= NFSV4OPEN_RESULTCONFIRM;
new_stp->ls_flags = NFSLCK_NEEDSCONFIRM;
@@ -5576,7 +5635,6 @@ nfsrv_checksequence(struct nfsrv_descrip
{
struct nfsdsession *sep;
struct nfssessionhash *shp;
- CLIENT *cl;
int error;
SVCXPRT *savxprt;
@@ -5614,11 +5672,10 @@ nfsrv_checksequence(struct nfsrv_descrip
SVC_RELEASE(savxprt);
}
- cl = sep->sess_clp->lc_req.nr_client;
- if (cl == NULL)
+ *sflagsp = 0;
+ if (sep->sess_clp->lc_req.nr_client == NULL)
*sflagsp |= NFSV4SEQ_CBPATHDOWN;
NFSUNLOCKSESSION(shp);
- *sflagsp = 0;
if (error == NFSERR_EXPIRED) {
*sflagsp |= NFSV4SEQ_EXPIREDALLSTATEREVOKED;
error = 0;
More information about the svn-src-projects
mailing list