Home | History | Annotate | Line # | Download | only in ultrix
ultrix_fs.c revision 1.1
      1  1.1  jonathan /*	$NetBSD: ultrix_fs.c,v 1.1 1995/12/26 04:44:37 jonathan Exp $	*/
      2  1.1  jonathan 
      3  1.1  jonathan /*
      4  1.1  jonathan  * Copyright (c) 1995
      5  1.1  jonathan  *	Jonathan Stone (hereinafter referred to as the author)
      6  1.1  jonathan  *
      7  1.1  jonathan  * Redistribution and use in source and binary forms, with or without
      8  1.1  jonathan  * modification, are permitted provided that the following conditions
      9  1.1  jonathan  * are met:
     10  1.1  jonathan  * 1. Redistributions of source code must retain the above copyright
     11  1.1  jonathan  *    notice, this list of conditions and the following disclaimer.
     12  1.1  jonathan  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jonathan  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  jonathan  *    documentation and/or other materials provided with the distribution.
     15  1.1  jonathan  * 3. The name of the author may not be used to endorse or promote products
     16  1.1  jonathan  *    derived from this software without specific prior written permission.
     17  1.1  jonathan  *
     18  1.1  jonathan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
     19  1.1  jonathan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  1.1  jonathan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  1.1  jonathan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
     22  1.1  jonathan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  1.1  jonathan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  1.1  jonathan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  1.1  jonathan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  1.1  jonathan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  1.1  jonathan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  1.1  jonathan  * SUCH DAMAGE.
     29  1.1  jonathan  */
     30  1.1  jonathan 
     31  1.1  jonathan #include <sys/param.h>
     32  1.1  jonathan #include <sys/systm.h>
     33  1.1  jonathan #include <sys/malloc.h>
     34  1.1  jonathan #include <sys/mount.h>
     35  1.1  jonathan 
     36  1.1  jonathan #include <compat/ultrix/ultrix_syscallargs.h>
     37  1.1  jonathan 
     38  1.1  jonathan #define	ULTRIX_MAXPATHLEN	1024
     39  1.1  jonathan 
     40  1.1  jonathan /**
     41  1.1  jonathan  ** Ultrix filesystem operations: mount(), getmnt().
     42  1.1  jonathan  ** These are included purely so one can place an (ECOFF or ELF)
     43  1.1  jonathan  ** NetBSD/pmax kernel in an Ultrix root filesystem, boot it,
     44  1.1  jonathan  ** and over-write the Ultrix root parition with NetBSD binaries.
     45  1.1  jonathan  **/
     46  1.1  jonathan 
     47  1.1  jonathan /*
     48  1.1  jonathan  * Ultrix file system data structure, as modified by
     49  1.1  jonathan  * Ultrix getmntent(). This  structure is padded to 2560 bytes, for
     50  1.1  jonathan  * compatiblity with the size the Ultrix kernel and user apps expect.
     51  1.1  jonathan  */
     52  1.1  jonathan struct ultrix_fs_data {
     53  1.1  jonathan 	u_int32_t	ufsd_flags;	/* how mounted */
     54  1.1  jonathan 	u_int32_t	ufsd_mtsize;	/* max transfer size in bytes */
     55  1.1  jonathan 	u_int32_t	ufsd_otsize;	/* optimal transfer size in bytes */
     56  1.1  jonathan 	u_int32_t	ufsd_bsize;	/* fs block size (bytes) for vm code */
     57  1.1  jonathan 	u_int32_t	ufsd_fstype;	/* see ../h/fs_types.h  */
     58  1.1  jonathan 	u_int32_t	ufsd_gtot;	/* total number of gnodes */
     59  1.1  jonathan 	u_int32_t	ufsd_gfree;	/* # of free gnodes */
     60  1.1  jonathan 	u_int32_t	ufsd_btot;	/* total number of 1K blocks */
     61  1.1  jonathan 	u_int32_t	ufsd_bfree;	/* # of free 1K blocks */
     62  1.1  jonathan 	u_int32_t	ufsd_bfreen;	/* user consumable 1K blocks */
     63  1.1  jonathan 	u_int32_t	ufsd_pgthresh;	/* min size in bytes before paging*/
     64  1.1  jonathan 	int32_t		ufsd_uid;	/* uid that mounted me */
     65  1.1  jonathan 	int16_t		ufsd_dev;	/* major/minor of fs */
     66  1.1  jonathan 	int16_t		ufsd_exroot;	/* root mapping from exports */
     67  1.1  jonathan 	char		ufsd_devname[ULTRIX_MAXPATHLEN + 4]; /* name of dev */
     68  1.1  jonathan 	char		ufsd_path[ULTRIX_MAXPATHLEN + 4]; /* name of mnt point */
     69  1.1  jonathan 	u_int32_t	ufsd_nupdate;	/* number of writes */
     70  1.1  jonathan 	u_int32_t	ufsd_pad[112];	/* pad to 2560 bytes. */
     71  1.1  jonathan };
     72  1.1  jonathan 
     73  1.1  jonathan /*
     74  1.1  jonathan  * Get statistics on mounted filesystems.
     75  1.1  jonathan  */
     76  1.1  jonathan #if 0
     77  1.1  jonathan struct ultrix_getmnt_args {
     78  1.1  jonathan 	int32_t *start;
     79  1.1  jonathan 	struct ultrix_fs_data *buf;
     80  1.1  jonathan 	int32_t bufsize;
     81  1.1  jonathan 	int32_t mode;
     82  1.1  jonathan 	char *path;
     83  1.1  jonathan };
     84  1.1  jonathan 
     85  1.1  jonathan #endif
     86  1.1  jonathan /*
     87  1.1  jonathan  * Ultrix getmnt() flags.
     88  1.1  jonathan  * The operation getmnt() should perform is incoded in the flag
     89  1.1  jonathan  * argument.  There are two independent attributes.
     90  1.1  jonathan  *
     91  1.1  jonathan  * ULTRIX_NOSTAT_xxx will never hang, but it may not return
     92  1.1  jonathan  * up-to-date statistics. (For NFS clients, it returns whatever is
     93  1.1  jonathan  * in the cache.) ULTRIX_STAT_xxx returns up-to-date info but may
     94  1.1  jonathan  * hang (e.g., on dead NFS servers).
     95  1.1  jonathan  *
     96  1.1  jonathan  * ULTRIX_xxSTAT_ONE returns statistics on just one filesystem, determined
     97  1.1  jonathan  * by the parth argument.  ULTRIX_xxSTAT_MANY ignores the path argument and
     98  1.1  jonathan  * returns info on as many  filesystems fit in the structure.
     99  1.1  jonathan  * the start argument, which should be zero on the first call,
    100  1.1  jonathan  * can be used to iterate over all filesystems.
    101  1.1  jonathan  *
    102  1.1  jonathan  */
    103  1.1  jonathan #define	ULTRIX_NOSTAT_MANY	1
    104  1.1  jonathan #define	ULTRIX_STAT_MANY	2
    105  1.1  jonathan #define	ULTRIX_STAT_ONE		3
    106  1.1  jonathan #define	ULTRIX_NOSTAT_ONE	4
    107  1.1  jonathan 
    108  1.1  jonathan /*
    109  1.1  jonathan  * Ultrix gnode-layer  filesystem codes.
    110  1.1  jonathan  */
    111  1.1  jonathan #define ULTRIX_FSTYPE_UNKNOWN	0x0
    112  1.1  jonathan #define ULTRIX_FSTYPE_ULTRIX	0x1	/* 4.2bsd ffs */
    113  1.1  jonathan #define ULTRIX_FSTYPE_NFS	0x5	/*  NFS v2 */
    114  1.1  jonathan 
    115  1.1  jonathan /*
    116  1.1  jonathan  * Construct an Ultrix getmnt() ultrix_fs_data from the native NetBSD
    117  1.1  jonathan  * struct statfs.
    118  1.1  jonathan  */
    119  1.1  jonathan static void
    120  1.1  jonathan make_ultrix_mntent(sp, tem)
    121  1.1  jonathan 	register struct statfs *sp;
    122  1.1  jonathan 	register struct ultrix_fs_data *tem;
    123  1.1  jonathan {
    124  1.1  jonathan 
    125  1.1  jonathan 	tem->ufsd_mtsize = sp->f_bsize;		/* XXX max transfer size */
    126  1.1  jonathan 	tem->ufsd_flags = sp->f_flags;		/* XXX translate */
    127  1.1  jonathan 	tem->ufsd_otsize = sp->f_iosize;
    128  1.1  jonathan 	tem->ufsd_bsize = sp->f_bsize;
    129  1.1  jonathan 	/*
    130  1.1  jonathan 	 * Translate file system type. NetBSD/1.1 seems to always
    131  1.1  jonathan 	 * have f_type zero.
    132  1.1  jonathan 	 */
    133  1.1  jonathan 	tem->ufsd_fstype = ULTRIX_FSTYPE_NFS;	/* a hack */
    134  1.1  jonathan 
    135  1.1  jonathan 	tem->ufsd_gtot = 0;			/* XXX kept where? superblk? */
    136  1.1  jonathan 	tem->ufsd_gfree = sp->f_ffree;
    137  1.1  jonathan 	tem->ufsd_bfree = sp->f_bfree;		/* free 1k blocks */
    138  1.1  jonathan 	tem->ufsd_bfreen = sp->f_bfree;		/* blocks available to users */
    139  1.1  jonathan 	tem->ufsd_pgthresh = 0;			/* not relevant */
    140  1.1  jonathan 	tem->ufsd_uid = 0;			/* XXX kept where ?*/
    141  1.1  jonathan 	tem->ufsd_dev = 0;			/* ?? */
    142  1.1  jonathan 	tem->ufsd_exroot  = 0;			/* ?? */
    143  1.1  jonathan 	strncpy(tem->ufsd_path, sp->f_mntonname, ULTRIX_MAXPATHLEN);
    144  1.1  jonathan 	strncpy(tem->ufsd_devname, sp->f_mntfromname, ULTRIX_MAXPATHLEN);
    145  1.1  jonathan 	printf("mntent: %s type %d\n", tem->ufsd_devname, tem->ufsd_fstype);
    146  1.1  jonathan }
    147  1.1  jonathan 
    148  1.1  jonathan int
    149  1.1  jonathan ultrix_sys_getmnt(p, v, retval)
    150  1.1  jonathan 	struct proc *p;
    151  1.1  jonathan 	void *v;
    152  1.1  jonathan 	int *retval;
    153  1.1  jonathan {
    154  1.1  jonathan 	struct ultrix_sys_getmnt_args *uap = v;
    155  1.1  jonathan 	struct mount *mp, *nmp;
    156  1.1  jonathan 	struct statfs *sp;
    157  1.1  jonathan 	struct ultrix_fs_data *sfsp;
    158  1.1  jonathan 	char *path;
    159  1.1  jonathan 	int mntflags;
    160  1.1  jonathan 	int skip;
    161  1.1  jonathan 	int start;
    162  1.1  jonathan 	long count, maxcount;
    163  1.1  jonathan 	int error = 0;
    164  1.1  jonathan 
    165  1.1  jonathan 	path = NULL;
    166  1.1  jonathan 	error = 0;
    167  1.1  jonathan 	maxcount = SCARG(uap, bufsize) / sizeof(struct ultrix_fs_data);
    168  1.1  jonathan 	sfsp = SCARG(uap, buf);
    169  1.1  jonathan 
    170  1.1  jonathan 	if (SCARG(uap, mode) == ULTRIX_STAT_ONE ||
    171  1.1  jonathan 	    SCARG(uap, mode) == ULTRIX_STAT_MANY)
    172  1.1  jonathan 		mntflags = MNT_WAIT;
    173  1.1  jonathan 	else
    174  1.1  jonathan 		mntflags = MNT_NOWAIT;
    175  1.1  jonathan 
    176  1.1  jonathan 	if (SCARG(uap, mode) == ULTRIX_STAT_ONE || SCARG(uap, mode) == ULTRIX_NOSTAT_ONE) {
    177  1.1  jonathan 		/*
    178  1.1  jonathan 		 * Only get info on mountpoints that matches the path
    179  1.1  jonathan 		 * provided.
    180  1.1  jonathan 		 */
    181  1.1  jonathan 		MALLOC(path, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
    182  1.1  jonathan 		if (error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL))
    183  1.1  jonathan 			goto bad;
    184  1.1  jonathan 		maxcount = 1;
    185  1.1  jonathan 	} else {
    186  1.1  jonathan 		/*
    187  1.1  jonathan 		 * Get info on any mountpoints, somewhat like readdir().
    188  1.1  jonathan 		 * Find out how many mount list entries to skip, and skip
    189  1.1  jonathan 		 * them.
    190  1.1  jonathan 		 */
    191  1.1  jonathan 		if (error =
    192  1.1  jonathan 		    copyin((caddr_t)SCARG(uap, start), &start,
    193  1.1  jonathan 					  sizeof(*SCARG(uap, start))))
    194  1.1  jonathan 			goto bad;
    195  1.1  jonathan 		for (skip = start, mp = mountlist.cqh_first;
    196  1.1  jonathan 		    mp != (void*)&mountlist && skip-- > 0; mp = nmp)
    197  1.1  jonathan 			nmp = mp->mnt_list.cqe_next;
    198  1.1  jonathan 	}
    199  1.1  jonathan 
    200  1.1  jonathan 	for (count = 0, mp = mountlist.cqh_first;
    201  1.1  jonathan 	    mp != (void*)&mountlist && count < maxcount; mp = nmp) {
    202  1.1  jonathan 		nmp = mp->mnt_list.cqe_next;
    203  1.1  jonathan 		if (sfsp != NULL && (mp->mnt_flag & MNT_MLOCK) == 0) {
    204  1.1  jonathan 			struct ultrix_fs_data tem;
    205  1.1  jonathan 			sp = &mp->mnt_stat;
    206  1.1  jonathan 
    207  1.1  jonathan 			/*
    208  1.1  jonathan 			 * If requested, refresh the fsstat cache.
    209  1.1  jonathan 			 */
    210  1.1  jonathan 			if ((mntflags & MNT_WAIT) != 0 &&
    211  1.1  jonathan 			    (error = VFS_STATFS(mp, sp, p)) != 0)
    212  1.1  jonathan 				continue;
    213  1.1  jonathan 
    214  1.1  jonathan 			/*
    215  1.1  jonathan 			 * XXX what does this do? -- cgd
    216  1.1  jonathan 			 */
    217  1.1  jonathan 			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
    218  1.1  jonathan 			if (path == NULL ||
    219  1.1  jonathan 			    strcmp(path, sp->f_mntonname) == 0) {
    220  1.1  jonathan 				make_ultrix_mntent(sp, &tem);
    221  1.1  jonathan 				if (error =
    222  1.1  jonathan 				    copyout((caddr_t)&tem, sfsp, sizeof(tem)))
    223  1.1  jonathan 					goto bad;
    224  1.1  jonathan 				sfsp++;
    225  1.1  jonathan 				count++;
    226  1.1  jonathan 			}
    227  1.1  jonathan 		}
    228  1.1  jonathan 	}
    229  1.1  jonathan 
    230  1.1  jonathan 	if (sfsp != NULL && count > maxcount)
    231  1.1  jonathan 		*retval = maxcount;
    232  1.1  jonathan 	else
    233  1.1  jonathan 		*retval = count;
    234  1.1  jonathan 
    235  1.1  jonathan bad:
    236  1.1  jonathan 	if (path)
    237  1.1  jonathan 		FREE(path, M_TEMP);
    238  1.1  jonathan 	return (error);
    239  1.1  jonathan }
    240