]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/linux/linux_stats.c
This commit was generated by cvs2svn to compensate for changes in r53024,
[FreeBSD/FreeBSD.git] / sys / i386 / linux / linux_stats.c
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
9  *    notice, this list of conditions and the following disclaimer 
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software withough specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
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$
29  */
30
31 #include <sys/param.h>
32 #include <sys/systm.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/socketvar.h>
40 #include <sys/stat.h>
41 #include <sys/vnode.h>
42 #include <sys/pipe.h>
43
44 #include <i386/linux/linux.h>
45 #include <i386/linux/linux_proto.h>
46 #include <i386/linux/linux_util.h>
47
48 struct linux_newstat {
49         u_short stat_dev;
50         u_short __pad1;
51         u_long  stat_ino;
52         u_short stat_mode;
53         u_short stat_nlink;
54         u_short stat_uid;
55         u_short stat_gid;
56         u_short stat_rdev;
57         u_short __pad2;
58         u_long  stat_size;
59         u_long  stat_blksize;
60         u_long  stat_blocks;
61         u_long  stat_atime;
62         u_long  __unused1;
63         u_long  stat_mtime;
64         u_long  __unused2;
65         u_long  stat_ctime;
66         u_long  __unused3;
67         u_long  __unused4;
68         u_long  __unused5;
69 };
70
71 static int
72 newstat_copyout(struct stat *buf, void *ubuf)
73 {
74         struct linux_newstat tbuf;
75
76         tbuf.stat_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8);
77         tbuf.stat_ino = buf->st_ino;
78         tbuf.stat_mode = buf->st_mode;
79         tbuf.stat_nlink = buf->st_nlink;
80         tbuf.stat_uid = buf->st_uid;
81         tbuf.stat_gid = buf->st_gid;
82         tbuf.stat_rdev = buf->st_rdev;
83         tbuf.stat_size = buf->st_size;
84         tbuf.stat_atime = buf->st_atime;
85         tbuf.stat_mtime = buf->st_mtime;
86         tbuf.stat_ctime = buf->st_ctime;
87         tbuf.stat_blksize = buf->st_blksize;
88         tbuf.stat_blocks = buf->st_blocks;
89
90         return (copyout(&tbuf, ubuf, sizeof(tbuf)));
91 }
92
93 int
94 linux_newstat(struct proc *p, struct linux_newstat_args *args)
95 {
96         struct stat buf;
97         struct nameidata nd;
98         int error;
99         caddr_t sg;
100
101         sg = stackgap_init();
102         CHECKALTEXIST(p, &sg, args->path);
103
104 #ifdef DEBUG
105         printf("Linux-emul(%ld): newstat(%s, *)\n", (long)p->p_pid,
106                args->path);
107 #endif
108
109         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
110                args->path, p);
111         error = namei(&nd);
112         if (error)
113                 return (error);
114
115         error = vn_stat(nd.ni_vp, &buf, p);
116         vput(nd.ni_vp);
117         if (error)
118                 return (error);
119
120         return (newstat_copyout(&buf, args->buf));
121 }
122
123 /*
124  * Get file status; this version does not follow links.
125  */
126 int
127 linux_newlstat(p, uap)
128         struct proc *p;
129         struct linux_newlstat_args *uap;
130 {
131         int error;
132         struct vnode *vp;
133         struct stat sb;
134         struct nameidata nd;
135         caddr_t sg;
136
137         sg = stackgap_init();
138         CHECKALTEXIST(p, &sg, uap->path);
139
140 #ifdef DEBUG
141         printf("Linux-emul(%ld): newlstat(%s, *)\n", (long)p->p_pid,
142                uap->path);
143 #endif
144
145         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
146                uap->path, p);
147         error = namei(&nd);
148         if (error)
149                 return (error);
150
151         vp = nd.ni_vp;
152         error = vn_stat(vp, &sb, p);
153         vput(vp);
154         if (error)
155                 return (error);
156
157         return (newstat_copyout(&sb, uap->buf));
158 }
159
160 int
161 linux_newfstat(struct proc *p, struct linux_newfstat_args *args)
162 {
163         struct filedesc *fdp;
164         struct file *fp;
165         struct stat buf;
166         int error;
167
168         fdp = p->p_fd;
169
170 #ifdef DEBUG
171         printf("Linux-emul(%ld): newfstat(%d, *)\n", (long)p->p_pid, args->fd);
172 #endif
173
174         if ((unsigned)args->fd >= fdp->fd_nfiles ||
175             (fp = fdp->fd_ofiles[args->fd]) == NULL)
176                 return (EBADF);
177
178         error = fo_stat(fp, &buf, p);
179         if (!error)
180                 error = newstat_copyout(&buf, args->buf);
181
182         return (error);
183 }
184
185 struct linux_statfs_buf {
186         long ftype;
187         long fbsize;
188         long fblocks;
189         long fbfree;
190         long fbavail;
191         long ffiles;
192         long fffree;
193         linux_fsid_t ffsid;
194         long fnamelen;
195         long fspare[6];
196 };
197
198 int
199 linux_statfs(struct proc *p, struct linux_statfs_args *args)
200 {
201         struct mount *mp;
202         struct nameidata *ndp;
203         struct statfs *bsd_statfs;
204         struct nameidata nd;
205         struct linux_statfs_buf linux_statfs_buf;
206         int error;
207         caddr_t sg;
208
209         sg = stackgap_init();
210         CHECKALTEXIST(p, &sg, args->path);
211
212 #ifdef DEBUG
213         printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path);
214 #endif
215         ndp = &nd;
216         NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc);
217         error = namei(ndp);
218         if (error)
219                 return error;
220         mp = ndp->ni_vp->v_mount;
221         bsd_statfs = &mp->mnt_stat;
222         vrele(ndp->ni_vp);
223         error = VFS_STATFS(mp, bsd_statfs, p);
224         if (error)
225                 return error;
226         bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
227         linux_statfs_buf.ftype = bsd_statfs->f_type;
228         linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
229         linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
230         linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
231         linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
232         linux_statfs_buf.fffree = bsd_statfs->f_ffree;
233         linux_statfs_buf.ffiles = bsd_statfs->f_files;
234         linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
235         linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
236         linux_statfs_buf.fnamelen = MAXNAMLEN;
237         return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
238                        sizeof(struct linux_statfs_buf));
239 }
240
241 int
242 linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args)
243 {
244         struct file *fp;
245         struct mount *mp;
246         struct statfs *bsd_statfs;
247         struct linux_statfs_buf linux_statfs_buf;
248         int error;
249
250 #ifdef DEBUG
251         printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd);
252 #endif
253         error = getvnode(p->p_fd, args->fd, &fp);
254         if (error)
255                 return error;
256         mp = ((struct vnode *)fp->f_data)->v_mount;
257         bsd_statfs = &mp->mnt_stat;
258         error = VFS_STATFS(mp, bsd_statfs, p);
259         if (error)
260                 return error;
261         bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
262         linux_statfs_buf.ftype = bsd_statfs->f_type;
263         linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
264         linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
265         linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
266         linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
267         linux_statfs_buf.fffree = bsd_statfs->f_ffree;
268         linux_statfs_buf.ffiles = bsd_statfs->f_files;
269         linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
270         linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
271         linux_statfs_buf.fnamelen = MAXNAMLEN;
272         return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
273                        sizeof(struct linux_statfs_buf));
274 }