fm/ipmitopo: fix 64-bit compilation
[unleashed.git] / kernel / syscall / statvfs.c
blob9167e3c0339e9a2c2b3e822608edf0f9a87df89f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 * under license from the Regents of the University of California.
34 #pragma ident "%Z%%M% %I% %E% SMI"
37 * Get file system statistics (statvfs and fstatvfs).
40 #include <sys/types.h>
41 #include <sys/inttypes.h>
42 #include <sys/t_lock.h>
43 #include <sys/param.h>
44 #include <sys/errno.h>
45 #include <sys/fstyp.h>
46 #include <sys/systm.h>
47 #include <sys/vfs.h>
48 #include <sys/statvfs.h>
49 #include <sys/vnode.h>
50 #include <sys/file.h>
51 #include <sys/cmn_err.h>
52 #include <sys/debug.h>
53 #include <sys/pathname.h>
55 #include <vm/page.h>
56 #include <sys/fs_subr.h>
58 #define STATVFSCOPY(dst, src) \
59 (dst)->f_bsize = (src)->f_bsize; \
60 (dst)->f_frsize = (src)->f_frsize; \
61 (dst)->f_blocks = (src)->f_blocks; \
62 (dst)->f_bfree = (src)->f_bfree; \
63 (dst)->f_bavail = (src)->f_bavail; \
64 (dst)->f_files = (src)->f_files; \
65 (dst)->f_ffree = (src)->f_ffree; \
66 (dst)->f_favail = (src)->f_favail; \
67 (dst)->f_fsid = (src)->f_fsid; \
68 bcopy((src)->f_basetype, (dst)->f_basetype, \
69 sizeof ((dst)->f_basetype)); \
70 (dst)->f_flag = (src)->f_flag; \
71 (dst)->f_namemax = (src)->f_namemax; \
72 bcopy((src)->f_fstr, (dst)->f_fstr, \
73 sizeof ((dst)->f_fstr))
76 * Common routines for statvfs and fstatvfs.
79 static int
80 cstatvfs32(struct vfs *vfsp, struct statvfs32 *ubp)
82 struct statvfs64 ds64;
83 struct statvfs32 ds32;
84 int error;
86 ASSERT32(sizeof (struct statvfs) == sizeof (struct statvfs32));
87 ASSERT32(sizeof (struct statvfs64) == sizeof (struct statvfs64_32));
89 bzero(&ds64, sizeof (ds64));
90 if ((error = VFS_STATVFS(vfsp, &ds64)) != 0)
91 return (error);
94 * VFS_STATVFS can return data that is incompatible with the space
95 * available the 32-bit statvfs structure. Check here to see if
96 * it will fit into the 32-bit structure, if not, return EOVERFLOW.
98 * The check for -1 is because some file systems return -1 in the
99 * fields that are irrelevant or nonessential, and we do not want
100 * to return EOVERFLOW for them. For example: df is expected to
101 * show -1 in the output for some of these fields on NFS mounted
102 * filesystems.
104 if (ds64.f_files == (fsfilcnt64_t)-1)
105 ds64.f_files = UINT32_MAX;
106 if (ds64.f_ffree == (fsfilcnt64_t)-1)
107 ds64.f_ffree = UINT32_MAX;
108 if (ds64.f_favail == (fsfilcnt64_t)-1)
109 ds64.f_favail = UINT32_MAX;
110 if (ds64.f_bavail == (fsblkcnt64_t)-1)
111 ds64.f_bavail = UINT32_MAX;
112 if (ds64.f_bfree == (fsblkcnt64_t)-1)
113 ds64.f_bfree = UINT32_MAX;
115 if (ds64.f_blocks > UINT32_MAX || ds64.f_bfree > UINT32_MAX ||
116 ds64.f_bavail > UINT32_MAX || ds64.f_files > UINT32_MAX ||
117 ds64.f_ffree > UINT32_MAX || ds64.f_favail > UINT32_MAX)
118 return (EOVERFLOW);
119 #ifdef _LP64
121 * On the 64-bit kernel, even these fields grow to 64-bit
122 * quantities in the statvfs64 structure.
124 if (ds64.f_namemax == (ulong_t)-1l)
125 ds64.f_namemax = UINT32_MAX;
127 if (ds64.f_bsize > UINT32_MAX || ds64.f_frsize > UINT32_MAX ||
128 ds64.f_fsid > UINT32_MAX || ds64.f_flag > UINT32_MAX ||
129 ds64.f_namemax > UINT32_MAX)
130 return (EOVERFLOW);
131 #endif
133 bzero(&ds32, sizeof (ds32));
134 STATVFSCOPY(&ds32, &ds64);
135 if (copyout(&ds32, ubp, sizeof (ds32)) != 0)
136 return (EFAULT);
137 return (0);
140 static int
141 cstatvfs64(struct vfs *vfsp, struct statvfs64 *ubp)
143 struct statvfs64 ds64;
144 int error;
146 ASSERT64(sizeof (struct statvfs) == sizeof (struct statvfs64));
147 bzero(&ds64, sizeof (ds64));
148 if ((error = VFS_STATVFS(vfsp, &ds64)) != 0)
149 return (error);
150 if (copyout(&ds64, ubp, sizeof (ds64)) != 0)
151 return (EFAULT);
152 return (0);
156 * Native system calls
159 statvfs(char *fname, struct statvfs *sbp)
161 vnode_t *vp;
162 int error;
163 int estale_retry = 0;
165 lookup:
166 if (error = lookupname(fname, UIO_USERSPACE, FOLLOW, NULLVPP, &vp)) {
167 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
168 goto lookup;
169 return (set_errno(error));
171 #ifdef _LP64
172 error = cstatvfs64(vp->v_vfsp, (struct statvfs64 *)sbp);
173 #else
174 error = cstatvfs32(vp->v_vfsp, (struct statvfs32 *)sbp);
175 #endif
176 VN_RELE(vp);
177 if (error) {
178 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
179 goto lookup;
180 return (set_errno(error));
182 return (0);
186 fstatvfs(int fdes, struct statvfs *sbp)
188 struct file *fp;
189 int error;
191 if ((fp = getf(fdes)) == NULL)
192 return (set_errno(EBADF));
193 #ifdef _LP64
194 error = cstatvfs64(fp->f_vnode->v_vfsp, (struct statvfs64 *)sbp);
195 #else
196 error = cstatvfs32(fp->f_vnode->v_vfsp, (struct statvfs32 *)sbp);
197 #endif
198 releasef(fdes);
199 if (error)
200 return (set_errno(error));
201 return (0);
204 #if defined(_ILP32)
207 * Large File system calls.
209 * (We deliberately don't have special "large file" system calls in the
210 * 64-bit kernel -- we just use the native versions, since they're just
211 * as functional.)
214 statvfs64(char *fname, struct statvfs64 *sbp)
216 vnode_t *vp;
217 int error;
218 int estale_retry = 0;
220 lookup:
221 if (error = lookupname(fname, UIO_USERSPACE, FOLLOW, NULLVPP, &vp)) {
222 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
223 goto lookup;
224 return (set_errno(error));
226 error = cstatvfs64(vp->v_vfsp, sbp);
227 VN_RELE(vp);
228 if (error) {
229 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
230 goto lookup;
231 return (set_errno(error));
233 return (0);
237 fstatvfs64(int fdes, struct statvfs64 *sbp)
239 struct file *fp;
240 int error;
242 if ((fp = getf(fdes)) == NULL)
243 return (set_errno(EBADF));
244 error = cstatvfs64(fp->f_vnode->v_vfsp, sbp);
245 releasef(fdes);
246 if (error)
247 return (set_errno(error));
248 return (0);
251 #endif /* _ILP32 */
253 #ifdef _SYSCALL32_IMPL
255 static int
256 cstatvfs64_32(struct vfs *vfsp, struct statvfs64_32 *ubp)
258 struct statvfs64 ds64;
259 struct statvfs64_32 ds64_32;
260 int error;
262 bzero(&ds64, sizeof (ds64));
263 if ((error = VFS_STATVFS(vfsp, &ds64)) != 0)
264 return (error);
267 * On the 64-bit kernel, even these fields grow to 64-bit
268 * quantities in the statvfs64 structure.
270 if (ds64.f_namemax == (ulong_t)-1l)
271 ds64.f_namemax = UINT32_MAX;
273 if (ds64.f_bsize > UINT32_MAX || ds64.f_frsize > UINT32_MAX ||
274 ds64.f_fsid > UINT32_MAX || ds64.f_flag > UINT32_MAX ||
275 ds64.f_namemax > UINT32_MAX)
276 return (EOVERFLOW);
278 STATVFSCOPY(&ds64_32, &ds64);
279 if (copyout(&ds64_32, ubp, sizeof (ds64_32)) != 0)
280 return (EFAULT);
281 return (0);
285 * ILP32 Large File system calls on LP64 kernel
288 statvfs64_32(char *fname, struct statvfs64_32 *sbp)
290 vnode_t *vp;
291 int error;
292 int estale_retry = 0;
294 lookup:
295 if (error = lookupname(fname, UIO_USERSPACE, FOLLOW, NULLVPP, &vp)) {
296 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
297 goto lookup;
298 return (set_errno(error));
300 error = cstatvfs64_32(vp->v_vfsp, sbp);
301 VN_RELE(vp);
302 if (error) {
303 if ((error == ESTALE) && fs_need_estale_retry(estale_retry++))
304 goto lookup;
305 return (set_errno(error));
307 return (0);
311 fstatvfs64_32(int fdes, struct statvfs64_32 *sbp)
313 struct file *fp;
314 int error;
316 if ((fp = getf(fdes)) == NULL)
317 return (set_errno(EBADF));
318 error = cstatvfs64_32(fp->f_vnode->v_vfsp, sbp);
319 releasef(fdes);
320 if (error)
321 return (set_errno(error));
322 return (0);
325 #endif /* _SYSCALL32_IMPL */