diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2014-05-06 21:47:43 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2014-05-06 21:47:43 +0000 |
commit | 5809be0d871c26c91c40ed9a467bc81e8560ddaf (patch) | |
tree | 67d06e8d3f92b4bb767ae1429da39f07ef90a46e | |
parent | acc2cc1958eac5d09263a090dffe8a3dca007da6 (diff) | |
download | FreeBSD-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.c | 2 | ||||
-rw-r--r-- | sys/fs/nfsclient/nfs_clrpcops.c | 20 |
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, |