summaryrefslogtreecommitdiffstats
path: root/sys/nfs
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-05-31 19:49:31 +0000
committerpeter <peter@FreeBSD.org>1998-05-31 19:49:31 +0000
commit401c250cc40de5fcfc5f53856a8194793ba32667 (patch)
tree77292b0fb6150895d044dedafa84184c95243d2e /sys/nfs
parent5080277e0ee6d3017bdd8ac4e416ccef13a15697 (diff)
downloadFreeBSD-src-401c250cc40de5fcfc5f53856a8194793ba32667.zip
FreeBSD-src-401c250cc40de5fcfc5f53856a8194793ba32667.tar.gz
Support 'mount -u' remounts. This may require disconnecting and rebinding
the socket. Certain mode changes are not allowed. Obtained from: NetBSD
Diffstat (limited to 'sys/nfs')
-rw-r--r--sys/nfs/nfs.h3
-rw-r--r--sys/nfs/nfs_socket.c15
-rw-r--r--sys/nfs/nfs_vfsops.c260
3 files changed, 174 insertions, 104 deletions
diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h
index ec0d530..a9fa37e 100644
--- a/sys/nfs/nfs.h
+++ b/sys/nfs/nfs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.37 1998/05/31 17:27:45 peter Exp $
+ * $Id: nfs.h,v 1.38 1998/05/31 17:48:03 peter Exp $
*/
#ifndef _NFS_NFS_H_
@@ -639,6 +639,7 @@ void nfsrv_updatecache __P((struct nfsrv_descript *, int, struct mbuf *));
void nfsrv_cleancache __P((void));
int nfs_connect __P((struct nfsmount *, struct nfsreq *));
void nfs_disconnect __P((struct nfsmount *));
+void nfs_safedisconnect __P((struct nfsmount *));
int nfs_getattrcache __P((struct vnode *, struct vattr *));
int nfsm_strtmbuf __P((struct mbuf **, char **, const char *, long));
int nfs_bioread __P((struct vnode *, struct uio *, int, struct ucred *,
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c
index 45f2b61..8fcefeb 100644
--- a/sys/nfs/nfs_socket.c
+++ b/sys/nfs/nfs_socket.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_socket.c,v 1.37 1998/05/31 18:06:07 peter Exp $
+ * $Id: nfs_socket.c,v 1.38 1998/05/31 18:08:09 peter Exp $
*/
/*
@@ -371,6 +371,19 @@ nfs_disconnect(nmp)
}
}
+void
+nfs_safedisconnect(nmp)
+ struct nfsmount *nmp;
+{
+ struct nfsreq dummyreq;
+
+ bzero(&dummyreq, sizeof(dummyreq));
+ dummyreq.r_nmp = nmp;
+ nfs_rcvlock(&dummyreq);
+ nfs_disconnect(nmp);
+ nfs_rcvunlock(&nmp->nm_flag, &nmp->nm_state);
+}
+
/*
* This is the nfs send routine. For connection based socket types, it
* must be called with an nfs_sndlock() on the socket.
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index 167e6c9..d7bb8e2 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
- * $Id: nfs_vfsops.c,v 1.66 1998/05/31 18:19:43 peter Exp $
+ * $Id: nfs_vfsops.c,v 1.67 1998/05/31 19:20:44 peter Exp $
*/
#include <sys/param.h>
@@ -93,6 +93,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, "");
#endif
static int nfs_iosize __P((struct nfsmount *nmp));
+static void nfs_decode_args __P((struct nfsmount *nmp,
+ struct nfs_args *argp));
static int mountnfs __P((struct nfs_args *,struct mount *,
struct sockaddr *,char *,char *,struct vnode **));
static int nfs_mount __P(( struct mount *mp, char *path, caddr_t data,
@@ -589,6 +591,142 @@ nfs_mountdiskless(path, which, mountflag, sin, args, p, vpp, mpp)
return (0);
}
+static void
+nfs_decode_args(nmp, argp)
+ struct nfsmount *nmp;
+ struct nfs_args *argp;
+{
+ int s;
+ int adjsock;
+ int maxio;
+
+ s = splnet();
+ /*
+ * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
+ * no sense in that context.
+ */
+ if (argp->sotype == SOCK_STREAM)
+ nmp->nm_flag &= ~NFSMNT_NOCONN;
+
+ /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
+ if ((argp->flags & NFSMNT_NFSV3) == 0)
+ nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
+
+ /* Re-bind if rsrvd port requested and wasn't on one */
+ adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
+ && (argp->flags & NFSMNT_RESVPORT);
+ /* Also re-bind if we're switching to/from a connected UDP socket */
+ adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
+ (argp->flags & NFSMNT_NOCONN));
+
+ /* Update flags atomically. Don't change the lock bits. */
+ nmp->nm_flag = argp->flags | nmp->nm_flag;
+ splx(s);
+
+ if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
+ nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
+ if (nmp->nm_timeo < NFS_MINTIMEO)
+ nmp->nm_timeo = NFS_MINTIMEO;
+ else if (nmp->nm_timeo > NFS_MAXTIMEO)
+ nmp->nm_timeo = NFS_MAXTIMEO;
+ }
+
+ if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
+ nmp->nm_retry = argp->retrans;
+ if (nmp->nm_retry > NFS_MAXREXMIT)
+ nmp->nm_retry = NFS_MAXREXMIT;
+ }
+
+ if (argp->flags & NFSMNT_NFSV3) {
+ if (argp->sotype == SOCK_DGRAM)
+ maxio = NFS_MAXDGRAMDATA;
+ else
+ maxio = NFS_MAXDATA;
+ } else
+ maxio = NFS_V2MAXDATA;
+
+ if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
+ nmp->nm_wsize = argp->wsize;
+ /* Round down to multiple of blocksize */
+ nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
+ if (nmp->nm_wsize <= 0)
+ nmp->nm_wsize = NFS_FABLKSIZE;
+ }
+ if (nmp->nm_wsize > maxio)
+ nmp->nm_wsize = maxio;
+ if (nmp->nm_wsize > MAXBSIZE)
+ nmp->nm_wsize = MAXBSIZE;
+
+ if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
+ nmp->nm_rsize = argp->rsize;
+ /* Round down to multiple of blocksize */
+ nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
+ if (nmp->nm_rsize <= 0)
+ nmp->nm_rsize = NFS_FABLKSIZE;
+ }
+ if (nmp->nm_rsize > maxio)
+ nmp->nm_rsize = maxio;
+ if (nmp->nm_rsize > MAXBSIZE)
+ nmp->nm_rsize = MAXBSIZE;
+
+ if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
+ nmp->nm_readdirsize = argp->readdirsize;
+ }
+ if (nmp->nm_readdirsize > maxio)
+ nmp->nm_readdirsize = maxio;
+ if (nmp->nm_readdirsize > nmp->nm_rsize)
+ nmp->nm_readdirsize = nmp->nm_rsize;
+
+ if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
+ nmp->nm_acregmin = argp->acregmin;
+ else
+ nmp->nm_acregmin = NFS_MINATTRTIMO;
+ if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
+ nmp->nm_acregmax = argp->acregmax;
+ else
+ nmp->nm_acregmax = NFS_MAXATTRTIMO;
+ if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
+ nmp->nm_acdirmin = argp->acdirmin;
+ else
+ nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
+ if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
+ nmp->nm_acdirmax = argp->acdirmax;
+ else
+ nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
+ if (nmp->nm_acdirmin > nmp->nm_acdirmax)
+ nmp->nm_acdirmin = nmp->nm_acdirmax;
+ if (nmp->nm_acregmin > nmp->nm_acregmax)
+ nmp->nm_acregmin = nmp->nm_acregmax;
+
+ if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&
+ argp->maxgrouplist <= NFS_MAXGRPS)
+ nmp->nm_numgrps = argp->maxgrouplist;
+ if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 &&
+ argp->readahead <= NFS_MAXRAHEAD)
+ nmp->nm_readahead = argp->readahead;
+ if ((argp->flags & NFSMNT_LEASETERM) && argp->leaseterm >= 2 &&
+ argp->leaseterm <= NQ_MAXLEASE)
+ nmp->nm_leaseterm = argp->leaseterm;
+ if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 1 &&
+ argp->deadthresh <= NQ_NEVERDEAD)
+ nmp->nm_deadthresh = argp->deadthresh;
+
+ adjsock |= ((nmp->nm_sotype != argp->sotype) ||
+ (nmp->nm_soproto != argp->proto));
+ nmp->nm_sotype = argp->sotype;
+ nmp->nm_soproto = argp->proto;
+
+ if (nmp->nm_so && adjsock) {
+ nfs_safedisconnect(nmp);
+ if (nmp->nm_sotype == SOCK_DGRAM)
+ while (nfs_connect(nmp, (struct nfsreq *)0)) {
+ printf("nfs_args: retrying connect\n");
+ (void) tsleep((caddr_t)&lbolt,
+ PSOCK, "nfscon", 0);
+ }
+ }
+}
+
/*
* VFS Operations.
*
@@ -638,6 +776,22 @@ nfs_mount(mp, path, data, ndp, p)
return (EPROGMISMATCH);
#endif /* !NO_COMPAT_PRELITE2 */
}
+ if (mp->mnt_flag & MNT_UPDATE) {
+ register struct nfsmount *nmp = VFSTONFS(mp);
+
+ if (nmp == NULL)
+ return (EIO);
+ /*
+ * When doing an update, we can't change from or to
+ * v3 and/or nqnfs, or change cookie translation
+ */
+ args.flags = (args.flags &
+ ~(NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)) |
+ (nmp->nm_flag &
+ (NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/));
+ nfs_decode_args(nmp, &args);
+ return (0);
+ }
error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize);
if (error)
return (error);
@@ -688,8 +842,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
- nmp->nm_flag = argp->flags;
- if (nmp->nm_flag & NFSMNT_NQNFS)
+ if (argp->flags & NFSMNT_NQNFS)
/*
* We have to set mnt_maxsymlink to a non-zero value so
* that COMPAT_43 routines will know that we are setting
@@ -721,109 +874,12 @@ mountnfs(argp, mp, nam, pth, hst, vpp)
bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);
nmp->nm_nam = nam;
-
- /*
- * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
- * no sense in that context.
- */
- if (argp->sotype == SOCK_STREAM)
- nmp->nm_flag &= ~NFSMNT_NOCONN;
-
- /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
- if ((argp->flags & NFSMNT_NFSV3) == 0)
- nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
-
- if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
- nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
- if (nmp->nm_timeo < NFS_MINTIMEO)
- nmp->nm_timeo = NFS_MINTIMEO;
- else if (nmp->nm_timeo > NFS_MAXTIMEO)
- nmp->nm_timeo = NFS_MAXTIMEO;
- }
-
- if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
- nmp->nm_retry = argp->retrans;
- if (nmp->nm_retry > NFS_MAXREXMIT)
- nmp->nm_retry = NFS_MAXREXMIT;
- }
-
- if (argp->flags & NFSMNT_NFSV3) {
- if (argp->sotype == SOCK_DGRAM)
- maxio = NFS_MAXDGRAMDATA;
- else
- maxio = NFS_MAXDATA;
- } else
- maxio = NFS_V2MAXDATA;
-
- if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
- nmp->nm_wsize = argp->wsize;
- /* Round down to multiple of blocksize */
- nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_wsize <= 0)
- nmp->nm_wsize = NFS_FABLKSIZE;
- }
- if (nmp->nm_wsize > maxio)
- nmp->nm_wsize = maxio;
- if (nmp->nm_wsize > MAXBSIZE)
- nmp->nm_wsize = MAXBSIZE;
-
- if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
- nmp->nm_rsize = argp->rsize;
- /* Round down to multiple of blocksize */
- nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_rsize <= 0)
- nmp->nm_rsize = NFS_FABLKSIZE;
- }
- if (nmp->nm_rsize > maxio)
- nmp->nm_rsize = maxio;
- if (nmp->nm_rsize > MAXBSIZE)
- nmp->nm_rsize = MAXBSIZE;
-
- if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
- nmp->nm_readdirsize = argp->readdirsize;
- }
- if (nmp->nm_readdirsize > maxio)
- nmp->nm_readdirsize = maxio;
- if (nmp->nm_readdirsize > nmp->nm_rsize)
- nmp->nm_readdirsize = nmp->nm_rsize;
-
- if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
- nmp->nm_acregmin = argp->acregmin;
- else
- nmp->nm_acregmin = NFS_MINATTRTIMO;
- if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
- nmp->nm_acregmax = argp->acregmax;
- else
- nmp->nm_acregmax = NFS_MAXATTRTIMO;
- if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
- nmp->nm_acdirmin = argp->acdirmin;
- else
- nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
- if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
- nmp->nm_acdirmax = argp->acdirmax;
- else
- nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
- if (nmp->nm_acdirmin > nmp->nm_acdirmax)
- nmp->nm_acdirmin = nmp->nm_acdirmax;
- if (nmp->nm_acregmin > nmp->nm_acregmax)
- nmp->nm_acregmin = nmp->nm_acregmax;
-
- if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&
- argp->maxgrouplist <= NFS_MAXGRPS)
- nmp->nm_numgrps = argp->maxgrouplist;
- if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 &&
- argp->readahead <= NFS_MAXRAHEAD)
- nmp->nm_readahead = argp->readahead;
- if ((argp->flags & NFSMNT_LEASETERM) && argp->leaseterm >= 2 &&
- argp->leaseterm <= NQ_MAXLEASE)
- nmp->nm_leaseterm = argp->leaseterm;
- if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 1 &&
- argp->deadthresh <= NQ_NEVERDEAD)
- nmp->nm_deadthresh = argp->deadthresh;
/* Set up the sockets and per-host congestion */
nmp->nm_sotype = argp->sotype;
nmp->nm_soproto = argp->proto;
+ nfs_decode_args(nmp, argp);
+
/*
* For Connection based sockets (TCP,...) defer the connect until
* the first request, in case the server is not responding.
OpenPOWER on IntegriCloud