Sat Sep 11 10:08:56 2021 UTC ()
sys/kern: Allow custom fileops to specify fo_seek method.

Previously only vnodes allowed lseek/pread[v]/pwrite[v], which meant
converting a regular device to a cloning device doesn't always work.

Semantics is:

(*fp->f_ops->fo_seek)(fp, delta, whence, newoffp, flags)

1. Compute a new offset according to whence + delta -- that is, if
   whence is SEEK_CUR, add delta to fp->f_offset; if whence is
   SEEK_END, add delta to end of file; if whence is SEEK_CUR, use delta
   as is.

2. If newoffp is nonnull, return the new offset in *newoffp.

3. If flags & FOF_UPDATE_OFFSET, set fp->f_offset to the new offset.

Access to fp->f_offset, and *newoffp if newoffp = &fp->f_offset, must
happen under the object lock (e.g., vnode lock), in order to
synchronize fp->f_offset reads and writes.

This change has the side effect that every call to VOP_SEEK happens
under the vnode lock now, when previously it didn't.  However, from a
review of all the VOP_SEEK implementations, it does not appear that
any file system even examines the vnode, let alone locks it.  So I
think this is safe -- and essentially the only reasonable way to do
things, given that it is used to validate a change from oldoff to
newoff, and oldoff becomes stale the moment we unlock the vnode.

No kernel bump because this reuses a spare entry in struct fileops,
and it is safe for the entry to be null, so all existing fileops will
continue to work as before (rejecting seek).


(riastradh)
diff -r1.93 -r1.94 src/sys/compat/netbsd32/netbsd32_fs.c
diff -r1.132 -r1.133 src/sys/kern/sys_generic.c
diff -r1.551 -r1.552 src/sys/kern/vfs_syscalls.c
diff -r1.221 -r1.222 src/sys/kern/vfs_vnops.c
diff -r1.86 -r1.87 src/sys/sys/file.h

cvs diff -r1.93 -r1.94 src/sys/compat/netbsd32/netbsd32_fs.c (expand / switch to unified diff)

--- src/sys/compat/netbsd32/netbsd32_fs.c 2021/02/16 14:47:20 1.93
+++ src/sys/compat/netbsd32/netbsd32_fs.c 2021/09/11 10:08:55 1.94
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: netbsd32_fs.c,v 1.93 2021/02/16 14:47:20 simonb Exp $ */ 1/* $NetBSD: netbsd32_fs.c,v 1.94 2021/09/11 10:08:55 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2001 Matthew R. Green 4 * Copyright (c) 1998, 2001 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.93 2021/02/16 14:47:20 simonb Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.94 2021/09/11 10:08:55 riastradh Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34#include <sys/mount.h> 34#include <sys/mount.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36#include <sys/socketvar.h> 36#include <sys/socketvar.h>
37#include <sys/stat.h> 37#include <sys/stat.h>
38#include <sys/time.h> 38#include <sys/time.h>
39#include <sys/ktrace.h> 39#include <sys/ktrace.h>
40#include <sys/resourcevar.h> 40#include <sys/resourcevar.h>
41#include <sys/vnode.h> 41#include <sys/vnode.h>
42#include <sys/file.h> 42#include <sys/file.h>
43#include <sys/filedesc.h> 43#include <sys/filedesc.h>
@@ -638,97 +638,85 @@ netbsd32___fhstat50(struct lwp *l, const @@ -638,97 +638,85 @@ netbsd32___fhstat50(struct lwp *l, const
638} 638}
639 639
640int 640int
641netbsd32_preadv(struct lwp *l, const struct netbsd32_preadv_args *uap, register_t *retval) 641netbsd32_preadv(struct lwp *l, const struct netbsd32_preadv_args *uap, register_t *retval)
642{ 642{
643 /* { 643 /* {
644 syscallarg(int) fd; 644 syscallarg(int) fd;
645 syscallarg(const netbsd32_iovecp_t) iovp; 645 syscallarg(const netbsd32_iovecp_t) iovp;
646 syscallarg(int) iovcnt; 646 syscallarg(int) iovcnt;
647 syscallarg(int) pad; 647 syscallarg(int) pad;
648 syscallarg(netbsd32_off_t) offset; 648 syscallarg(netbsd32_off_t) offset;
649 } */ 649 } */
650 file_t *fp; 650 file_t *fp;
651 struct vnode *vp; 
652 off_t offset; 651 off_t offset;
653 int error, fd = SCARG(uap, fd); 652 int error, fd = SCARG(uap, fd);
654 653
655 if ((fp = fd_getfile(fd)) == NULL) 654 if ((fp = fd_getfile(fd)) == NULL)
656 return EBADF; 655 return EBADF;
657 656
658 if ((fp->f_flag & FREAD) == 0) { 657 if ((fp->f_flag & FREAD) == 0) {
659 fd_putfile(fd); 658 fd_putfile(fd);
660 return EBADF; 659 return EBADF;
661 } 660 }
662 661
663 vp = fp->f_vnode; 662 if (fp->f_ops->fo_seek == NULL) {
664 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 
665 error = ESPIPE; 663 error = ESPIPE;
666 goto out; 664 goto out;
667 } 665 }
668 666
669 offset = SCARG(uap, offset); 667 offset = SCARG(uap, offset);
670 668 error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0);
671 /* 669 if (error)
672 * XXX This works because no file systems actually 
673 * XXX take any action on the seek operation. 
674 */ 
675 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0) 
676 goto out; 670 goto out;
677 671
678 return dofilereadv32(fd, fp, SCARG_P32(uap, iovp), 672 return dofilereadv32(fd, fp, SCARG_P32(uap, iovp),
679 SCARG(uap, iovcnt), &offset, 0, retval); 673 SCARG(uap, iovcnt), &offset, 0, retval);
680 674
681out: 675out:
682 fd_putfile(fd); 676 fd_putfile(fd);
683 return error; 677 return error;
684} 678}
685 679
686int 680int
687netbsd32_pwritev(struct lwp *l, const struct netbsd32_pwritev_args *uap, register_t *retval) 681netbsd32_pwritev(struct lwp *l, const struct netbsd32_pwritev_args *uap, register_t *retval)
688{ 682{
689 /* { 683 /* {
690 syscallarg(int) fd; 684 syscallarg(int) fd;
691 syscallarg(const netbsd32_iovecp_t) iovp; 685 syscallarg(const netbsd32_iovecp_t) iovp;
692 syscallarg(int) iovcnt; 686 syscallarg(int) iovcnt;
693 syscallarg(int) pad; 687 syscallarg(int) pad;
694 syscallarg(netbsd32_off_t) offset; 688 syscallarg(netbsd32_off_t) offset;
695 } */ 689 } */
696 file_t *fp; 690 file_t *fp;
697 struct vnode *vp; 
698 off_t offset; 691 off_t offset;
699 int error, fd = SCARG(uap, fd); 692 int error, fd = SCARG(uap, fd);
700 693
701 if ((fp = fd_getfile(fd)) == NULL) 694 if ((fp = fd_getfile(fd)) == NULL)
702 return EBADF; 695 return EBADF;
703 696
704 if ((fp->f_flag & FWRITE) == 0) { 697 if ((fp->f_flag & FWRITE) == 0) {
705 fd_putfile(fd); 698 fd_putfile(fd);
706 return EBADF; 699 return EBADF;
707 } 700 }
708 701
709 vp = fp->f_vnode; 702 if (fp->f_ops->fo_seek == NULL) {
710 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 
711 error = ESPIPE; 703 error = ESPIPE;
712 goto out; 704 goto out;
713 } 705 }
714 706
715 offset = SCARG(uap, offset); 707 offset = SCARG(uap, offset);
716 708 error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0);
717 /* 709 if (error)
718 * XXX This works because no file systems actually 
719 * XXX take any action on the seek operation. 
720 */ 
721 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0) 
722 goto out; 710 goto out;
723 711
724 return dofilewritev32(fd, fp, SCARG_P32(uap, iovp), 712 return dofilewritev32(fd, fp, SCARG_P32(uap, iovp),
725 SCARG(uap, iovcnt), &offset, 0, retval); 713 SCARG(uap, iovcnt), &offset, 0, retval);
726 714
727out: 715out:
728 fd_putfile(fd); 716 fd_putfile(fd);
729 return error; 717 return error;
730} 718}
731 719
732/* 720/*
733 * Find pathname of process's current directory. 721 * Find pathname of process's current directory.
734 * 722 *

cvs diff -r1.132 -r1.133 src/sys/kern/sys_generic.c (expand / switch to unified diff)

--- src/sys/kern/sys_generic.c 2020/05/23 23:42:43 1.132
+++ src/sys/kern/sys_generic.c 2021/09/11 10:08:55 1.133
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sys_generic.c,v 1.132 2020/05/23 23:42:43 ad Exp $ */ 1/* $NetBSD: sys_generic.c,v 1.133 2021/09/11 10:08:55 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -60,27 +60,27 @@ @@ -60,27 +60,27 @@
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95 65 * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95
66 */ 66 */
67 67
68/* 68/*
69 * System calls relating to files. 69 * System calls relating to files.
70 */ 70 */
71 71
72#include <sys/cdefs.h> 72#include <sys/cdefs.h>
73__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.132 2020/05/23 23:42:43 ad Exp $"); 73__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.133 2021/09/11 10:08:55 riastradh Exp $");
74 74
75#include <sys/param.h> 75#include <sys/param.h>
76#include <sys/systm.h> 76#include <sys/systm.h>
77#include <sys/filedesc.h> 77#include <sys/filedesc.h>
78#include <sys/ioctl.h> 78#include <sys/ioctl.h>
79#include <sys/file.h> 79#include <sys/file.h>
80#include <sys/proc.h> 80#include <sys/proc.h>
81#include <sys/socketvar.h> 81#include <sys/socketvar.h>
82#include <sys/signalvar.h> 82#include <sys/signalvar.h>
83#include <sys/uio.h> 83#include <sys/uio.h>
84#include <sys/kernel.h> 84#include <sys/kernel.h>
85#include <sys/stat.h> 85#include <sys/stat.h>
86#include <sys/kmem.h> 86#include <sys/kmem.h>
@@ -198,37 +198,38 @@ do_filereadv(int fd, const struct iovec  @@ -198,37 +198,38 @@ do_filereadv(int fd, const struct iovec
198 return EINVAL; 198 return EINVAL;
199 199
200 if ((fp = fd_getfile(fd)) == NULL) 200 if ((fp = fd_getfile(fd)) == NULL)
201 return EBADF; 201 return EBADF;
202 202
203 if ((fp->f_flag & FREAD) == 0) { 203 if ((fp->f_flag & FREAD) == 0) {
204 fd_putfile(fd); 204 fd_putfile(fd);
205 return EBADF; 205 return EBADF;
206 } 206 }
207 207
208 if (offset == NULL) 208 if (offset == NULL)
209 offset = &fp->f_offset; 209 offset = &fp->f_offset;
210 else { 210 else {
211 struct vnode *vp = fp->f_vnode; 211 /*
212 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 212 * Caller must not specify &fp->f_offset -- we can't
 213 * safely dereference it for the call to fo_seek
 214 * without holding some underlying object lock.
 215 */
 216 KASSERT(offset != &fp->f_offset);
 217 if (fp->f_ops->fo_seek == NULL) {
213 error = ESPIPE; 218 error = ESPIPE;
214 goto out; 219 goto out;
215 } 220 }
216 /* 221 error = (*fp->f_ops->fo_seek)(fp, *offset, SEEK_SET, NULL,
217 * Test that the device is seekable ? 222 0);
218 * XXX This works because no file systems actually 
219 * XXX take any action on the seek operation. 
220 */ 
221 error = VOP_SEEK(vp, fp->f_offset, *offset, fp->f_cred); 
222 if (error != 0) 223 if (error != 0)
223 goto out; 224 goto out;
224 } 225 }
225 226
226 iovlen = iovcnt * sizeof(struct iovec); 227 iovlen = iovcnt * sizeof(struct iovec);
227 if (flags & FOF_IOV_SYSSPACE) 228 if (flags & FOF_IOV_SYSSPACE)
228 iov = __UNCONST(iovp); 229 iov = __UNCONST(iovp);
229 else { 230 else {
230 iov = aiov; 231 iov = aiov;
231 if ((u_int)iovcnt > UIO_SMALLIOV) { 232 if ((u_int)iovcnt > UIO_SMALLIOV) {
232 if ((u_int)iovcnt > IOV_MAX) { 233 if ((u_int)iovcnt > IOV_MAX) {
233 error = EINVAL; 234 error = EINVAL;
234 goto out; 235 goto out;
@@ -398,37 +399,38 @@ do_filewritev(int fd, const struct iovec @@ -398,37 +399,38 @@ do_filewritev(int fd, const struct iovec
398 return EINVAL; 399 return EINVAL;
399 400
400 if ((fp = fd_getfile(fd)) == NULL) 401 if ((fp = fd_getfile(fd)) == NULL)
401 return EBADF; 402 return EBADF;
402 403
403 if ((fp->f_flag & FWRITE) == 0) { 404 if ((fp->f_flag & FWRITE) == 0) {
404 fd_putfile(fd); 405 fd_putfile(fd);
405 return EBADF; 406 return EBADF;
406 } 407 }
407 408
408 if (offset == NULL) 409 if (offset == NULL)
409 offset = &fp->f_offset; 410 offset = &fp->f_offset;
410 else { 411 else {
411 struct vnode *vp = fp->f_vnode; 412 /*
412 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 413 * Caller must not specify &fp->f_offset -- we can't
 414 * safely dereference it for the call to fo_seek
 415 * without holding some underlying object lock.
 416 */
 417 KASSERT(offset != &fp->f_offset);
 418 if (fp->f_ops->fo_seek == NULL) {
413 error = ESPIPE; 419 error = ESPIPE;
414 goto out; 420 goto out;
415 } 421 }
416 /* 422 error = (*fp->f_ops->fo_seek)(fp, *offset, SEEK_SET, NULL,
417 * Test that the device is seekable ? 423 0);
418 * XXX This works because no file systems actually 
419 * XXX take any action on the seek operation. 
420 */ 
421 error = VOP_SEEK(vp, fp->f_offset, *offset, fp->f_cred); 
422 if (error != 0) 424 if (error != 0)
423 goto out; 425 goto out;
424 } 426 }
425 427
426 iovlen = iovcnt * sizeof(struct iovec); 428 iovlen = iovcnt * sizeof(struct iovec);
427 if (flags & FOF_IOV_SYSSPACE) 429 if (flags & FOF_IOV_SYSSPACE)
428 iov = __UNCONST(iovp); 430 iov = __UNCONST(iovp);
429 else { 431 else {
430 iov = aiov; 432 iov = aiov;
431 if ((u_int)iovcnt > UIO_SMALLIOV) { 433 if ((u_int)iovcnt > UIO_SMALLIOV) {
432 if ((u_int)iovcnt > IOV_MAX) { 434 if ((u_int)iovcnt > IOV_MAX) {
433 error = EINVAL; 435 error = EINVAL;
434 goto out; 436 goto out;

cvs diff -r1.551 -r1.552 src/sys/kern/vfs_syscalls.c (expand / switch to unified diff)

--- src/sys/kern/vfs_syscalls.c 2021/07/03 09:39:26 1.551
+++ src/sys/kern/vfs_syscalls.c 2021/09/11 10:08:55 1.552
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_syscalls.c,v 1.551 2021/07/03 09:39:26 mlelstv Exp $ */ 1/* $NetBSD: vfs_syscalls.c,v 1.552 2021/09/11 10:08:55 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008, 2009, 2019, 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2009, 2019, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -60,27 +60,27 @@ @@ -60,27 +60,27 @@
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95 65 * @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95
66 */ 66 */
67 67
68/* 68/*
69 * Virtual File System System Calls 69 * Virtual File System System Calls
70 */ 70 */
71 71
72#include <sys/cdefs.h> 72#include <sys/cdefs.h>
73__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.551 2021/07/03 09:39:26 mlelstv Exp $"); 73__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.552 2021/09/11 10:08:55 riastradh Exp $");
74 74
75#ifdef _KERNEL_OPT 75#ifdef _KERNEL_OPT
76#include "opt_fileassoc.h" 76#include "opt_fileassoc.h"
77#include "veriexec.h" 77#include "veriexec.h"
78#endif 78#endif
79 79
80#include <sys/param.h> 80#include <sys/param.h>
81#include <sys/systm.h> 81#include <sys/systm.h>
82#include <sys/namei.h> 82#include <sys/namei.h>
83#include <sys/filedesc.h> 83#include <sys/filedesc.h>
84#include <sys/kernel.h> 84#include <sys/kernel.h>
85#include <sys/file.h> 85#include <sys/file.h>
86#include <sys/fcntl.h> 86#include <sys/fcntl.h>
@@ -2846,113 +2846,87 @@ out: @@ -2846,113 +2846,87 @@ out:
2846 2846
2847/* 2847/*
2848 * Reposition read/write file offset. 2848 * Reposition read/write file offset.
2849 */ 2849 */
2850int 2850int
2851sys_lseek(struct lwp *l, const struct sys_lseek_args *uap, register_t *retval) 2851sys_lseek(struct lwp *l, const struct sys_lseek_args *uap, register_t *retval)
2852{ 2852{
2853 /* { 2853 /* {
2854 syscallarg(int) fd; 2854 syscallarg(int) fd;
2855 syscallarg(int) pad; 2855 syscallarg(int) pad;
2856 syscallarg(off_t) offset; 2856 syscallarg(off_t) offset;
2857 syscallarg(int) whence; 2857 syscallarg(int) whence;
2858 } */ 2858 } */
2859 kauth_cred_t cred = l->l_cred; 
2860 file_t *fp; 2859 file_t *fp;
2861 struct vnode *vp; 
2862 struct vattr vattr; 
2863 off_t newoff; 
2864 int error, fd; 2860 int error, fd;
2865 2861
 2862 switch (SCARG(uap, whence)) {
 2863 case SEEK_CUR:
 2864 case SEEK_END:
 2865 case SEEK_SET:
 2866 break;
 2867 default:
 2868 return EINVAL;
 2869 }
 2870
2866 fd = SCARG(uap, fd); 2871 fd = SCARG(uap, fd);
2867 2872
2868 if ((fp = fd_getfile(fd)) == NULL) 2873 if ((fp = fd_getfile(fd)) == NULL)
2869 return (EBADF); 2874 return (EBADF);
2870 2875
2871 vp = fp->f_vnode; 2876 if (fp->f_ops->fo_seek == NULL) {
2872 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 
2873 error = ESPIPE; 2877 error = ESPIPE;
2874 goto out; 2878 goto out;
2875 } 2879 }
2876 2880
2877 vn_lock(vp, LK_SHARED | LK_RETRY); 2881 error = (*fp->f_ops->fo_seek)(fp, SCARG(uap, offset),
2878 2882 SCARG(uap, whence), (off_t *)retval, FOF_UPDATE_OFFSET);
2879 switch (SCARG(uap, whence)) { 
2880 case SEEK_CUR: 
2881 newoff = fp->f_offset + SCARG(uap, offset); 
2882 break; 
2883 case SEEK_END: 
2884 error = VOP_GETATTR(vp, &vattr, cred); 
2885 if (error) { 
2886 VOP_UNLOCK(vp); 
2887 goto out; 
2888 } 
2889 newoff = SCARG(uap, offset) + vattr.va_size; 
2890 break; 
2891 case SEEK_SET: 
2892 newoff = SCARG(uap, offset); 
2893 break; 
2894 default: 
2895 error = EINVAL; 
2896 VOP_UNLOCK(vp); 
2897 goto out; 
2898 } 
2899 VOP_UNLOCK(vp); 
2900 if ((error = VOP_SEEK(vp, fp->f_offset, newoff, cred)) == 0) { 
2901 *(off_t *)retval = fp->f_offset = newoff; 
2902 } 
2903 out: 2883 out:
2904 fd_putfile(fd); 2884 fd_putfile(fd);
2905 return (error); 2885 return (error);
2906} 2886}
2907 2887
2908/* 2888/*
2909 * Positional read system call. 2889 * Positional read system call.
2910 */ 2890 */
2911int 2891int
2912sys_pread(struct lwp *l, const struct sys_pread_args *uap, register_t *retval) 2892sys_pread(struct lwp *l, const struct sys_pread_args *uap, register_t *retval)
2913{ 2893{
2914 /* { 2894 /* {
2915 syscallarg(int) fd; 2895 syscallarg(int) fd;
2916 syscallarg(void *) buf; 2896 syscallarg(void *) buf;
2917 syscallarg(size_t) nbyte; 2897 syscallarg(size_t) nbyte;
2918 syscallarg(off_t) offset; 2898 syscallarg(off_t) offset;
2919 } */ 2899 } */
2920 file_t *fp; 2900 file_t *fp;
2921 struct vnode *vp; 
2922 off_t offset; 2901 off_t offset;
2923 int error, fd = SCARG(uap, fd); 2902 int error, fd = SCARG(uap, fd);
2924 2903
2925 if ((fp = fd_getfile(fd)) == NULL) 2904 if ((fp = fd_getfile(fd)) == NULL)
2926 return (EBADF); 2905 return (EBADF);
2927 2906
2928 if ((fp->f_flag & FREAD) == 0) { 2907 if ((fp->f_flag & FREAD) == 0) {
2929 fd_putfile(fd); 2908 fd_putfile(fd);
2930 return (EBADF); 2909 return (EBADF);
2931 } 2910 }
2932 2911
2933 vp = fp->f_vnode; 2912 if (fp->f_ops->fo_seek == NULL) {
2934 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 
2935 error = ESPIPE; 2913 error = ESPIPE;
2936 goto out; 2914 goto out;
2937 } 2915 }
2938 2916
2939 offset = SCARG(uap, offset); 2917 offset = SCARG(uap, offset);
2940 2918 error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0);
2941 /* 2919 if (error)
2942 * XXX This works because no file systems actually 
2943 * XXX take any action on the seek operation. 
2944 */ 
2945 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0) 
2946 goto out; 2920 goto out;
2947 2921
2948 /* dofileread() will unuse the descriptor for us */ 2922 /* dofileread() will unuse the descriptor for us */
2949 return (dofileread(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 2923 return (dofileread(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
2950 &offset, 0, retval)); 2924 &offset, 0, retval));
2951 2925
2952 out: 2926 out:
2953 fd_putfile(fd); 2927 fd_putfile(fd);
2954 return (error); 2928 return (error);
2955} 2929}
2956 2930
2957/* 2931/*
2958 * Positional scatter read system call. 2932 * Positional scatter read system call.
@@ -2975,51 +2949,45 @@ sys_preadv(struct lwp *l, const struct s @@ -2975,51 +2949,45 @@ sys_preadv(struct lwp *l, const struct s
2975/* 2949/*
2976 * Positional write system call. 2950 * Positional write system call.
2977 */ 2951 */
2978int 2952int
2979sys_pwrite(struct lwp *l, const struct sys_pwrite_args *uap, register_t *retval) 2953sys_pwrite(struct lwp *l, const struct sys_pwrite_args *uap, register_t *retval)
2980{ 2954{
2981 /* { 2955 /* {
2982 syscallarg(int) fd; 2956 syscallarg(int) fd;
2983 syscallarg(const void *) buf; 2957 syscallarg(const void *) buf;
2984 syscallarg(size_t) nbyte; 2958 syscallarg(size_t) nbyte;
2985 syscallarg(off_t) offset; 2959 syscallarg(off_t) offset;
2986 } */ 2960 } */
2987 file_t *fp; 2961 file_t *fp;
2988 struct vnode *vp; 
2989 off_t offset; 2962 off_t offset;
2990 int error, fd = SCARG(uap, fd); 2963 int error, fd = SCARG(uap, fd);
2991 2964
2992 if ((fp = fd_getfile(fd)) == NULL) 2965 if ((fp = fd_getfile(fd)) == NULL)
2993 return (EBADF); 2966 return (EBADF);
2994 2967
2995 if ((fp->f_flag & FWRITE) == 0) { 2968 if ((fp->f_flag & FWRITE) == 0) {
2996 fd_putfile(fd); 2969 fd_putfile(fd);
2997 return (EBADF); 2970 return (EBADF);
2998 } 2971 }
2999 2972
3000 vp = fp->f_vnode; 2973 if (fp->f_ops->fo_seek == NULL) {
3001 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 
3002 error = ESPIPE; 2974 error = ESPIPE;
3003 goto out; 2975 goto out;
3004 } 2976 }
3005 2977
3006 offset = SCARG(uap, offset); 2978 offset = SCARG(uap, offset);
3007 2979 error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0);
3008 /* 2980 if (error)
3009 * XXX This works because no file systems actually 
3010 * XXX take any action on the seek operation. 
3011 */ 
3012 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0) 
3013 goto out; 2981 goto out;
3014 2982
3015 /* dofilewrite() will unuse the descriptor for us */ 2983 /* dofilewrite() will unuse the descriptor for us */
3016 return (dofilewrite(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 2984 return (dofilewrite(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
3017 &offset, 0, retval)); 2985 &offset, 0, retval));
3018 2986
3019 out: 2987 out:
3020 fd_putfile(fd); 2988 fd_putfile(fd);
3021 return (error); 2989 return (error);
3022} 2990}
3023 2991
3024/* 2992/*
3025 * Positional gather write system call. 2993 * Positional gather write system call.

cvs diff -r1.221 -r1.222 src/sys/kern/vfs_vnops.c (expand / switch to unified diff)

--- src/sys/kern/vfs_vnops.c 2021/07/18 09:30:36 1.221
+++ src/sys/kern/vfs_vnops.c 2021/09/11 10:08:55 1.222
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_vnops.c,v 1.221 2021/07/18 09:30:36 dholland Exp $ */ 1/* $NetBSD: vfs_vnops.c,v 1.222 2021/09/11 10:08:55 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -56,27 +56,27 @@ @@ -56,27 +56,27 @@
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95 65 * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.221 2021/07/18 09:30:36 dholland Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.222 2021/09/11 10:08:55 riastradh Exp $");
70 70
71#include "veriexec.h" 71#include "veriexec.h"
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/systm.h> 74#include <sys/systm.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/file.h> 76#include <sys/file.h>
77#include <sys/stat.h> 77#include <sys/stat.h>
78#include <sys/buf.h> 78#include <sys/buf.h>
79#include <sys/proc.h> 79#include <sys/proc.h>
80#include <sys/mount.h> 80#include <sys/mount.h>
81#include <sys/namei.h> 81#include <sys/namei.h>
82#include <sys/vnode.h> 82#include <sys/vnode.h>
@@ -111,39 +111,41 @@ int (*vn_union_readdir_hook) (struct vno @@ -111,39 +111,41 @@ int (*vn_union_readdir_hook) (struct vno
111#include <sys/verified_exec.h> 111#include <sys/verified_exec.h>
112 112
113static int vn_read(file_t *fp, off_t *offset, struct uio *uio, 113static int vn_read(file_t *fp, off_t *offset, struct uio *uio,
114 kauth_cred_t cred, int flags); 114 kauth_cred_t cred, int flags);
115static int vn_write(file_t *fp, off_t *offset, struct uio *uio, 115static int vn_write(file_t *fp, off_t *offset, struct uio *uio,
116 kauth_cred_t cred, int flags); 116 kauth_cred_t cred, int flags);
117static int vn_closefile(file_t *fp); 117static int vn_closefile(file_t *fp);
118static int vn_poll(file_t *fp, int events); 118static int vn_poll(file_t *fp, int events);
119static int vn_fcntl(file_t *fp, u_int com, void *data); 119static int vn_fcntl(file_t *fp, u_int com, void *data);
120static int vn_statfile(file_t *fp, struct stat *sb); 120static int vn_statfile(file_t *fp, struct stat *sb);
121static int vn_ioctl(file_t *fp, u_long com, void *data); 121static int vn_ioctl(file_t *fp, u_long com, void *data);
122static int vn_mmap(struct file *, off_t *, size_t, int, int *, int *, 122static int vn_mmap(struct file *, off_t *, size_t, int, int *, int *,
123 struct uvm_object **, int *); 123 struct uvm_object **, int *);
 124static int vn_seek(struct file *, off_t, int, off_t *, int);
124 125
125const struct fileops vnops = { 126const struct fileops vnops = {
126 .fo_name = "vn", 127 .fo_name = "vn",
127 .fo_read = vn_read, 128 .fo_read = vn_read,
128 .fo_write = vn_write, 129 .fo_write = vn_write,
129 .fo_ioctl = vn_ioctl, 130 .fo_ioctl = vn_ioctl,
130 .fo_fcntl = vn_fcntl, 131 .fo_fcntl = vn_fcntl,
131 .fo_poll = vn_poll, 132 .fo_poll = vn_poll,
132 .fo_stat = vn_statfile, 133 .fo_stat = vn_statfile,
133 .fo_close = vn_closefile, 134 .fo_close = vn_closefile,
134 .fo_kqfilter = vn_kqfilter, 135 .fo_kqfilter = vn_kqfilter,
135 .fo_restart = fnullop_restart, 136 .fo_restart = fnullop_restart,
136 .fo_mmap = vn_mmap, 137 .fo_mmap = vn_mmap,
 138 .fo_seek = vn_seek,
137}; 139};
138 140
139/* 141/*
140 * Common code for vnode open operations. 142 * Common code for vnode open operations.
141 * Check permissions, and call the VOP_OPEN or VOP_CREATE routine. 143 * Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
142 * 144 *
143 * at_dvp is the directory for openat(), if any. 145 * at_dvp is the directory for openat(), if any.
144 * pb is the path. 146 * pb is the path.
145 * nmode is additional namei flags, restricted to TRYEMULROOT and NOCHROOT. 147 * nmode is additional namei flags, restricted to TRYEMULROOT and NOCHROOT.
146 * fmode is the open flags, converted from O_* to F* 148 * fmode is the open flags, converted from O_* to F*
147 * cmode is the creation file permissions. 149 * cmode is the creation file permissions.
148 * 150 *
149 * XXX shouldn't cmode be mode_t? 151 * XXX shouldn't cmode be mode_t?
@@ -1100,27 +1102,76 @@ vn_mmap(struct file *fp, off_t *offp, si @@ -1100,27 +1102,76 @@ vn_mmap(struct file *fp, off_t *offp, si
1100 * it can't be made executable later. 1102 * it can't be made executable later.
1101 */ 1103 */
1102 maxprot &= ~VM_PROT_EXECUTE; 1104 maxprot &= ~VM_PROT_EXECUTE;
1103 } 1105 }
1104#endif /* NVERIEXEC > 0 */ 1106#endif /* NVERIEXEC > 0 */
1105 1107
1106 *uobjp = uobj; 1108 *uobjp = uobj;
1107 *maxprotp = maxprot; 1109 *maxprotp = maxprot;
1108 *flagsp = flags; 1110 *flagsp = flags;
1109 1111
1110 return 0; 1112 return 0;
1111} 1113}
1112 1114
 1115static int
 1116vn_seek(struct file *fp, off_t delta, int whence, off_t *newoffp,
 1117 int flags)
 1118{
 1119 kauth_cred_t cred = fp->f_cred;
 1120 off_t oldoff, newoff;
 1121 struct vnode *vp = fp->f_vnode;
 1122 struct vattr vattr;
 1123 int error;
 1124
 1125 if (vp->v_type == VFIFO)
 1126 return ESPIPE;
 1127
 1128 vn_lock(vp, LK_SHARED | LK_RETRY);
 1129
 1130 /* Compute the old and new offsets. */
 1131 oldoff = fp->f_offset;
 1132 switch (whence) {
 1133 case SEEK_CUR:
 1134 newoff = oldoff + delta; /* XXX arithmetic overflow */
 1135 break;
 1136 case SEEK_END:
 1137 error = VOP_GETATTR(vp, &vattr, cred);
 1138 if (error)
 1139 goto out;
 1140 newoff = delta + vattr.va_size; /* XXX arithmetic overflow */
 1141 break;
 1142 case SEEK_SET:
 1143 newoff = delta;
 1144 break;
 1145 default:
 1146 error = EINVAL;
 1147 goto out;
 1148 }
 1149
 1150 /* Pass the proposed change to the file system to audit. */
 1151 error = VOP_SEEK(vp, oldoff, newoff, cred);
 1152 if (error)
 1153 goto out;
 1154
 1155 /* Success! */
 1156 if (newoffp)
 1157 *newoffp = newoff;
 1158 if (flags & FOF_UPDATE_OFFSET)
 1159 fp->f_offset = newoff;
 1160 error = 0;
1113 1161
 1162out: VOP_UNLOCK(vp);
 1163 return error;
 1164}
1114 1165
1115/* 1166/*
1116 * Check that the vnode is still valid, and if so 1167 * Check that the vnode is still valid, and if so
1117 * acquire requested lock. 1168 * acquire requested lock.
1118 */ 1169 */
1119int 1170int
1120vn_lock(struct vnode *vp, int flags) 1171vn_lock(struct vnode *vp, int flags)
1121{ 1172{
1122 struct lwp *l; 1173 struct lwp *l;
1123 int error; 1174 int error;
1124 1175
1125#if 0 1176#if 0
1126 KASSERT(vrefcnt(vp) > 0 || (vp->v_iflag & VI_ONWORKLST) != 0); 1177 KASSERT(vrefcnt(vp) > 0 || (vp->v_iflag & VI_ONWORKLST) != 0);

cvs diff -r1.86 -r1.87 src/sys/sys/file.h (expand / switch to unified diff)

--- src/sys/sys/file.h 2020/05/02 18:43:02 1.86
+++ src/sys/sys/file.h 2021/09/11 10:08:55 1.87
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: file.h,v 1.86 2020/05/02 18:43:02 christos Exp $ */ 1/* $NetBSD: file.h,v 1.87 2021/09/11 10:08:55 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -84,27 +84,27 @@ struct fileops { @@ -84,27 +84,27 @@ struct fileops {
84 int (*fo_read) (struct file *, off_t *, struct uio *, 84 int (*fo_read) (struct file *, off_t *, struct uio *,
85 kauth_cred_t, int); 85 kauth_cred_t, int);
86 int (*fo_write) (struct file *, off_t *, struct uio *, 86 int (*fo_write) (struct file *, off_t *, struct uio *,
87 kauth_cred_t, int); 87 kauth_cred_t, int);
88 int (*fo_ioctl) (struct file *, u_long, void *); 88 int (*fo_ioctl) (struct file *, u_long, void *);
89 int (*fo_fcntl) (struct file *, u_int, void *); 89 int (*fo_fcntl) (struct file *, u_int, void *);
90 int (*fo_poll) (struct file *, int); 90 int (*fo_poll) (struct file *, int);
91 int (*fo_stat) (struct file *, struct stat *); 91 int (*fo_stat) (struct file *, struct stat *);
92 int (*fo_close) (struct file *); 92 int (*fo_close) (struct file *);
93 int (*fo_kqfilter) (struct file *, struct knote *); 93 int (*fo_kqfilter) (struct file *, struct knote *);
94 void (*fo_restart) (struct file *); 94 void (*fo_restart) (struct file *);
95 int (*fo_mmap) (struct file *, off_t *, size_t, int, int *, 95 int (*fo_mmap) (struct file *, off_t *, size_t, int, int *,
96 int *, struct uvm_object **, int *); 96 int *, struct uvm_object **, int *);
97 void (*fo_spare2) (void); 97 int (*fo_seek) (struct file *, off_t, int, off_t *, int);
98}; 98};
99 99
100union file_data { 100union file_data {
101 struct vnode *fd_vp; // DTYPE_VNODE 101 struct vnode *fd_vp; // DTYPE_VNODE
102 struct socket *fd_so; // DTYPE_SOCKET 102 struct socket *fd_so; // DTYPE_SOCKET
103 struct pipe *fd_pipe; // DTYPE_PIPE 103 struct pipe *fd_pipe; // DTYPE_PIPE
104 struct kqueue *fd_kq; // DTYPE_KQUEUE 104 struct kqueue *fd_kq; // DTYPE_KQUEUE
105 void *fd_data; // DTYPE_MISC 105 void *fd_data; // DTYPE_MISC
106 struct audio_file *fd_audioctx; // DTYPE_MISC (audio) 106 struct audio_file *fd_audioctx; // DTYPE_MISC (audio)
107 struct pad_softc *fd_pad; // DTYPE_MISC (pad) 107 struct pad_softc *fd_pad; // DTYPE_MISC (pad)
108 int fd_devunit; // DTYPE_MISC (tap) 108 int fd_devunit; // DTYPE_MISC (tap)
109 struct bpf_d *fd_bpf; // DTYPE_MISC (bpf) 109 struct bpf_d *fd_bpf; // DTYPE_MISC (bpf)
110 struct fcrypt *fd_fcrypt; // DTYPE_CRYPTO is not used 110 struct fcrypt *fd_fcrypt; // DTYPE_CRYPTO is not used