1 /* $NetBSD: netbsd32_fs.c,v 1.57 2009/01/26 13:00:05 njoly Exp $ */
4 * Copyright (c) 1998, 2001 Matthew R. Green
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.57 2009/01/26 13:00:05 njoly Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/mount.h>
36 #include <sys/socket.h>
37 #include <sys/socketvar.h>
40 #include <sys/ktrace.h>
41 #include <sys/resourcevar.h>
42 #include <sys/vnode.h>
44 #include <sys/filedesc.h>
45 #include <sys/namei.h>
46 #include <sys/statvfs.h>
47 #include <sys/syscallargs.h>
49 #include <sys/dirent.h>
50 #include <sys/kauth.h>
51 #include <sys/vfs_syscalls.h>
53 #include <fs/cd9660/cd9660_mount.h>
54 #include <ufs/ufs/ufsmount.h>
56 #include <compat/netbsd32/netbsd32.h>
57 #include <compat/netbsd32/netbsd32_syscallargs.h>
58 #include <compat/netbsd32/netbsd32_conv.h>
59 #include <compat/sys/mount.h>
62 static int dofilereadv32(int, struct file
*, struct netbsd32_iovec
*,
63 int, off_t
*, int, register_t
*);
64 static int dofilewritev32(int, struct file
*, struct netbsd32_iovec
*,
65 int, off_t
*, int, register_t
*);
68 netbsd32_get_iov(struct netbsd32_iovec
*iov32
, int iovlen
, struct iovec
*aiov
,
72 struct netbsd32_iovec aiov32
[N_IOV32
];
73 struct iovec
*iov
= aiov
;
78 if (iovlen
< 0 || iovlen
> IOV_MAX
)
81 if (iovlen
> aiov_len
)
82 iov
= malloc(iovlen
* sizeof (*iov
), M_TEMP
, M_WAITOK
);
85 for (i
= 0; i
< iovlen
; iov32
+= N_IOV32
, i
+= N_IOV32
) {
89 error
= copyin(iov32
, aiov32
, n
* sizeof (*iov32
));
95 for (j
= 0; j
< n
; iovp
++, j
++) {
96 iovp
->iov_base
= NETBSD32PTR64(aiov32
[j
].iov_base
);
97 iovp
->iov_len
= aiov32
[j
].iov_len
;
105 netbsd32_readv(struct lwp
*l
, const struct netbsd32_readv_args
*uap
, register_t
*retval
)
109 syscallarg(const netbsd32_iovecp_t) iovp;
110 syscallarg(int) iovcnt;
112 int fd
= SCARG(uap
, fd
);
115 if ((fp
= fd_getfile(fd
)) == NULL
)
118 if ((fp
->f_flag
& FREAD
) == 0) {
123 return (dofilereadv32(fd
, fp
,
124 (struct netbsd32_iovec
*)SCARG_P32(uap
, iovp
),
125 SCARG(uap
, iovcnt
), &fp
->f_offset
, FOF_UPDATE_OFFSET
, retval
));
128 /* Damn thing copies in the iovec! */
130 dofilereadv32(int fd
, struct file
*fp
, struct netbsd32_iovec
*iovp
, int iovcnt
, off_t
*offset
, int flags
, register_t
*retval
)
134 struct iovec
*needfree
;
135 struct iovec aiov
[UIO_SMALLIOV
];
136 long i
, cnt
, error
= 0;
138 struct iovec
*ktriov
= NULL
;
140 /* note: can't use iovlen until iovcnt is validated */
141 iovlen
= iovcnt
* sizeof(struct iovec
);
142 if ((u_int
)iovcnt
> UIO_SMALLIOV
) {
143 if ((u_int
)iovcnt
> IOV_MAX
) {
147 iov
= malloc(iovlen
, M_IOV
, M_WAITOK
);
149 } else if ((u_int
)iovcnt
> 0) {
158 auio
.uio_iovcnt
= iovcnt
;
159 auio
.uio_rw
= UIO_READ
;
160 auio
.uio_vmspace
= curproc
->p_vmspace
;
161 error
= netbsd32_to_iovecin(iovp
, iov
, iovcnt
);
165 for (i
= 0; i
< iovcnt
; i
++) {
166 auio
.uio_resid
+= iov
->iov_len
;
168 * Reads return ssize_t because -1 is returned on error.
169 * Therefore we must restrict the length to SSIZE_MAX to
170 * avoid garbage return values.
172 if (iov
->iov_len
> SSIZE_MAX
|| auio
.uio_resid
> SSIZE_MAX
) {
180 * if tracing, save a copy of iovec
182 if (ktrpoint(KTR_GENIO
)) {
183 ktriov
= malloc(iovlen
, M_TEMP
, M_WAITOK
);
184 memcpy((void *)ktriov
, (void *)auio
.uio_iov
, iovlen
);
187 cnt
= auio
.uio_resid
;
188 error
= (*fp
->f_ops
->fo_read
)(fp
, offset
, &auio
, fp
->f_cred
, flags
);
190 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
191 error
== EINTR
|| error
== EWOULDBLOCK
))
193 cnt
-= auio
.uio_resid
;
195 if (ktriov
!= NULL
) {
196 ktrgeniov(fd
, UIO_READ
, ktriov
, cnt
, error
);
197 free(ktriov
, M_TEMP
);
203 free(needfree
, M_IOV
);
210 netbsd32_writev(struct lwp
*l
, const struct netbsd32_writev_args
*uap
, register_t
*retval
)
214 syscallarg(const netbsd32_iovecp_t) iovp;
215 syscallarg(int) iovcnt;
217 int fd
= SCARG(uap
, fd
);
220 if ((fp
= fd_getfile(fd
)) == NULL
)
223 if ((fp
->f_flag
& FWRITE
) == 0) {
228 return (dofilewritev32(fd
, fp
,
229 (struct netbsd32_iovec
*)SCARG_P32(uap
, iovp
),
230 SCARG(uap
, iovcnt
), &fp
->f_offset
, FOF_UPDATE_OFFSET
, retval
));
234 dofilewritev32(int fd
, struct file
*fp
, struct netbsd32_iovec
*iovp
, int iovcnt
, off_t
*offset
, int flags
, register_t
*retval
)
238 struct iovec
*needfree
;
239 struct iovec aiov
[UIO_SMALLIOV
];
240 long i
, cnt
, error
= 0;
242 struct iovec
*ktriov
= NULL
;
244 /* note: can't use iovlen until iovcnt is validated */
245 iovlen
= iovcnt
* sizeof(struct iovec
);
246 if ((u_int
)iovcnt
> UIO_SMALLIOV
) {
247 if ((u_int
)iovcnt
> IOV_MAX
) {
251 iov
= malloc(iovlen
, M_IOV
, M_WAITOK
);
253 } else if ((u_int
)iovcnt
> 0) {
262 auio
.uio_iovcnt
= iovcnt
;
263 auio
.uio_rw
= UIO_WRITE
;
264 auio
.uio_vmspace
= curproc
->p_vmspace
;
265 error
= netbsd32_to_iovecin(iovp
, iov
, iovcnt
);
269 for (i
= 0; i
< iovcnt
; i
++) {
270 auio
.uio_resid
+= iov
->iov_len
;
272 * Writes return ssize_t because -1 is returned on error.
273 * Therefore we must restrict the length to SSIZE_MAX to
274 * avoid garbage return values.
276 if (iov
->iov_len
> SSIZE_MAX
|| auio
.uio_resid
> SSIZE_MAX
) {
284 * if tracing, save a copy of iovec
286 if (ktrpoint(KTR_GENIO
)) {
287 ktriov
= malloc(iovlen
, M_TEMP
, M_WAITOK
);
288 memcpy((void *)ktriov
, (void *)auio
.uio_iov
, iovlen
);
291 cnt
= auio
.uio_resid
;
292 error
= (*fp
->f_ops
->fo_write
)(fp
, offset
, &auio
, fp
->f_cred
, flags
);
294 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
295 error
== EINTR
|| error
== EWOULDBLOCK
))
297 if (error
== EPIPE
) {
298 mutex_enter(proc_lock
);
299 psignal(curproc
, SIGPIPE
);
300 mutex_exit(proc_lock
);
303 cnt
-= auio
.uio_resid
;
304 if (ktriov
!= NULL
) {
305 ktrgenio(fd
, UIO_WRITE
, ktriov
, cnt
, error
);
306 free(ktriov
, M_TEMP
);
311 free(needfree
, M_IOV
);
318 * Common routine to set access and modification times given a vnode.
321 get_utimes32(const netbsd32_timevalp_t
*tptr
, struct timeval
*tv
,
322 struct timeval
**tvp
)
325 struct netbsd32_timeval tv32
[2];
332 error
= copyin(tptr
, tv32
, sizeof(tv32
));
335 netbsd32_to_timeval(&tv32
[0], &tv
[0]);
336 netbsd32_to_timeval(&tv32
[1], &tv
[1]);
343 netbsd32___utimes50(struct lwp
*l
, const struct netbsd32___utimes50_args
*uap
, register_t
*retval
)
346 syscallarg(const netbsd32_charp) path;
347 syscallarg(const netbsd32_timevalp_t) tptr;
350 struct timeval tv
[2], *tvp
;
352 error
= get_utimes32(SCARG_P32(uap
, tptr
), tv
, &tvp
);
356 return do_sys_utimes(l
, NULL
, SCARG_P32(uap
, path
), FOLLOW
,
361 netbds32_copyout_statvfs(const void *kp
, void *up
, size_t len
)
363 struct netbsd32_statvfs
*sbuf_32
;
366 sbuf_32
= malloc(sizeof *sbuf_32
, M_TEMP
, M_WAITOK
);
367 netbsd32_from_statvfs(kp
, sbuf_32
);
368 error
= copyout(sbuf_32
, up
, sizeof(*sbuf_32
));
369 free(sbuf_32
, M_TEMP
);
375 netbsd32_statvfs1(struct lwp
*l
, const struct netbsd32_statvfs1_args
*uap
, register_t
*retval
)
378 syscallarg(const netbsd32_charp) path;
379 syscallarg(netbsd32_statvfsp_t) buf;
380 syscallarg(int) flags;
385 sb
= STATVFSBUF_GET();
386 error
= do_sys_pstatvfs(l
, SCARG_P32(uap
, path
), SCARG(uap
, flags
), sb
);
388 error
= netbds32_copyout_statvfs(sb
, SCARG_P32(uap
, buf
), 0);
394 netbsd32_fstatvfs1(struct lwp
*l
, const struct netbsd32_fstatvfs1_args
*uap
, register_t
*retval
)
398 syscallarg(netbsd32_statvfsp_t) buf;
399 syscallarg(int) flags;
404 sb
= STATVFSBUF_GET();
405 error
= do_sys_fstatvfs(l
, SCARG(uap
, fd
), SCARG(uap
, flags
), sb
);
407 error
= netbds32_copyout_statvfs(sb
, SCARG_P32(uap
, buf
), 0);
413 netbsd32_getvfsstat(struct lwp
*l
, const struct netbsd32_getvfsstat_args
*uap
, register_t
*retval
)
416 syscallarg(netbsd32_statvfsp_t) buf;
417 syscallarg(netbsd32_size_t) bufsize;
418 syscallarg(int) flags;
421 return do_sys_getvfsstat(l
, SCARG_P32(uap
, buf
), SCARG(uap
, bufsize
),
422 SCARG(uap
, flags
), netbds32_copyout_statvfs
,
423 sizeof (struct netbsd32_statvfs
), retval
);
427 netbsd32___fhstatvfs140(struct lwp
*l
, const struct netbsd32___fhstatvfs140_args
*uap
, register_t
*retval
)
430 syscallarg(const netbsd32_pointer_t) fhp;
431 syscallarg(netbsd32_size_t) fh_size;
432 syscallarg(netbsd32_statvfsp_t) buf;
433 syscallarg(int) flags;
438 sb
= STATVFSBUF_GET();
439 error
= do_fhstatvfs(l
, SCARG_P32(uap
, fhp
), SCARG(uap
, fh_size
), sb
,
443 error
= netbds32_copyout_statvfs(sb
, SCARG_P32(uap
, buf
), 0);
450 netbsd32___futimes50(struct lwp
*l
, const struct netbsd32___futimes50_args
*uap
, register_t
*retval
)
454 syscallarg(const netbsd32_timevalp_t) tptr;
458 struct timeval tv
[2], *tvp
;
460 error
= get_utimes32(SCARG_P32(uap
, tptr
), tv
, &tvp
);
464 /* fd_getvnode() will use the descriptor for us */
465 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
468 error
= do_sys_utimes(l
, fp
->f_data
, NULL
, 0, tvp
, UIO_SYSSPACE
);
470 fd_putfile(SCARG(uap
, fd
));
475 netbsd32___getdents30(struct lwp
*l
,
476 const struct netbsd32___getdents30_args
*uap
, register_t
*retval
)
480 syscallarg(netbsd32_charp) buf;
481 syscallarg(netbsd32_size_t) count;
486 /* fd_getvnode() will use the descriptor for us */
487 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
489 if ((fp
->f_flag
& FREAD
) == 0) {
493 error
= vn_readdir(fp
, SCARG_P32(uap
, buf
),
494 UIO_USERSPACE
, SCARG(uap
, count
), &done
, l
, 0, 0);
497 fd_putfile(SCARG(uap
, fd
));
502 netbsd32___lutimes50(struct lwp
*l
,
503 const struct netbsd32___lutimes50_args
*uap
, register_t
*retval
)
506 syscallarg(const netbsd32_charp) path;
507 syscallarg(const netbsd32_timevalp_t) tptr;
510 struct timeval tv
[2], *tvp
;
512 error
= get_utimes32(SCARG_P32(uap
, tptr
), tv
, &tvp
);
516 return do_sys_utimes(l
, NULL
, SCARG_P32(uap
, path
), NOFOLLOW
,
521 netbsd32___stat50(struct lwp
*l
, const struct netbsd32___stat50_args
*uap
, register_t
*retval
)
524 syscallarg(const netbsd32_charp) path;
525 syscallarg(netbsd32_statp_t) ub;
527 struct netbsd32_stat sb32
;
532 path
= SCARG_P32(uap
, path
);
534 error
= do_sys_stat(path
, FOLLOW
, &sb
);
537 netbsd32_from_stat(&sb
, &sb32
);
538 error
= copyout(&sb32
, SCARG_P32(uap
, ub
), sizeof(sb32
));
543 netbsd32___fstat50(struct lwp
*l
, const struct netbsd32___fstat50_args
*uap
, register_t
*retval
)
547 syscallarg(netbsd32_statp_t) sb;
549 struct netbsd32_stat sb32
;
553 error
= do_sys_fstat(SCARG(uap
, fd
), &ub
);
555 netbsd32_from_stat(&ub
, &sb32
);
556 error
= copyout(&sb32
, SCARG_P32(uap
, sb
), sizeof(sb32
));
562 netbsd32___lstat50(struct lwp
*l
, const struct netbsd32___lstat50_args
*uap
, register_t
*retval
)
565 syscallarg(const netbsd32_charp) path;
566 syscallarg(netbsd32_statp_t) ub;
568 struct netbsd32_stat sb32
;
573 path
= SCARG_P32(uap
, path
);
575 error
= do_sys_stat(path
, NOFOLLOW
, &sb
);
578 netbsd32_from_stat(&sb
, &sb32
);
579 error
= copyout(&sb32
, SCARG_P32(uap
, ub
), sizeof(sb32
));
584 netbsd32___fhstat50(struct lwp
*l
, const struct netbsd32___fhstat50_args
*uap
, register_t
*retval
)
587 syscallarg(const netbsd32_pointer_t) fhp;
588 syscallarg(netbsd32_size_t) fh_size;
589 syscallarg(netbsd32_statp_t) sb;
592 struct netbsd32_stat sb32
;
595 error
= do_fhstat(l
, SCARG_P32(uap
, fhp
), SCARG(uap
, fh_size
), &sb
);
597 netbsd32_from_stat(&sb
, &sb32
);
598 error
= copyout(&sb32
, SCARG_P32(uap
, sb
), sizeof(sb
));
604 netbsd32_preadv(struct lwp
*l
, const struct netbsd32_preadv_args
*uap
, register_t
*retval
)
608 syscallarg(const netbsd32_iovecp_t) iovp;
609 syscallarg(int) iovcnt;
611 syscallarg(off_t) offset;
616 int error
, fd
= SCARG(uap
, fd
);
618 if ((fp
= fd_getfile(fd
)) == NULL
)
621 if ((fp
->f_flag
& FREAD
) == 0) {
627 if (fp
->f_type
!= DTYPE_VNODE
|| vp
->v_type
== VFIFO
) {
632 offset
= SCARG(uap
, offset
);
635 * XXX This works because no file systems actually
636 * XXX take any action on the seek operation.
638 if ((error
= VOP_SEEK(vp
, fp
->f_offset
, offset
, fp
->f_cred
)) != 0)
641 return (dofilereadv32(fd
, fp
, SCARG_P32(uap
, iovp
),
642 SCARG(uap
, iovcnt
), &offset
, 0, retval
));
650 netbsd32_pwritev(struct lwp
*l
, const struct netbsd32_pwritev_args
*uap
, register_t
*retval
)
654 syscallarg(const netbsd32_iovecp_t) iovp;
655 syscallarg(int) iovcnt;
657 syscallarg(off_t) offset;
662 int error
, fd
= SCARG(uap
, fd
);
664 if ((fp
= fd_getfile(fd
)) == NULL
)
667 if ((fp
->f_flag
& FWRITE
) == 0) {
673 if (fp
->f_type
!= DTYPE_VNODE
|| vp
->v_type
== VFIFO
) {
678 offset
= SCARG(uap
, offset
);
681 * XXX This works because no file systems actually
682 * XXX take any action on the seek operation.
684 if ((error
= VOP_SEEK(vp
, fp
->f_offset
, offset
, fp
->f_cred
)) != 0)
687 return (dofilewritev32(fd
, fp
, SCARG_P32(uap
, iovp
),
688 SCARG(uap
, iovcnt
), &offset
, 0, retval
));
696 * Find pathname of process's current directory.
698 * Use vfs vnode-to-name reverse cache; if that fails, fall back
699 * to reading directory contents.
701 /* XXX NH Why does this exist */
703 getcwd_common(struct vnode
*, struct vnode
*,
704 char **, char *, int, int, struct lwp
*);
707 netbsd32___getcwd(struct lwp
*l
, const struct netbsd32___getcwd_args
*uap
, register_t
*retval
)
710 syscallarg(char *) bufp;
711 syscallarg(size_t) length;
713 struct proc
*p
= l
->l_proc
;
717 int len
= (int)SCARG(uap
, length
);
719 struct cwdinfo
*cwdi
;
721 if (len
> MAXPATHLEN
*4)
726 path
= (char *)malloc(len
, M_TEMP
, M_WAITOK
);
735 * 5th argument here is "max number of vnodes to traverse".
736 * Since each entry takes up at least 2 bytes in the output buffer,
737 * limit it to N/2 vnodes for an N byte buffer.
739 #define GETCWD_CHECK_ACCESS 0x0001
741 rw_enter(&cwdi
->cwdi_lock
, RW_READER
);
742 error
= getcwd_common (cwdi
->cwdi_cdir
, NULL
, &bp
, path
, len
/2,
743 GETCWD_CHECK_ACCESS
, l
);
744 rw_exit(&cwdi
->cwdi_lock
);
750 /* put the result into user buffer */
751 error
= copyout(bp
, SCARG_P32(uap
, bufp
), lenused
);
759 netbsd32___mount50(struct lwp
*l
, const struct netbsd32___mount50_args
*uap
,
763 syscallarg(netbsd32_charp) type;
764 syscallarg(netbsd32_charp) path;
765 syscallarg(int) flags;
766 syscallarg(netbsd32_voidp) data;
767 syscallarg(netbsd32_size_t) data_len;
769 char mtype
[MNAMELEN
];
771 struct netbsd32_ufs_args ufs_args
;
772 struct netbsd32_mfs_args mfs_args
;
773 struct netbsd32_iso_args iso_args
;
776 struct ufs_args ufs_args
;
777 struct mfs_args mfs_args
;
778 struct iso_args iso_args
;
780 const char *type
= SCARG_P32(uap
, type
);
781 const char *path
= SCARG_P32(uap
, path
);
782 int flags
= SCARG(uap
, flags
);
783 void *data
= SCARG_P32(uap
, data
);
784 size_t data_len
= SCARG(uap
, data_len
);
785 enum uio_seg data_seg
;
789 error
= copyinstr(type
, mtype
, sizeof(mtype
), &len
);
792 if (strcmp(mtype
, MOUNT_MFS
) == 0) {
793 if (data_len
!= sizeof(fs_args32
.mfs_args
))
795 if ((flags
& MNT_GETARGS
) == 0) {
796 error
= copyin(data
, &fs_args32
.mfs_args
,
797 sizeof(fs_args32
.mfs_args
));
800 fs_args
.mfs_args
.fspec
=
801 NETBSD32PTR64(fs_args32
.mfs_args
.fspec
);
802 memset(&fs_args
.mfs_args
._pad1
, 0,
803 sizeof(fs_args
.mfs_args
._pad1
));
804 fs_args
.mfs_args
.base
=
805 NETBSD32PTR64(fs_args32
.mfs_args
.base
);
806 fs_args
.mfs_args
.size
= fs_args32
.mfs_args
.size
;
808 data_seg
= UIO_SYSSPACE
;
809 data
= &fs_args
.mfs_args
;
810 data_len
= sizeof(fs_args
.mfs_args
);
811 } else if (strcmp(mtype
, MOUNT_UFS
) == 0) {
812 if (data_len
> sizeof(fs_args32
.ufs_args
))
814 if ((flags
& MNT_GETARGS
) == 0) {
815 error
= copyin(data
, &fs_args32
.ufs_args
,
816 sizeof(fs_args32
.ufs_args
));
819 fs_args
.ufs_args
.fspec
=
820 NETBSD32PTR64(fs_args32
.ufs_args
.fspec
);
822 data_seg
= UIO_SYSSPACE
;
823 data
= &fs_args
.ufs_args
;
824 data_len
= sizeof(fs_args
.ufs_args
);
825 } else if (strcmp(mtype
, MOUNT_CD9660
) == 0) {
826 if (data_len
!= sizeof(fs_args32
.iso_args
))
828 if ((flags
& MNT_GETARGS
) == 0) {
829 error
= copyin(data
, &fs_args32
.iso_args
,
830 sizeof(fs_args32
.iso_args
));
833 fs_args
.iso_args
.fspec
=
834 NETBSD32PTR64(fs_args32
.iso_args
.fspec
);
835 memset(&fs_args
.iso_args
._pad1
, 0,
836 sizeof(fs_args
.iso_args
._pad1
));
837 fs_args
.iso_args
.flags
= fs_args32
.iso_args
.flags
;
839 data_seg
= UIO_SYSSPACE
;
840 data
= &fs_args
.iso_args
;
841 data_len
= sizeof(fs_args
.iso_args
);
843 data_seg
= UIO_USERSPACE
;
845 error
= do_sys_mount(l
, NULL
, type
, path
, flags
, data
, data_seg
,
849 if (flags
& MNT_GETARGS
) {
851 if (strcmp(mtype
, MOUNT_MFS
) == 0) {
852 if (data_len
!= sizeof(fs_args
.mfs_args
))
854 NETBSD32PTR32(fs_args32
.mfs_args
.fspec
,
855 fs_args
.mfs_args
.fspec
);
856 memset(&fs_args32
.mfs_args
._pad1
, 0,
857 sizeof(fs_args32
.mfs_args
._pad1
));
858 NETBSD32PTR32(fs_args32
.mfs_args
.base
,
859 fs_args
.mfs_args
.base
);
860 fs_args32
.mfs_args
.size
= fs_args
.mfs_args
.size
;
861 error
= copyout(&fs_args32
.mfs_args
, data
,
862 sizeof(fs_args32
.mfs_args
));
863 } else if (strcmp(mtype
, MOUNT_UFS
) == 0) {
864 if (data_len
!= sizeof(fs_args
.ufs_args
))
866 NETBSD32PTR32(fs_args32
.ufs_args
.fspec
,
867 fs_args
.ufs_args
.fspec
);
868 error
= copyout(&fs_args32
.ufs_args
, data
,
869 sizeof(fs_args32
.ufs_args
));
870 } else if (strcmp(mtype
, MOUNT_CD9660
) == 0) {
871 if (data_len
!= sizeof(fs_args
.iso_args
))
873 NETBSD32PTR32(fs_args32
.iso_args
.fspec
,
874 fs_args
.iso_args
.fspec
);
875 memset(&fs_args32
.iso_args
._pad1
, 0,
876 sizeof(fs_args32
.iso_args
._pad1
));
877 fs_args32
.iso_args
.flags
= fs_args
.iso_args
.flags
;
878 error
= copyout(&fs_args32
.iso_args
, data
,
879 sizeof(fs_args32
.iso_args
));