summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2014-05-06 21:47:43 +0000
committerrmacklem <rmacklem@FreeBSD.org>2014-05-06 21:47:43 +0000
commit5809be0d871c26c91c40ed9a467bc81e8560ddaf (patch)
tree67d06e8d3f92b4bb767ae1429da39f07ef90a46e
parentacc2cc1958eac5d09263a090dffe8a3dca007da6 (diff)
downloadFreeBSD-src-5809be0d871c26c91c40ed9a467bc81e8560ddaf.zip
FreeBSD-src-5809be0d871c26c91c40ed9a467bc81e8560ddaf.tar.gz
MFC: r264681
Modify the NFSv4 client open/create RPC so that it acquires post-open/create directory attributes. This allows the RPC to name cache the newly created file and reduces the lookup RPC count by about 10% for software builds.
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c20
2 files changed, 17 insertions, 5 deletions
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index bc47172..db4f173 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -66,7 +66,7 @@ static struct {
{ NFSV4OP_READLINK, 2, "Readlink", 8, },
{ NFSV4OP_READ, 1, "Read", 4, },
{ NFSV4OP_WRITE, 2, "Write", 5, },
- { NFSV4OP_OPEN, 3, "Open", 4, },
+ { NFSV4OP_OPEN, 5, "Open", 4, },
{ NFSV4OP_CREATE, 3, "Create", 6, },
{ NFSV4OP_CREATE, 1, "Create", 6, },
{ NFSV4OP_CREATE, 3, "Create", 6, },
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index bd4025a..a691531 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -1956,6 +1956,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
struct nfsmount *nmp;
nmp = VFSTONFS(dvp->v_mount);
+ np = VTONFS(dvp);
*unlockedp = 0;
*nfhpp = NULL;
*dpp = NULL;
@@ -2005,17 +2006,22 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV4OPEN_CLAIMNULL);
(void) nfsm_strtom(nd, name, namelen);
+ /* Get the new file's handle and attributes. */
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV4OP_GETFH);
*tl = txdr_unsigned(NFSV4OP_GETATTR);
NFSGETATTR_ATTRBIT(&attrbits);
(void) nfsrv_putattrbit(nd, &attrbits);
+ /* Get the directory's post-op attributes. */
+ NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_PUTFH);
+ (void) nfsm_fhtom(nd, np->n_fhp->nfh_fh, np->n_fhp->nfh_len, 0);
+ NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_GETATTR);
+ (void) nfsrv_putattrbit(nd, &attrbits);
error = nfscl_request(nd, dvp, p, cred, dstuff);
if (error)
return (error);
- error = nfscl_wcc_data(nd, dvp, dnap, dattrflagp, NULL, dstuff);
- if (error)
- goto nfsmout;
NFSCL_INCRSEQID(owp->nfsow_seqid, nd);
if (nd->nd_repstat == 0) {
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID +
@@ -2087,6 +2093,13 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
error = nfscl_mtofh(nd, nfhpp, nnap, attrflagp);
if (error)
goto nfsmout;
+ /* Get rid of the PutFH and Getattr status values. */
+ NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
+ /* Load the directory attributes. */
+ error = nfsm_loadattr(nd, dnap);
+ if (error)
+ goto nfsmout;
+ *dattrflagp = 1;
if (dp != NULL && *attrflagp) {
dp->nfsdl_change = nnap->na_filerev;
dp->nfsdl_modtime = nnap->na_mtime;
@@ -2130,7 +2143,6 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
if ((rflags & NFSV4OPEN_RESULTCONFIRM) &&
(owp->nfsow_clp->nfsc_flags & NFSCLFLAGS_GOTDELEG) &&
!error && dp == NULL) {
- np = VTONFS(dvp);
do {
ret = nfsrpc_openrpc(VFSTONFS(vnode_mount(dvp)), dvp,
np->n_fhp->nfh_fh, np->n_fhp->nfh_len,
OpenPOWER on IntegriCloud