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