summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsserver')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdcache.c19
-rw-r--r--sys/fs/nfsserver/nfs_nfsdkrpc.c37
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c30
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c12
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c8
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c18
6 files changed, 81 insertions, 43 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdcache.c b/sys/fs/nfsserver/nfs_nfsdcache.c
index bcffd6c..fc513a3 100644
--- a/sys/fs/nfsserver/nfs_nfsdcache.c
+++ b/sys/fs/nfsserver/nfs_nfsdcache.c
@@ -405,6 +405,7 @@ nfsrvd_updatecache(struct nfsrv_descript *nd, struct socket *so)
{
struct nfsrvcache *rp;
struct nfsrvcache *retrp = NULL;
+ mbuf_t m;
rp = nd->nd_rp;
if (!rp)
@@ -457,9 +458,9 @@ nfsrvd_updatecache(struct nfsrv_descript *nd, struct socket *so)
}
if ((nd->nd_flag & ND_NFSV2) &&
nfsv2_repstat[newnfsv2_procid[nd->nd_procnum]]) {
- NFSUNLOCKCACHE();
rp->rc_status = nd->nd_repstat;
rp->rc_flag |= RC_REPSTATUS;
+ NFSUNLOCKCACHE();
} else {
if (!(rp->rc_flag & RC_UDP)) {
nfsrc_tcpsavedreplies++;
@@ -469,9 +470,11 @@ nfsrvd_updatecache(struct nfsrv_descript *nd, struct socket *so)
nfsrc_tcpsavedreplies;
}
NFSUNLOCKCACHE();
- rp->rc_reply = m_copym(nd->nd_mreq, 0, M_COPYALL,
- M_WAIT);
+ m = m_copym(nd->nd_mreq, 0, M_COPYALL, M_WAIT);
+ NFSLOCKCACHE();
+ rp->rc_reply = m;
rp->rc_flag |= RC_REPMBUF;
+ NFSUNLOCKCACHE();
}
if (rp->rc_flag & RC_UDP) {
rp->rc_timestamp = NFSD_MONOSEC +
@@ -518,6 +521,7 @@ nfsrvd_delcache(struct nfsrvcache *rp)
APPLESTATIC void
nfsrvd_sentcache(struct nfsrvcache *rp, struct socket *so, int err)
{
+ tcp_seq tmp_seq;
if (!(rp->rc_flag & RC_LOCKED))
panic("nfsrvd_sentcache not locked");
@@ -526,8 +530,12 @@ nfsrvd_sentcache(struct nfsrvcache *rp, struct socket *so, int err)
so->so_proto->pr_domain->dom_family != AF_INET6) ||
so->so_proto->pr_protocol != IPPROTO_TCP)
panic("nfs sent cache");
- if (nfsrv_getsockseqnum(so, &rp->rc_tcpseq))
+ if (nfsrv_getsockseqnum(so, &tmp_seq)) {
+ NFSLOCKCACHE();
+ rp->rc_tcpseq = tmp_seq;
rp->rc_flag |= RC_TCPSEQ;
+ NFSUNLOCKCACHE();
+ }
}
nfsrc_unlock(rp);
}
@@ -687,8 +695,11 @@ nfsrc_lock(struct nfsrvcache *rp)
static void
nfsrc_unlock(struct nfsrvcache *rp)
{
+
+ NFSLOCKCACHE();
rp->rc_flag &= ~RC_LOCKED;
nfsrc_wanted(rp);
+ NFSUNLOCKCACHE();
}
/*
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index 8ce70fa..2484919 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -386,18 +386,14 @@ nfsrvd_addsock(struct file *fp)
int
nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
{
-#ifdef KGSSAPI
char principal[MAXHOSTNAMELEN + 5];
int error;
bool_t ret2, ret3, ret4;
-#endif
-#ifdef KGSSAPI
error = copyinstr(args->principal, principal, sizeof (principal),
NULL);
if (error)
return (error);
-#endif
/*
* Only the first nfsd actually does any work. The RPC code
@@ -412,38 +408,29 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
NFSD_UNLOCK();
-#ifdef KGSSAPI
/* An empty string implies AUTH_SYS only. */
if (principal[0] != '\0') {
- ret2 = rpc_gss_set_svc_name(principal, "kerberosv5",
- GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
- ret3 = rpc_gss_set_svc_name(principal, "kerberosv5",
- GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
- ret4 = rpc_gss_set_svc_name(principal, "kerberosv5",
- GSS_C_INDEFINITE, NFS_PROG, NFS_VER4);
-
- if (!ret2 || !ret3 || !ret4) {
- NFSD_LOCK();
- newnfs_numnfsd--;
- nfsrvd_init(1);
- NFSD_UNLOCK();
- return (EAUTH);
- }
+ ret2 = rpc_gss_set_svc_name_call(principal,
+ "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
+ ret3 = rpc_gss_set_svc_name_call(principal,
+ "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
+ ret4 = rpc_gss_set_svc_name_call(principal,
+ "kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER4);
+
+ if (!ret2 || !ret3 || !ret4)
+ printf("nfsd: can't register svc name\n");
}
-#endif
nfsrvd_pool->sp_minthreads = args->minthreads;
nfsrvd_pool->sp_maxthreads = args->maxthreads;
svc_run(nfsrvd_pool);
-#ifdef KGSSAPI
if (principal[0] != '\0') {
- rpc_gss_clear_svc_name(NFS_PROG, NFS_VER2);
- rpc_gss_clear_svc_name(NFS_PROG, NFS_VER3);
- rpc_gss_clear_svc_name(NFS_PROG, NFS_VER4);
+ rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2);
+ rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3);
+ rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER4);
}
-#endif
NFSD_LOCK();
newnfs_numnfsd--;
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index d62be99..5b96729 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2592,6 +2592,36 @@ nfsvno_pathconf(struct vnode *vp, int flag, register_t *retf,
int error;
error = VOP_PATHCONF(vp, flag, retf);
+ if (error == EOPNOTSUPP || error == EINVAL) {
+ /*
+ * Some file systems return EINVAL for name arguments not
+ * supported and some return EOPNOTSUPP for this case.
+ * So the NFSv3 Pathconf RPC doesn't fail for these cases,
+ * just fake them.
+ */
+ switch (flag) {
+ case _PC_LINK_MAX:
+ *retf = LINK_MAX;
+ break;
+ case _PC_NAME_MAX:
+ *retf = NAME_MAX;
+ break;
+ case _PC_CHOWN_RESTRICTED:
+ *retf = 1;
+ break;
+ case _PC_NO_TRUNC:
+ *retf = 1;
+ break;
+ default:
+ /*
+ * Only happens if a _PC_xxx is added to the server,
+ * but this isn't updated.
+ */
+ *retf = 0;
+ printf("nfsrvd pathconf flag=%d not supp\n", flag);
+ };
+ error = 0;
+ }
return (error);
}
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index ee55031..fc296c0 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -454,7 +454,7 @@ nfsmout:
APPLESTATIC int
nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram,
vnode_t dp, vnode_t *vpp, fhandle_t *fhp, NFSPROC_T *p,
- __unused struct nfsexstuff *exp)
+ struct nfsexstuff *exp)
{
struct nameidata named;
vnode_t vp, dirp = NULL;
@@ -508,7 +508,15 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram,
vrele(named.ni_startdir);
nfsvno_relpathbuf(&named);
vp = named.ni_vp;
- nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
+ if ((nd->nd_flag & ND_NFSV4) != 0 && !NFSVNO_EXPORTED(exp) &&
+ vp->v_type != VDIR && vp->v_type != VLNK)
+ /*
+ * Only allow lookup of VDIR and VLNK for traversal of
+ * non-exported volumes during NFSv4 mounting.
+ */
+ nd->nd_repstat = ENOENT;
+ if (nd->nd_repstat == 0)
+ nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
if (vpp != NULL && nd->nd_repstat == 0)
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index eeecded..33be284 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -525,10 +525,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
NFSLOCKV4ROOTMUTEX();
if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
else
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
if (igotlock) {
/*
@@ -576,7 +576,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
*/
NFSLOCKV4ROOTMUTEX();
nfsv4_getref(&nfsv4rootfs_lock, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
}
@@ -786,6 +786,8 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
op != NFSV4OP_LOOKUP &&
op != NFSV4OP_GETATTR &&
op != NFSV4OP_GETFH &&
+ op != NFSV4OP_ACCESS &&
+ op != NFSV4OP_READLINK &&
op != NFSV4OP_SECINFO)
nd->nd_repstat = NFSERR_NOFILEHANDLE;
else if (nfsvno_testexp(nd, &vpnes) &&
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index ab94f0e..fc84d72 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -169,7 +169,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
@@ -419,7 +419,7 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
} else if (opflags != CLOPS_RENEW) {
@@ -548,7 +548,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
NFSLOCKV4ROOTMUTEX();
do {
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!igotlock);
NFSUNLOCKV4ROOTMUTEX();
@@ -608,7 +608,7 @@ nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt)
* exclusive lock cannot be acquired while dumping the clients.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
NFSLOCKSTATE();
/*
@@ -709,7 +709,7 @@ nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt,
* exclusive lock on it cannot be acquired while dumping the locks.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
NFSLOCKSTATE();
if (!ret)
@@ -4254,7 +4254,7 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp,
nfsv4_relref(&nfsv4rootfs_lock);
do {
gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
@@ -4422,7 +4422,7 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
nfsv4_relref(&nfsv4rootfs_lock);
do {
gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
- NFSV4ROOTLOCKMUTEXPTR);
+ NFSV4ROOTLOCKMUTEXPTR, NULL);
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
@@ -4616,7 +4616,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
* exclusive lock cannot be acquired by another thread.
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR);
+ nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
NFSUNLOCKV4ROOTMUTEX();
/*
@@ -5179,7 +5179,7 @@ nfsrv_locklf(struct nfslockfile *lfp)
lfp->lf_usecount++;
do {
gotlock = nfsv4_lock(&lfp->lf_locallock_lck, 1, NULL,
- NFSSTATEMUTEXPTR);
+ NFSSTATEMUTEXPTR, NULL);
} while (gotlock == 0);
lfp->lf_usecount--;
}
OpenPOWER on IntegriCloud