svn commit: r317889 - projects/pnfs-planb-server/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sat May 6 22:47:06 UTC 2017
Author: rmacklem
Date: Sat May 6 22:47:04 2017
New Revision: 317889
URL: https://svnweb.freebsd.org/changeset/base/317889
Log:
Fix the search for a Read/Write Layout + Open/Write or Write Delegation for
the case where these are held by a different client than the one doing the RPC.
Modified:
projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c
Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Sat May 6 21:43:55 2017 (r317888)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Sat May 6 22:47:04 2017 (r317889)
@@ -188,6 +188,7 @@ static void nfsrv_allocdevid(struct nfsd
static void nfsrv_freealldevids(void);
static int nfsrv_findlayout(struct nfsrv_descript *nd, fhandle_t *fhp,
NFSPROC_T *, struct nfslayout **lypp);
+static int nfsrv_fndclid(nfsquad_t *clidvec, nfsquad_t clid, int clidcnt);
/*
* Scan the client list for a match and either return the current one,
@@ -6816,6 +6817,7 @@ nfsrv_freealldevids(void)
* This function is used by nfsrv_proxyds() to decide if doing a Proxy
* Getattr RPC to the Data Server (DS) is necessary.
*/
+#define NFSCLIDVECSIZE 6
APPLESTATIC int
nfsrv_checkdsattr(struct nfsrv_descript *nd, vnode_t vp, NFSPROC_T *p)
{
@@ -6825,24 +6827,30 @@ nfsrv_checkdsattr(struct nfsrv_descript
struct nfslayouthash *lhyp;
struct nfslockhashhead *hp;
struct nfslockfile *lfp;
- int ret;
+ nfsquad_t clid[NFSCLIDVECSIZE];
+ int clidcnt, ret;
- KASSERT((nd->nd_flag & ND_IMPLIEDCLID) != 0,
- ("nfsrv_chechdsattr: no nd_clientid\n"));
ret = nfsvno_getfh(vp, &fh, p);
if (ret != 0)
return (0);
/* First check for a Read/Write Layout. */
+ clidcnt = 0;
lhyp = NFSLAYOUTHASH(&fh);
NFSLOCKLAYOUT(lhyp);
- ret = nfsrv_findlayout(nd, &fh, p, &lyp);
- if (ret != 0 || lyp->lay_rw == 0) {
+ LIST_FOREACH(lyp, &lhyp->list, lay_list) {
+ if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0 && lyp->lay_rw
+ != 0) {
+ if (clidcnt < NFSCLIDVECSIZE)
+ clid[clidcnt].qval = lyp->lay_clientid.qval;
+ clidcnt++;
+ }
+ }
+ NFSUNLOCKLAYOUT(lhyp);
+ if (clidcnt == 0) {
/* None found, so return 0. */
- NFSUNLOCKLAYOUT(lhyp);
return (0);
}
- NFSUNLOCKLAYOUT(lhyp);
/* Get the nfslockfile for this fh. */
NFSLOCKSTATE();
@@ -6861,7 +6869,7 @@ nfsrv_checkdsattr(struct nfsrv_descript
/* Now, look for a Write delegation for this clientid. */
LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) {
if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0 &&
- stp->ls_clp->lc_clientid.qval == nd->nd_clientid.qval)
+ nfsrv_fndclid(clid, stp->ls_clp->lc_clientid, clidcnt) != 0)
break;
}
if (stp != NULL) {
@@ -6875,7 +6883,7 @@ nfsrv_checkdsattr(struct nfsrv_descript
KASSERT((stp->ls_flags & NFSLCK_OPEN) != 0,
("nfsrv_checkdsattr: Non-open in Open list\n"));
if ((stp->ls_flags & NFSLCK_WRITEACCESS) != 0 &&
- stp->ls_clp->lc_clientid.qval == nd->nd_clientid.qval)
+ nfsrv_fndclid(clid, stp->ls_clp->lc_clientid, clidcnt) != 0)
break;
}
NFSUNLOCKSTATE();
@@ -6884,3 +6892,21 @@ nfsrv_checkdsattr(struct nfsrv_descript
return (0);
}
+/*
+ * Look for a matching clientid in the vector. Return 1 if one might match.
+ */
+static int
+nfsrv_fndclid(nfsquad_t *clidvec, nfsquad_t clid, int clidcnt)
+{
+ int i;
+
+ /* If too many for the vector, return 1 since there might be a match. */
+ if (clidcnt > NFSCLIDVECSIZE)
+ return (1);
+
+ for (i = 0; i < clidcnt; i++)
+ if (clidvec[i].qval == clid.qval)
+ return (1);
+ return (0);
+}
+
More information about the svn-src-projects
mailing list