Mercurial > illumos > illumos-gate
changeset 10276:f3e12ac807fa
6833526 4-way hang in the NFSv4 client
author | Pavel Filipensky <Pavel.Filipensky@Sun.COM> |
---|---|
date | Fri, 07 Aug 2009 10:48:38 +0100 |
parents | f0b35eb34c31 |
children | 8c0d8d983f7d |
files | usr/src/uts/common/fs/nfs/nfs4_client.c usr/src/uts/common/fs/nfs/nfs4_vnops.c usr/src/uts/common/nfs/nfs4_clnt.h |
diffstat | 3 files changed, 14 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/nfs/nfs4_client.c Fri Aug 07 15:32:17 2009 +0800 +++ b/usr/src/uts/common/fs/nfs/nfs4_client.c Fri Aug 07 10:48:38 2009 +0100 @@ -106,7 +106,6 @@ static int nfs4renew(nfs4_server_t *); static void nfs4_attrcache_va(vnode_t *, nfs4_ga_res_t *, int); static void nfs4_pgflush_thread(pgflush_t *); -static void flush_pages(vnode_t *, cred_t *); static boolean_t nfs4_client_cpr_callb(void *, int); @@ -302,7 +301,7 @@ if (nfs4_has_pages(vp) && !pgflush) { if (!asyncpg) { (void) nfs4_waitfor_purge_complete(vp); - flush_pages(vp, cr); + nfs4_flush_pages(vp, cr); } else { pgflush_t *args; @@ -343,8 +342,8 @@ * ones. */ -static void -flush_pages(vnode_t *vp, cred_t *cr) +void +nfs4_flush_pages(vnode_t *vp, cred_t *cr) { int error; rnode4_t *rp = VTOR4(vp); @@ -373,7 +372,7 @@ rp->r_pgflush = curthread; mutex_exit(&rp->r_statelock); - flush_pages(args->vp, args->cr); + nfs4_flush_pages(args->vp, args->cr); mutex_enter(&rp->r_statelock); rp->r_pgflush = NULL;
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c Fri Aug 07 15:32:17 2009 +0800 +++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c Fri Aug 07 10:48:38 2009 +0100 @@ -13994,6 +13994,7 @@ rnode4_t *rp = VTOR4(vp); int error = *errorp; nfs_argop4 *argop; + int do_flush_pages = 0; ASSERT(nfs_zone() == mi->mi_zone); /* @@ -14018,22 +14019,11 @@ * work since VOP_PUTPAGE can call nfs4_commit which calls * nfs4_start_fop. We flush the pages below after calling * nfs4_end_fop above - */ - if (!error && resp && resp->status == NFS4_OK) { - int error; - - error = VOP_PUTPAGE(vp, (u_offset_t)0, - 0, B_INVAL, cred, NULL); - - if (error && (error == ENOSPC || error == EDQUOT)) { - rnode4_t *rp = VTOR4(vp); - - mutex_enter(&rp->r_statelock); - if (!rp->r_error) - rp->r_error = error; - mutex_exit(&rp->r_statelock); - } - } + * The flush of the page cache must be done after + * nfs4_end_open_seqid_sync() to avoid a 4-way hang. + */ + if (!error && resp && resp->status == NFS4_OK) + do_flush_pages = 1; } if (argsp) { ASSERT(argsp->array_len == 2); @@ -14063,6 +14053,9 @@ open_owner_rele(oop); } + if (do_flush_pages) + nfs4_flush_pages(vp, cred); + (void) convoff(vp, flk, whence, offset); lm_rel_sysid(ls);
--- a/usr/src/uts/common/nfs/nfs4_clnt.h Fri Aug 07 15:32:17 2009 +0800 +++ b/usr/src/uts/common/nfs/nfs4_clnt.h Fri Aug 07 10:48:38 2009 +0100 @@ -1461,6 +1461,7 @@ extern void nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *); extern void nfs4_purge_caches(vnode_t *, int, cred_t *, int); extern void nfs4_purge_stale_fh(int, vnode_t *, cred_t *); +extern void nfs4_flush_pages(vnode_t *vp, cred_t *cr); extern void nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *); extern void nfs4_update_paths(vnode_t *, char *, vnode_t *, char *,