svn commit: r333179 - projects/pnfs-planb-server/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Wed May 2 20:10:28 UTC 2018
Author: rmacklem
Date: Wed May 2 20:10:27 2018
New Revision: 333179
URL: https://svnweb.freebsd.org/changeset/base/333179
Log:
Add some diagnostics and fix up layout recall in a few ways:
- Increment the layout's stateid.seqid as required by the RFC.
- Fix the locking, moving one lock up and using the correct lock in another
place.
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 Wed May 2 20:04:31 2018 (r333178)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Wed May 2 20:10:27 2018 (r333179)
@@ -4392,9 +4392,11 @@ errout:
if (clp->lc_flags & LCL_CBDOWN)
clp->lc_flags &= ~(LCL_CBDOWN | LCL_CALLBACKSON);
NFSUNLOCKSTATE();
- if (nd->nd_repstat)
+ if (nd->nd_repstat) {
error = nd->nd_repstat;
- else if (error == 0 && procnum == NFSV4OP_CBGETATTR)
+ NFSD_DEBUG(1, "nfsrv_docallback op=%d err=%d\n",
+ procnum, error);
+ } else if (error == 0 && procnum == NFSV4OP_CBGETATTR)
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL,
p, NULL);
@@ -6592,6 +6594,12 @@ nfsrv_flexmirrordel(char *devid, NFSPROC_T *p)
/* Now, try to do a Layout recall for each one found. */
LIST_FOREACH_SAFE(lyp, &loclyp, lay_list, nlyp) {
NFSD_DEBUG(4, "do layout recall\n");
+ /*
+ * The layout stateid.seqid needs to be incremented
+ * before doing a LAYOUT_RECALL callback.
+ */
+ if (++lyp->lay_stateid.seqid == 0)
+ lyp->lay_stateid.seqid = 1;
nfsrv_recalllayout(lyp, p);
nfsrv_freelayout(lyp);
}
@@ -6612,10 +6620,18 @@ nfsrv_recalllayout(struct nfslayout *lyp, NFSPROC_T *p
NFSD_DEBUG(4, "aft nfsrv_getclient=%d\n", error);
if (error != 0)
return;
- if ((clp->lc_flags & LCL_NFSV41) != 0)
- nfsrv_docallback(clp, NFSV4OP_CBLAYOUTRECALL, NULL, 0, NULL,
- NULL, NULL, lyp, p);
- else
+ if ((clp->lc_flags & LCL_NFSV41) != 0) {
+ error = nfsrv_docallback(clp, NFSV4OP_CBLAYOUTRECALL, NULL, 0,
+ NULL, NULL, NULL, lyp, p);
+ if (error == NFSERR_NOMATCHLAYOUT) {
+ NFSDRECALLLOCK();
+ if ((lyp->lay_flags & NFSLAY_RECALL) != 0) {
+ lyp->lay_flags |= NFSLAY_RETURNED;
+ wakeup(lyp);
+ }
+ NFSDRECALLUNLOCK();
+ }
+ } else
printf("nfsrv_recalllayout: clp not NFSv4.1\n");
}
@@ -6645,10 +6661,14 @@ nfsrv_layoutreturn(struct nfsrv_descript *nd, vnode_t
}
if (error == 0) {
lhyp = NFSLAYOUTHASH(&fh);
+ NFSDRECALLLOCK();
NFSLOCKLAYOUT(lhyp);
error = nfsrv_findlayout(nd, &fh, layouttype, p, &lyp);
NFSD_DEBUG(4, "layoutret findlay=%d\n", error);
- if (error == 0) {
+ if (error == 0 &&
+ stateidp->other[0] == lyp->lay_stateid.other[0] &&
+ stateidp->other[1] == lyp->lay_stateid.other[1] &&
+ stateidp->other[2] == lyp->lay_stateid.other[2]) {
NFSD_DEBUG(4, "nfsrv_layoutreturn: stateid %d"
" %x %x %x laystateid %d %x %x %x"
" off=%ju len=%ju flgs=0x%x\n",
@@ -6660,15 +6680,6 @@ nfsrv_layoutreturn(struct nfsrv_descript *nd, vnode_t
lyp->lay_stateid.other[2],
(uintmax_t)offset, (uintmax_t)len,
lyp->lay_flags);
- if (stateidp->other[0] !=
- lyp->lay_stateid.other[0] ||
- stateidp->other[1] !=
- lyp->lay_stateid.other[1] ||
- stateidp->other[2] !=
- lyp->lay_stateid.other[2])
- error = NFSERR_BADSTATEID;
- }
- if (error == 0) {
if (++lyp->lay_stateid.seqid == 0)
lyp->lay_stateid.seqid = 1;
stateidp->seqid = lyp->lay_stateid.seqid;
@@ -6685,23 +6696,18 @@ nfsrv_layoutreturn(struct nfsrv_descript *nd, vnode_t
}
}
NFSUNLOCKLAYOUT(lhyp);
- if (error != 0) {
- /* Search the nfsrv_recalllist for a match. */
- NFSDDSLOCK();
- LIST_FOREACH(lyp, &nfsrv_recalllisthead,
- lay_list) {
- if (NFSBCMP(&lyp->lay_fh, &fh,
- sizeof(fh)) == 0 &&
- lyp->lay_clientid.qval ==
- nd->nd_clientid.qval) {
- lyp->lay_flags |=
- NFSLAY_RETURNED;
- wakeup(lyp);
- error = 0;
- }
+ /* Search the nfsrv_recalllist for a match. */
+ LIST_FOREACH(lyp, &nfsrv_recalllisthead, lay_list) {
+ if (NFSBCMP(&lyp->lay_fh, &fh,
+ sizeof(fh)) == 0 &&
+ lyp->lay_clientid.qval ==
+ nd->nd_clientid.qval) {
+ lyp->lay_flags |= NFSLAY_RETURNED;
+ wakeup(lyp);
+ error = 0;
}
- NFSDDSUNLOCK();
}
+ NFSDRECALLUNLOCK();
}
if (layouttype == NFSLAYOUT_FLEXFILE)
nfsrv_flexlayouterr(nd, layp, maxcnt, p);
@@ -7602,7 +7608,7 @@ nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, str
off_t rdpos, wrpos;
ssize_t aresid;
char *dat;
- int ret, retacl, xfer;
+ int didprintf, ret, retacl, xfer;
ASSERT_VOP_LOCKED(fvp, "nfsrv_copymr fvp");
ASSERT_VOP_LOCKED(vp, "nfsrv_copymr vp");
@@ -7639,7 +7645,7 @@ nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, str
/*
* Search for all RW layouts for this file. Move them to the
- * recall list, so they can be recalled and their return noted.
+ * recall list, so they can be recalled and their return noted.
*/
lhyp = NFSLAYOUTHASH(&fh);
NFSDRECALLLOCK();
@@ -7655,6 +7661,7 @@ nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, str
NFSDRECALLUNLOCK();
ret = 0;
+ didprintf = 0;
LIST_INIT(&thl);
/* Unlock the MDS vp, so that a LayoutReturn can be done on it. */
NFSVOPUNLOCK(vp, 0);
@@ -7665,6 +7672,12 @@ tryagain:
if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0 &&
(lyp->lay_flags & NFSLAY_RECALL) == 0) {
lyp->lay_flags |= NFSLAY_RECALL;
+ /*
+ * The layout stateid.seqid needs to be incremented
+ * before doing a LAYOUT_RECALL callback.
+ */
+ if (++lyp->lay_stateid.seqid == 0)
+ lyp->lay_stateid.seqid = 1;
NFSDRECALLUNLOCK();
nfsrv_recalllayout(lyp, p);
NFSD_DEBUG(4, "nfsrv_copymr: recalled layout\n");
@@ -7683,11 +7696,17 @@ tryagain2:
"nfsrv_copymr: layout returned\n");
} else {
ret = mtx_sleep(lyp, NFSDRECALLMUTEXPTR,
- PVFS | PCATCH, "nfsmrl", 0);
+ PVFS | PCATCH, "nfsmrl", hz);
NFSD_DEBUG(4, "nfsrv_copymr: aft sleep=%d\n",
ret);
if (ret == EINTR || ret == ERESTART)
break;
+ if ((lyp->lay_flags & NFSLAY_RETURNED) == 0 &&
+ didprintf == 0) {
+ printf("nfsrv_copymr: layout not "
+ "returned\n");
+ didprintf = 1;
+ }
}
goto tryagain2;
}
More information about the svn-src-projects
mailing list