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