1 /* $NetBSD: darwin_mount.c,v 1.18 2008/06/24 11:18:15 ad Exp $ */
2
3 /*-
4 * Copyright (c) 2003, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: darwin_mount.c,v 1.18 2008/06/24 11:18:15 ad Exp $");
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/mount.h>
39 #include <sys/proc.h>
40 #include <sys/vnode.h>
41 #include <sys/namei.h>
42 #include <sys/file.h>
43 #include <sys/filedesc.h>
44 #include <sys/syscallargs.h>
45
46 #include <compat/sys/signal.h>
47
48 #include <compat/mach/mach_types.h>
49 #include <compat/mach/mach_vm.h>
50
51 #include <compat/darwin/darwin_audit.h>
52 #include <compat/darwin/darwin_mount.h>
53 #include <compat/darwin/darwin_syscallargs.h>
54
55 static void native_to_darwin_statvfs(const struct statvfs *,
56 struct darwin_statfs *);
57
58 int
59 darwin_sys_fstatfs(struct lwp *l, const struct darwin_sys_fstatfs_args *uap, register_t *retval)
60 {
61 /* {
62 syscallarg(int) fd;
63 syscallarg(struct darwin_statfs *) buf;
64 } */
65 file_t *fp;
66 struct mount *mp;
67 struct statvfs *bs;
68 struct darwin_statfs ds;
69 int error;
70
71 /* fd_getvnode() will use the descriptor for us */
72 if ((error = fd_getvnode(SCARG(uap, fd), &fp)))
73 return (error);
74
75 mp = ((struct vnode *)fp->f_data)->v_mount;
76 bs = &mp->mnt_stat;
77
78 if ((error = VFS_STATVFS(mp, bs)) != 0)
79 goto out;
80
81 native_to_darwin_statvfs(bs, &ds);
82
83 error = copyout(&ds, SCARG(uap, buf), sizeof(ds));
84
85 out:
86 fd_putfile(SCARG(uap, fd));
87 return (error);
88 }
89
90 int
91 darwin_sys_getfsstat(struct lwp *l, const struct darwin_sys_getfsstat_args *uap, register_t *retval)
92 {
93 /* {
94 syscallarg(struct darwin_statfs *) buf;
95 syscallarg(long) bufsize;
96 syscallarg(int) flags;
97 } */
98 struct mount *mp, *nmp;
99 struct statvfs *bs;
100 struct darwin_statfs ds;
101 struct darwin_statfs *uds;
102 long count, maxcount, error;
103
104 maxcount = SCARG(uap, bufsize) / sizeof(struct darwin_statfs);
105 uds = SCARG(uap, buf);
106
107 for (count = 0, mp = mountlist.cqh_first;
108 mp != (void *)&mountlist; mp = nmp) {
109 nmp = mp->mnt_list.cqe_next;
110
111 if ((uds != NULL) && (count < maxcount)) {
112 bs = &mp->mnt_stat;
113
114 if (((SCARG(uap, flags) & MNT_NOWAIT) == 0 ||
115 (SCARG(uap, flags) & MNT_WAIT)) &&
116 (error = VFS_STATVFS(mp, bs)))
117 continue;
118
119 native_to_darwin_statvfs(bs, &ds);
120
121 if ((error = copyout(&ds, uds, sizeof(*uds))) != 0)
122 return error;
123 uds++;
124 }
125 count++;
126 }
127
128 if ((uds != NULL) && (count > maxcount))
129 *retval = maxcount;
130 else
131 *retval = count;
132
133 return 0;
134 }
135
136 int
137 darwin_sys_statfs(struct lwp *l, const struct darwin_sys_statfs_args *uap, register_t *retval)
138 {
139 /* {
140 syscallarg(char *) path;
141 syscallarg(struct statfs *) buf;
142 } */
143 struct mount *mp;
144 struct statvfs *bs;
145 struct darwin_statfs ds;
146 struct nameidata nd;
147 int error;
148
149 NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE,
150 SCARG(uap, path));
151 if ((error = namei(&nd)) != 0)
152 return error;
153
154 mp = nd.ni_vp->v_mount;
155 bs = &mp->mnt_stat;
156 vrele(nd.ni_vp);
157
158 if ((error = VFS_STATVFS(mp, bs)) != 0)
159 return error;
160
161 native_to_darwin_statvfs(bs, &ds);
162
163 error = copyout(&ds, SCARG(uap, buf), sizeof(ds));
164
165 return error;
166 }
167
168
169 static void
170 native_to_darwin_statvfs(const struct statvfs *bs, struct darwin_statfs *ds)
171 {
172 long dflags = 0;
173 long sflags = bs->f_flag & MNT_VISFLAGMASK;
174
175 if (sflags|MNT_RDONLY)
176 dflags |= DARWIN_MNT_RDONLY;
177 if (sflags|MNT_SYNCHRONOUS)
178 dflags |= DARWIN_MNT_SYNCHRONOUS;
179 if (sflags|MNT_NOEXEC)
180 dflags |= DARWIN_MNT_NOEXEC;
181 if (sflags|MNT_NOSUID)
182 dflags |= DARWIN_MNT_NOSUID;
183 if (sflags|MNT_NODEV)
184 dflags |= DARWIN_MNT_NODEV;
185 if (sflags|MNT_UNION)
186 dflags |= DARWIN_MNT_UNION;
187 if (sflags|MNT_ASYNC)
188 dflags |= DARWIN_MNT_ASYNC;
189 if (sflags|MNT_IGNORE)
190 dflags |= DARWIN_MNT_DONTBROWSE;
191
192 ds->f_otype = 0;
193 ds->f_oflags = dflags & 0xffff;
194 ds->f_bsize = bs->f_bsize;
195 ds->f_iosize = bs->f_iosize;
196 ds->f_blocks = bs->f_blocks;
197 ds->f_bfree = bs->f_bfree;
198 ds->f_bavail = bs->f_bavail;
199 ds->f_files = bs->f_files;
200 ds->f_ffree = bs->f_ffree;
201 (void)memcpy(&ds->f_fsid, &bs->f_fsidx, sizeof(ds->f_fsid));
202 ds->f_owner = bs->f_owner;
203 ds->f_reserved1 = 0;
204 ds->f_type = 0;
205 ds->f_flags = dflags;
206 (void)strlcpy(ds->f_fstypename, bs->f_fstypename, DARWIN_MFSNAMELEN);
207 (void)strlcpy(ds->f_mntonname, bs->f_mntonname, DARWIN_MNAMELEN);
208 (void)strlcpy(ds->f_mntfromname, bs->f_mntfromname, DARWIN_MNAMELEN);
209
210 return;
211 }
Cache object: 85736e4dbba868ee5032c4598f81f6ff
|