The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/ultrix/ultrix_fs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ultrix_fs.c,v 1.49 2008/05/06 18:43:44 ad Exp $        */
    2 
    3 /*
    4  * Copyright (c) 1995, 1997 Jonathan Stone
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Jonathan Stone for
   18  *      the NetBSD Project.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __KERNEL_RCSID(0, "$NetBSD: ultrix_fs.c,v 1.49 2008/05/06 18:43:44 ad Exp $");
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/malloc.h>
   41 #include <sys/exec.h>
   42 #include <sys/namei.h>
   43 #include <sys/mount.h>
   44 #include <sys/proc.h>
   45 #include <sys/vnode.h>
   46 #include <sys/vnode_if.h>
   47 #include <net/if.h>
   48 #include <netinet/in.h>
   49 
   50 #include <nfs/rpcv2.h>
   51 #include <nfs/nfsproto.h>
   52 #include <nfs/nfs.h>
   53 #include <nfs/nfsmount.h>
   54 
   55 #include <ufs/ufs/quota.h>
   56 #include <ufs/ufs/ufsmount.h>
   57 
   58 #include <sys/syscallargs.h>
   59 #include <compat/ultrix/ultrix_syscallargs.h>
   60 #include <compat/common/compat_util.h>
   61 #include <compat/sys/mount.h>
   62 
   63 #define ULTRIX_MAXPATHLEN       1024
   64 
   65 /**
   66  ** Ultrix filesystem operations: mount(), getmnt().
   67  ** These are included purely so one can place an (ECOFF or ELF)
   68  ** NetBSD/pmax kernel in an Ultrix root filesystem, boot it,
   69  ** and over-write the Ultrix root parition with NetBSD binaries.
   70  **/
   71 
   72 /*
   73  * Ultrix file system data structure, as modified by
   74  * Ultrix getmntent(). This  structure is padded to 2560 bytes, for
   75  * compatibility with the size the Ultrix kernel and user apps expect.
   76  */
   77 struct ultrix_fs_data {
   78         u_int32_t       ufsd_flags;     /* how mounted */
   79         u_int32_t       ufsd_mtsize;    /* max transfer size in bytes */
   80         u_int32_t       ufsd_otsize;    /* optimal transfer size in bytes */
   81         u_int32_t       ufsd_bsize;     /* fs block size (bytes) for vm code */
   82         u_int32_t       ufsd_fstype;    /* see ../h/fs_types.h  */
   83         u_int32_t       ufsd_gtot;      /* total number of gnodes */
   84         u_int32_t       ufsd_gfree;     /* # of free gnodes */
   85         u_int32_t       ufsd_btot;      /* total number of 1K blocks */
   86         u_int32_t       ufsd_bfree;     /* # of free 1K blocks */
   87         u_int32_t       ufsd_bfreen;    /* user consumable 1K blocks */
   88         u_int32_t       ufsd_pgthresh;  /* min size in bytes before paging*/
   89         int32_t         ufsd_uid;       /* uid that mounted me */
   90         int16_t         ufsd_dev;       /* major/minor of fs */
   91         int16_t         ufsd_exroot;    /* root mapping from exports */
   92         char            ufsd_devname[ULTRIX_MAXPATHLEN + 4]; /* name of dev */
   93         char            ufsd_path[ULTRIX_MAXPATHLEN + 4]; /* name of mnt point */
   94         u_int32_t       ufsd_nupdate;   /* number of writes */
   95         u_int32_t       ufsd_pad[112];  /* pad to 2560 bytes. */
   96 };
   97 
   98 /*
   99  * Get statistics on mounted filesystems.
  100  */
  101 #if 0
  102 struct ultrix_getmnt_args {
  103         int32_t *start;
  104         struct ultrix_fs_data *buf;
  105         int32_t bufsize;
  106         int32_t mode;
  107         char *path;
  108 };
  109 
  110 #endif
  111 /*
  112  * Ultrix getmnt() flags.
  113  * The operation getmnt() should perform is incoded in the flag
  114  * argument.  There are two independent attributes.
  115  *
  116  * ULTRIX_NOSTAT_xxx will never hang, but it may not return
  117  * up-to-date statistics. (For NFS clients, it returns whatever is
  118  * in the cache.) ULTRIX_STAT_xxx returns up-to-date info but may
  119  * hang (e.g., on dead NFS servers).
  120  *
  121  * ULTRIX_xxSTAT_ONE returns statistics on just one filesystem, determined
  122  * by the parth argument.  ULTRIX_xxSTAT_MANY ignores the path argument and
  123  * returns info on as many  filesystems fit in the structure.
  124  * the start argument, which should be zero on the first call,
  125  * can be used to iterate over all filesystems.
  126  *
  127  */
  128 #define ULTRIX_NOSTAT_MANY      1
  129 #define ULTRIX_STAT_MANY        2
  130 #define ULTRIX_STAT_ONE         3
  131 #define ULTRIX_NOSTAT_ONE       4
  132 
  133 /*
  134  * Ultrix gnode-layer  filesystem codes.
  135  */
  136 #define ULTRIX_FSTYPE_UNKNOWN   0x0
  137 #define ULTRIX_FSTYPE_ULTRIX    0x1     /*  Ultrix UFS: basically 4.2bsd FFS */
  138 #define ULTRIX_FSTYPE_NFS       0x5     /*  NFS v2 */
  139 
  140 /*
  141  * Ultrix mount(2) options
  142  */
  143 #define ULTRIX_NM_RONLY    0x0001  /* mount read-only */
  144 #define ULTRIX_NM_SOFT     0x0002  /* soft mount (hard is default) */
  145 #define ULTRIX_NM_WSIZE    0x0004  /* set write size */
  146 #define ULTRIX_NM_RSIZE    0x0008  /* set read size */
  147 #define ULTRIX_NM_TIMEO    0x0010  /* set initial timeout */
  148 #define ULTRIX_NM_RETRANS  0x0020  /* set number of request retrys */
  149 #define ULTRIX_NM_HOSTNAME 0x0040  /* set hostname for error printf */
  150 #define ULTRIX_NM_PGTHRESH 0x0080  /* set page threshold for exec */
  151 #define ULTRIX_NM_INT      0x0100  /* allow hard mount keyboard interrupts */
  152 #define ULTRIX_NM_NOAC     0x0200  /* don't cache attributes */
  153 
  154 
  155 static void
  156 make_ultrix_mntent(struct statvfs *, struct ultrix_fs_data *);
  157 
  158 /*
  159  * Construct an Ultrix getmnt() ultrix_fs_data from the native NetBSD
  160  * struct statfs.
  161  */
  162 static void
  163 make_ultrix_mntent(struct statvfs *sp, struct ultrix_fs_data *tem)
  164 {
  165 
  166         memset(tem, 0, sizeof (*tem));
  167 
  168         tem->ufsd_flags = sp->f_flag;           /* XXX translate */
  169         tem->ufsd_mtsize = sp->f_bsize;         /* XXX max transfer size */
  170         tem->ufsd_otsize = sp->f_iosize;
  171         tem->ufsd_bsize = sp->f_bsize;
  172         /*
  173          * Translate file system type. NetBSD/1.1 has f_type zero,
  174          * and uses an fstype string instead.
  175          * For now, map types not in Ultrix (kernfs, null, procfs...)
  176          * to UFS, since Ultrix mout will try and call mount_unknown
  177          * for ULTRIX_FSTYPE_UNKNOWN, but lacks a mount_unknown binary.
  178          */
  179         tem->ufsd_fstype = ULTRIX_FSTYPE_NFS;
  180         if (strcmp(sp->f_fstypename, "ffs") == 0)
  181                 tem->ufsd_fstype = ULTRIX_FSTYPE_ULTRIX;
  182 
  183         tem->ufsd_gtot = sp->f_files;           /* total "gnodes" */
  184         tem->ufsd_gfree = sp->f_ffree;          /* free "gnodes" */
  185         tem->ufsd_btot = sp->f_blocks;          /* total 1k blocks */
  186 #ifdef needsmorethought /* XXX */
  187         /* tem->ufsd_bfree = sp->f_bfree; */    /* free 1k blocks */
  188         /* tem->ufsd_bfree = sp->f_bavail; */   /* free 1k blocks */
  189 #endif
  190 
  191         tem->ufsd_bfreen = sp->f_bavail;        /* blocks available to users */
  192         tem->ufsd_pgthresh = 0;                 /* not relevant */
  193         tem->ufsd_uid = 0;                      /* XXX kept where ?*/
  194         tem->ufsd_dev = 0;                      /* ?? */
  195         tem->ufsd_exroot  = 0;                  /* ?? */
  196         strncpy(tem->ufsd_path, sp->f_mntonname, ULTRIX_MAXPATHLEN);
  197         strncpy(tem->ufsd_devname, sp->f_mntfromname, ULTRIX_MAXPATHLEN);
  198 #if 0
  199         /* In NetBSD-1.1, filesystem type is unused and always 0 */
  200         printf("mntent: %s type %d\n", tem->ufsd_devname, tem->ufsd_fstype);
  201         printf("mntent: %s tot %d free %d user%d\n",
  202          tem->ufsd_devname, sp->f_blocks, sp->f_bfree, sp->f_bavail);
  203 #endif
  204 }
  205 
  206 int
  207 ultrix_sys_getmnt(struct lwp *l, const struct ultrix_sys_getmnt_args *uap, register_t *retval)
  208 {
  209         struct mount *mp, *nmp;
  210         struct statvfs *sp;
  211         struct ultrix_fs_data *sfsp;
  212         char *path;
  213         int mntflags;
  214         int skip;
  215         int start;
  216         long count, maxcount;
  217         int error = 0;
  218 
  219         nmp = NULL;     /* XXX keep gcc quiet */
  220         path = NULL;
  221         error = 0;
  222         maxcount = SCARG(uap, bufsize) / sizeof(struct ultrix_fs_data);
  223         sfsp = SCARG(uap, buf);
  224 
  225         if (SCARG(uap, mode) == ULTRIX_STAT_ONE ||
  226             SCARG(uap, mode) == ULTRIX_STAT_MANY)
  227                 mntflags = MNT_WAIT;
  228         else
  229                 mntflags = MNT_NOWAIT;
  230 
  231         if (SCARG(uap, mode) == ULTRIX_STAT_ONE || SCARG(uap, mode) == ULTRIX_NOSTAT_ONE) {
  232                 /*
  233                  * Only get info on mountpoints that matches the path
  234                  * provided.
  235                  */
  236                 MALLOC(path, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
  237                 if ((error = copyinstr(SCARG(uap, path), path,
  238                                        MAXPATHLEN, NULL)) != 0)
  239                         goto bad;
  240                 maxcount = 1;
  241         } else {
  242                 /*
  243                  * Get info on any mountpoints, somewhat like readdir().
  244                  * Find out how many mount list entries to skip, and skip
  245                  * them.
  246                  */
  247                 if ((error = copyin((void *)SCARG(uap, start), &start,
  248                                     sizeof(*SCARG(uap, start))))  != 0)
  249                         goto bad;
  250                 mutex_enter(&mountlist_lock);
  251                 for (skip = start, mp = mountlist.cqh_first;
  252                     mp != (void*)&mountlist && skip-- > 0; mp = nmp)
  253                         nmp = mp->mnt_list.cqe_next;
  254                 mutex_exit(&mountlist_lock);
  255         }
  256 
  257         mutex_enter(&mountlist_lock);
  258         for (count = 0, mp = mountlist.cqh_first;
  259             mp != (void*)&mountlist && count < maxcount; mp = nmp) {
  260                 if (vfs_busy(mp, &nmp)) {
  261                         continue;
  262                 }
  263                 if (sfsp != NULL) {
  264                         struct ultrix_fs_data tem;
  265                         sp = &mp->mnt_stat;
  266 
  267                         /*
  268                          * If requested, refresh the fsstat cache.
  269                          */
  270                         if (mntflags != MNT_WAIT &&
  271                             (error = VFS_STATVFS(mp, sp)) != 0)
  272                                 continue;
  273 
  274                         /*
  275                          * XXX what does this do? -- cgd
  276                          */
  277                         sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
  278                         if (path == NULL ||
  279                             strcmp(path, sp->f_mntonname) == 0) {
  280                                 make_ultrix_mntent(sp, &tem);
  281                                 if ((error = copyout((void *)&tem, sfsp,
  282                                     sizeof(tem))) != 0) {
  283                                         vfs_unbusy(mp, false, NULL);
  284                                         goto bad;
  285                                 }
  286                                 sfsp++;
  287                                 count++;
  288                         }
  289                 }
  290                 vfs_unbusy(mp, false, &nmp);
  291         }
  292         mutex_exit(&mountlist_lock);
  293 
  294         if (sfsp != NULL && count > maxcount)
  295                 *retval = maxcount;
  296         else
  297                 *retval = count;
  298 
  299 bad:
  300         if (path)
  301                 FREE(path, M_TEMP);
  302         return error;
  303 }
  304 
  305 
  306 
  307 /* Old-style inet sockaddr (no len field) as passed to Ultrix mount(2) */
  308 struct osockaddr_in {
  309         short   sin_family;
  310         u_short sin_port;
  311         struct  in_addr sin_addr;
  312         char    sin_zero[8];
  313 };
  314 
  315 
  316 /*
  317  * fstype-dependent structure passed to Ultrix mount(2) when
  318  * mounting NFS filesystems
  319  */
  320 struct  ultrix_nfs_args {
  321         struct  osockaddr_in *addr;     /* file server address */
  322         void    *fh;                    /* file handle to be mounted */
  323         int     flags;                  /* flags */
  324         int     wsize;                  /* write size in bytes */
  325         int     rsize;                  /* read size in bytes */
  326         int     timeo;                  /* initial timeout in .1 secs */
  327         int     retrans;                /* times to retry send */
  328         char    *hostname;              /* server's hostname */
  329         char    *optstr;                /* string of nfs mount options*/
  330         int     gfs_flags;              /* gnode flags (ugh) */
  331         int     pg_thresh;              /* paging threshold ? */
  332 };
  333 
  334 
  335 /*
  336  * fstype-dependent structure passed to Ultrix mount(2) when
  337  * mounting local (4.2bsd FFS) filesystems
  338  */
  339 struct ultrix_ufs_args {
  340         u_long ufs_flags;               /* mount flags?*/
  341         u_long ufs_pgthresh;            /* minimum file size to page */
  342 };
  343 
  344 int
  345 ultrix_sys_mount(struct lwp *l, const struct ultrix_sys_mount_args *uap, register_t *retval)
  346 {
  347         int error;
  348         int otype = SCARG(uap, type);
  349         char fsname[MFSNAMELEN];
  350         register_t dummy;
  351         int nflags;
  352 
  353         nflags = 0;
  354 
  355         /*
  356          * Translate Ultrix integer mount codes for UFS and NFS to
  357          * NetBSD fstype strings.  Other Ultrix filesystem types
  358          *  (msdos, DEC ods-2) are not supported.
  359          */
  360 
  361         /* Translate the Ultrix mount-readonly option parameter */
  362         if (SCARG(uap, rdonly))
  363                 nflags |= MNT_RDONLY;
  364 
  365 
  366 #ifdef later
  367         parse ultrix mount option string and set NetBSD flags
  368 #endif
  369 
  370         if (otype == ULTRIX_FSTYPE_NFS) {
  371                 struct ultrix_nfs_args una;
  372                 struct nfs_args na;
  373 
  374                 if ((error = copyin(SCARG(uap, data), &una, sizeof(una))) != 0)
  375                         return error;
  376 #if 0
  377                 /*
  378                  * This is the only syscall boundary the
  379                  * address of the server passes, so do backwards
  380                  * compatibility on 4.3style sockaddrs here.
  381                  */
  382                 if ((error = copyin(una.addr, &osa, sizeof osa)) != 0) {
  383                         printf("ultrix_mount: nfs copyin osa\n");
  384                         return error;
  385                 }
  386                 sap->sin_family = (u_char)osa.sin_family;
  387                 sap->sin_len = sizeof(*sap);
  388                 /* XXXX teach nfs how to do the above */
  389 #endif
  390                 na.version = NFS_ARGSVERSION;
  391                 na.addr = (void *)una.addr;
  392                 na.addrlen = sizeof (struct sockaddr_in);
  393                 na.sotype = SOCK_DGRAM;
  394                 na.proto = IPPROTO_UDP;
  395                 na.fh = una.fh;
  396                 na.fhsize = NFSX_V2FH;
  397                 na.flags = /*una.flags;*/ NFSMNT_NOCONN | NFSMNT_RESVPORT;
  398                 na.wsize = una.wsize;
  399                 na.rsize = una.rsize;
  400                 na.timeo = una.timeo;
  401                 na.retrans = una.retrans;
  402                 na.hostname = una.hostname;
  403                 return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL,
  404                     SCARG(uap, special), nflags, &na, UIO_SYSSPACE,
  405                     sizeof na, &dummy);
  406         }
  407 
  408         /*
  409          * Translate fstype-dependent mount options from
  410          * Ultrix format to native.
  411          */
  412         if (otype == ULTRIX_FSTYPE_ULTRIX) {
  413                 /* attempt to mount a native, rather than 4.2bsd, ffs */
  414                 struct ufs_args ua;
  415 
  416                 memset(&ua, 0, sizeof(ua));
  417                 ua.fspec = SCARG(uap, special);
  418 
  419                 /*
  420                  * Ultrix mount has no MNT_UPDATE flag.
  421                  * Attempt to see if this is the root we're mounting,
  422                  * and if so, set MNT_UPDATE so we can mount / read-write.
  423                  */
  424                 fsname[0] = 0;
  425                 if ((error = copyinstr(SCARG(uap, dir), fsname,
  426                                       sizeof fsname, NULL)) != 0)
  427                         return(error);
  428                 if (strcmp(fsname, "/") == 0) {
  429                         nflags |= MNT_UPDATE;
  430                         printf("COMPAT_ULTRIX: mount with MNT_UPDATE on %s\n",
  431                             fsname);
  432                 }
  433                 return do_sys_mount(l, vfs_getopsbyname("ffs"), NULL,
  434                     SCARG(uap, dir), nflags, &ua, UIO_SYSSPACE, sizeof ua,
  435                     &dummy);
  436         }
  437 
  438         return EINVAL;
  439 }

Cache object: d6a9bfe7c0985787e1dfe8d3cd7085b1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.