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 * 28c3aac50fSPeter Wemm * $FreeBSD$ 29c21dee17SSøren Schmidt */ 30c21dee17SSøren Schmidt 31c21dee17SSøren Schmidt #include <sys/param.h> 32408da119SMarcel Moolenaar #include <sys/conf.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> 40408da119SMarcel Moolenaar #include <sys/systm.h> 41c21dee17SSøren Schmidt #include <sys/vnode.h> 42c21dee17SSøren Schmidt 43c21dee17SSøren Schmidt #include <i386/linux/linux.h> 44d66a5066SPeter Wemm #include <i386/linux/linux_proto.h> 45d66a5066SPeter Wemm #include <i386/linux/linux_util.h> 46c21dee17SSøren Schmidt 47762e6b85SEivind Eklund #include <vm/vm_zone.h> 48762e6b85SEivind Eklund 49c21dee17SSøren Schmidt struct linux_newstat { 504e0eaf69SMarcel Moolenaar u_short stat_dev; 514e0eaf69SMarcel Moolenaar u_short __pad1; 524e0eaf69SMarcel Moolenaar u_long stat_ino; 534e0eaf69SMarcel Moolenaar u_short stat_mode; 544e0eaf69SMarcel Moolenaar u_short stat_nlink; 554e0eaf69SMarcel Moolenaar u_short stat_uid; 564e0eaf69SMarcel Moolenaar u_short stat_gid; 574e0eaf69SMarcel Moolenaar u_short stat_rdev; 584e0eaf69SMarcel Moolenaar u_short __pad2; 594e0eaf69SMarcel Moolenaar u_long stat_size; 604e0eaf69SMarcel Moolenaar u_long stat_blksize; 614e0eaf69SMarcel Moolenaar u_long stat_blocks; 624e0eaf69SMarcel Moolenaar u_long stat_atime; 634e0eaf69SMarcel Moolenaar u_long __unused1; 644e0eaf69SMarcel Moolenaar u_long stat_mtime; 654e0eaf69SMarcel Moolenaar u_long __unused2; 664e0eaf69SMarcel Moolenaar u_long stat_ctime; 674e0eaf69SMarcel Moolenaar u_long __unused3; 684e0eaf69SMarcel Moolenaar u_long __unused4; 694e0eaf69SMarcel Moolenaar u_long __unused5; 70c21dee17SSøren Schmidt }; 71c21dee17SSøren Schmidt 72408da119SMarcel Moolenaar struct linux_ustat 73408da119SMarcel Moolenaar { 74408da119SMarcel Moolenaar int f_tfree; 75408da119SMarcel Moolenaar u_long f_tinode; 76408da119SMarcel Moolenaar char f_fname[6]; 77408da119SMarcel Moolenaar char f_fpack[6]; 78408da119SMarcel Moolenaar }; 79408da119SMarcel Moolenaar 80c21dee17SSøren Schmidt static int 81c21dee17SSøren Schmidt newstat_copyout(struct stat *buf, void *ubuf) 82c21dee17SSøren Schmidt { 83c21dee17SSøren Schmidt struct linux_newstat tbuf; 84c21dee17SSøren Schmidt 85e459b442SMarcel Moolenaar tbuf.stat_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8); 86c21dee17SSøren Schmidt tbuf.stat_ino = buf->st_ino; 87c21dee17SSøren Schmidt tbuf.stat_mode = buf->st_mode; 88c21dee17SSøren Schmidt tbuf.stat_nlink = buf->st_nlink; 89c21dee17SSøren Schmidt tbuf.stat_uid = buf->st_uid; 90c21dee17SSøren Schmidt tbuf.stat_gid = buf->st_gid; 91c21dee17SSøren Schmidt tbuf.stat_rdev = buf->st_rdev; 92c21dee17SSøren Schmidt tbuf.stat_size = buf->st_size; 93c21dee17SSøren Schmidt tbuf.stat_atime = buf->st_atime; 94c21dee17SSøren Schmidt tbuf.stat_mtime = buf->st_mtime; 95c21dee17SSøren Schmidt tbuf.stat_ctime = buf->st_ctime; 96c21dee17SSøren Schmidt tbuf.stat_blksize = buf->st_blksize; 97c21dee17SSøren Schmidt tbuf.stat_blocks = buf->st_blocks; 984e0eaf69SMarcel Moolenaar 994e0eaf69SMarcel Moolenaar return (copyout(&tbuf, ubuf, sizeof(tbuf))); 100c21dee17SSøren Schmidt } 101c21dee17SSøren Schmidt 102c21dee17SSøren Schmidt int 103cb226aaaSPoul-Henning Kamp linux_newstat(struct proc *p, struct linux_newstat_args *args) 104c21dee17SSøren Schmidt { 105c21dee17SSøren Schmidt struct stat buf; 106c21dee17SSøren Schmidt struct nameidata nd; 107c21dee17SSøren Schmidt int error; 108d66a5066SPeter Wemm caddr_t sg; 109d66a5066SPeter Wemm 110d66a5066SPeter Wemm sg = stackgap_init(); 111d66a5066SPeter Wemm CHECKALTEXIST(p, &sg, args->path); 112c21dee17SSøren Schmidt 113c21dee17SSøren Schmidt #ifdef DEBUG 1144e0eaf69SMarcel Moolenaar printf("Linux-emul(%ld): newstat(%s, *)\n", (long)p->p_pid, 1154e0eaf69SMarcel Moolenaar args->path); 116c21dee17SSøren Schmidt #endif 1174e0eaf69SMarcel Moolenaar 1184e0eaf69SMarcel Moolenaar NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1194e0eaf69SMarcel Moolenaar args->path, p); 120c21dee17SSøren Schmidt error = namei(&nd); 1214e0eaf69SMarcel Moolenaar if (error) 1224e0eaf69SMarcel Moolenaar return (error); 123762e6b85SEivind Eklund NDFREE(&nd, NDF_ONLY_PNBUF); 1244e0eaf69SMarcel Moolenaar 125c21dee17SSøren Schmidt error = vn_stat(nd.ni_vp, &buf, p); 126c21dee17SSøren Schmidt vput(nd.ni_vp); 1274e0eaf69SMarcel Moolenaar if (error) 1284e0eaf69SMarcel Moolenaar return (error); 1294e0eaf69SMarcel Moolenaar 1304e0eaf69SMarcel Moolenaar return (newstat_copyout(&buf, args->buf)); 131c21dee17SSøren Schmidt } 132c21dee17SSøren Schmidt 133d66a5066SPeter Wemm /* 134d66a5066SPeter Wemm * Get file status; this version does not follow links. 135d66a5066SPeter Wemm */ 136c21dee17SSøren Schmidt int 137cb226aaaSPoul-Henning Kamp linux_newlstat(p, uap) 138d66a5066SPeter Wemm struct proc *p; 139d66a5066SPeter Wemm struct linux_newlstat_args *uap; 140c21dee17SSøren Schmidt { 141c21dee17SSøren Schmidt int error; 1424e0eaf69SMarcel Moolenaar struct vnode *vp; 1434e0eaf69SMarcel Moolenaar struct stat sb; 144d66a5066SPeter Wemm struct nameidata nd; 145d66a5066SPeter Wemm caddr_t sg; 146d66a5066SPeter Wemm 147d66a5066SPeter Wemm sg = stackgap_init(); 148d66a5066SPeter Wemm CHECKALTEXIST(p, &sg, uap->path); 149c21dee17SSøren Schmidt 150c21dee17SSøren Schmidt #ifdef DEBUG 1514e0eaf69SMarcel Moolenaar printf("Linux-emul(%ld): newlstat(%s, *)\n", (long)p->p_pid, 1524e0eaf69SMarcel Moolenaar uap->path); 153c21dee17SSøren Schmidt #endif 1544e0eaf69SMarcel Moolenaar 1554e0eaf69SMarcel Moolenaar NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 156d66a5066SPeter Wemm uap->path, p); 157c21dee17SSøren Schmidt error = namei(&nd); 158d66a5066SPeter Wemm if (error) 159d66a5066SPeter Wemm return (error); 160762e6b85SEivind Eklund NDFREE(&nd, NDF_ONLY_PNBUF); 1614e0eaf69SMarcel Moolenaar 162d66a5066SPeter Wemm vp = nd.ni_vp; 163d66a5066SPeter Wemm error = vn_stat(vp, &sb, p); 164d66a5066SPeter Wemm vput(vp); 165d66a5066SPeter Wemm if (error) 166d66a5066SPeter Wemm return (error); 1674e0eaf69SMarcel Moolenaar 1684e0eaf69SMarcel Moolenaar return (newstat_copyout(&sb, uap->buf)); 169d66a5066SPeter Wemm } 170c21dee17SSøren Schmidt 171c21dee17SSøren Schmidt int 172cb226aaaSPoul-Henning Kamp linux_newfstat(struct proc *p, struct linux_newfstat_args *args) 173c21dee17SSøren Schmidt { 1744e0eaf69SMarcel Moolenaar struct filedesc *fdp; 175c21dee17SSøren Schmidt struct file *fp; 176c21dee17SSøren Schmidt struct stat buf; 177c21dee17SSøren Schmidt int error; 178c21dee17SSøren Schmidt 1794e0eaf69SMarcel Moolenaar fdp = p->p_fd; 1804e0eaf69SMarcel Moolenaar 181c21dee17SSøren Schmidt #ifdef DEBUG 1824e0eaf69SMarcel Moolenaar printf("Linux-emul(%ld): newfstat(%d, *)\n", (long)p->p_pid, args->fd); 183c21dee17SSøren Schmidt #endif 1844e0eaf69SMarcel Moolenaar 1854e0eaf69SMarcel Moolenaar if ((unsigned)args->fd >= fdp->fd_nfiles || 1864e0eaf69SMarcel Moolenaar (fp = fdp->fd_ofiles[args->fd]) == NULL) 1874e0eaf69SMarcel Moolenaar return (EBADF); 1884e0eaf69SMarcel Moolenaar 18953c2c4e2SPeter Wemm error = fo_stat(fp, &buf, p); 190c21dee17SSøren Schmidt if (!error) 191c21dee17SSøren Schmidt error = newstat_copyout(&buf, args->buf); 1924e0eaf69SMarcel Moolenaar 1934e0eaf69SMarcel Moolenaar return (error); 194c21dee17SSøren Schmidt } 195c21dee17SSøren Schmidt 196d66a5066SPeter Wemm struct linux_statfs_buf { 197c21dee17SSøren Schmidt long ftype; 198c21dee17SSøren Schmidt long fbsize; 199c21dee17SSøren Schmidt long fblocks; 200c21dee17SSøren Schmidt long fbfree; 201c21dee17SSøren Schmidt long fbavail; 202c21dee17SSøren Schmidt long ffiles; 203c21dee17SSøren Schmidt long fffree; 204c21dee17SSøren Schmidt linux_fsid_t ffsid; 205c21dee17SSøren Schmidt long fnamelen; 206c21dee17SSøren Schmidt long fspare[6]; 207c21dee17SSøren Schmidt }; 208c21dee17SSøren Schmidt 209c21dee17SSøren Schmidt int 210cb226aaaSPoul-Henning Kamp linux_statfs(struct proc *p, struct linux_statfs_args *args) 211c21dee17SSøren Schmidt { 212c21dee17SSøren Schmidt struct mount *mp; 213c21dee17SSøren Schmidt struct nameidata *ndp; 214c21dee17SSøren Schmidt struct statfs *bsd_statfs; 215c21dee17SSøren Schmidt struct nameidata nd; 216d66a5066SPeter Wemm struct linux_statfs_buf linux_statfs_buf; 217c21dee17SSøren Schmidt int error; 218d66a5066SPeter Wemm caddr_t sg; 219d66a5066SPeter Wemm 220d66a5066SPeter Wemm sg = stackgap_init(); 221d66a5066SPeter Wemm CHECKALTEXIST(p, &sg, args->path); 222c21dee17SSøren Schmidt 223c21dee17SSøren Schmidt #ifdef DEBUG 224c21dee17SSøren Schmidt printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path); 225c21dee17SSøren Schmidt #endif 226c21dee17SSøren Schmidt ndp = &nd; 2272b14f991SJulian Elischer NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc); 228d5558c00SPeter Wemm error = namei(ndp); 229d5558c00SPeter Wemm if (error) 230c21dee17SSøren Schmidt return error; 231762e6b85SEivind Eklund NDFREE(ndp, NDF_ONLY_PNBUF); 232c21dee17SSøren Schmidt mp = ndp->ni_vp->v_mount; 233c21dee17SSøren Schmidt bsd_statfs = &mp->mnt_stat; 234c21dee17SSøren Schmidt vrele(ndp->ni_vp); 235d5558c00SPeter Wemm error = VFS_STATFS(mp, bsd_statfs, p); 236d5558c00SPeter Wemm if (error) 237c21dee17SSøren Schmidt return error; 238c21dee17SSøren Schmidt bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 239d66a5066SPeter Wemm linux_statfs_buf.ftype = bsd_statfs->f_type; 240d66a5066SPeter Wemm linux_statfs_buf.fbsize = bsd_statfs->f_bsize; 241d66a5066SPeter Wemm linux_statfs_buf.fblocks = bsd_statfs->f_blocks; 242d66a5066SPeter Wemm linux_statfs_buf.fbfree = bsd_statfs->f_bfree; 243d66a5066SPeter Wemm linux_statfs_buf.fbavail = bsd_statfs->f_bavail; 244d66a5066SPeter Wemm linux_statfs_buf.fffree = bsd_statfs->f_ffree; 245d66a5066SPeter Wemm linux_statfs_buf.ffiles = bsd_statfs->f_files; 246d66a5066SPeter Wemm linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0]; 247d66a5066SPeter Wemm linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1]; 248d66a5066SPeter Wemm linux_statfs_buf.fnamelen = MAXNAMLEN; 249d66a5066SPeter Wemm return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf, 250d66a5066SPeter Wemm sizeof(struct linux_statfs_buf)); 251c21dee17SSøren Schmidt } 252c21dee17SSøren Schmidt 253c21dee17SSøren Schmidt int 254cb226aaaSPoul-Henning Kamp linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args) 255c21dee17SSøren Schmidt { 256c21dee17SSøren Schmidt struct file *fp; 257c21dee17SSøren Schmidt struct mount *mp; 258c21dee17SSøren Schmidt struct statfs *bsd_statfs; 259d66a5066SPeter Wemm struct linux_statfs_buf linux_statfs_buf; 260c21dee17SSøren Schmidt int error; 261c21dee17SSøren Schmidt 262c21dee17SSøren Schmidt #ifdef DEBUG 263c21dee17SSøren Schmidt printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd); 264c21dee17SSøren Schmidt #endif 265d5558c00SPeter Wemm error = getvnode(p->p_fd, args->fd, &fp); 266d5558c00SPeter Wemm if (error) 267c21dee17SSøren Schmidt return error; 268c21dee17SSøren Schmidt mp = ((struct vnode *)fp->f_data)->v_mount; 269c21dee17SSøren Schmidt bsd_statfs = &mp->mnt_stat; 270d5558c00SPeter Wemm error = VFS_STATFS(mp, bsd_statfs, p); 271d5558c00SPeter Wemm if (error) 272c21dee17SSøren Schmidt return error; 273c21dee17SSøren Schmidt bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 274d66a5066SPeter Wemm linux_statfs_buf.ftype = bsd_statfs->f_type; 275d66a5066SPeter Wemm linux_statfs_buf.fbsize = bsd_statfs->f_bsize; 276d66a5066SPeter Wemm linux_statfs_buf.fblocks = bsd_statfs->f_blocks; 277d66a5066SPeter Wemm linux_statfs_buf.fbfree = bsd_statfs->f_bfree; 278d66a5066SPeter Wemm linux_statfs_buf.fbavail = bsd_statfs->f_bavail; 279d66a5066SPeter Wemm linux_statfs_buf.fffree = bsd_statfs->f_ffree; 280d66a5066SPeter Wemm linux_statfs_buf.ffiles = bsd_statfs->f_files; 281d66a5066SPeter Wemm linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0]; 282d66a5066SPeter Wemm linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1]; 283d66a5066SPeter Wemm linux_statfs_buf.fnamelen = MAXNAMLEN; 284d66a5066SPeter Wemm return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf, 285d66a5066SPeter Wemm sizeof(struct linux_statfs_buf)); 286c21dee17SSøren Schmidt } 287408da119SMarcel Moolenaar 288408da119SMarcel Moolenaar int 289408da119SMarcel Moolenaar linux_ustat(p, uap) 290408da119SMarcel Moolenaar struct proc *p; 291408da119SMarcel Moolenaar struct linux_ustat_args *uap; 292408da119SMarcel Moolenaar { 293408da119SMarcel Moolenaar struct linux_ustat lu; 294408da119SMarcel Moolenaar dev_t dev; 295408da119SMarcel Moolenaar struct vnode *vp; 296408da119SMarcel Moolenaar struct statfs *stat; 297408da119SMarcel Moolenaar int error; 298408da119SMarcel Moolenaar 299408da119SMarcel Moolenaar #ifdef DEBUG 300408da119SMarcel Moolenaar printf("Linux-emul(%ld): ustat(%d, *)\n", (long)p->p_pid, uap->dev); 301408da119SMarcel Moolenaar #endif 302408da119SMarcel Moolenaar 303408da119SMarcel Moolenaar /* 304408da119SMarcel Moolenaar * lu.f_fname and lu.f_fpack are not used. They are always zeroed. 305408da119SMarcel Moolenaar * lu.f_tinode and lu.f_tfree are set from the device's super block. 306408da119SMarcel Moolenaar */ 307408da119SMarcel Moolenaar bzero(&lu, sizeof(lu)); 308408da119SMarcel Moolenaar 309408da119SMarcel Moolenaar /* 310408da119SMarcel Moolenaar * XXX - Don't return an error if we can't find a vnode for the 311408da119SMarcel Moolenaar * device. Our dev_t is 32-bits whereas Linux only has a 16-bits 312408da119SMarcel Moolenaar * dev_t. The dev_t that is used now may as well be a truncated 313408da119SMarcel Moolenaar * dev_t returned from previous syscalls. Just return a bzeroed 314408da119SMarcel Moolenaar * ustat in that case. 315408da119SMarcel Moolenaar */ 316408da119SMarcel Moolenaar dev = makebdev(uap->dev >> 8, uap->dev & 0xFF); 317408da119SMarcel Moolenaar if (vfinddev(dev, VBLK, &vp)) { 318408da119SMarcel Moolenaar if (vp->v_mount == NULL) 319408da119SMarcel Moolenaar return (EINVAL); 320408da119SMarcel Moolenaar stat = &(vp->v_mount->mnt_stat); 321408da119SMarcel Moolenaar error = VFS_STATFS(vp->v_mount, stat, p); 322408da119SMarcel Moolenaar if (error) 323408da119SMarcel Moolenaar return (error); 324408da119SMarcel Moolenaar 325408da119SMarcel Moolenaar lu.f_tfree = stat->f_bfree; 326408da119SMarcel Moolenaar lu.f_tinode = stat->f_ffree; 327408da119SMarcel Moolenaar } 328408da119SMarcel Moolenaar 329408da119SMarcel Moolenaar return (copyout(&lu, uap->ubuf, sizeof(lu))); 330408da119SMarcel Moolenaar } 331