svn commit: r322420 - projects/pnfs-planb-server-stable11/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Fri Aug 11 23:07:57 UTC 2017
Author: rmacklem
Date: Fri Aug 11 23:07:56 2017
New Revision: 322420
URL: https://svnweb.freebsd.org/changeset/base/322420
Log:
Fix nfsrv_dsgetsockmnt() so that it handles the mirrors. Also, change
nfsrv_dsgetdevandfh() so that it allocates the maximum size for mirrors
and not just the maximum mirrors for this running case.
Modified:
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdport.c
projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdstate.c
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdport.c Fri Aug 11 22:47:32 2017 (r322419)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdport.c Fri Aug 11 23:07:56 2017 (r322420)
@@ -4001,16 +4001,17 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char
int *mirrorcntp, NFSPROC_T *p, struct vnode **dvpp, struct nfsmount **nmpp,
fhandle_t *fhp, char *devid, char *fnamep)
{
- struct vnode *dvp;
+ struct vnode *dvp, **tdvpp;
struct nfsmount *nmp;
struct sockaddr *sad;
struct nfsdevice *ds;
struct pnfsdsfile *pf;
uint32_t dsdir;
- int error, fhiszero;
+ int error, fhiszero, i, j, mirrorcnt;
*mirrorcntp = 1;
fhiszero = 0;
+ tdvpp = dvpp;
if (lktype == 0)
lktype = LK_SHARED;
if (dvpp != NULL) {
@@ -4019,62 +4020,81 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char
}
error = vn_extattr_get(vp, IO_NODELOCKED, EXTATTR_NAMESPACE_SYSTEM,
"pnfsd.dsfile", &buflen, buf, p);
- if (error == 0 && buflen != sizeof(*pf))
+ mirrorcnt = buflen / sizeof(*pf);
+ if (error == 0 && (mirrorcnt < 1 || mirrorcnt > NFSDEV_MAXMIRRORS ||
+ buflen != sizeof(*pf) * mirrorcnt))
error = ENOATTR;
- if (error == 0) {
- pf = (struct pnfsdsfile *)buf;
+ pf = (struct pnfsdsfile *)buf;
+ for (i = 0; i < mirrorcnt && error == 0; i++, pf++) {
sad = (struct sockaddr *)&pf->dsf_sin;
dsdir = pf->dsf_dir;
if (dsdir >= nfsrv_dsdirsize) {
printf("nfsrv_dsgetsockmnt: dsdir=%d\n", dsdir);
error = ENOATTR;
}
- }
- 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) {
- dvp = ds->nfsdev_dvp;
- nmp = VFSTONFS(dvp->v_mount);
- if (nfsaddr2_match(sad, nmp->nm_nam))
- break;
- }
- NFSDDSUNLOCK();
- if (ds != NULL) {
- if (dvpp != NULL || fhiszero != 0) {
- dvp = ds->nfsdev_dsdir[dsdir];
- 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 (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) {
+ dvp = ds->nfsdev_dvp;
+ nmp = VFSTONFS(dvp->v_mount);
+ if (nfsaddr2_match(sad, nmp->nm_nam))
+ break;
+ }
+ NFSDDSUNLOCK();
+ if (ds != NULL) {
+ if (dvpp != NULL || fhiszero != 0) {
+ dvp = ds->nfsdev_dsdir[dsdir];
+ 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 dvpp == NULL or the Lookup fails,
+ * unlock dvp after the call.
+ */
+ 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,
+ NFSX_V4DEVICEID);
+ devid += NFSX_V4DEVICEID;
+ }
+ } else
+ error = ENOENT;
+ }
+ if (error == 0) {
+ if (dvpp != NULL) {
+ *tdvpp++ = dvp;
+ *nmpp++ = nmp;
}
- if (devid != NULL)
- NFSBCOPY(ds->nfsdev_deviceid, devid,
- NFSX_V4DEVICEID);
+ if (fhp != NULL)
+ NFSBCOPY(&pf->dsf_fh, fhp++, NFSX_MYFH);
+ if (fnamep != NULL && i == 0)
+ strlcpy(fnamep, pf->dsf_filename,
+ sizeof(pf->dsf_filename));
} else
- error = ENOENT;
+ NFSD_DEBUG(4, "nfsrv_dsgetsockmnt err=%d\n", error);
}
- if (error == 0) {
- if (dvpp != NULL) {
- *dvpp = dvp;
- *nmpp = nmp;
- }
- if (fhp != NULL)
- NFSBCOPY(&pf->dsf_fh, fhp, NFSX_MYFH);
- if (fnamep != NULL)
- strlcpy(fnamep, pf->dsf_filename,
- sizeof(pf->dsf_filename));
- } else
- NFSD_DEBUG(4, "nfsrv_dsgetsockmnt err=%d\n", error);
+
+ if (error == 0)
+ *mirrorcntp = mirrorcnt;
+ else if (i > 1 && dvpp != NULL) {
+ /*
+ * If the error didn't occur on the first one and dvpp != NULL,
+ * the one(s) prior to the failure will have locked dvp's that
+ * need to be unlocked.
+ */
+ for (j = 1; j < i; j++)
+ NFSVOPUNLOCK(*dvpp++, 0);
+ }
return (error);
}
Modified: projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdstate.c Fri Aug 11 22:47:32 2017 (r322419)
+++ projects/pnfs-planb-server-stable11/sys/fs/nfsserver/nfs_nfsdstate.c Fri Aug 11 23:07:56 2017 (r322420)
@@ -6287,9 +6287,8 @@ nfsrv_layoutget(struct nfsrv_descript *nd, vnode_t vp,
NFSUNLOCKLAYOUT(lhyp);
/* Find the device id and file handle. */
- dsfhp = malloc(sizeof(fhandle_t) * nfsrv_maxpnfsmirror, M_TEMP,
- M_WAITOK);
- devid = malloc(NFSX_V4DEVICEID * nfsrv_maxpnfsmirror, M_TEMP, M_WAITOK);
+ dsfhp = malloc(sizeof(fhandle_t) * NFSDEV_MAXMIRRORS, M_TEMP, M_WAITOK);
+ devid = malloc(NFSX_V4DEVICEID * NFSDEV_MAXMIRRORS, M_TEMP, M_WAITOK);
error = nfsrv_dsgetdevandfh(vp, p, &mirrorcnt, dsfhp, devid);
NFSD_DEBUG(4, "layoutget devandfh=%d\n", error);
if (error == 0) {
More information about the svn-src-projects
mailing list