2 * Copyright (c) 1994-1995 Søren Schmidt
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 without specific prior written permission
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.
28 * $FreeBSD: src/sys/compat/linux/linux_file.c,v 1.41.2.6 2003/01/06 09:19:43 fjoe Exp $
29 * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.39 2008/09/28 05:08:16 dillon Exp $
32 #include "opt_compat.h"
34 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <sys/dirent.h>
38 #include <sys/fcntl.h>
41 #include <sys/filedesc.h>
42 #include <sys/kern_syscall.h>
44 #include <sys/malloc.h>
45 #include <sys/mount.h>
46 #include <sys/nlookup.h>
48 #include <sys/sysproto.h>
50 #include <sys/vnode.h>
52 #include <vfs/ufs/quota.h>
53 #include <vfs/ufs/ufsmount.h>
55 #include <sys/file2.h>
56 #include <sys/mplock2.h>
58 #include <arch_linux/linux.h>
59 #include <arch_linux/linux_proto.h>
60 #include "linux_util.h"
66 sys_linux_creat(struct linux_creat_args *args)
69 struct nlookupdata nd;
73 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
78 kprintf(ARGS(creat, "%s, %d"), path, args->mode);
81 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
83 error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC,
84 args->mode, &args->sysmsg_iresult);
87 linux_free_path(&path);
95 linux_open_common(int dfd, char *lpath, int lflags, int mode, int *iresult)
98 struct thread *td = curthread;
99 struct proc *p = td->td_proc;
100 struct nlookupdata nd;
105 if (lflags & LINUX_O_CREAT) {
106 error = linux_copyin_path(lpath, &path,
109 error = linux_copyin_path(lpath, &path,
116 if (lflags & LINUX_O_RDONLY)
118 if (lflags & LINUX_O_WRONLY)
120 if (lflags & LINUX_O_RDWR)
122 if (lflags & LINUX_O_NDELAY)
124 if (lflags & LINUX_O_APPEND)
126 if (lflags & LINUX_O_SYNC)
128 if (lflags & LINUX_O_NONBLOCK)
130 if (lflags & LINUX_FASYNC)
132 if (lflags & LINUX_O_CREAT)
134 if (lflags & LINUX_O_TRUNC)
136 if (lflags & LINUX_O_EXCL)
138 if (lflags & LINUX_O_NOCTTY)
142 error = nlookup_init_at(&nd, &fp, dfd, path, UIO_SYSSPACE, NLC_FOLLOW);
144 error = kern_open(&nd, flags, mode, iresult);
146 nlookup_done_at(&nd, fp);
148 if (error == 0 && !(flags & O_NOCTTY) &&
149 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
152 fp = holdfp(p->p_fd, *iresult, -1);
154 if (fp->f_type == DTYPE_VNODE) {
155 fo_ioctl(fp, TIOCSCTTY, NULL,
162 if (error == 0 && lflags & LINUX_O_DIRECTORY) {
166 fp = holdfp(p->p_fd, *iresult, -1);
168 vp = (struct vnode *) fp->f_data;
169 if (vp->v_type != VDIR)
174 kern_close(*iresult);
180 linux_free_path(&path);
185 sys_linux_open(struct linux_open_args *args)
191 kprintf(ARGS(open, "%s, 0x%x, 0x%x"), args->path, args->flags,
195 error = linux_open_common(AT_FDCWD, args->path, args->flags,
196 args->mode, &args->sysmsg_iresult);
200 kprintf(LMSG("open returns error %d"), error);
206 sys_linux_openat(struct linux_openat_args *args)
213 kprintf(ARGS(openat, "%s, 0x%x, 0x%x"), args->path,
214 args->flags, args->mode);
217 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
219 error = linux_open_common(dfd, args->path, args->flags,
220 args->mode, &args->sysmsg_iresult);
224 kprintf(LMSG("openat returns error %d"), error);
233 sys_linux_lseek(struct linux_lseek_args *args)
239 kprintf(ARGS(lseek, "%d, %ld, %d"),
240 args->fdes, (long)args->off, args->whence);
242 error = kern_lseek(args->fdes, args->off, args->whence,
243 &args->sysmsg_offset);
252 sys_linux_llseek(struct linux_llseek_args *args)
259 kprintf(ARGS(llseek, "%d, %d:%d, %d"),
260 args->fd, args->ohigh, args->olow, args->whence);
262 off = (args->olow) | (((off_t) args->ohigh) << 32);
264 error = kern_lseek(args->fd, off, args->whence, &res);
267 error = copyout(&res, args->res, sizeof(res));
275 sys_linux_readdir(struct linux_readdir_args *args)
277 struct linux_getdents_args lda;
281 lda.dent = args->dent;
283 lda.sysmsg_iresult = 0;
284 error = sys_linux_getdents(&lda);
285 args->sysmsg_iresult = lda.sysmsg_iresult;
290 * Note that linux_getdents(2) and linux_getdents64(2) have the same
291 * arguments. They only differ in the definition of struct dirent they
292 * operate on. We use this to common the code, with the exception of
293 * accessing struct dirent. Note that linux_readdir(2) is implemented
294 * by means of linux_getdents(2). In this case we never operate on
295 * struct dirent64 and thus don't need to handle it...
302 char d_name[LINUX_NAME_MAX + 1];
310 char d_name[LINUX_NAME_MAX + 1];
313 #define LINUX_RECLEN(de,namlen) \
314 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
316 #define LINUX_DIRBLKSIZ 512
322 getdents_common(struct linux_getdents64_args *args, int is64bit)
324 struct thread *td = curthread;
325 struct proc *p = td->td_proc;
328 caddr_t inp, buf; /* BSD-format */
329 int reclen; /* BSD-format */
331 caddr_t outp; /* Linux-format */
332 int linuxreclen = 0; /* Linux-format */
339 struct l_dirent linux_dirent;
340 struct l_dirent64 linux_dirent64;
341 int error, eofflag, justone;
342 size_t buflen, nbytes;
343 off_t *cookies = NULL, *cookiep;
346 if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0)
350 if ((fp->f_flag & FREAD) == 0) {
355 vp = (struct vnode *) fp->f_data;
356 if (vp->v_type != VDIR) {
361 if ((error = VOP_GETATTR(vp, &va)) != 0)
364 nbytes = args->count;
365 if (nbytes == (size_t)-1) {
366 /* readdir(2) case. Always struct dirent. */
371 nbytes = sizeof(linux_dirent);
376 if ((size_t)nbytes < 0)
381 buflen = max(LINUX_DIRBLKSIZ, nbytes);
382 buflen = min(buflen, MAXBSIZE);
383 buf = kmalloc(buflen, M_TEMP, M_WAITOK);
387 aiov.iov_len = buflen;
388 auio.uio_iov = &aiov;
390 auio.uio_rw = UIO_READ;
391 auio.uio_segflg = UIO_SYSSPACE;
393 auio.uio_resid = buflen;
394 auio.uio_offset = off;
397 kfree(cookies, M_TEMP);
403 if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
408 outp = (caddr_t)args->dirent;
410 if (auio.uio_resid >= buflen)
412 len = buflen - auio.uio_resid;
417 * When using cookies, the vfs has the option of reading from
418 * a different offset than that supplied (UFS truncates the
419 * offset to a block boundary to make sure that it never reads
420 * partway through a directory entry, even if the directory
421 * has been compacted).
423 while (len > 0 && ncookies > 0 && *cookiep < off) {
424 bdp = (struct dirent *) inp;
425 len -= _DIRENT_DIRSIZ(bdp);
426 inp += _DIRENT_DIRSIZ(bdp);
433 if (cookiep && ncookies == 0)
435 bdp = (struct dirent *) inp;
436 reclen = _DIRENT_DIRSIZ(bdp);
442 if (bdp->d_ino == 0) {
455 linuxreclen = (is64bit)
456 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
457 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
459 if (reclen > len || resid < linuxreclen) {
464 bzero(&linux_dirent, sizeof(linux_dirent));
465 bzero(&linux_dirent64, sizeof(linux_dirent64));
467 /* readdir(2) case. */
468 linux_dirent.d_ino = (l_long)INO64TO32(bdp->d_ino);
469 linux_dirent.d_off = (l_off_t)linuxreclen;
470 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
471 strcpy(linux_dirent.d_name, bdp->d_name);
472 error = copyout(&linux_dirent, outp, linuxreclen);
475 linux_dirent64.d_ino = INO64TO32(bdp->d_ino);
476 linux_dirent64.d_off = (cookiep)
478 : (l_off_t)(off + reclen);
479 linux_dirent64.d_reclen =
480 (l_ushort)linuxreclen;
481 linux_dirent64.d_type = bdp->d_type;
482 strcpy(linux_dirent64.d_name, bdp->d_name);
483 error = copyout(&linux_dirent64, outp,
486 linux_dirent.d_ino = INO64TO32(bdp->d_ino);
487 linux_dirent.d_off = (cookiep)
489 : (l_off_t)(off + reclen);
490 linux_dirent.d_reclen = (l_ushort)linuxreclen;
491 strcpy(linux_dirent.d_name, bdp->d_name);
492 error = copyout(&linux_dirent, outp,
509 resid -= linuxreclen;
515 if (outp == (caddr_t)args->dirent && eofflag == 0)
520 nbytes = resid + linuxreclen;
523 args->sysmsg_iresult = (int)(nbytes - resid);
527 kfree(cookies, M_TEMP);
540 sys_linux_getdents(struct linux_getdents_args *args)
543 if (ldebug(getdents))
544 kprintf(ARGS(getdents, "%d, *, %d"), args->fd, args->count);
546 return (getdents_common((struct linux_getdents64_args*)args, 0));
553 sys_linux_getdents64(struct linux_getdents64_args *args)
556 if (ldebug(getdents64))
557 kprintf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count);
559 return (getdents_common(args, 1));
563 * These exist mainly for hooks for doing /compat/linux translation.
568 sys_linux_access(struct linux_access_args *args)
570 struct nlookupdata nd;
574 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
579 kprintf(ARGS(access, "%s, %d"), path, args->flags);
582 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
584 error = kern_access(&nd, args->flags, 0);
587 linux_free_path(&path);
595 sys_linux_unlink(struct linux_unlink_args *args)
597 struct nlookupdata nd;
601 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
606 kprintf(ARGS(unlink, "%s"), path);
609 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
611 error = kern_unlink(&nd);
614 linux_free_path(&path);
619 sys_linux_unlinkat(struct linux_unlinkat_args *args)
621 struct nlookupdata nd;
626 if (args->flag & ~LINUX_AT_REMOVEDIR)
629 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
631 kprintf("linux_copyin_path says error = %d\n", error);
636 kprintf(ARGS(unlink, "%s"), path);
639 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
641 error = nlookup_init_at(&nd, &fp, dfd, path, UIO_SYSSPACE, 0);
643 if (args->flag & LINUX_AT_REMOVEDIR)
644 error = kern_rmdir(&nd);
646 error = kern_unlink(&nd);
648 nlookup_done_at(&nd, fp);
650 linux_free_path(&path);
658 sys_linux_chdir(struct linux_chdir_args *args)
660 struct nlookupdata nd;
664 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
669 kprintf(ARGS(chdir, "%s"), path);
672 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
674 error = kern_chdir(&nd);
678 linux_free_path(&path);
686 sys_linux_chmod(struct linux_chmod_args *args)
688 struct nlookupdata nd;
692 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
697 kprintf(ARGS(chmod, "%s, %d"), path, args->mode);
700 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
702 error = kern_chmod(&nd, args->mode);
705 linux_free_path(&path);
713 sys_linux_mkdir(struct linux_mkdir_args *args)
715 struct nlookupdata nd;
719 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
724 kprintf(ARGS(mkdir, "%s, %d"), path, args->mode);
727 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
729 error = kern_mkdir(&nd, args->mode);
733 linux_free_path(&path);
738 sys_linux_mkdirat(struct linux_mkdirat_args *args)
740 struct nlookupdata nd;
745 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
750 kprintf(ARGS(mkdir, "%s, %d"), path, args->mode);
752 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
754 error = nlookup_init_at(&nd, &fp, dfd, path, UIO_SYSSPACE, 0);
756 error = kern_mkdir(&nd, args->mode);
757 nlookup_done_at(&nd, fp);
760 linux_free_path(&path);
768 sys_linux_rmdir(struct linux_rmdir_args *args)
770 struct nlookupdata nd;
774 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
779 kprintf(ARGS(rmdir, "%s"), path);
782 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
784 error = kern_rmdir(&nd);
787 linux_free_path(&path);
795 sys_linux_rename(struct linux_rename_args *args)
797 struct nlookupdata fromnd, tond;
801 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
804 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
806 linux_free_path(&from);
811 kprintf(ARGS(rename, "%s, %s"), from, to);
814 error = nlookup_init(&fromnd, from, UIO_SYSSPACE, 0);
816 error = nlookup_init(&tond, to, UIO_SYSSPACE, 0);
818 error = kern_rename(&fromnd, &tond);
821 nlookup_done(&fromnd);
823 linux_free_path(&from);
824 linux_free_path(&to);
829 sys_linux_renameat(struct linux_renameat_args *args)
831 struct nlookupdata fromnd, tond;
832 struct file *fp, *fp2;
834 int olddfd, newdfd,error;
836 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
839 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
841 linux_free_path(&from);
846 kprintf(ARGS(rename, "%s, %s"), from, to);
848 olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd;
849 newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
851 error = nlookup_init_at(&fromnd, &fp, olddfd, from, UIO_SYSSPACE, 0);
853 error = nlookup_init_at(&tond, &fp2, newdfd, to, UIO_SYSSPACE, 0);
855 error = kern_rename(&fromnd, &tond);
856 nlookup_done_at(&tond, fp2);
858 nlookup_done_at(&fromnd, fp);
860 linux_free_path(&from);
861 linux_free_path(&to);
869 sys_linux_symlink(struct linux_symlink_args *args)
871 struct thread *td = curthread;
872 struct nlookupdata nd;
877 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
880 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
882 linux_free_path(&path);
887 kprintf(ARGS(symlink, "%s, %s"), path, link);
890 error = nlookup_init(&nd, link, UIO_SYSSPACE, 0);
892 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
893 error = kern_symlink(&nd, path, mode);
897 linux_free_path(&path);
898 linux_free_path(&link);
903 sys_linux_symlinkat(struct linux_symlinkat_args *args)
905 struct thread *td = curthread;
906 struct nlookupdata nd;
912 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
915 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
917 linux_free_path(&path);
922 kprintf(ARGS(symlink, "%s, %s"), path, link);
924 newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
926 error = nlookup_init_at(&nd, &fp, newdfd, link, UIO_SYSSPACE, 0);
928 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
929 error = kern_symlink(&nd, path, mode);
931 nlookup_done_at(&nd, fp);
933 linux_free_path(&path);
934 linux_free_path(&link);
942 sys_linux_readlink(struct linux_readlink_args *args)
944 struct nlookupdata nd;
948 error = linux_copyin_path(args->name, &path, LINUX_PATH_EXISTS);
952 if (ldebug(readlink))
953 kprintf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
957 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
959 error = kern_readlink(&nd, args->buf, args->count,
960 &args->sysmsg_iresult);
964 linux_free_path(&path);
969 sys_linux_readlinkat(struct linux_readlinkat_args *args)
971 struct nlookupdata nd;
976 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
980 if (ldebug(readlink))
981 kprintf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
984 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
986 error = nlookup_init_at(&nd, &fp, dfd, path, UIO_SYSSPACE, 0);
988 error = kern_readlink(&nd, args->buf, args->count,
989 &args->sysmsg_iresult);
991 nlookup_done_at(&nd, fp);
993 linux_free_path(&path);
1001 sys_linux_truncate(struct linux_truncate_args *args)
1003 struct nlookupdata nd;
1007 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1011 if (ldebug(truncate))
1012 kprintf(ARGS(truncate, "%s, %ld"), path,
1013 (long)args->length);
1016 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1018 error = kern_truncate(&nd, args->length);
1021 linux_free_path(&path);
1029 sys_linux_truncate64(struct linux_truncate64_args *args)
1031 struct nlookupdata nd;
1035 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1039 if (ldebug(truncate64))
1040 kprintf(ARGS(truncate64, "%s, %lld"), path,
1041 (off_t)args->length);
1044 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1046 error = kern_truncate(&nd, args->length);
1049 linux_free_path(&path);
1057 sys_linux_ftruncate(struct linux_ftruncate_args *args)
1062 if (ldebug(ftruncate))
1063 kprintf(ARGS(ftruncate, "%d, %ld"), args->fd,
1064 (long)args->length);
1067 error = kern_ftruncate(args->fd, args->length);
1077 sys_linux_ftruncate64(struct linux_ftruncate64_args *args)
1082 if (ldebug(ftruncate))
1083 kprintf(ARGS(ftruncate64, "%d, %lld"), args->fd,
1084 (off_t)args->length);
1087 error = kern_ftruncate(args->fd, args->length);
1097 sys_linux_link(struct linux_link_args *args)
1099 struct nlookupdata nd, linknd;
1103 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1106 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
1108 linux_free_path(&path);
1113 kprintf(ARGS(link, "%s, %s"), path, link);
1116 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1118 error = nlookup_init(&linknd, link, UIO_SYSSPACE, 0);
1120 error = kern_link(&nd, &linknd);
1121 nlookup_done(&linknd);
1125 linux_free_path(&path);
1126 linux_free_path(&link);
1131 sys_linux_linkat(struct linux_linkat_args *args)
1133 struct nlookupdata nd, linknd;
1134 struct file *fp, *fp2;
1136 int olddfd, newdfd, error;
1138 if (args->flags != 0)
1141 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1144 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
1146 linux_free_path(&path);
1151 kprintf(ARGS(link, "%s, %s"), path, link);
1153 olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd;
1154 newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
1156 error = nlookup_init_at(&nd, &fp, olddfd, path, UIO_SYSSPACE, NLC_FOLLOW);
1158 error = nlookup_init_at(&linknd, &fp2, newdfd, link, UIO_SYSSPACE, 0);
1160 error = kern_link(&nd, &linknd);
1161 nlookup_done_at(&linknd, fp2);
1163 nlookup_done_at(&nd, fp);
1165 linux_free_path(&path);
1166 linux_free_path(&link);
1174 sys_linux_fdatasync(struct linux_fdatasync_args *uap)
1176 struct fsync_args bsd;
1180 bsd.sysmsg_iresult = 0;
1182 error = sys_fsync(&bsd);
1183 uap->sysmsg_iresult = bsd.sysmsg_iresult;
1191 sys_linux_pread(struct linux_pread_args *uap)
1193 struct thread *td = curthread;
1198 aiov.iov_base = uap->buf;
1199 aiov.iov_len = uap->nbyte;
1200 auio.uio_iov = &aiov;
1201 auio.uio_iovcnt = 1;
1202 auio.uio_offset = uap->offset;
1203 auio.uio_resid = uap->nbyte;
1204 auio.uio_rw = UIO_READ;
1205 auio.uio_segflg = UIO_USERSPACE;
1208 if ((ssize_t)auio.uio_resid < 0) {
1211 error = kern_preadv(uap->fd, &auio, O_FOFFSET,
1212 &uap->sysmsg_szresult);
1221 sys_linux_pwrite(struct linux_pwrite_args *uap)
1223 struct thread *td = curthread;
1228 aiov.iov_base = uap->buf;
1229 aiov.iov_len = uap->nbyte;
1230 auio.uio_iov = &aiov;
1231 auio.uio_iovcnt = 1;
1232 auio.uio_offset = uap->offset;
1233 auio.uio_resid = uap->nbyte;
1234 auio.uio_rw = UIO_WRITE;
1235 auio.uio_segflg = UIO_USERSPACE;
1238 if ((ssize_t)auio.uio_resid < 0) {
1241 error = kern_pwritev(uap->fd, &auio, O_FOFFSET,
1242 &uap->sysmsg_szresult);
1251 sys_linux_oldumount(struct linux_oldumount_args *args)
1253 struct linux_umount_args args2;
1256 args2.path = args->path;
1258 args2.sysmsg_iresult = 0;
1259 error = sys_linux_umount(&args2);
1260 args->sysmsg_iresult = args2.sysmsg_iresult;
1268 sys_linux_umount(struct linux_umount_args *args)
1270 struct unmount_args bsd;
1273 bsd.path = args->path;
1274 bsd.flags = args->flags; /* XXX correct? */
1275 bsd.sysmsg_iresult = 0;
1277 error = sys_unmount(&bsd);
1278 args->sysmsg_iresult = bsd.sysmsg_iresult;
1283 * fcntl family of syscalls
1297 linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock)
1299 switch (linux_flock->l_type) {
1301 bsd_flock->l_type = F_RDLCK;
1304 bsd_flock->l_type = F_WRLCK;
1307 bsd_flock->l_type = F_UNLCK;
1310 bsd_flock->l_type = -1;
1313 bsd_flock->l_whence = linux_flock->l_whence;
1314 bsd_flock->l_start = (off_t)linux_flock->l_start;
1315 bsd_flock->l_len = (off_t)linux_flock->l_len;
1316 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1323 bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock)
1325 switch (bsd_flock->l_type) {
1327 linux_flock->l_type = LINUX_F_RDLCK;
1330 linux_flock->l_type = LINUX_F_WRLCK;
1333 linux_flock->l_type = LINUX_F_UNLCK;
1336 linux_flock->l_whence = bsd_flock->l_whence;
1337 linux_flock->l_start = (l_off_t)bsd_flock->l_start;
1338 linux_flock->l_len = (l_off_t)bsd_flock->l_len;
1339 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1342 #if defined(__i386__)
1355 linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock)
1357 switch (linux_flock->l_type) {
1359 bsd_flock->l_type = F_RDLCK;
1362 bsd_flock->l_type = F_WRLCK;
1365 bsd_flock->l_type = F_UNLCK;
1368 bsd_flock->l_type = -1;
1371 bsd_flock->l_whence = linux_flock->l_whence;
1372 bsd_flock->l_start = (off_t)linux_flock->l_start;
1373 bsd_flock->l_len = (off_t)linux_flock->l_len;
1374 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1381 bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
1383 switch (bsd_flock->l_type) {
1385 linux_flock->l_type = LINUX_F_RDLCK;
1388 linux_flock->l_type = LINUX_F_WRLCK;
1391 linux_flock->l_type = LINUX_F_UNLCK;
1394 linux_flock->l_whence = bsd_flock->l_whence;
1395 linux_flock->l_start = (l_loff_t)bsd_flock->l_start;
1396 linux_flock->l_len = (l_loff_t)bsd_flock->l_len;
1397 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1399 #endif /* __i386__ */
1405 linux_fcntl_common(struct linux_fcntl64_args *args)
1407 struct thread *td = curthread;
1408 struct l_flock linux_flock;
1410 union fcntl_dat dat;
1413 switch (args->cmd) {
1416 dat.fc_fd = args->arg;
1423 dat.fc_cloexec = args->arg;
1431 if (args->arg & LINUX_O_NDELAY)
1432 dat.fc_flags |= O_NONBLOCK;
1433 if (args->arg & LINUX_O_APPEND)
1434 dat.fc_flags |= O_APPEND;
1435 if (args->arg & LINUX_O_SYNC)
1436 dat.fc_flags |= O_FSYNC;
1437 if (args->arg & LINUX_FASYNC)
1438 dat.fc_flags |= O_ASYNC;
1442 case LINUX_F_SETLKW:
1444 error = copyin((caddr_t)args->arg, &linux_flock,
1445 sizeof(linux_flock));
1448 linux_to_bsd_flock(&linux_flock, &dat.fc_flock);
1450 case LINUX_F_GETOWN:
1453 case LINUX_F_SETOWN:
1455 * XXX some Linux applications depend on F_SETOWN having no
1456 * significant effect for pipes (SIGIO is not delivered for
1457 * pipes under Linux-2.2.35 at least).
1459 fp = holdfp(td->td_proc->p_fd, args->fd, -1);
1462 if (fp->f_type == DTYPE_PIPE) {
1468 dat.fc_owner = args->arg;
1475 error = kern_fcntl(args->fd, cmd, &dat, td->td_ucred);
1478 switch (args->cmd) {
1480 args->sysmsg_iresult = dat.fc_fd;
1483 args->sysmsg_iresult = dat.fc_cloexec;
1488 args->sysmsg_iresult = 0;
1489 if (dat.fc_flags & O_RDONLY)
1490 args->sysmsg_iresult |= LINUX_O_RDONLY;
1491 if (dat.fc_flags & O_WRONLY)
1492 args->sysmsg_iresult |= LINUX_O_WRONLY;
1493 if (dat.fc_flags & O_RDWR)
1494 args->sysmsg_iresult |= LINUX_O_RDWR;
1495 if (dat.fc_flags & O_NDELAY)
1496 args->sysmsg_iresult |= LINUX_O_NONBLOCK;
1497 if (dat.fc_flags & O_APPEND)
1498 args->sysmsg_iresult |= LINUX_O_APPEND;
1499 if (dat.fc_flags & O_FSYNC)
1500 args->sysmsg_iresult |= LINUX_O_SYNC;
1501 if (dat.fc_flags & O_ASYNC)
1502 args->sysmsg_iresult |= LINUX_FASYNC;
1505 bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
1506 error = copyout(&linux_flock, (caddr_t)args->arg,
1507 sizeof(linux_flock));
1510 case LINUX_F_SETLKW:
1512 case LINUX_F_GETOWN:
1513 args->sysmsg_iresult = dat.fc_owner;
1515 case LINUX_F_SETOWN:
1527 sys_linux_fcntl(struct linux_fcntl_args *args)
1529 struct linux_fcntl64_args args64;
1534 kprintf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
1537 args64.fd = args->fd;
1538 args64.cmd = args->cmd;
1539 args64.arg = args->arg;
1540 args64.sysmsg_iresult = 0;
1541 error = linux_fcntl_common(&args64);
1542 args->sysmsg_iresult = args64.sysmsg_iresult;
1546 #if defined(__i386__)
1551 sys_linux_fcntl64(struct linux_fcntl64_args *args)
1553 struct thread *td = curthread;
1554 struct l_flock64 linux_flock;
1555 union fcntl_dat dat;
1559 if (ldebug(fcntl64))
1560 kprintf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd);
1562 if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 ||
1563 args->cmd == LINUX_F_SETLKW64) {
1564 switch (args->cmd) {
1565 case LINUX_F_GETLK64:
1568 case LINUX_F_SETLK64:
1571 case LINUX_F_SETLKW64:
1576 error = copyin((caddr_t)args->arg, &linux_flock,
1577 sizeof(linux_flock));
1580 linux_to_bsd_flock64(&linux_flock, &dat.fc_flock);
1583 error = kern_fcntl(args->fd, cmd, &dat, td->td_ucred);
1585 if (error == 0 && args->cmd == LINUX_F_GETLK64) {
1586 bsd_to_linux_flock64(&dat.fc_flock, &linux_flock);
1587 error = copyout(&linux_flock, (caddr_t)args->arg,
1588 sizeof(linux_flock));
1591 error = linux_fcntl_common(args);
1596 #endif /* __i386__ */
1602 sys_linux_chown(struct linux_chown_args *args)
1604 struct nlookupdata nd;
1608 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1613 kprintf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1616 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1618 error = kern_chown(&nd, args->uid, args->gid);
1621 linux_free_path(&path);
1629 sys_linux_lchown(struct linux_lchown_args *args)
1631 struct nlookupdata nd;
1635 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1640 kprintf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1643 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
1645 error = kern_chown(&nd, args->uid, args->gid);
1648 linux_free_path(&path);
1653 sys_linux_fchmodat(struct linux_fchmodat_args *args)
1655 struct fchmodat_args uap;
1658 uap.fd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
1659 uap.path = args->filename;
1660 uap.mode = args->mode;
1663 error = sys_fchmodat(&uap);
1669 sys_linux_fchownat(struct linux_fchownat_args *args)
1671 struct fchownat_args uap;
1674 if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
1677 uap.fd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
1678 uap.path = args->filename;
1679 uap.uid = args->uid;
1680 uap.gid = args->gid;
1681 uap.flags = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 :
1682 AT_SYMLINK_NOFOLLOW;
1684 error = sys_fchownat(&uap);
1690 sys_linux_faccessat(struct linux_faccessat_args *args)
1692 struct faccessat_args uap;
1695 uap.fd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
1696 uap.path = args->filename;
1697 uap.amode = args->mode;
1700 error = sys_faccessat(&uap);