BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / amd / amd / nfs_ops.c
index 2e3a2ad..b9df9a6 100644 (file)
@@ -1,6 +1,4 @@
 /*
 /*
- * $Id: nfs_ops.c,v 5.2 90/06/23 22:19:45 jsp Rel $
- *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  * Copyright (c) 1990 The Regents of the University of California.
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  * Copyright (c) 1990 The Regents of the University of California.
@@ -9,21 +7,38 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)nfs_ops.c   5.3 (Berkeley) 5/12/91
+ *
+ * $Id: nfs_ops.c,v 5.2.1.6 91/05/07 22:18:16 jsp Alpha $
  *
  *
- *     @(#)nfs_ops.c   5.1 (Berkeley) 6/29/90
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -172,7 +187,7 @@ fserver *fs;
 {
        fh_cache *fp;
        ITER(fp, fh_cache, &fh_head) {
 {
        fh_cache *fp;
        ITER(fp, fh_cache, &fh_head) {
-               if (fp->fh_fs == fs) {
+               if (fp->fh_fs == fs || fs == 0) {
                        fp->fh_sin.sin_port = (u_short) 0;
                        fp->fh_error = -1;
                }
                        fp->fh_sin.sin_port = (u_short) 0;
                        fp->fh_error = -1;
                }
@@ -319,6 +334,25 @@ voidp wchan;
        return error;
 }
 
        return error;
 }
 
+int make_nfs_auth P((void))
+{
+#ifdef HAS_NFS_QUALIFIED_NAMES
+       /*
+        * From: Chris Metcalf <metcalf@masala.lcs.mit.edu>
+        * Use hostd, not just hostname.  Note that uids
+        * and gids and the gidlist are type *int* and not the
+        * system uid_t and gid_t types.
+        */
+       static int group_wheel = 0;
+       nfs_auth = authunix_create(hostd, 0, 0, 1, &group_wheel);
+#else
+       nfs_auth = authunix_create_default();
+#endif
+       if (!nfs_auth)
+               return ENOBUFS;
+       return 0;
+}
+
 static int call_mountd P((fh_cache *fp, u_long proc, fwd_fun f, voidp wchan));
 static int call_mountd(fp, proc, f, wchan)
 fh_cache *fp;
 static int call_mountd P((fh_cache *fp, u_long proc, fwd_fun f, voidp wchan));
 static int call_mountd(fp, proc, f, wchan)
 fh_cache *fp;
@@ -332,9 +366,9 @@ voidp wchan;
        int error;
 
        if (!nfs_auth) {
        int error;
 
        if (!nfs_auth) {
-               nfs_auth = authunix_create_default();
-               if (!nfs_auth)
-                       return ENOBUFS;
+               error = make_nfs_auth();
+               if (error)
+                       return error;
        }
 
        if (fp->fh_sin.sin_port == 0) {
        }
 
        if (fp->fh_sin.sin_port == 0) {
@@ -365,9 +399,10 @@ voidp wchan;
  * remote hostname.
  * Local filesystem defaults to remote and vice-versa.
  */
  * remote hostname.
  * Local filesystem defaults to remote and vice-versa.
  */
-static int nfs_match(fo)
+static char *nfs_match(fo)
 am_opts *fo;
 {
 am_opts *fo;
 {
+       char *xmtab;
        if (fo->opt_fs && !fo->opt_rfs)
                fo->opt_rfs = fo->opt_fs;
        if (!fo->opt_rfs) {
        if (fo->opt_fs && !fo->opt_rfs)
                fo->opt_rfs = fo->opt_fs;
        if (!fo->opt_rfs) {
@@ -381,15 +416,14 @@ am_opts *fo;
        /*
         * Determine magic cookie to put in mtab
         */
        /*
         * Determine magic cookie to put in mtab
         */
-       fo->fs_mtab = (char *) xrealloc(fo->fs_mtab, strlen(fo->opt_rhost) +
-                               strlen(fo->opt_rfs) + 2);
-       sprintf(fo->fs_mtab, "%s:%s", fo->opt_rhost, fo->opt_rfs);
+       xmtab = (char *) xmalloc(strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2);
+       sprintf(xmtab, "%s:%s", fo->opt_rhost, fo->opt_rfs);
 #ifdef DEBUG
        dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
                fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
 #endif /* DEBUG */
 
 #ifdef DEBUG
        dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
                fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
 #endif /* DEBUG */
 
-       return TRUE;
+       return xmtab;
 }
 
 /*
 }
 
 /*
@@ -398,17 +432,27 @@ am_opts *fo;
 static int nfs_init(mf)
 mntfs *mf;
 {
 static int nfs_init(mf)
 mntfs *mf;
 {
-       int error;
-       char *colon = strchr(mf->mf_info, ':');
-       if (colon == 0)
-               return ENOENT;
-
-       error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, (struct fhstatus *) 0, (voidp) mf);
+       if (!mf->mf_private) {
+               int error;
+               struct fhstatus fhs;
+       
+               char *colon = strchr(mf->mf_info, ':');
+               if (colon == 0)
+                       return ENOENT;
+
+               error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) mf);
+               if (!error) {
+                       mf->mf_private = (voidp) ALLOC(fhstatus);
+                       mf->mf_prfree = (void (*)()) free;
+                       bcopy((voidp) &fhs, mf->mf_private, sizeof(fhs));
+               }
+               return error;
+       }
 
 
-       return error;
+       return 0;
 }
 
 }
 
-mount_nfs_fh(fhp, dir, fs_name, opts, mf)
+int mount_nfs_fh(fhp, dir, fs_name, opts, mf)
 struct fhstatus *fhp;
 char *dir;
 char *fs_name;
 struct fhstatus *fhp;
 char *dir;
 char *fs_name;
@@ -419,7 +463,7 @@ mntfs *mf;
        struct mntent mnt;
        int retry;
        char *colon;
        struct mntent mnt;
        int retry;
        char *colon;
-       char *path;
+       /*char *path;*/
        char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
        fserver *fs = mf->mf_server;
        int flags;
        char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
        fserver *fs = mf->mf_server;
        int flags;
@@ -443,7 +487,7 @@ mntfs *mf;
 #ifndef NFS_ARGS_NEEDS_PATH
        *colon = ':';
 #endif /* NFS_ARGS_NEEDS_PATH */
 #ifndef NFS_ARGS_NEEDS_PATH
        *colon = ':';
 #endif /* NFS_ARGS_NEEDS_PATH */
-       path = colon + 1;
+       /*path = colon + 1;*/
 
        bzero((voidp) &nfs_args, sizeof(nfs_args));
 
 
        bzero((voidp) &nfs_args, sizeof(nfs_args));
 
@@ -511,6 +555,16 @@ mntfs *mf;
        if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL)
                nfs_args.flags |= NFSMNT_SOFT;
 
        if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL)
                nfs_args.flags |= NFSMNT_SOFT;
 
+#ifdef NFSMNT_SPONGY
+       if (hasmntopt(&mnt, "spongy") != NULL) {
+               nfs_args.flags |= NFSMNT_SPONGY;
+               if (nfs_args.flags & NFSMNT_SOFT) {
+                       plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored");
+                       nfs_args.flags &= ~NFSMNT_SOFT;
+               }
+       }
+#endif /* MNTOPT_SPONGY */
+
 #ifdef MNTOPT_INTR
        if (hasmntopt(&mnt, MNTOPT_INTR) != NULL)
                nfs_args.flags |= NFSMNT_INT;
 #ifdef MNTOPT_INTR
        if (hasmntopt(&mnt, MNTOPT_INTR) != NULL)
                nfs_args.flags |= NFSMNT_INT;
@@ -521,6 +575,16 @@ mntfs *mf;
                nfs_args.flags |= NFSMNT_NODEVS;
 #endif /* MNTOPT_NODEVS */
 
                nfs_args.flags |= NFSMNT_NODEVS;
 #endif /* MNTOPT_NODEVS */
 
+#ifdef MNTOPT_COMPRESS
+       if (hasmntopt(&mnt, "compress") != NULL)
+               nfs_args.flags |= NFSMNT_COMPRESS;
+#endif /* MNTOPT_COMPRESS */
+
+#ifdef MNTOPT_NOCONN
+       if (hasmntopt(&mnt, "noconn") != NULL)
+               nfs_args.flags |= NFSMNT_NOCONN;
+#endif /* MNTOPT_NOCONN */
+
 #ifdef NFSMNT_PGTHRESH
        if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh"))
                nfs_args.flags |= NFSMNT_PGTHRESH;
 #ifdef NFSMNT_PGTHRESH
        if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh"))
                nfs_args.flags |= NFSMNT_PGTHRESH;
@@ -530,6 +594,11 @@ mntfs *mf;
 
        flags = compute_mount_flags(&mnt);
 
 
        flags = compute_mount_flags(&mnt);
 
+#ifdef NFSMNT_NOCTO
+       if (hasmntopt(&mnt, "nocto") != NULL)
+               nfs_args.flags |= NFSMNT_NOCTO;
+#endif /* NFSMNT_NOCTO */
+
 #ifdef HAS_TCP_NFS
        if (hasmntopt(&mnt, "tcp") != NULL)
                nfs_args.sotype = SOCK_STREAM;
 #ifdef HAS_TCP_NFS
        if (hasmntopt(&mnt, "tcp") != NULL)
                nfs_args.sotype = SOCK_STREAM;
@@ -556,12 +625,13 @@ mntfs *mf;
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
-static mount_nfs(dir, fs_name, opts, mf)
+static int mount_nfs(dir, fs_name, opts, mf)
 char *dir;
 char *fs_name;
 char *opts;
 mntfs *mf;
 {
 char *dir;
 char *fs_name;
 char *opts;
 mntfs *mf;
 {
+#ifdef notdef
        int error;
        struct fhstatus fhs;
        char *colon;
        int error;
        struct fhstatus fhs;
        char *colon;
@@ -578,15 +648,21 @@ mntfs *mf;
                return error;
 
        return mount_nfs_fh(&fhs, dir, fs_name, opts, mf);
                return error;
 
        return mount_nfs_fh(&fhs, dir, fs_name, opts, mf);
+#endif
+       if (!mf->mf_private) {
+               plog(XLOG_ERROR, "Missing filehandle for %s", fs_name);
+               return EINVAL;
+       }
+
+       return mount_nfs_fh((struct fhstatus *) mf->mf_private, dir, fs_name, opts, mf);
 }
 
 }
 
-static int nfs_mount(mp)
-am_node *mp;
+static int nfs_fmount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
+       int error;
 
 
-       int error = mount_nfs(mf->mf_mount, mf->mf_info,
-                       mf->mf_fo->opt_opts, mf);
+       error = mount_nfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, mf);
 
 #ifdef DEBUG
        if (error) {
 
 #ifdef DEBUG
        if (error) {
@@ -597,11 +673,9 @@ am_node *mp;
        return error;
 }
 
        return error;
 }
 
-static int nfs_umount(mp)
-am_node *mp;
+static int nfs_fumount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        int error = UMOUNT_FS(mf->mf_mount);
        if (error)
                return error;
        int error = UMOUNT_FS(mf->mf_mount);
        if (error)
                return error;
@@ -666,8 +740,10 @@ am_ops nfs_ops = {
        "nfs",
        nfs_match,
        nfs_init,
        "nfs",
        nfs_match,
        nfs_init,
-       nfs_mount,
-       nfs_umount,
+       auto_fmount,
+       nfs_fmount,
+       auto_fumount,
+       nfs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* nfs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* nfs_readlink */