Deleted Added
full compact
linux_stats.c (77675) linux_stats.c (83221)
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/compat/linux/linux_stats.c 77675 2001-06-04 03:39:14Z paul $
28 * $FreeBSD: head/sys/compat/linux/linux_stats.c 83221 2001-09-08 19:07:04Z marcel $
29 */
30
31#include <sys/param.h>
32#include <sys/conf.h>
33#include <sys/dirent.h>
34#include <sys/file.h>
35#include <sys/filedesc.h>
36#include <sys/proc.h>
37#include <sys/mount.h>
38#include <sys/namei.h>
39#include <sys/stat.h>
29 */
30
31#include <sys/param.h>
32#include <sys/conf.h>
33#include <sys/dirent.h>
34#include <sys/file.h>
35#include <sys/filedesc.h>
36#include <sys/proc.h>
37#include <sys/mount.h>
38#include <sys/namei.h>
39#include <sys/stat.h>
40#include <sys/sysctl.h>
40#include <sys/systm.h>
41#include <sys/vnode.h>
42
43#include <machine/../linux/linux.h>
44#include <machine/../linux/linux_proto.h>
45#include <compat/linux/linux_util.h>
46
41#include <sys/systm.h>
42#include <sys/vnode.h>
43
44#include <machine/../linux/linux.h>
45#include <machine/../linux/linux_proto.h>
46#include <compat/linux/linux_util.h>
47
47#include <sys/sysctl.h>
48
49struct linux_newstat {
50#ifdef __alpha__
51 u_int stat_dev;
52 u_int stat_ino;
53 u_int stat_mode;
54 u_int stat_nlink;
55 u_int stat_uid;
56 u_int stat_gid;
57 u_int stat_rdev;
58 long stat_size;
59 u_long stat_atime;
60 u_long stat_mtime;
61 u_long stat_ctime;
62 u_int stat_blksize;
63 int stat_blocks;
64 u_int stat_flags;
65 u_int stat_gen;
66#else
67 u_short stat_dev;
68 u_short __pad1;
69 u_long stat_ino;
70 u_short stat_mode;
71 u_short stat_nlink;
72 u_short stat_uid;
73 u_short stat_gid;
74 u_short stat_rdev;
75 u_short __pad2;
76 u_long stat_size;
77 u_long stat_blksize;
78 u_long stat_blocks;
79 u_long stat_atime;
80 u_long __unused1;
81 u_long stat_mtime;
82 u_long __unused2;
83 u_long stat_ctime;
84 u_long __unused3;
85 u_long __unused4;
86 u_long __unused5;
87#endif
88};
89
90
91struct linux_ustat
92{
93 int f_tfree;
94 u_long f_tinode;
95 char f_fname[6];
96 char f_fpack[6];
97};
98
99static int
100newstat_copyout(struct stat *buf, void *ubuf)
101{
48static int
49newstat_copyout(struct stat *buf, void *ubuf)
50{
102 struct linux_newstat tbuf;
51 struct l_newstat tbuf;
103 struct cdevsw *cdevsw;
104 dev_t dev;
105
52 struct cdevsw *cdevsw;
53 dev_t dev;
54
106 tbuf.stat_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
107 tbuf.stat_ino = buf->st_ino;
108 tbuf.stat_mode = buf->st_mode;
109 tbuf.stat_nlink = buf->st_nlink;
110 tbuf.stat_uid = buf->st_uid;
111 tbuf.stat_gid = buf->st_gid;
112 tbuf.stat_rdev = buf->st_rdev;
113 tbuf.stat_size = buf->st_size;
114 tbuf.stat_atime = buf->st_atime;
115 tbuf.stat_mtime = buf->st_mtime;
116 tbuf.stat_ctime = buf->st_ctime;
117 tbuf.stat_blksize = buf->st_blksize;
118 tbuf.stat_blocks = buf->st_blocks;
55 tbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
56 tbuf.st_ino = buf->st_ino;
57 tbuf.st_mode = buf->st_mode;
58 tbuf.st_nlink = buf->st_nlink;
59 tbuf.st_uid = buf->st_uid;
60 tbuf.st_gid = buf->st_gid;
61 tbuf.st_rdev = buf->st_rdev;
62 tbuf.st_size = buf->st_size;
63 tbuf.st_atime = buf->st_atime;
64 tbuf.st_mtime = buf->st_mtime;
65 tbuf.st_ctime = buf->st_ctime;
66 tbuf.st_blksize = buf->st_blksize;
67 tbuf.st_blocks = buf->st_blocks;
119
120 /* Lie about disk drives which are character devices
121 * in FreeBSD but block devices under Linux.
122 */
68
69 /* Lie about disk drives which are character devices
70 * in FreeBSD but block devices under Linux.
71 */
123 if (S_ISCHR(tbuf.stat_mode) &&
72 if (S_ISCHR(tbuf.st_mode) &&
124 (dev = udev2dev(buf->st_rdev, 0)) != NODEV) {
125 cdevsw = devsw(dev);
126 if (cdevsw != NULL && (cdevsw->d_flags & D_DISK)) {
73 (dev = udev2dev(buf->st_rdev, 0)) != NODEV) {
74 cdevsw = devsw(dev);
75 if (cdevsw != NULL && (cdevsw->d_flags & D_DISK)) {
127 tbuf.stat_mode &= ~S_IFMT;
128 tbuf.stat_mode |= S_IFBLK;
76 tbuf.st_mode &= ~S_IFMT;
77 tbuf.st_mode |= S_IFBLK;
129
130 /* XXX this may not be quite right */
131 /* Map major number to 0 */
78
79 /* XXX this may not be quite right */
80 /* Map major number to 0 */
132 tbuf.stat_dev = uminor(buf->st_dev) & 0xf;
133 tbuf.stat_rdev = buf->st_rdev & 0xff;
81 tbuf.st_dev = uminor(buf->st_dev) & 0xf;
82 tbuf.st_rdev = buf->st_rdev & 0xff;
134 }
135 }
136
137 return (copyout(&tbuf, ubuf, sizeof(tbuf)));
138}
139
140int
141linux_newstat(struct proc *p, struct linux_newstat_args *args)

--- 7 unchanged lines hidden (view full) ---

149 CHECKALTEXIST(p, &sg, args->path);
150
151#ifdef DEBUG
152 if (ldebug(newstat))
153 printf(ARGS(newstat, "%s, *"), args->path);
154#endif
155
156 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
83 }
84 }
85
86 return (copyout(&tbuf, ubuf, sizeof(tbuf)));
87}
88
89int
90linux_newstat(struct proc *p, struct linux_newstat_args *args)

--- 7 unchanged lines hidden (view full) ---

98 CHECKALTEXIST(p, &sg, args->path);
99
100#ifdef DEBUG
101 if (ldebug(newstat))
102 printf(ARGS(newstat, "%s, *"), args->path);
103#endif
104
105 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
157 args->path, p);
106 args->path, p);
158 error = namei(&nd);
159 if (error)
160 return (error);
161 NDFREE(&nd, NDF_ONLY_PNBUF);
162
163 error = vn_stat(nd.ni_vp, &buf, p);
164 vput(nd.ni_vp);
165 if (error)
166 return (error);
167
168 return (newstat_copyout(&buf, args->buf));
169}
170
107 error = namei(&nd);
108 if (error)
109 return (error);
110 NDFREE(&nd, NDF_ONLY_PNBUF);
111
112 error = vn_stat(nd.ni_vp, &buf, p);
113 vput(nd.ni_vp);
114 if (error)
115 return (error);
116
117 return (newstat_copyout(&buf, args->buf));
118}
119
171/*
172 * Get file status; this version does not follow links.
173 */
174int
120int
175linux_newlstat(p, uap)
176 struct proc *p;
177 struct linux_newlstat_args *uap;
121linux_newlstat(struct proc *p, struct linux_newlstat_args *args)
178{
179 int error;
122{
123 int error;
180 struct vnode *vp;
181 struct stat sb;
182 struct nameidata nd;
183 caddr_t sg;
184
185 sg = stackgap_init();
124 struct stat sb;
125 struct nameidata nd;
126 caddr_t sg;
127
128 sg = stackgap_init();
186 CHECKALTEXIST(p, &sg, uap->path);
129 CHECKALTEXIST(p, &sg, args->path);
187
188#ifdef DEBUG
189 if (ldebug(newlstat))
130
131#ifdef DEBUG
132 if (ldebug(newlstat))
190 printf(ARGS(newlstat, "%s, *"), uap->path);
133 printf(ARGS(newlstat, "%s, *"), args->path);
191#endif
192
193 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
134#endif
135
136 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
194 uap->path, p);
137 args->path, p);
195 error = namei(&nd);
196 if (error)
197 return (error);
198 NDFREE(&nd, NDF_ONLY_PNBUF);
199
138 error = namei(&nd);
139 if (error)
140 return (error);
141 NDFREE(&nd, NDF_ONLY_PNBUF);
142
200 vp = nd.ni_vp;
201 error = vn_stat(vp, &sb, p);
202 vput(vp);
143 error = vn_stat(nd.ni_vp, &sb, p);
144 vput(nd.ni_vp);
203 if (error)
204 return (error);
205
145 if (error)
146 return (error);
147
206 return (newstat_copyout(&sb, uap->buf));
148 return (newstat_copyout(&sb, args->buf));
207}
208
209int
210linux_newfstat(struct proc *p, struct linux_newfstat_args *args)
211{
212 struct filedesc *fdp;
213 struct file *fp;
214 struct stat buf;
215 int error;
216
149}
150
151int
152linux_newfstat(struct proc *p, struct linux_newfstat_args *args)
153{
154 struct filedesc *fdp;
155 struct file *fp;
156 struct stat buf;
157 int error;
158
217 fdp = p->p_fd;
218
219#ifdef DEBUG
220 if (ldebug(newfstat))
221 printf(ARGS(newfstat, "%d, *"), args->fd);
222#endif
223
159#ifdef DEBUG
160 if (ldebug(newfstat))
161 printf(ARGS(newfstat, "%d, *"), args->fd);
162#endif
163
164 fdp = p->p_fd;
224 if ((unsigned)args->fd >= fdp->fd_nfiles ||
225 (fp = fdp->fd_ofiles[args->fd]) == NULL)
226 return (EBADF);
227
228 error = fo_stat(fp, &buf, p);
229 if (!error)
230 error = newstat_copyout(&buf, args->buf);
231
232 return (error);
233}
234
165 if ((unsigned)args->fd >= fdp->fd_nfiles ||
166 (fp = fdp->fd_ofiles[args->fd]) == NULL)
167 return (EBADF);
168
169 error = fo_stat(fp, &buf, p);
170 if (!error)
171 error = newstat_copyout(&buf, args->buf);
172
173 return (error);
174}
175
235struct linux_statfs_buf {
236 int ftype;
237 int fbsize;
238 int fblocks;
239 int fbfree;
240 int fbavail;
241 int ffiles;
242 int fffree;
243 linux_fsid_t ffsid;
244 int fnamelen;
245 int fspare[6];
176/* XXX - All fields of type l_int are defined as l_long on i386 */
177struct l_statfs {
178 l_int f_type;
179 l_int f_bsize;
180 l_int f_blocks;
181 l_int f_bfree;
182 l_int f_bavail;
183 l_int f_files;
184 l_int f_ffree;
185 l_fsid_t f_fsid;
186 l_int f_namelen;
187 l_int f_spare[6];
246};
247
248#ifndef VT_NWFS
188};
189
190#ifndef VT_NWFS
249#define VT_NWFS VT_TFS /* XXX - bug compatibility with sys/fs/nwfs/nwfs_node.h */
191#define VT_NWFS VT_TFS /* XXX - bug compat. with sys/fs/nwfs/nwfs_node.h */
250#endif
251
252#define LINUX_CODA_SUPER_MAGIC 0x73757245L
253#define LINUX_EXT2_SUPER_MAGIC 0xEF53L
254#define LINUX_HPFS_SUPER_MAGIC 0xf995e849L
255#define LINUX_ISOFS_SUPER_MAGIC 0x9660L
256#define LINUX_MSDOS_SUPER_MAGIC 0x4d44L
257#define LINUX_NCP_SUPER_MAGIC 0x564cL

--- 36 unchanged lines hidden (view full) ---

294
295int
296linux_statfs(struct proc *p, struct linux_statfs_args *args)
297{
298 struct mount *mp;
299 struct nameidata *ndp;
300 struct statfs *bsd_statfs;
301 struct nameidata nd;
192#endif
193
194#define LINUX_CODA_SUPER_MAGIC 0x73757245L
195#define LINUX_EXT2_SUPER_MAGIC 0xEF53L
196#define LINUX_HPFS_SUPER_MAGIC 0xf995e849L
197#define LINUX_ISOFS_SUPER_MAGIC 0x9660L
198#define LINUX_MSDOS_SUPER_MAGIC 0x4d44L
199#define LINUX_NCP_SUPER_MAGIC 0x564cL

--- 36 unchanged lines hidden (view full) ---

236
237int
238linux_statfs(struct proc *p, struct linux_statfs_args *args)
239{
240 struct mount *mp;
241 struct nameidata *ndp;
242 struct statfs *bsd_statfs;
243 struct nameidata nd;
302 struct linux_statfs_buf linux_statfs_buf;
244 struct l_statfs linux_statfs;
303 int error;
304 caddr_t sg;
305
306 sg = stackgap_init();
307 CHECKALTEXIST(p, &sg, args->path);
308
309#ifdef DEBUG
310 if (ldebug(statfs))

--- 7 unchanged lines hidden (view full) ---

318 NDFREE(ndp, NDF_ONLY_PNBUF);
319 mp = ndp->ni_vp->v_mount;
320 bsd_statfs = &mp->mnt_stat;
321 vrele(ndp->ni_vp);
322 error = VFS_STATFS(mp, bsd_statfs, p);
323 if (error)
324 return error;
325 bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
245 int error;
246 caddr_t sg;
247
248 sg = stackgap_init();
249 CHECKALTEXIST(p, &sg, args->path);
250
251#ifdef DEBUG
252 if (ldebug(statfs))

--- 7 unchanged lines hidden (view full) ---

260 NDFREE(ndp, NDF_ONLY_PNBUF);
261 mp = ndp->ni_vp->v_mount;
262 bsd_statfs = &mp->mnt_stat;
263 vrele(ndp->ni_vp);
264 error = VFS_STATFS(mp, bsd_statfs, p);
265 if (error)
266 return error;
267 bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
326 linux_statfs_buf.ftype = bsd_to_linux_ftype(bsd_statfs->f_type);
327 linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
328 linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
329 linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
330 linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
331 linux_statfs_buf.fffree = bsd_statfs->f_ffree;
332 linux_statfs_buf.ffiles = bsd_statfs->f_files;
333 linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
334 linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
335 linux_statfs_buf.fnamelen = MAXNAMLEN;
336 return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
337 sizeof(struct linux_statfs_buf));
268 linux_statfs.f_type = bsd_to_linux_ftype(bsd_statfs->f_type);
269 linux_statfs.f_bsize = bsd_statfs->f_bsize;
270 linux_statfs.f_blocks = bsd_statfs->f_blocks;
271 linux_statfs.f_bfree = bsd_statfs->f_bfree;
272 linux_statfs.f_bavail = bsd_statfs->f_bavail;
273 linux_statfs.f_ffree = bsd_statfs->f_ffree;
274 linux_statfs.f_files = bsd_statfs->f_files;
275 linux_statfs.f_fsid.val[0] = bsd_statfs->f_fsid.val[0];
276 linux_statfs.f_fsid.val[1] = bsd_statfs->f_fsid.val[1];
277 linux_statfs.f_namelen = MAXNAMLEN;
278 return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
279 sizeof(linux_statfs));
338}
339
340int
341linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args)
342{
343 struct file *fp;
344 struct mount *mp;
345 struct statfs *bsd_statfs;
280}
281
282int
283linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args)
284{
285 struct file *fp;
286 struct mount *mp;
287 struct statfs *bsd_statfs;
346 struct linux_statfs_buf linux_statfs_buf;
288 struct l_statfs linux_statfs;
347 int error;
348
349#ifdef DEBUG
350 if (ldebug(fstatfs))
351 printf(ARGS(fstatfs, "%d, *"), args->fd);
352#endif
353 error = getvnode(p->p_fd, args->fd, &fp);
354 if (error)
355 return error;
356 mp = ((struct vnode *)fp->f_data)->v_mount;
357 bsd_statfs = &mp->mnt_stat;
358 error = VFS_STATFS(mp, bsd_statfs, p);
359 if (error)
360 return error;
361 bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
289 int error;
290
291#ifdef DEBUG
292 if (ldebug(fstatfs))
293 printf(ARGS(fstatfs, "%d, *"), args->fd);
294#endif
295 error = getvnode(p->p_fd, args->fd, &fp);
296 if (error)
297 return error;
298 mp = ((struct vnode *)fp->f_data)->v_mount;
299 bsd_statfs = &mp->mnt_stat;
300 error = VFS_STATFS(mp, bsd_statfs, p);
301 if (error)
302 return error;
303 bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
362 linux_statfs_buf.ftype = bsd_to_linux_ftype(bsd_statfs->f_type);
363 linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
364 linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
365 linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
366 linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
367 linux_statfs_buf.fffree = bsd_statfs->f_ffree;
368 linux_statfs_buf.ffiles = bsd_statfs->f_files;
369 linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
370 linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
371 linux_statfs_buf.fnamelen = MAXNAMLEN;
372 return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
373 sizeof(struct linux_statfs_buf));
304 linux_statfs.f_type = bsd_to_linux_ftype(bsd_statfs->f_type);
305 linux_statfs.f_bsize = bsd_statfs->f_bsize;
306 linux_statfs.f_blocks = bsd_statfs->f_blocks;
307 linux_statfs.f_bfree = bsd_statfs->f_bfree;
308 linux_statfs.f_bavail = bsd_statfs->f_bavail;
309 linux_statfs.f_ffree = bsd_statfs->f_ffree;
310 linux_statfs.f_files = bsd_statfs->f_files;
311 linux_statfs.f_fsid.val[0] = bsd_statfs->f_fsid.val[0];
312 linux_statfs.f_fsid.val[1] = bsd_statfs->f_fsid.val[1];
313 linux_statfs.f_namelen = MAXNAMLEN;
314 return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
315 sizeof(linux_statfs));
374}
375
316}
317
318struct l_ustat
319{
320 l_daddr_t f_tfree;
321 l_ino_t f_tinode;
322 char f_fname[6];
323 char f_fpack[6];
324};
325
376int
326int
377linux_ustat(p, uap)
378 struct proc *p;
379 struct linux_ustat_args *uap;
327linux_ustat(struct proc *p, struct linux_ustat_args *args)
380{
328{
381 struct linux_ustat lu;
329 struct l_ustat lu;
382 dev_t dev;
383 struct vnode *vp;
384 struct statfs *stat;
385 int error;
386
387#ifdef DEBUG
388 if (ldebug(ustat))
330 dev_t dev;
331 struct vnode *vp;
332 struct statfs *stat;
333 int error;
334
335#ifdef DEBUG
336 if (ldebug(ustat))
389 printf(ARGS(ustat, "%d, *"), uap->dev);
337 printf(ARGS(ustat, "%d, *"), args->dev);
390#endif
391
392 /*
393 * lu.f_fname and lu.f_fpack are not used. They are always zeroed.
394 * lu.f_tinode and lu.f_tfree are set from the device's super block.
395 */
396 bzero(&lu, sizeof(lu));
397
398 /*
399 * XXX - Don't return an error if we can't find a vnode for the
400 * device. Our dev_t is 32-bits whereas Linux only has a 16-bits
401 * dev_t. The dev_t that is used now may as well be a truncated
402 * dev_t returned from previous syscalls. Just return a bzeroed
403 * ustat in that case.
404 */
338#endif
339
340 /*
341 * lu.f_fname and lu.f_fpack are not used. They are always zeroed.
342 * lu.f_tinode and lu.f_tfree are set from the device's super block.
343 */
344 bzero(&lu, sizeof(lu));
345
346 /*
347 * XXX - Don't return an error if we can't find a vnode for the
348 * device. Our dev_t is 32-bits whereas Linux only has a 16-bits
349 * dev_t. The dev_t that is used now may as well be a truncated
350 * dev_t returned from previous syscalls. Just return a bzeroed
351 * ustat in that case.
352 */
405 dev = makedev(uap->dev >> 8, uap->dev & 0xFF);
353 dev = makedev(args->dev >> 8, args->dev & 0xFF);
406 if (vfinddev(dev, VCHR, &vp)) {
407 if (vp->v_mount == NULL)
408 return (EINVAL);
409 stat = &(vp->v_mount->mnt_stat);
410 error = VFS_STATFS(vp->v_mount, stat, p);
411 if (error)
412 return (error);
413
414 lu.f_tfree = stat->f_bfree;
415 lu.f_tinode = stat->f_ffree;
416 }
417
354 if (vfinddev(dev, VCHR, &vp)) {
355 if (vp->v_mount == NULL)
356 return (EINVAL);
357 stat = &(vp->v_mount->mnt_stat);
358 error = VFS_STATFS(vp->v_mount, stat, p);
359 if (error)
360 return (error);
361
362 lu.f_tfree = stat->f_bfree;
363 lu.f_tinode = stat->f_ffree;
364 }
365
418 return (copyout(&lu, uap->ubuf, sizeof(lu)));
366 return (copyout(&lu, args->ubuf, sizeof(lu)));
419}
367}
368
369#if defined(__i386__)
370
371static int
372stat64_copyout(struct stat *buf, void *ubuf)
373{
374 struct l_stat64 lbuf;
375
376 bzero(&lbuf, sizeof(lbuf));
377 lbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
378 lbuf.st_ino = buf->st_ino;
379 lbuf.st_mode = buf->st_mode;
380 lbuf.st_nlink = buf->st_nlink;
381 lbuf.st_uid = buf->st_uid;
382 lbuf.st_gid = buf->st_gid;
383 lbuf.st_rdev = buf->st_rdev;
384 lbuf.st_size = buf->st_size;
385 lbuf.st_atime = buf->st_atime;
386 lbuf.st_mtime = buf->st_mtime;
387 lbuf.st_ctime = buf->st_ctime;
388 lbuf.st_blksize = buf->st_blksize;
389 lbuf.st_blocks = buf->st_blocks;
390
391 /*
392 * The __st_ino field makes all the difference. In the Linux kernel
393 * it is conditionally compiled based on STAT64_HAS_BROKEN_ST_INO,
394 * but without the assignment to __st_ino the runtime linker refuses
395 * to mmap(2) any shared libraries. I guess it's broken alright :-)
396 */
397 lbuf.__st_ino = buf->st_ino;
398
399 return (copyout(&lbuf, ubuf, sizeof(lbuf)));
400}
401
402int
403linux_stat64(struct proc *p, struct linux_stat64_args *args)
404{
405 struct stat buf;
406 struct nameidata nd;
407 int error;
408 caddr_t sg;
409
410 sg = stackgap_init();
411 CHECKALTEXIST(p, &sg, args->filename);
412
413#ifdef DEBUG
414 if (ldebug(stat64))
415 printf(ARGS(stat64, "%s, *"), args->filename);
416#endif
417
418 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
419 args->filename, p);
420 error = namei(&nd);
421 if (error)
422 return (error);
423 NDFREE(&nd, NDF_ONLY_PNBUF);
424
425 error = vn_stat(nd.ni_vp, &buf, p);
426 vput(nd.ni_vp);
427 if (error)
428 return (error);
429
430 return (stat64_copyout(&buf, args->statbuf));
431}
432
433int
434linux_lstat64(struct proc *p, struct linux_lstat64_args *args)
435{
436 int error;
437 struct stat sb;
438 struct nameidata nd;
439 caddr_t sg;
440
441 sg = stackgap_init();
442 CHECKALTEXIST(p, &sg, args->filename);
443
444#ifdef DEBUG
445 if (ldebug(lstat64))
446 printf(ARGS(lstat64, "%s, *"), args->filename);
447#endif
448
449 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
450 args->filename, p);
451 error = namei(&nd);
452 if (error)
453 return (error);
454 NDFREE(&nd, NDF_ONLY_PNBUF);
455
456 error = vn_stat(nd.ni_vp, &sb, p);
457 vput(nd.ni_vp);
458 if (error)
459 return (error);
460
461 return (stat64_copyout(&sb, args->statbuf));
462}
463
464int
465linux_fstat64(struct proc *p, struct linux_fstat64_args *args)
466{
467 struct filedesc *fdp;
468 struct file *fp;
469 struct stat buf;
470 int error;
471
472#ifdef DEBUG
473 if (ldebug(fstat64))
474 printf(ARGS(fstat64, "%d, *"), args->fd);
475#endif
476
477 fdp = p->p_fd;
478 if ((unsigned)args->fd >= fdp->fd_nfiles ||
479 (fp = fdp->fd_ofiles[args->fd]) == NULL)
480 return (EBADF);
481
482 error = fo_stat(fp, &buf, p);
483 if (!error)
484 error = stat64_copyout(&buf, args->statbuf);
485
486 return (error);
487}
488
489#endif /* __i386__ */