From owner-svn-src-projects@freebsd.org Sat May 6 22:47:06 2017 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 66725D61876 for ; Sat, 6 May 2017 22:47:06 +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 mx1.freebsd.org (Postfix) with ESMTPS id EF6819F8; Sat, 6 May 2017 22:47:05 +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 v46Ml4Cq093013; Sat, 6 May 2017 22:47:04 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v46Ml4RA093012; Sat, 6 May 2017 22:47:04 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201705062247.v46Ml4RA093012@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Sat, 6 May 2017 22:47:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r317889 - projects/pnfs-planb-server/sys/fs/nfsserver X-SVN-Group: projects 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.23 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: Sat, 06 May 2017 22:47:06 -0000 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); +} +