aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/fuse/fuse_internal.c5
-rw-r--r--sys/fs/fuse/fuse_ipc.h1
-rw-r--r--sys/fs/fuse/fuse_vnops.c10
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c31
-rw-r--r--sys/fs/nfs/nfs_var.h4
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c2
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c3
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c16
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c18
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c9
10 files changed, 68 insertions, 31 deletions
diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c
index 61fe2ed032f6..eba0a8a79ff3 100644
--- a/sys/fs/fuse/fuse_internal.c
+++ b/sys/fs/fuse/fuse_internal.c
@@ -1063,6 +1063,8 @@ fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio)
if (!fuse_libabi_geq(data, 7, 28))
fsess_set_notimpl(data->mp, FUSE_COPY_FILE_RANGE);
+ if (fuse_libabi_geq(data, 7, 33) && (fiio->flags & FUSE_SETXATTR_EXT))
+ data->dataflags |= FSESS_SETXATTR_EXT;
out:
if (err) {
fdata_set_dead(data);
@@ -1115,7 +1117,8 @@ fuse_internal_send_init(struct fuse_data *data, struct thread *td)
*/
fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT
| FUSE_BIG_WRITES | FUSE_WRITEBACK_CACHE
- | FUSE_NO_OPEN_SUPPORT | FUSE_NO_OPENDIR_SUPPORT;
+ | FUSE_NO_OPEN_SUPPORT | FUSE_NO_OPENDIR_SUPPORT
+ | FUSE_SETXATTR_EXT;
fuse_insert_callback(fdi.tick, fuse_internal_init_callback);
fuse_insert_message(fdi.tick, false);
diff --git a/sys/fs/fuse/fuse_ipc.h b/sys/fs/fuse/fuse_ipc.h
index 3bfc859dbac9..d9d79f38c269 100644
--- a/sys/fs/fuse/fuse_ipc.h
+++ b/sys/fs/fuse/fuse_ipc.h
@@ -243,6 +243,7 @@ struct fuse_data {
#define FSESS_MNTOPTS_MASK ( \
FSESS_DAEMON_CAN_SPY | FSESS_PUSH_SYMLINKS_IN | \
FSESS_DEFAULT_PERMISSIONS | FSESS_INTR)
+#define FSESS_SETXATTR_EXT 0x8000000 /* extended fuse_setxattr_in */
extern int fuse_data_cache_mode;
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index 97aa23bfb0b0..ef5aee5de34c 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -625,7 +625,7 @@ fuse_vnop_allocate(struct vop_allocate_args *ap)
return (EROFS);
if (fsess_not_impl(mp, FUSE_FALLOCATE))
- return (EXTERROR(EINVAL, "This server does not implement "
+ return (EXTERROR(EOPNOTSUPP, "This server does not implement "
"FUSE_FALLOCATE"));
io.uio_offset = *offset;
@@ -656,14 +656,14 @@ fuse_vnop_allocate(struct vop_allocate_args *ap)
if (err == ENOSYS) {
fsess_set_notimpl(mp, FUSE_FALLOCATE);
- err = EXTERROR(EINVAL, "This server does not implement "
+ err = EXTERROR(EOPNOTSUPP, "This server does not implement "
"FUSE_ALLOCATE");
} else if (err == EOPNOTSUPP) {
/*
* The file system server does not support FUSE_FALLOCATE with
* the supplied mode for this particular file.
*/
- err = EXTERROR(EINVAL, "This file can't be pre-allocated");
+ err = EXTERROR(EOPNOTSUPP, "This file can't be pre-allocated");
} else if (!err) {
*offset += *len;
*len = 0;
@@ -2777,7 +2777,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
strlen(ap->a_name) + 1;
/* older FUSE servers use a smaller fuse_setxattr_in struct*/
- if (fuse_libabi_geq(fuse_get_mpdata(mp), 7, 33))
+ if (fuse_get_mpdata(mp)->dataflags & FSESS_SETXATTR_EXT)
struct_size = sizeof(*set_xattr_in);
fdisp_init(&fdi, len + struct_size + uio->uio_resid);
@@ -2786,7 +2786,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
set_xattr_in = fdi.indata;
set_xattr_in->size = uio->uio_resid;
- if (fuse_libabi_geq(fuse_get_mpdata(mp), 7, 33)) {
+ if (fuse_get_mpdata(mp)->dataflags & FSESS_SETXATTR_EXT) {
set_xattr_in->setxattr_flags = 0;
set_xattr_in->padding = 0;
}
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index f580a394a735..707ad5749ab2 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -658,7 +658,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap,
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL,
- false, false, false, 0);
+ false, false, false, 0, NULL, false);
break;
}
}
@@ -1706,11 +1706,18 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
attrsum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEINSENSITIVE:
- NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
if (compare) {
if (!(*retcmpp)) {
- if (*tl != newnfs_false)
- *retcmpp = NFSERR_NOTSAME;
+ if (vp == NULL || VOP_PATHCONF(vp,
+ _PC_CASE_INSENSITIVE,
+ &has_pathconf) != 0)
+ has_pathconf = 0;
+ if ((has_pathconf != 0 &&
+ *tl != newnfs_true) ||
+ (has_pathconf == 0 &&
+ *tl != newnfs_false))
+ *retcmpp = NFSERR_NOTSAME;
}
} else if (pc != NULL) {
pc->pc_caseinsensitive =
@@ -2690,7 +2697,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem,
- bool has_namedattr, uint32_t clone_blksize)
+ bool has_namedattr, uint32_t clone_blksize, fsid_t *fsidp,
+ bool has_caseinsensitive)
{
int bitpos, retnum = 0;
u_int32_t *tl;
@@ -2865,10 +2873,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
break;
case NFSATTRBIT_FSID:
NFSM_BUILD(tl, u_int32_t *, NFSX_V4FSID);
+ if (fsidp == NULL)
+ fsidp = &mp->mnt_stat.f_fsid;
*tl++ = 0;
- *tl++ = txdr_unsigned(mp->mnt_stat.f_fsid.val[0]);
+ *tl++ = txdr_unsigned(fsidp->val[0]);
*tl++ = 0;
- *tl = txdr_unsigned(mp->mnt_stat.f_fsid.val[1]);
+ *tl = txdr_unsigned(fsidp->val[1]);
retnum += NFSX_V4FSID;
break;
case NFSATTRBIT_UNIQUEHANDLES:
@@ -2914,8 +2924,11 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEINSENSITIVE:
- NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
- *tl = newnfs_false;
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ if (has_caseinsensitive)
+ *tl = newnfs_true;
+ else
+ *tl = newnfs_false;
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEPRESERVING:
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 16a76c060e78..7db3952ecf5c 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -398,7 +398,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
struct vattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *,
NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *, bool, bool,
- bool, uint32_t);
+ bool, uint32_t, fsid_t *, bool);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
struct mbuf *nfsrv_adj(struct mbuf *, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
@@ -740,7 +740,7 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *,
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool,
- bool, uint32_t);
+ bool, uint32_t, bool);
int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
NFSACL_T *, NFSPROC_T *);
int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index b61218958550..f5deef183efb 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -5452,7 +5452,7 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, aclp, NULL, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, false, false,
- false, 0);
+ false, 0, NULL, false);
error = nfscl_request(nd, vp, p, cred);
if (error)
return (error);
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index aa9d01fc4632..712d49c7160c 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3701,7 +3701,8 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
if (!error)
(void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va,
NULL, 0, &rattrbits, NULL, p, 0, 0, 0, 0,
- (uint64_t)0, NULL, false, false, false, 0);
+ (uint64_t)0, NULL, false, false, false, 0,
+ NULL, false);
break;
case NFSV4OP_CBRECALL:
NFSCL_DEBUG(4, "cbrecall\n");
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index f80cf30669ca..193d8b6cd5eb 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3896,11 +3896,15 @@ nfs_allocate(struct vop_allocate_args *ap)
mtx_lock(&nmp->nm_mtx);
nmp->nm_privflag |= NFSMNTP_NOALLOCATE;
mtx_unlock(&nmp->nm_mtx);
- error = EINVAL;
+ error = EOPNOTSUPP;
}
} else {
+ /*
+ * Pre-v4.2 NFS server that doesn't support it, or a newer
+ * NFS server that has indicated that it doesn't support it.
+ */
mtx_unlock(&nmp->nm_mtx);
- error = EINVAL;
+ error = EOPNOTSUPP;
}
if (attrflag != 0) {
ret = nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
@@ -4677,12 +4681,13 @@ nfs_pathconf(struct vop_pathconf_args *ap)
clone_blksize = 0;
if ((NFS_ISV34(vp) && (ap->a_name == _PC_LINK_MAX ||
ap->a_name == _PC_NAME_MAX || ap->a_name == _PC_CHOWN_RESTRICTED ||
- ap->a_name == _PC_NO_TRUNC)) ||
+ ap->a_name == _PC_NO_TRUNC ||
+ ap->a_name == _PC_CASE_INSENSITIVE)) ||
(NFS_ISV4(vp) && (ap->a_name == _PC_ACL_NFS4 ||
ap->a_name == _PC_HAS_NAMEDATTR ||
ap->a_name == _PC_CLONE_BLKSIZE))) {
/*
- * Since only the above 4 a_names are returned by the NFSv3
+ * Since only the above 5 a_names are returned by the NFSv3
* Pathconf RPC, there is no point in doing it for others.
* For NFSv4, the Pathconf RPC (actually a Getattr Op.) can
* be used for _PC_ACL_NFS4, _PC_HAS_NAMEDATTR and
@@ -4849,6 +4854,9 @@ nfs_pathconf(struct vop_pathconf_args *ap)
case _PC_CLONE_BLKSIZE:
*ap->a_retval = clone_blksize;
break;
+ case _PC_CASE_INSENSITIVE:
+ *ap->a_retval = pc.pc_caseinsensitive;
+ break;
default:
error = vop_stdpathconf(ap);
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 9fe3f4426124..841ec2315f1c 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2114,7 +2114,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
struct ucred *cred, struct thread *p, int isdgram, int reterr,
int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
bool xattrsupp, bool has_hiddensystem, bool has_namedattr,
- uint32_t clone_blksize)
+ uint32_t clone_blksize, bool has_caseinsensitive)
{
struct statfs *sf;
int error;
@@ -2135,7 +2135,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
mounted_on_fileno, sf, xattrsupp, has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, NULL, has_caseinsensitive);
free(sf, M_TEMP);
NFSEXITCODE2(0, nd);
return (error);
@@ -2468,7 +2468,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
int bextpg0, bextpg1, bextpgsiz0, bextpgsiz1;
size_t atsiz;
long pathval;
- bool has_hiddensystem, has_namedattr, xattrsupp;
+ bool has_caseinsensitive, has_hiddensystem, has_namedattr, xattrsupp;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
@@ -2949,6 +2949,7 @@ ateof:
xattrsupp = false;
has_hiddensystem = false;
has_namedattr = false;
+ has_caseinsensitive = false;
clone_blksize = 0;
if (nvp != NULL) {
supports_nfsv4acls =
@@ -2978,6 +2979,11 @@ ateof:
&pathval) != 0)
pathval = 0;
clone_blksize = pathval;
+ if (VOP_PATHCONF(nvp,
+ _PC_CASE_INSENSITIVE,
+ &pathval) != 0)
+ pathval = 0;
+ has_caseinsensitive = pathval > 0;
NFSVOPUNLOCK(nvp);
} else
supports_nfsv4acls = 0;
@@ -2999,7 +3005,7 @@ ateof:
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, has_caseinsensitive);
} else {
dirlen += nfsvno_fillattr(nd, new_mp,
nvp, nvap, &nfh, r, &attrbits,
@@ -3007,7 +3013,7 @@ ateof:
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, has_caseinsensitive);
}
if (nvp != NULL)
vrele(nvp);
@@ -6405,7 +6411,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
* the same type (VREG).
*/
nfsv4_fillattr(nd, NULL, vp, aclp, NULL, NULL, 0, &attrbits, NULL,
- NULL, 0, 0, 0, 0, 0, NULL, false, false, false, 0);
+ NULL, 0, 0, 0, 0, 0, NULL, false, false, false, 0, NULL, false);
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
if (error != 0) {
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index 67af0cf71175..394b63c2ab07 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -252,7 +252,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
struct thread *p = curthread;
size_t atsiz;
long pathval;
- bool has_hiddensystem, has_namedattr, xattrsupp;
+ bool has_caseinsensitive, has_hiddensystem, has_namedattr, xattrsupp;
uint32_t clone_blksize;
if (nd->nd_repstat)
@@ -336,6 +336,10 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
&pathval) != 0)
pathval = 0;
clone_blksize = pathval;
+ if (VOP_PATHCONF(vp, _PC_CASE_INSENSITIVE,
+ &pathval) != 0)
+ pathval = 0;
+ has_caseinsensitive = pathval > 0;
mp = vp->v_mount;
if (nfsrv_enable_crossmntpt != 0 &&
vp->v_type == VDIR &&
@@ -371,7 +375,8 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
isdgram, 1, supports_nfsv4acls,
at_root, mounted_on_fileno,
xattrsupp, has_hiddensystem,
- has_namedattr, clone_blksize);
+ has_namedattr, clone_blksize,
+ has_caseinsensitive);
vfs_unbusy(mp);
}
vrele(vp);