Modify the Lookup RPC for NFSv4 so that it acquires directory
attributes. This allows the client to cache directory names when they are looked up, reducing the Lookup RPC count by about 40% for software builds. MFC after: 2 weeks
This commit is contained in:
parent
b281166740
commit
f55eac8e60
@ -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 */
|
||||
|
@ -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 ||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user