summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsclient/nfs_clrpcops.c
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2014-05-06 12:15:05 +0000
committerrmacklem <rmacklem@FreeBSD.org>2014-05-06 12:15:05 +0000
commitcab8f4561e24d722e9e9b500434936a03a8c3ca7 (patch)
tree02b6fc32ec0bd40d82b0a35c3d073679eb48ec39 /sys/fs/nfsclient/nfs_clrpcops.c
parent941905ca5c3b6f7b8839045aac22a789ed5c8ba0 (diff)
downloadFreeBSD-src-cab8f4561e24d722e9e9b500434936a03a8c3ca7.zip
FreeBSD-src-cab8f4561e24d722e9e9b500434936a03a8c3ca7.tar.gz
MFC: r264672
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.
Diffstat (limited to 'sys/fs/nfsclient/nfs_clrpcops.c')
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c57
1 files changed, 32 insertions, 25 deletions
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