aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nfs/nfsport.h2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c19
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c12
3 files changed, 29 insertions, 4 deletions
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 4e9aae70da6f..f6b6cfb22908 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -1040,6 +1040,7 @@ void ncl_copy_vattr(struct vnode *vp, struct vattr *dst, struct vattr *src);
#define NFSSTA_HASWRITEVERF 0x00040000 /* Has write verifier */
#define NFSSTA_GOTFSINFO 0x00100000 /* Got the fsinfo */
#define NFSSTA_OPENMODE 0x00200000 /* Must use correct open mode */
+#define NFSSTA_CASEINSENSITIVE 0x00400000 /* Case insensitive fs */
#define NFSSTA_FLEXFILE 0x00800000 /* Use Flex File Layout */
#define NFSSTA_NOLAYOUTCOMMIT 0x04000000 /* Don't do LayoutCommit */
#define NFSSTA_SESSPERSIST 0x08000000 /* Has a persistent session */
@@ -1073,6 +1074,7 @@ void ncl_copy_vattr(struct vnode *vp, struct vattr *dst, struct vattr *src);
#define NFSHASPNFS(n) ((n)->nm_state & NFSSTA_PNFS)
#define NFSHASFLEXFILE(n) ((n)->nm_state & NFSSTA_FLEXFILE)
#define NFSHASOPENMODE(n) ((n)->nm_state & NFSSTA_OPENMODE)
+#define NFSHASCASEINSENSITIVE(n) ((n)->nm_state & NFSSTA_CASEINSENSITIVE)
#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
(n)->nm_minorvers > 0)
#define NFSHASTLS(n) (((n)->nm_newflag & NFSMNT_TLS) != 0)
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 9bdc2b776575..a0423ab23111 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 7ecd1619a0ad..0d54b869d74c 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
@@ -2206,6 +2207,14 @@ nfs_rename(struct vop_rename_args *ap)
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
* can be flushed out later after the file has gone stale
@@ -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) ||