xref: /freebsd/sys/compat/linux/linux_stats.c (revision c21dee177fdd039bd54a169d52bad2c66942d766)
1c21dee17SSøren Schmidt /*-
2c21dee17SSøren Schmidt  * Copyright (c) 1994-1995 S�ren Schmidt
3c21dee17SSøren Schmidt  * All rights reserved.
4c21dee17SSøren Schmidt  *
5c21dee17SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
6c21dee17SSøren Schmidt  * modification, are permitted provided that the following conditions
7c21dee17SSøren Schmidt  * are met:
8c21dee17SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
9c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
10c21dee17SSøren Schmidt  *    in this position and unchanged.
11c21dee17SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
12c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
13c21dee17SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
14c21dee17SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
15c21dee17SSøren Schmidt  *    derived from this software withough specific prior written permission
16c21dee17SSøren Schmidt  *
17c21dee17SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18c21dee17SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19c21dee17SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20c21dee17SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21c21dee17SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22c21dee17SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c21dee17SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c21dee17SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c21dee17SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26c21dee17SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c21dee17SSøren Schmidt  *
28c21dee17SSøren Schmidt  *  $Id: linux_stats.c,v 1.3 1995/06/08 13:50:52 sos Exp $
29c21dee17SSøren Schmidt  */
30c21dee17SSøren Schmidt 
31c21dee17SSøren Schmidt #include <sys/param.h>
32c21dee17SSøren Schmidt #include <sys/systm.h>
33c21dee17SSøren Schmidt #include <sys/dirent.h>
34c21dee17SSøren Schmidt #include <sys/file.h>
35c21dee17SSøren Schmidt #include <sys/filedesc.h>
36c21dee17SSøren Schmidt #include <sys/proc.h>
37c21dee17SSøren Schmidt #include <sys/mount.h>
38c21dee17SSøren Schmidt #include <sys/namei.h>
39c21dee17SSøren Schmidt #include <sys/stat.h>
40c21dee17SSøren Schmidt #include <sys/vnode.h>
41c21dee17SSøren Schmidt 
42c21dee17SSøren Schmidt #include <machine/cpu.h>
43c21dee17SSøren Schmidt #include <machine/psl.h>
44c21dee17SSøren Schmidt #include <machine/reg.h>
45c21dee17SSøren Schmidt 
46c21dee17SSøren Schmidt #include <i386/linux/linux.h>
47c21dee17SSøren Schmidt 
48c21dee17SSøren Schmidt struct linux_newstat {
49c21dee17SSøren Schmidt     unsigned short stat_dev;
50c21dee17SSøren Schmidt     unsigned short __pad1;
51c21dee17SSøren Schmidt     unsigned long stat_ino;
52c21dee17SSøren Schmidt     unsigned short stat_mode;
53c21dee17SSøren Schmidt     unsigned short stat_nlink;
54c21dee17SSøren Schmidt     unsigned short stat_uid;
55c21dee17SSøren Schmidt     unsigned short stat_gid;
56c21dee17SSøren Schmidt     unsigned short stat_rdev;
57c21dee17SSøren Schmidt     unsigned short __pad2;
58c21dee17SSøren Schmidt     unsigned long stat_size;
59c21dee17SSøren Schmidt     unsigned long stat_blksize;
60c21dee17SSøren Schmidt     unsigned long stat_blocks;
61c21dee17SSøren Schmidt     unsigned long stat_atime;
62c21dee17SSøren Schmidt     unsigned long __unused1;
63c21dee17SSøren Schmidt     unsigned long stat_mtime;
64c21dee17SSøren Schmidt     unsigned long __unused2;
65c21dee17SSøren Schmidt     unsigned long stat_ctime;
66c21dee17SSøren Schmidt     unsigned long __unused3;
67c21dee17SSøren Schmidt     unsigned long __unused4;
68c21dee17SSøren Schmidt     unsigned long __unused5;
69c21dee17SSøren Schmidt };
70c21dee17SSøren Schmidt 
71c21dee17SSøren Schmidt struct linux_newstat_args {
72c21dee17SSøren Schmidt     char *path;
73c21dee17SSøren Schmidt     struct linux_newstat *buf;
74c21dee17SSøren Schmidt };
75c21dee17SSøren Schmidt 
76c21dee17SSøren Schmidt static int
77c21dee17SSøren Schmidt newstat_copyout(struct stat *buf, void *ubuf)
78c21dee17SSøren Schmidt {
79c21dee17SSøren Schmidt     struct linux_newstat tbuf;
80c21dee17SSøren Schmidt 
81c21dee17SSøren Schmidt     tbuf.stat_dev = (buf->st_dev & 0xff) | ((buf->st_dev & 0xff00)<<10);
82c21dee17SSøren Schmidt     tbuf.stat_ino = buf->st_ino;
83c21dee17SSøren Schmidt     tbuf.stat_mode = buf->st_mode;
84c21dee17SSøren Schmidt     tbuf.stat_nlink = buf->st_nlink;
85c21dee17SSøren Schmidt     tbuf.stat_uid = buf->st_uid;
86c21dee17SSøren Schmidt     tbuf.stat_gid = buf->st_gid;
87c21dee17SSøren Schmidt     tbuf.stat_rdev = buf->st_rdev;
88c21dee17SSøren Schmidt     tbuf.stat_size = buf->st_size;
89c21dee17SSøren Schmidt     tbuf.stat_atime = buf->st_atime;
90c21dee17SSøren Schmidt     tbuf.stat_mtime = buf->st_mtime;
91c21dee17SSøren Schmidt     tbuf.stat_ctime = buf->st_ctime;
92c21dee17SSøren Schmidt     tbuf.stat_blksize = buf->st_blksize;
93c21dee17SSøren Schmidt     tbuf.stat_blocks = buf->st_blocks;
94c21dee17SSøren Schmidt     return copyout(&tbuf, ubuf, sizeof(tbuf));
95c21dee17SSøren Schmidt }
96c21dee17SSøren Schmidt 
97c21dee17SSøren Schmidt int
98c21dee17SSøren Schmidt linux_newstat(struct proc *p, struct linux_newstat_args *args, int *retval)
99c21dee17SSøren Schmidt {
100c21dee17SSøren Schmidt     struct stat buf;
101c21dee17SSøren Schmidt     struct linux_newstat tbuf;
102c21dee17SSøren Schmidt     struct nameidata nd;
103c21dee17SSøren Schmidt     int error;
104c21dee17SSøren Schmidt 
105c21dee17SSøren Schmidt #ifdef DEBUG
106c21dee17SSøren Schmidt     printf("Linux-emul(%d): newstat(%s, *)\n", p->p_pid, args->path);
107c21dee17SSøren Schmidt #endif
108c21dee17SSøren Schmidt     NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
109c21dee17SSøren Schmidt     error = namei(&nd);
110c21dee17SSøren Schmidt     if (!error) {
111c21dee17SSøren Schmidt 	error = vn_stat(nd.ni_vp, &buf, p);
112c21dee17SSøren Schmidt 	vput(nd.ni_vp);
113c21dee17SSøren Schmidt     }
114c21dee17SSøren Schmidt     if (!error)
115c21dee17SSøren Schmidt 	error = newstat_copyout(&buf, args->buf);
116c21dee17SSøren Schmidt     return error;
117c21dee17SSøren Schmidt }
118c21dee17SSøren Schmidt 
119c21dee17SSøren Schmidt int
120c21dee17SSøren Schmidt linux_newlstat(struct proc *p, struct linux_newstat_args *args, int *retval)
121c21dee17SSøren Schmidt {
122c21dee17SSøren Schmidt     struct stat buf;
123c21dee17SSøren Schmidt     struct linux_newstat tbuf;
124c21dee17SSøren Schmidt     struct nameidata nd;
125c21dee17SSøren Schmidt     int error;
126c21dee17SSøren Schmidt 
127c21dee17SSøren Schmidt #ifdef DEBUG
128c21dee17SSøren Schmidt     printf("Linux-emul(%d): newlstat(%s, *)\n", p->p_pid, args->path);
129c21dee17SSøren Schmidt #endif
130c21dee17SSøren Schmidt     NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
131c21dee17SSøren Schmidt     error = namei(&nd);
132c21dee17SSøren Schmidt     if (!error) {
133c21dee17SSøren Schmidt 	error = vn_stat(nd.ni_vp, &buf, p);
134c21dee17SSøren Schmidt 	vput(nd.ni_vp);
135c21dee17SSøren Schmidt     }
136c21dee17SSøren Schmidt     if (!error)
137c21dee17SSøren Schmidt 	error = newstat_copyout(&buf, args->buf);
138c21dee17SSøren Schmidt     return error;
139c21dee17SSøren Schmidt }
140c21dee17SSøren Schmidt 
141c21dee17SSøren Schmidt struct linux_newfstat_args {
142c21dee17SSøren Schmidt     int fd;
143c21dee17SSøren Schmidt     struct linux_newstat *buf;
144c21dee17SSøren Schmidt };
145c21dee17SSøren Schmidt 
146c21dee17SSøren Schmidt int
147c21dee17SSøren Schmidt linux_newfstat(struct proc *p, struct linux_newfstat_args *args, int *retval)
148c21dee17SSøren Schmidt {
149c21dee17SSøren Schmidt     struct linux_newstat tbuf;
150c21dee17SSøren Schmidt     struct filedesc *fdp = p->p_fd;
151c21dee17SSøren Schmidt     struct file *fp;
152c21dee17SSøren Schmidt     struct stat buf;
153c21dee17SSøren Schmidt     int error;
154c21dee17SSøren Schmidt 
155c21dee17SSøren Schmidt #ifdef DEBUG
156c21dee17SSøren Schmidt     printf("Linux-emul(%d): newlstat(%d, *)\n", p->p_pid, args->fd);
157c21dee17SSøren Schmidt #endif
158c21dee17SSøren Schmidt     if ((unsigned)args->fd >= fdp->fd_nfiles
159c21dee17SSøren Schmidt 	|| (fp = fdp->fd_ofiles[args->fd]) == NULL)
160c21dee17SSøren Schmidt 	return EBADF;
161c21dee17SSøren Schmidt     switch (fp->f_type) {
162c21dee17SSøren Schmidt     case DTYPE_VNODE:
163c21dee17SSøren Schmidt 	error = vn_stat((struct vnode *)fp->f_data, &buf, p);
164c21dee17SSøren Schmidt 	break;
165c21dee17SSøren Schmidt     case DTYPE_SOCKET:
166c21dee17SSøren Schmidt 	error = soo_stat((struct socket *)fp->f_data, &buf);
167c21dee17SSøren Schmidt 	break;
168c21dee17SSøren Schmidt     default:
169c21dee17SSøren Schmidt 	panic("LINUX newfstat");
170c21dee17SSøren Schmidt     }
171c21dee17SSøren Schmidt     if (!error)
172c21dee17SSøren Schmidt 	error = newstat_copyout(&buf, args->buf);
173c21dee17SSøren Schmidt     return error;
174c21dee17SSøren Schmidt }
175c21dee17SSøren Schmidt 
176c21dee17SSøren Schmidt struct linux_statfs {
177c21dee17SSøren Schmidt 	long ftype;
178c21dee17SSøren Schmidt 	long fbsize;
179c21dee17SSøren Schmidt 	long fblocks;
180c21dee17SSøren Schmidt 	long fbfree;
181c21dee17SSøren Schmidt 	long fbavail;
182c21dee17SSøren Schmidt 	long ffiles;
183c21dee17SSøren Schmidt 	long fffree;
184c21dee17SSøren Schmidt 	linux_fsid_t ffsid;
185c21dee17SSøren Schmidt 	long fnamelen;
186c21dee17SSøren Schmidt 	long fspare[6];
187c21dee17SSøren Schmidt };
188c21dee17SSøren Schmidt 
189c21dee17SSøren Schmidt 
190c21dee17SSøren Schmidt struct linux_statfs_args {
191c21dee17SSøren Schmidt 	char *path;
192c21dee17SSøren Schmidt 	struct statfs *buf;
193c21dee17SSøren Schmidt };
194c21dee17SSøren Schmidt 
195c21dee17SSøren Schmidt int
196c21dee17SSøren Schmidt linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
197c21dee17SSøren Schmidt {
198c21dee17SSøren Schmidt 	struct mount *mp;
199c21dee17SSøren Schmidt 	struct nameidata *ndp;
200c21dee17SSøren Schmidt 	struct statfs *bsd_statfs;
201c21dee17SSøren Schmidt 	struct nameidata nd;
202c21dee17SSøren Schmidt 	struct linux_statfs linux_statfs;
203c21dee17SSøren Schmidt 	int error;
204c21dee17SSøren Schmidt 
205c21dee17SSøren Schmidt #ifdef DEBUG
206c21dee17SSøren Schmidt 	printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path);
207c21dee17SSøren Schmidt #endif
208c21dee17SSøren Schmidt 	ndp = &nd;
209c21dee17SSøren Schmidt   	ndp->ni_cnd.cn_nameiop = LOOKUP;
210c21dee17SSøren Schmidt 	ndp->ni_cnd.cn_flags = FOLLOW;
211c21dee17SSøren Schmidt 	ndp->ni_cnd.cn_proc = curproc;
212c21dee17SSøren Schmidt 	ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
213c21dee17SSøren Schmidt 	ndp->ni_segflg = UIO_USERSPACE;
214c21dee17SSøren Schmidt 	ndp->ni_dirp = args->path;
215c21dee17SSøren Schmidt 	if (error = namei(ndp))
216c21dee17SSøren Schmidt 		return error;
217c21dee17SSøren Schmidt 	mp = ndp->ni_vp->v_mount;
218c21dee17SSøren Schmidt 	bsd_statfs = &mp->mnt_stat;
219c21dee17SSøren Schmidt 	vrele(ndp->ni_vp);
220c21dee17SSøren Schmidt 	if (error = VFS_STATFS(mp, bsd_statfs, p))
221c21dee17SSøren Schmidt 		return error;
222c21dee17SSøren Schmidt 	bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
223c21dee17SSøren Schmidt 	linux_statfs.ftype = bsd_statfs->f_type;
224c21dee17SSøren Schmidt 	linux_statfs.fbsize = bsd_statfs->f_bsize;
225c21dee17SSøren Schmidt 	linux_statfs.fblocks = bsd_statfs->f_blocks;
226c21dee17SSøren Schmidt 	linux_statfs.fbfree = bsd_statfs->f_bfree;
227c21dee17SSøren Schmidt 	linux_statfs.fbavail = bsd_statfs->f_bavail;
228c21dee17SSøren Schmidt   	linux_statfs.fffree = bsd_statfs->f_ffree;
229c21dee17SSøren Schmidt 	linux_statfs.ffiles = bsd_statfs->f_files;
230c21dee17SSøren Schmidt 	linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
231c21dee17SSøren Schmidt 	linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
232c21dee17SSøren Schmidt 	linux_statfs.fnamelen = MAXNAMLEN;
233c21dee17SSøren Schmidt 	return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
234c21dee17SSøren Schmidt 		       sizeof(struct linux_statfs));
235c21dee17SSøren Schmidt }
236c21dee17SSøren Schmidt 
237c21dee17SSøren Schmidt struct linux_fstatfs_args {
238c21dee17SSøren Schmidt 	int fd;
239c21dee17SSøren Schmidt 	struct statfs *buf;
240c21dee17SSøren Schmidt };
241c21dee17SSøren Schmidt 
242c21dee17SSøren Schmidt int
243c21dee17SSøren Schmidt linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args, int *retval)
244c21dee17SSøren Schmidt {
245c21dee17SSøren Schmidt 	struct file *fp;
246c21dee17SSøren Schmidt 	struct mount *mp;
247c21dee17SSøren Schmidt 	struct statfs *bsd_statfs;
248c21dee17SSøren Schmidt 	struct linux_statfs linux_statfs;
249c21dee17SSøren Schmidt 	int error;
250c21dee17SSøren Schmidt 
251c21dee17SSøren Schmidt #ifdef DEBUG
252c21dee17SSøren Schmidt 	printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd);
253c21dee17SSøren Schmidt #endif
254c21dee17SSøren Schmidt 	if (error = getvnode(p->p_fd, args->fd, &fp))
255c21dee17SSøren Schmidt 		return error;
256c21dee17SSøren Schmidt 	mp = ((struct vnode *)fp->f_data)->v_mount;
257c21dee17SSøren Schmidt 	bsd_statfs = &mp->mnt_stat;
258c21dee17SSøren Schmidt 	if (error = VFS_STATFS(mp, bsd_statfs, p))
259c21dee17SSøren Schmidt 		return error;
260c21dee17SSøren Schmidt 	bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
261c21dee17SSøren Schmidt 	linux_statfs.ftype = bsd_statfs->f_type;
262c21dee17SSøren Schmidt 	linux_statfs.fbsize = bsd_statfs->f_bsize;
263c21dee17SSøren Schmidt 	linux_statfs.fblocks = bsd_statfs->f_blocks;
264c21dee17SSøren Schmidt 	linux_statfs.fbfree = bsd_statfs->f_bfree;
265c21dee17SSøren Schmidt 	linux_statfs.fbavail = bsd_statfs->f_bavail;
266c21dee17SSøren Schmidt   	linux_statfs.fffree = bsd_statfs->f_ffree;
267c21dee17SSøren Schmidt 	linux_statfs.ffiles = bsd_statfs->f_files;
268c21dee17SSøren Schmidt 	linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
269c21dee17SSøren Schmidt 	linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
270c21dee17SSøren Schmidt 	linux_statfs.fnamelen = MAXNAMLEN;
271c21dee17SSøren Schmidt 	return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
272c21dee17SSøren Schmidt 		       sizeof(struct linux_statfs));
273c21dee17SSøren Schmidt }
274