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