summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c4
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c13
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c57
3 files changed, 45 insertions, 29 deletions
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 11833438..76ee9e2 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -101,8 +101,8 @@ struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS] = {
{ 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lock */
{ 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* LockT */
{ 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* LockU */
- { 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookup */
- { 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookupp */
+ { 1, 2, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookup */
+ { 1, 2, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookupp */
{ 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* NVerify */
{ 1, 1, 0, 1, LK_EXCLUSIVE, 1 }, /* Open */
{ 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* OpenAttr */
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index 52dcaad..bc47172 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -219,9 +219,18 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
procnum != NFSPROC_COMMITDS) {
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV4OP_GETATTR);
- NFSWCCATTR_ATTRBIT(&attrbits);
+ /*
+ * For Lookup Ops, we want all the directory
+ * attributes, so we can load the name cache.
+ */
+ if (procnum == NFSPROC_LOOKUP ||
+ procnum == NFSPROC_LOOKUPP)
+ NFSGETATTR_ATTRBIT(&attrbits);
+ else {
+ NFSWCCATTR_ATTRBIT(&attrbits);
+ nd->nd_flag |= ND_V4WCCATTR;
+ }
(void) nfsrv_putattrbit(nd, &attrbits);
- nd->nd_flag |= ND_V4WCCATTR;
}
}
if (procnum != NFSPROC_RENEW ||
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index a89b907..bd4025a 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -1238,14 +1238,23 @@ nfsrpc_lookup(vnode_t dvp, char *name, int len, struct ucred *cred,
}
if (nd->nd_flag & ND_NFSV3)
error = nfscl_postop_attr(nd, dnap, dattrflagp, stuff);
+ else if ((nd->nd_flag & (ND_NFSV4 | ND_NOMOREDATA)) ==
+ ND_NFSV4) {
+ /* Load the directory attributes. */
+ error = nfsm_loadattr(nd, dnap);
+ if (error == 0)
+ *dattrflagp = 1;
+ }
goto nfsmout;
}
if ((nd->nd_flag & (ND_NFSV4 | ND_NOMOREDATA)) == ND_NFSV4) {
- NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- if (*(tl + 1)) {
- nd->nd_flag |= ND_NOMOREDATA;
+ /* Load the directory attributes. */
+ error = nfsm_loadattr(nd, dnap);
+ if (error != 0)
goto nfsmout;
- }
+ *dattrflagp = 1;
+ /* Skip over the Lookup and GetFH operation status values. */
+ NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
}
error = nfsm_getfh(nd, nfhpp);
if (error)
@@ -2702,14 +2711,6 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
* Joy, oh joy. For V4 we get to hand craft '.' and '..'.
*/
if (uiop->uio_offset == 0) {
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
- error = VOP_GETATTR(vp, &nfsva.na_vattr, cred);
-#else
- error = VOP_GETATTR(vp, &nfsva.na_vattr, cred, p);
-#endif
- if (error)
- return (error);
- dotfileid = nfsva.na_fileid;
NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV4OP_GETFH);
@@ -2718,9 +2719,16 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
error = nfscl_request(nd, vp, p, cred, stuff);
if (error)
return (error);
+ dotfileid = 0; /* Fake out the compiler. */
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0) {
+ error = nfsm_loadattr(nd, &nfsva);
+ if (error != 0)
+ goto nfsmout;
+ dotfileid = nfsva.na_fileid;
+ }
if (nd->nd_repstat == 0) {
- NFSM_DISSECT(tl, u_int32_t *, 3*NFSX_UNSIGNED);
- len = fxdr_unsigned(int, *(tl + 2));
+ NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
+ len = fxdr_unsigned(int, *(tl + 4));
if (len > 0 && len <= NFSX_V4FHMAX)
error = nfsm_advance(nd, NFSM_RNDUP(len), -1);
else
@@ -3129,15 +3137,6 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
* Joy, oh joy. For V4 we get to hand craft '.' and '..'.
*/
if (uiop->uio_offset == 0) {
-#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
- error = VOP_GETATTR(vp, &nfsva.na_vattr, cred);
-#else
- error = VOP_GETATTR(vp, &nfsva.na_vattr, cred, p);
-#endif
- if (error)
- return (error);
- dctime = nfsva.na_ctime;
- dotfileid = nfsva.na_fileid;
NFSCL_REQSTART(nd, NFSPROC_LOOKUPP, vp);
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV4OP_GETFH);
@@ -3146,9 +3145,17 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
error = nfscl_request(nd, vp, p, cred, stuff);
if (error)
return (error);
+ dotfileid = 0; /* Fake out the compiler. */
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0) {
+ error = nfsm_loadattr(nd, &nfsva);
+ if (error != 0)
+ goto nfsmout;
+ dctime = nfsva.na_ctime;
+ dotfileid = nfsva.na_fileid;
+ }
if (nd->nd_repstat == 0) {
- NFSM_DISSECT(tl, u_int32_t *, 3*NFSX_UNSIGNED);
- len = fxdr_unsigned(int, *(tl + 2));
+ NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
+ len = fxdr_unsigned(int, *(tl + 4));
if (len > 0 && len <= NFSX_V4FHMAX)
error = nfsm_advance(nd, NFSM_RNDUP(len), -1);
else
OpenPOWER on IntegriCloud