From owner-svn-src-projects@freebsd.org Fri Jun 16 21:26:43 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 8B720D898C5 for ; Fri, 16 Jun 2017 21:26:43 +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 656C170968; Fri, 16 Jun 2017 21:26:43 +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 v5GLQfgX072139; Fri, 16 Jun 2017 21:26:41 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5GLQfir072138; Fri, 16 Jun 2017 21:26:41 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201706162126.v5GLQfir072138@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 16 Jun 2017 21:26:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r320026 - 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: Fri, 16 Jun 2017 21:26:43 -0000 Author: rmacklem Date: Fri Jun 16 21:26:41 2017 New Revision: 320026 URL: https://svnweb.freebsd.org/changeset/base/320026 Log: Modify the pNFS server so that it does a Lookup when the DS file handle in the extended attribute pnfsd.dsfile is all 0bits. This allows a sysadmin to zero out the file handle when it changes on the DS. This would normally happen when the file is restored from a backup. Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Fri Jun 16 21:20:39 2017 (r320025) +++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdport.c Fri Jun 16 21:26:41 2017 (r320026) @@ -82,6 +82,7 @@ static pid_t nfsd_master_pid = (pid_t)-1; static char nfsd_master_comm[MAXCOMLEN + 1]; static struct timeval nfsd_master_start; static uint32_t nfsv4_sysid = 0; +static fhandle_t zerofh; static int nfssvc_srvcall(struct thread *, struct nfssvc_args *, struct ucred *); @@ -116,6 +117,8 @@ static int nfsrv_setattrdsrpc(fhandle_t *, struct ucre static int nfsrv_getattrdsrpc(fhandle_t *, struct ucred *, NFSPROC_T *, struct vnode *, struct nfsmount *, struct nfsvattr *); static int nfsrv_putfhname(fhandle_t *, char *); +static int nfsrv_pnfslookupds(struct vnode *, struct pnfsdsfile *, + struct vnode *, NFSPROC_T *); SYSCTL_NODE(_vfs, OID_AUTO, nfsd, CTLFLAG_RW, 0, "NFS server"); SYSCTL_INT(_vfs_nfsd, OID_AUTO, mirrormnt, CTLFLAG_RW, @@ -3983,8 +3986,11 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char struct nfsdevice *ds; struct pnfsdsfile *pf; uint32_t dsdir; - int error; + int error, fhiszero; + fhiszero = 0; + if (lktype == 0) + lktype = LK_SHARED; if (dvpp != NULL) { *dvpp = NULL; *nmpp = NULL; @@ -4003,6 +4009,8 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char } } if (error == 0) { + if (NFSBCMP(&zerofh, &pf->dsf_fh, sizeof(zerofh)) == 0) + fhiszero = 1; /* Use the socket address to find the mount point. */ NFSDDSLOCK(); TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { @@ -4013,10 +4021,19 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char } NFSDDSUNLOCK(); if (ds != NULL) { - if (dvpp != NULL) { + if (dvpp != NULL || fhiszero != 0) { dvp = ds->nfsdev_dsdir[dsdir]; - if (error == 0) - error = vn_lock(dvp, lktype); + error = vn_lock(dvp, lktype); + /* + * If the file handle is all 0's, try to do a + * Lookup against the DS to acquire it. + */ + if (error == 0 && fhiszero != 0) { + error = nfsrv_pnfslookupds(vp, pf, dvp, + p); + if (error != 0 || dvpp == NULL) + NFSVOPUNLOCK(dvp, 0); + } } if (devid != NULL) NFSBCOPY(ds->nfsdev_deviceid, devid, @@ -4473,6 +4490,67 @@ nfsrv_dsgetdevandfh(struct vnode *vp, NFSPROC_T *p, fh error = nfsrv_dsgetsockmnt(vp, 0, buf, buflen, p, NULL, NULL, fhp, devid, NULL); free(buf, M_TEMP); + return (error); +} + +/* + * Do a Lookup against the DS for the filename and set the file handle + * to the correct one, if successful. + */ +static int +nfsrv_pnfslookupds(struct vnode *vp, struct pnfsdsfile *pf, struct vnode *dvp, + NFSPROC_T *p) +{ + struct nameidata named; + struct ucred *tcred; + struct mount *mp; + char *bufp; + u_long *hashp; + struct vnode *nvp; + struct nfsnode *np; + int error, ret; + + tcred = newnfs_getcred(); + named.ni_cnd.cn_nameiop = LOOKUP; + named.ni_cnd.cn_lkflags = LK_SHARED | LK_RETRY; + named.ni_cnd.cn_cred = tcred; + named.ni_cnd.cn_thread = p; + named.ni_cnd.cn_flags = ISLASTCN | LOCKPARENT | LOCKLEAF | SAVENAME; + nfsvno_setpathbuf(&named, &bufp, &hashp); + named.ni_cnd.cn_nameptr = bufp; + named.ni_cnd.cn_namelen = strlen(pf->dsf_filename); + strlcpy(bufp, pf->dsf_filename, NAME_MAX); + NFSD_DEBUG(4, "nfsrv_pnfslookupds: filename=%s\n", bufp); + error = VOP_LOOKUP(dvp, &nvp, &named.ni_cnd); + NFSD_DEBUG(4, "nfsrv_pnfslookupds: aft LOOKUP=%d\n", error); + NFSFREECRED(tcred); + nfsvno_relpathbuf(&named); + if (error == 0) { + np = VTONFS(nvp); + NFSBCOPY(np->n_fhp->nfh_fh, &pf->dsf_fh, NFSX_MYFH); + vput(nvp); + /* + * We can only do a setextattr for an exclusively + * locked vp. Instead of trying to upgrade a shared + * lock, just leave dsf_fh zeroed out and it will + * keep doing this lookup until it is done with an + * exclusively locked vp. + */ + if (NFSVOPISLOCKED(vp) == LK_EXCLUSIVE) { + ret = vn_start_write(vp, &mp, V_WAIT); + NFSD_DEBUG(4, "nfsrv_pnfslookupds: vn_start_write=%d\n", + ret); + if (ret == 0) { + ret = vn_extattr_set(vp, IO_NODELOCKED, + EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsfile", + sizeof(*pf), (char *)pf, p); + vn_finished_write(mp); + NFSD_DEBUG(4, "nfsrv_pnfslookupds: aft " + "vn_extattr_set=%d\n", ret); + } + } + } + NFSD_DEBUG(4, "eo nfsrv_pnfslookupds=%d\n", error); return (error); }