LS(n) (((n)->nm_newflag & NFSMNT_TLS) != 0) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 0cdcde6cca28..0213534d9230 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -4995,11 +4995,13 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struct nfsfsinfo *fsp, uint32_t *leasep, uint32_t *cloneblksizep, struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp) { + struct nfsvattr na; + struct nfsv3_pathconf pc; u_int32_t *tl = NULL; struct nfsrv_descript nfsd, *nd = &nfsd; struct nfsmount *nmp; nfsattrbit_t attrbits; - int error; + int attrflag, error; *attrflagp = 0; if (cloneblksizep != NULL) @@ -5066,6 +5068,15 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struct nfsfsinfo *fsp, sbp->sf_bfree = fxdr_unsigned(u_int32_t, *tl++); sbp->sf_bavail = fxdr_unsigned(u_int32_t, *tl); } + + /* Try and find out if the server fs is case-insensitive. */ + error = nfsrpc_pathconf(vp, &pc, NULL, NULL, cred, p, &na, &attrflag); + if (error == 0 && pc.pc_caseinsensitive != 0) { + NFSLOCKMNT(nmp); + nmp->nm_state |= NFSSTA_CASEINSENSITIVE; + NFSUNLOCKMNT(nmp); + } + error = 0; nfsmout: m_freem(nd->nd_mrep); return (error); @@ -5086,9 +5097,11 @@ nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, bool *has_namedattrp, int error; struct nfsnode *np; - *has_namedattrp = false; + if (has_namedattrp != NULL) + *has_namedattrp = false; *attrflagp = 0; - *clone_blksizep = 0; + if (clone_blksizep != NULL) + *clone_blksizep = 0; nmp = VFSTONFS(vp->v_mount); if (NFSHASNFSV4(nmp)) { np = VTONFS(vp); diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 1bd77ab27ced..8e4d58c0e554 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1492,7 +1492,8 @@ handle_error: return (EJUSTRETURN); } - if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) { + if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag && + !NFSHASCASEINSENSITIVE(nmp)) { /* * Cache the modification time of the parent * directory from the post-op attributes in @@ -2205,6 +2206,14 @@ nfs_rename(struct vop_rename_args *ap) if ((error = NFSVOPLOCK(fvp, LK_EXCLUSIVE)) != 0) goto out; + /* + * For case insensitive file systems, there may be multiple + * names cached for the one name being rename'd, so purge + * all names from the cache. + */ + if (NFSHASCASEINSENSITIVE(nmp)) + cache_purge(fvp); + /* * We have to flush B_DELWRI data prior to renaming * the file. If we don't, the delayed-write buffers @@ -2221,6 +2230,7 @@ nfs_rename(struct vop_rename_args *ap) if ((nmp->nm_flag & NFSMNT_NOCTO) == 0 || !NFSHASNFSV4(nmp) || !NFSHASNFSV4N(nmp) || nfscl_mustflush(fvp) != 0) error = VOP_FSYNC(fvp, MNT_WAIT, curthread); + NFSVOPUNLOCK(fvp); if (error == 0 && tvp != NULL && ((nmp->nm_flag & NFSMNT_NOCTO) == 0 || !NFSHASNFSV4(nmp) || !NFSHASNFSV4N(nmp) ||