[BACK]Return to ultrix_fs.c CVS log [TXT][DIR] Up to [local] / sys / compat / ultrix

Annotation of sys/compat/ultrix/ultrix_fs.c, Revision 1.1.1.1

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

CVSweb