1 /* $NetBSD: vfs_vnops.c,v 1.168 2009/12/20 09:36:06 dsl Exp $ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1982, 1986, 1989, 1993
34 * The Regents of the University of California. All rights reserved.
35 * (c) UNIX System Laboratories, Inc.
36 * All or some portions of this file are derived from material licensed
37 * to the University of California by American Telephone and Telegraph
38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39 * the permission of UNIX System Laboratories, Inc.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
65 * @(#)vfs_vnops.c 8.14 (Berkeley) 6/15/95
68 #include <sys/cdefs.h>
69 __KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.168 2009/12/20 09:36:06 dsl Exp $");
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/kernel.h>
80 #include <sys/mount.h>
81 #include <sys/namei.h>
82 #include <sys/vnode.h>
83 #include <sys/ioctl.h>
86 #include <sys/kauth.h>
87 #include <sys/syslog.h>
88 #include <sys/fstrans.h>
89 #include <sys/atomic.h>
90 #include <sys/filedesc.h>
91 #include <sys/wapbl.h>
93 #include <miscfs/specfs/specdev.h>
95 #include <uvm/uvm_extern.h>
96 #include <uvm/uvm_readahead.h>
99 #include <fs/union/union.h>
102 int (*vn_union_readdir_hook
) (struct vnode
**, struct file
*, struct lwp
*);
104 #include <sys/verified_exec.h>
106 static int vn_read(file_t
*fp
, off_t
*offset
, struct uio
*uio
,
107 kauth_cred_t cred
, int flags
);
108 static int vn_write(file_t
*fp
, off_t
*offset
, struct uio
*uio
,
109 kauth_cred_t cred
, int flags
);
110 static int vn_closefile(file_t
*fp
);
111 static int vn_poll(file_t
*fp
, int events
);
112 static int vn_fcntl(file_t
*fp
, u_int com
, void *data
);
113 static int vn_statfile(file_t
*fp
, struct stat
*sb
);
114 static int vn_ioctl(file_t
*fp
, u_long com
, void *data
);
116 const struct fileops vnops
= {
118 .fo_write
= vn_write
,
119 .fo_ioctl
= vn_ioctl
,
120 .fo_fcntl
= vn_fcntl
,
122 .fo_stat
= vn_statfile
,
123 .fo_close
= vn_closefile
,
124 .fo_kqfilter
= vn_kqfilter
,
125 .fo_restart
= fnullop_restart
,
129 * Common code for vnode open operations.
130 * Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
133 vn_open(struct nameidata
*ndp
, int fmode
, int cmode
)
136 struct lwp
*l
= curlwp
;
137 kauth_cred_t cred
= l
->l_cred
;
142 ndp
->ni_cnd
.cn_flags
&= TRYEMULROOT
| NOCHROOT
;
144 if (fmode
& O_CREAT
) {
145 ndp
->ni_cnd
.cn_nameiop
= CREATE
;
146 ndp
->ni_cnd
.cn_flags
|= LOCKPARENT
| LOCKLEAF
;
147 if ((fmode
& O_EXCL
) == 0 &&
148 ((fmode
& O_NOFOLLOW
) == 0))
149 ndp
->ni_cnd
.cn_flags
|= FOLLOW
;
151 ndp
->ni_cnd
.cn_nameiop
= LOOKUP
;
152 ndp
->ni_cnd
.cn_flags
|= LOCKLEAF
;
153 if ((fmode
& O_NOFOLLOW
) == 0)
154 ndp
->ni_cnd
.cn_flags
|= FOLLOW
;
157 VERIEXEC_PATH_GET(ndp
->ni_dirp
, ndp
->ni_segflg
, ndp
->ni_dirp
, path
);
166 error
= veriexec_openchk(l
, ndp
->ni_vp
, ndp
->ni_dirp
, fmode
);
169 #endif /* NVERIEXEC > 0 */
171 if (fmode
& O_CREAT
) {
172 if (ndp
->ni_vp
== NULL
) {
177 va
.va_vaflags
|= VA_EXCLUSIVE
;
178 error
= VOP_CREATE(ndp
->ni_dvp
, &ndp
->ni_vp
,
185 VOP_ABORTOP(ndp
->ni_dvp
, &ndp
->ni_cnd
);
186 if (ndp
->ni_dvp
== ndp
->ni_vp
)
192 if (fmode
& O_EXCL
) {
201 if (vp
->v_type
== VSOCK
) {
205 if (ndp
->ni_vp
->v_type
== VLNK
) {
210 if ((fmode
& O_CREAT
) == 0) {
211 error
= vn_openchk(vp
, cred
, fmode
);
216 if (fmode
& O_TRUNC
) {
217 VOP_UNLOCK(vp
, 0); /* XXX */
219 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
); /* XXX */
222 error
= VOP_SETATTR(vp
, &va
, cred
);
226 if ((error
= VOP_OPEN(vp
, fmode
, cred
)) != 0)
228 if (fmode
& FWRITE
) {
229 mutex_enter(&vp
->v_interlock
);
231 mutex_exit(&vp
->v_interlock
);
238 VERIEXEC_PATH_PUT(path
);
243 * Check for write permissions on the specified vnode.
244 * Prototype text segments cannot be written.
247 vn_writechk(struct vnode
*vp
)
251 * If the vnode is in use as a process's text,
252 * we can't allow writing.
254 if (vp
->v_iflag
& VI_TEXT
)
260 vn_openchk(struct vnode
*vp
, kauth_cred_t cred
, int fflags
)
265 if ((fflags
& FREAD
) != 0) {
268 if ((fflags
& (FWRITE
| O_TRUNC
)) != 0) {
270 if (vp
->v_type
== VDIR
) {
274 error
= vn_writechk(vp
);
278 error
= VOP_ACCESS(vp
, permbits
, cred
);
284 * Mark a vnode as having executable mappings.
287 vn_markexec(struct vnode
*vp
)
290 if ((vp
->v_iflag
& VI_EXECMAP
) != 0) {
291 /* Safe unlocked, as long as caller holds a reference. */
295 mutex_enter(&vp
->v_interlock
);
296 if ((vp
->v_iflag
& VI_EXECMAP
) == 0) {
297 atomic_add_int(&uvmexp
.filepages
, -vp
->v_uobj
.uo_npages
);
298 atomic_add_int(&uvmexp
.execpages
, vp
->v_uobj
.uo_npages
);
299 vp
->v_iflag
|= VI_EXECMAP
;
301 mutex_exit(&vp
->v_interlock
);
305 * Mark a vnode as being the text of a process.
306 * Fail if the vnode is currently writable.
309 vn_marktext(struct vnode
*vp
)
312 if ((vp
->v_iflag
& (VI_TEXT
|VI_EXECMAP
)) == (VI_TEXT
|VI_EXECMAP
)) {
313 /* Safe unlocked, as long as caller holds a reference. */
317 mutex_enter(&vp
->v_interlock
);
318 if (vp
->v_writecount
!= 0) {
319 KASSERT((vp
->v_iflag
& VI_TEXT
) == 0);
320 mutex_exit(&vp
->v_interlock
);
323 if ((vp
->v_iflag
& VI_EXECMAP
) == 0) {
324 atomic_add_int(&uvmexp
.filepages
, -vp
->v_uobj
.uo_npages
);
325 atomic_add_int(&uvmexp
.execpages
, vp
->v_uobj
.uo_npages
);
327 vp
->v_iflag
|= (VI_TEXT
| VI_EXECMAP
);
328 mutex_exit(&vp
->v_interlock
);
335 * Note: takes an unlocked vnode, while VOP_CLOSE takes a locked node.
338 vn_close(struct vnode
*vp
, int flags
, kauth_cred_t cred
)
342 if (flags
& FWRITE
) {
343 mutex_enter(&vp
->v_interlock
);
345 mutex_exit(&vp
->v_interlock
);
347 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
348 error
= VOP_CLOSE(vp
, flags
, cred
);
354 * Package up an I/O request on a vnode into a uio and do it.
357 vn_rdwr(enum uio_rw rw
, struct vnode
*vp
, void *base
, int len
, off_t offset
,
358 enum uio_seg segflg
, int ioflg
, kauth_cred_t cred
, size_t *aresid
,
365 if ((ioflg
& IO_NODELOCKED
) == 0) {
366 if (rw
== UIO_READ
) {
367 vn_lock(vp
, LK_SHARED
| LK_RETRY
);
368 } else /* UIO_WRITE */ {
369 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
372 auio
.uio_iov
= &aiov
;
374 aiov
.iov_base
= base
;
376 auio
.uio_resid
= len
;
377 auio
.uio_offset
= offset
;
379 if (segflg
== UIO_SYSSPACE
) {
380 UIO_SETUP_SYSSPACE(&auio
);
382 auio
.uio_vmspace
= l
->l_proc
->p_vmspace
;
384 if (rw
== UIO_READ
) {
385 error
= VOP_READ(vp
, &auio
, ioflg
, cred
);
387 error
= VOP_WRITE(vp
, &auio
, ioflg
, cred
);
390 *aresid
= auio
.uio_resid
;
392 if (auio
.uio_resid
&& error
== 0)
394 if ((ioflg
& IO_NODELOCKED
) == 0) {
401 vn_readdir(file_t
*fp
, char *bf
, int segflg
, u_int count
, int *done
,
402 struct lwp
*l
, off_t
**cookies
, int *ncookies
)
404 struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
409 /* Limit the size on any kernel buffers used by VOP_READDIR */
410 count
= min(MAXBSIZE
, count
);
413 if (vp
->v_type
!= VDIR
)
416 aiov
.iov_len
= count
;
417 auio
.uio_iov
= &aiov
;
419 auio
.uio_rw
= UIO_READ
;
420 if (segflg
== UIO_SYSSPACE
) {
421 UIO_SETUP_SYSSPACE(&auio
);
423 KASSERT(l
== curlwp
);
424 auio
.uio_vmspace
= l
->l_proc
->p_vmspace
;
426 auio
.uio_resid
= count
;
427 vn_lock(vp
, LK_SHARED
| LK_RETRY
);
428 auio
.uio_offset
= fp
->f_offset
;
429 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, cookies
,
431 mutex_enter(&fp
->f_lock
);
432 fp
->f_offset
= auio
.uio_offset
;
433 mutex_exit(&fp
->f_lock
);
438 if (count
== auio
.uio_resid
&& vn_union_readdir_hook
) {
439 struct vnode
*ovp
= vp
;
441 error
= (*vn_union_readdir_hook
)(&vp
, fp
, l
);
448 if (count
== auio
.uio_resid
&& (vp
->v_vflag
& VV_ROOT
) &&
449 (vp
->v_mount
->mnt_flag
& MNT_UNION
)) {
450 struct vnode
*tvp
= vp
;
451 vp
= vp
->v_mount
->mnt_vnodecovered
;
453 mutex_enter(&fp
->f_lock
);
456 mutex_exit(&fp
->f_lock
);
460 *done
= count
- auio
.uio_resid
;
465 * File table vnode read routine.
468 vn_read(file_t
*fp
, off_t
*offset
, struct uio
*uio
, kauth_cred_t cred
,
471 struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
472 int count
, error
, ioflag
, fflag
;
474 ioflag
= IO_ADV_ENCODE(fp
->f_advice
);
476 if (fflag
& FNONBLOCK
)
478 if ((fflag
& (FFSYNC
| FRSYNC
)) == (FFSYNC
| FRSYNC
))
481 ioflag
|= IO_ALTSEMANTICS
;
484 vn_lock(vp
, LK_SHARED
| LK_RETRY
);
485 uio
->uio_offset
= *offset
;
486 count
= uio
->uio_resid
;
487 error
= VOP_READ(vp
, uio
, ioflag
, cred
);
488 if (flags
& FOF_UPDATE_OFFSET
)
489 *offset
+= count
- uio
->uio_resid
;
495 * File table vnode write routine.
498 vn_write(file_t
*fp
, off_t
*offset
, struct uio
*uio
, kauth_cred_t cred
,
501 struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
502 int count
, error
, ioflag
, fflag
;
504 ioflag
= IO_ADV_ENCODE(fp
->f_advice
) | IO_UNIT
;
506 if (vp
->v_type
== VREG
&& (fflag
& O_APPEND
))
508 if (fflag
& FNONBLOCK
)
510 if (fflag
& FFSYNC
||
511 (vp
->v_mount
&& (vp
->v_mount
->mnt_flag
& MNT_SYNCHRONOUS
)))
513 else if (fflag
& FDSYNC
)
516 ioflag
|= IO_ALTSEMANTICS
;
519 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
520 uio
->uio_offset
= *offset
;
521 count
= uio
->uio_resid
;
522 error
= VOP_WRITE(vp
, uio
, ioflag
, cred
);
523 if (flags
& FOF_UPDATE_OFFSET
) {
524 if (ioflag
& IO_APPEND
) {
526 * SUSv3 describes behaviour for count = 0 as following:
527 * "Before any action ... is taken, and if nbyte is zero
528 * and the file is a regular file, the write() function
529 * ... in the absence of errors ... shall return zero
530 * and have no other results."
533 *offset
= uio
->uio_offset
;
535 *offset
+= count
- uio
->uio_resid
;
542 * File table vnode stat routine.
545 vn_statfile(file_t
*fp
, struct stat
*sb
)
547 struct vnode
*vp
= fp
->f_data
;
550 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
551 error
= vn_stat(vp
, sb
);
557 vn_stat(struct vnode
*vp
, struct stat
*sb
)
563 error
= VOP_GETATTR(vp
, &va
, kauth_cred_get());
567 * Copy from vattr table
569 sb
->st_dev
= va
.va_fsid
;
570 sb
->st_ino
= va
.va_fileid
;
572 switch (vp
->v_type
) {
598 sb
->st_nlink
= va
.va_nlink
;
599 sb
->st_uid
= va
.va_uid
;
600 sb
->st_gid
= va
.va_gid
;
601 sb
->st_rdev
= va
.va_rdev
;
602 sb
->st_size
= va
.va_size
;
603 sb
->st_atimespec
= va
.va_atime
;
604 sb
->st_mtimespec
= va
.va_mtime
;
605 sb
->st_ctimespec
= va
.va_ctime
;
606 sb
->st_birthtimespec
= va
.va_birthtime
;
607 sb
->st_blksize
= va
.va_blocksize
;
608 sb
->st_flags
= va
.va_flags
;
610 sb
->st_blocks
= va
.va_bytes
/ S_BLKSIZE
;
615 * File table vnode fcntl routine.
618 vn_fcntl(file_t
*fp
, u_int com
, void *data
)
620 struct vnode
*vp
= fp
->f_data
;
623 error
= VOP_FCNTL(vp
, com
, data
, fp
->f_flag
, kauth_cred_get());
628 * File table vnode ioctl routine.
631 vn_ioctl(file_t
*fp
, u_long com
, void *data
)
633 struct vnode
*vp
= fp
->f_data
, *ovp
;
637 switch (vp
->v_type
) {
641 if (com
== FIONREAD
) {
642 error
= VOP_GETATTR(vp
, &vattr
,
646 *(int *)data
= vattr
.va_size
- fp
->f_offset
;
649 if ((com
== FIONWRITE
) || (com
== FIONSPACE
)) {
651 * Files don't have send queues, so there never
652 * are any bytes in them, nor is there any
653 * open space in them.
658 if (com
== FIOGETBMAP
) {
661 if (*(daddr_t
*)data
< 0)
663 block
= (daddr_t
*)data
;
664 return (VOP_BMAP(vp
, *block
, NULL
, block
, NULL
));
666 if (com
== OFIOGETBMAP
) {
669 if (*(int32_t *)data
< 0)
671 ibn
= (daddr_t
)*(int32_t *)data
;
672 error
= VOP_BMAP(vp
, ibn
, NULL
, &obn
, NULL
);
673 *(int32_t *)data
= (int32_t)obn
;
676 if (com
== FIONBIO
|| com
== FIOASYNC
) /* XXX */
677 return (0); /* XXX */
682 error
= VOP_IOCTL(vp
, com
, data
, fp
->f_flag
,
684 if (error
== 0 && com
== TIOCSCTTY
) {
686 mutex_enter(proc_lock
);
687 ovp
= curproc
->p_session
->s_ttyvp
;
688 curproc
->p_session
->s_ttyvp
= vp
;
689 mutex_exit(proc_lock
);
696 return (EPASSTHROUGH
);
701 * File table vnode poll routine.
704 vn_poll(file_t
*fp
, int events
)
707 return (VOP_POLL(fp
->f_data
, events
));
711 * File table vnode kqfilter routine.
714 vn_kqfilter(file_t
*fp
, struct knote
*kn
)
717 return (VOP_KQFILTER(fp
->f_data
, kn
));
721 * Check that the vnode is still valid, and if so
722 * acquire requested lock.
725 vn_lock(struct vnode
*vp
, int flags
)
730 KASSERT(vp
->v_usecount
> 0 || (flags
& LK_INTERLOCK
) != 0
731 || (vp
->v_iflag
& VI_ONWORKLST
) != 0);
734 ~(LK_INTERLOCK
|LK_SHARED
|LK_EXCLUSIVE
|LK_NOWAIT
|LK_RETRY
|
739 if (wapbl_vphaswapbl(vp
))
740 WAPBL_JUNLOCK_ASSERT(wapbl_vptomp(vp
));
745 * XXX PR 37706 forced unmount of file systems is unsafe.
746 * Race between vclean() and this the remaining problem.
748 if (vp
->v_iflag
& VI_XLOCK
) {
749 if ((flags
& LK_INTERLOCK
) == 0) {
750 mutex_enter(&vp
->v_interlock
);
752 flags
&= ~LK_INTERLOCK
;
753 if (flags
& LK_NOWAIT
) {
754 mutex_exit(&vp
->v_interlock
);
758 mutex_exit(&vp
->v_interlock
);
761 if ((flags
& LK_INTERLOCK
) != 0) {
762 mutex_exit(&vp
->v_interlock
);
764 flags
&= ~LK_INTERLOCK
;
765 error
= VOP_LOCK(vp
, (flags
& ~LK_RETRY
));
766 if (error
== 0 || error
== EDEADLK
|| error
== EBUSY
)
769 } while (flags
& LK_RETRY
);
774 * File table vnode close routine.
777 vn_closefile(file_t
*fp
)
780 return vn_close(fp
->f_data
, fp
->f_flag
, fp
->f_cred
);
784 * Enable LK_CANRECURSE on lock. Return prior status.
787 vn_setrecurse(struct vnode
*vp
)
791 lkp
= (vp
->v_vnlock
!= NULL
? vp
->v_vnlock
: &vp
->v_lock
);
792 atomic_inc_uint(&lkp
->vl_canrecurse
);
798 * Called when done with locksetrecurse.
801 vn_restorerecurse(struct vnode
*vp
, u_int flags
)
805 lkp
= (vp
->v_vnlock
!= NULL
? vp
->v_vnlock
: &vp
->v_lock
);
806 atomic_dec_uint(&lkp
->vl_canrecurse
);
810 * Simplified in-kernel wrapper calls for extended attribute access.
811 * Both calls pass in a NULL credential, authorizing a "kernel" access.
812 * Set IO_NODELOCKED in ioflg if the vnode is already locked.
815 vn_extattr_get(struct vnode
*vp
, int ioflg
, int attrnamespace
,
816 const char *attrname
, size_t *buflen
, void *bf
, struct lwp
*l
)
822 aiov
.iov_len
= *buflen
;
825 auio
.uio_iov
= &aiov
;
827 auio
.uio_rw
= UIO_READ
;
829 auio
.uio_resid
= *buflen
;
830 UIO_SETUP_SYSSPACE(&auio
);
832 if ((ioflg
& IO_NODELOCKED
) == 0)
833 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
835 error
= VOP_GETEXTATTR(vp
, attrnamespace
, attrname
, &auio
, NULL
, NULL
);
837 if ((ioflg
& IO_NODELOCKED
) == 0)
841 *buflen
= *buflen
- auio
.uio_resid
;
847 * XXX Failure mode if partially written?
850 vn_extattr_set(struct vnode
*vp
, int ioflg
, int attrnamespace
,
851 const char *attrname
, size_t buflen
, const void *bf
, struct lwp
*l
)
857 aiov
.iov_len
= buflen
;
858 aiov
.iov_base
= __UNCONST(bf
); /* XXXUNCONST kills const */
860 auio
.uio_iov
= &aiov
;
862 auio
.uio_rw
= UIO_WRITE
;
864 auio
.uio_resid
= buflen
;
865 UIO_SETUP_SYSSPACE(&auio
);
867 if ((ioflg
& IO_NODELOCKED
) == 0) {
868 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
871 error
= VOP_SETEXTATTR(vp
, attrnamespace
, attrname
, &auio
, NULL
);
873 if ((ioflg
& IO_NODELOCKED
) == 0) {
881 vn_extattr_rm(struct vnode
*vp
, int ioflg
, int attrnamespace
,
882 const char *attrname
, struct lwp
*l
)
886 if ((ioflg
& IO_NODELOCKED
) == 0) {
887 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
890 error
= VOP_DELETEEXTATTR(vp
, attrnamespace
, attrname
, NULL
);
891 if (error
== EOPNOTSUPP
)
892 error
= VOP_SETEXTATTR(vp
, attrnamespace
, attrname
, NULL
, NULL
);
894 if ((ioflg
& IO_NODELOCKED
) == 0) {
902 vn_ra_allocctx(struct vnode
*vp
)
904 struct uvm_ractx
*ra
= NULL
;
906 KASSERT(mutex_owned(&vp
->v_interlock
));
908 if (vp
->v_type
!= VREG
) {
911 if (vp
->v_ractx
!= NULL
) {
914 if (vp
->v_ractx
== NULL
) {
915 mutex_exit(&vp
->v_interlock
);
916 ra
= uvm_ra_allocctx();
917 mutex_enter(&vp
->v_interlock
);
918 if (ra
!= NULL
&& vp
->v_ractx
== NULL
) {