]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/vfs_vnops.c
Stick the if_drv_flags access (check and modify) behind the ifq lock.
[FreeBSD/FreeBSD.git] / sys / kern / vfs_vnops.c
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
35  */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/fcntl.h>
43 #include <sys/file.h>
44 #include <sys/kdb.h>
45 #include <sys/stat.h>
46 #include <sys/priv.h>
47 #include <sys/proc.h>
48 #include <sys/limits.h>
49 #include <sys/lock.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/namei.h>
53 #include <sys/vnode.h>
54 #include <sys/bio.h>
55 #include <sys/buf.h>
56 #include <sys/filio.h>
57 #include <sys/resourcevar.h>
58 #include <sys/sx.h>
59 #include <sys/ttycom.h>
60 #include <sys/conf.h>
61 #include <sys/syslog.h>
62 #include <sys/unistd.h>
63
64 #include <security/audit/audit.h>
65 #include <security/mac/mac_framework.h>
66
67 #include <vm/vm.h>
68 #include <vm/vm_object.h>
69
70 static fo_rdwr_t        vn_read;
71 static fo_rdwr_t        vn_write;
72 static fo_truncate_t    vn_truncate;
73 static fo_ioctl_t       vn_ioctl;
74 static fo_poll_t        vn_poll;
75 static fo_kqfilter_t    vn_kqfilter;
76 static fo_stat_t        vn_statfile;
77 static fo_close_t       vn_closefile;
78
79 struct  fileops vnops = {
80         .fo_read = vn_read,
81         .fo_write = vn_write,
82         .fo_truncate = vn_truncate,
83         .fo_ioctl = vn_ioctl,
84         .fo_poll = vn_poll,
85         .fo_kqfilter = vn_kqfilter,
86         .fo_stat = vn_statfile,
87         .fo_close = vn_closefile,
88         .fo_chmod = vn_chmod,
89         .fo_chown = vn_chown,
90         .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
91 };
92
93 int
94 vn_open(ndp, flagp, cmode, fp)
95         struct nameidata *ndp;
96         int *flagp, cmode;
97         struct file *fp;
98 {
99         struct thread *td = ndp->ni_cnd.cn_thread;
100
101         return (vn_open_cred(ndp, flagp, cmode, 0, td->td_ucred, fp));
102 }
103
104 /*
105  * Common code for vnode open operations.
106  * Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
107  * 
108  * Note that this does NOT free nameidata for the successful case,
109  * due to the NDINIT being done elsewhere.
110  */
111 int
112 vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, u_int vn_open_flags,
113     struct ucred *cred, struct file *fp)
114 {
115         struct vnode *vp;
116         struct mount *mp;
117         struct thread *td = ndp->ni_cnd.cn_thread;
118         struct vattr vat;
119         struct vattr *vap = &vat;
120         int fmode, error;
121         accmode_t accmode;
122         int vfslocked, mpsafe;
123
124         mpsafe = ndp->ni_cnd.cn_flags & MPSAFE;
125 restart:
126         vfslocked = 0;
127         fmode = *flagp;
128         if (fmode & O_CREAT) {
129                 ndp->ni_cnd.cn_nameiop = CREATE;
130                 ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF |
131                     MPSAFE;
132                 if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
133                         ndp->ni_cnd.cn_flags |= FOLLOW;
134                 if (!(vn_open_flags & VN_OPEN_NOAUDIT))
135                         ndp->ni_cnd.cn_flags |= AUDITVNODE1;
136                 bwillwrite();
137                 if ((error = namei(ndp)) != 0)
138                         return (error);
139                 vfslocked = NDHASGIANT(ndp);
140                 if (!mpsafe)
141                         ndp->ni_cnd.cn_flags &= ~MPSAFE;
142                 if (ndp->ni_vp == NULL) {
143                         VATTR_NULL(vap);
144                         vap->va_type = VREG;
145                         vap->va_mode = cmode;
146                         if (fmode & O_EXCL)
147                                 vap->va_vaflags |= VA_EXCLUSIVE;
148                         if (vn_start_write(ndp->ni_dvp, &mp, V_NOWAIT) != 0) {
149                                 NDFREE(ndp, NDF_ONLY_PNBUF);
150                                 vput(ndp->ni_dvp);
151                                 VFS_UNLOCK_GIANT(vfslocked);
152                                 if ((error = vn_start_write(NULL, &mp,
153                                     V_XSLEEP | PCATCH)) != 0)
154                                         return (error);
155                                 goto restart;
156                         }
157 #ifdef MAC
158                         error = mac_vnode_check_create(cred, ndp->ni_dvp,
159                             &ndp->ni_cnd, vap);
160                         if (error == 0)
161 #endif
162                                 error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
163                                                    &ndp->ni_cnd, vap);
164                         vput(ndp->ni_dvp);
165                         vn_finished_write(mp);
166                         if (error) {
167                                 VFS_UNLOCK_GIANT(vfslocked);
168                                 NDFREE(ndp, NDF_ONLY_PNBUF);
169                                 return (error);
170                         }
171                         fmode &= ~O_TRUNC;
172                         vp = ndp->ni_vp;
173                 } else {
174                         if (ndp->ni_dvp == ndp->ni_vp)
175                                 vrele(ndp->ni_dvp);
176                         else
177                                 vput(ndp->ni_dvp);
178                         ndp->ni_dvp = NULL;
179                         vp = ndp->ni_vp;
180                         if (fmode & O_EXCL) {
181                                 error = EEXIST;
182                                 goto bad;
183                         }
184                         fmode &= ~O_CREAT;
185                 }
186         } else {
187                 ndp->ni_cnd.cn_nameiop = LOOKUP;
188                 ndp->ni_cnd.cn_flags = ISOPEN |
189                     ((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) |
190                     LOCKLEAF | MPSAFE;
191                 if (!(fmode & FWRITE))
192                         ndp->ni_cnd.cn_flags |= LOCKSHARED;
193                 if (!(vn_open_flags & VN_OPEN_NOAUDIT))
194                         ndp->ni_cnd.cn_flags |= AUDITVNODE1;
195                 if ((error = namei(ndp)) != 0)
196                         return (error);
197                 if (!mpsafe)
198                         ndp->ni_cnd.cn_flags &= ~MPSAFE;
199                 vfslocked = NDHASGIANT(ndp);
200                 vp = ndp->ni_vp;
201         }
202         if (vp->v_type == VLNK) {
203                 error = EMLINK;
204                 goto bad;
205         }
206         if (vp->v_type == VSOCK) {
207                 error = EOPNOTSUPP;
208                 goto bad;
209         }
210         if (vp->v_type != VDIR && fmode & O_DIRECTORY) {
211                 error = ENOTDIR;
212                 goto bad;
213         }
214         accmode = 0;
215         if (fmode & (FWRITE | O_TRUNC)) {
216                 if (vp->v_type == VDIR) {
217                         error = EISDIR;
218                         goto bad;
219                 }
220                 accmode |= VWRITE;
221         }
222         if (fmode & FREAD)
223                 accmode |= VREAD;
224         if (fmode & FEXEC)
225                 accmode |= VEXEC;
226         if ((fmode & O_APPEND) && (fmode & FWRITE))
227                 accmode |= VAPPEND;
228 #ifdef MAC
229         error = mac_vnode_check_open(cred, vp, accmode);
230         if (error)
231                 goto bad;
232 #endif
233         if ((fmode & O_CREAT) == 0) {
234                 if (accmode & VWRITE) {
235                         error = vn_writechk(vp);
236                         if (error)
237                                 goto bad;
238                 }
239                 if (accmode) {
240                         error = VOP_ACCESS(vp, accmode, cred, td);
241                         if (error)
242                                 goto bad;
243                 }
244         }
245         if ((error = VOP_OPEN(vp, fmode, cred, td, fp)) != 0)
246                 goto bad;
247
248         if (fmode & FWRITE) {
249                 vp->v_writecount++;
250                 CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d",
251                     __func__, vp, vp->v_writecount);
252         }
253         *flagp = fmode;
254         ASSERT_VOP_LOCKED(vp, "vn_open_cred");
255         if (!mpsafe)
256                 VFS_UNLOCK_GIANT(vfslocked);
257         return (0);
258 bad:
259         NDFREE(ndp, NDF_ONLY_PNBUF);
260         vput(vp);
261         VFS_UNLOCK_GIANT(vfslocked);
262         *flagp = fmode;
263         ndp->ni_vp = NULL;
264         return (error);
265 }
266
267 /*
268  * Check for write permissions on the specified vnode.
269  * Prototype text segments cannot be written.
270  */
271 int
272 vn_writechk(vp)
273         register struct vnode *vp;
274 {
275
276         ASSERT_VOP_LOCKED(vp, "vn_writechk");
277         /*
278          * If there's shared text associated with
279          * the vnode, try to free it up once.  If
280          * we fail, we can't allow writing.
281          */
282         if (vp->v_vflag & VV_TEXT)
283                 return (ETXTBSY);
284
285         return (0);
286 }
287
288 /*
289  * Vnode close call
290  */
291 int
292 vn_close(vp, flags, file_cred, td)
293         register struct vnode *vp;
294         int flags;
295         struct ucred *file_cred;
296         struct thread *td;
297 {
298         struct mount *mp;
299         int error, lock_flags;
300
301         if (!(flags & FWRITE) && vp->v_mount != NULL &&
302             vp->v_mount->mnt_kern_flag & MNTK_EXTENDED_SHARED)
303                 lock_flags = LK_SHARED;
304         else
305                 lock_flags = LK_EXCLUSIVE;
306
307         VFS_ASSERT_GIANT(vp->v_mount);
308
309         vn_start_write(vp, &mp, V_WAIT);
310         vn_lock(vp, lock_flags | LK_RETRY);
311         if (flags & FWRITE) {
312                 VNASSERT(vp->v_writecount > 0, vp, 
313                     ("vn_close: negative writecount"));
314                 vp->v_writecount--;
315                 CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d",
316                     __func__, vp, vp->v_writecount);
317         }
318         error = VOP_CLOSE(vp, flags, file_cred, td);
319         vput(vp);
320         vn_finished_write(mp);
321         return (error);
322 }
323
324 /*
325  * Heuristic to detect sequential operation.
326  */
327 static int
328 sequential_heuristic(struct uio *uio, struct file *fp)
329 {
330
331         if (atomic_load_acq_int(&(fp->f_flag)) & FRDAHEAD)
332                 return (fp->f_seqcount << IO_SEQSHIFT);
333
334         /*
335          * Offset 0 is handled specially.  open() sets f_seqcount to 1 so
336          * that the first I/O is normally considered to be slightly
337          * sequential.  Seeking to offset 0 doesn't change sequentiality
338          * unless previous seeks have reduced f_seqcount to 0, in which
339          * case offset 0 is not special.
340          */
341         if ((uio->uio_offset == 0 && fp->f_seqcount > 0) ||
342             uio->uio_offset == fp->f_nextoff) {
343                 /*
344                  * f_seqcount is in units of fixed-size blocks so that it
345                  * depends mainly on the amount of sequential I/O and not
346                  * much on the number of sequential I/O's.  The fixed size
347                  * of 16384 is hard-coded here since it is (not quite) just
348                  * a magic size that works well here.  This size is more
349                  * closely related to the best I/O size for real disks than
350                  * to any block size used by software.
351                  */
352                 fp->f_seqcount += howmany(uio->uio_resid, 16384);
353                 if (fp->f_seqcount > IO_SEQMAX)
354                         fp->f_seqcount = IO_SEQMAX;
355                 return (fp->f_seqcount << IO_SEQSHIFT);
356         }
357
358         /* Not sequential.  Quickly draw-down sequentiality. */
359         if (fp->f_seqcount > 1)
360                 fp->f_seqcount = 1;
361         else
362                 fp->f_seqcount = 0;
363         return (0);
364 }
365
366 /*
367  * Package up an I/O request on a vnode into a uio and do it.
368  */
369 int
370 vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred,
371     aresid, td)
372         enum uio_rw rw;
373         struct vnode *vp;
374         void *base;
375         int len;
376         off_t offset;
377         enum uio_seg segflg;
378         int ioflg;
379         struct ucred *active_cred;
380         struct ucred *file_cred;
381         ssize_t *aresid;
382         struct thread *td;
383 {
384         struct uio auio;
385         struct iovec aiov;
386         struct mount *mp;
387         struct ucred *cred;
388         int error, lock_flags;
389
390         VFS_ASSERT_GIANT(vp->v_mount);
391
392         if ((ioflg & IO_NODELOCKED) == 0) {
393                 mp = NULL;
394                 if (rw == UIO_WRITE) { 
395                         if (vp->v_type != VCHR &&
396                             (error = vn_start_write(vp, &mp, V_WAIT | PCATCH))
397                             != 0)
398                                 return (error);
399                         if (MNT_SHARED_WRITES(mp) ||
400                             ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) {
401                                 lock_flags = LK_SHARED;
402                         } else {
403                                 lock_flags = LK_EXCLUSIVE;
404                         }
405                         vn_lock(vp, lock_flags | LK_RETRY);
406                 } else
407                         vn_lock(vp, LK_SHARED | LK_RETRY);
408
409         }
410         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
411         auio.uio_iov = &aiov;
412         auio.uio_iovcnt = 1;
413         aiov.iov_base = base;
414         aiov.iov_len = len;
415         auio.uio_resid = len;
416         auio.uio_offset = offset;
417         auio.uio_segflg = segflg;
418         auio.uio_rw = rw;
419         auio.uio_td = td;
420         error = 0;
421 #ifdef MAC
422         if ((ioflg & IO_NOMACCHECK) == 0) {
423                 if (rw == UIO_READ)
424                         error = mac_vnode_check_read(active_cred, file_cred,
425                             vp);
426                 else
427                         error = mac_vnode_check_write(active_cred, file_cred,
428                             vp);
429         }
430 #endif
431         if (error == 0) {
432                 if (file_cred)
433                         cred = file_cred;
434                 else
435                         cred = active_cred;
436                 if (rw == UIO_READ)
437                         error = VOP_READ(vp, &auio, ioflg, cred);
438                 else
439                         error = VOP_WRITE(vp, &auio, ioflg, cred);
440         }
441         if (aresid)
442                 *aresid = auio.uio_resid;
443         else
444                 if (auio.uio_resid && error == 0)
445                         error = EIO;
446         if ((ioflg & IO_NODELOCKED) == 0) {
447                 if (rw == UIO_WRITE && vp->v_type != VCHR)
448                         vn_finished_write(mp);
449                 VOP_UNLOCK(vp, 0);
450         }
451         return (error);
452 }
453
454 /*
455  * Package up an I/O request on a vnode into a uio and do it.  The I/O
456  * request is split up into smaller chunks and we try to avoid saturating
457  * the buffer cache while potentially holding a vnode locked, so we 
458  * check bwillwrite() before calling vn_rdwr().  We also call kern_yield()
459  * to give other processes a chance to lock the vnode (either other processes
460  * core'ing the same binary, or unrelated processes scanning the directory).
461  */
462 int
463 vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, active_cred,
464     file_cred, aresid, td)
465         enum uio_rw rw;
466         struct vnode *vp;
467         void *base;
468         size_t len;
469         off_t offset;
470         enum uio_seg segflg;
471         int ioflg;
472         struct ucred *active_cred;
473         struct ucred *file_cred;
474         size_t *aresid;
475         struct thread *td;
476 {
477         int error = 0;
478         ssize_t iaresid;
479
480         VFS_ASSERT_GIANT(vp->v_mount);
481
482         do {
483                 int chunk;
484
485                 /*
486                  * Force `offset' to a multiple of MAXBSIZE except possibly
487                  * for the first chunk, so that filesystems only need to
488                  * write full blocks except possibly for the first and last
489                  * chunks.
490                  */
491                 chunk = MAXBSIZE - (uoff_t)offset % MAXBSIZE;
492
493                 if (chunk > len)
494                         chunk = len;
495                 if (rw != UIO_READ && vp->v_type == VREG)
496                         bwillwrite();
497                 iaresid = 0;
498                 error = vn_rdwr(rw, vp, base, chunk, offset, segflg,
499                     ioflg, active_cred, file_cred, &iaresid, td);
500                 len -= chunk;   /* aresid calc already includes length */
501                 if (error)
502                         break;
503                 offset += chunk;
504                 base = (char *)base + chunk;
505                 kern_yield(PRI_USER);
506         } while (len);
507         if (aresid)
508                 *aresid = len + iaresid;
509         return (error);
510 }
511
512 /*
513  * File table vnode read routine.
514  */
515 static int
516 vn_read(fp, uio, active_cred, flags, td)
517         struct file *fp;
518         struct uio *uio;
519         struct ucred *active_cred;
520         int flags;
521         struct thread *td;
522 {
523         struct vnode *vp;
524         int error, ioflag;
525         struct mtx *mtxp;
526         int advice, vfslocked;
527         off_t offset;
528
529         KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
530             uio->uio_td, td));
531         mtxp = NULL;
532         vp = fp->f_vnode;
533         ioflag = 0;
534         if (fp->f_flag & FNONBLOCK)
535                 ioflag |= IO_NDELAY;
536         if (fp->f_flag & O_DIRECT)
537                 ioflag |= IO_DIRECT;
538         advice = POSIX_FADV_NORMAL;
539         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
540         /*
541          * According to McKusick the vn lock was protecting f_offset here.
542          * It is now protected by the FOFFSET_LOCKED flag.
543          */
544         if ((flags & FOF_OFFSET) == 0 || fp->f_advice != NULL) {
545                 mtxp = mtx_pool_find(mtxpool_sleep, fp);
546                 mtx_lock(mtxp);
547                 if ((flags & FOF_OFFSET) == 0) {
548                         while (fp->f_vnread_flags & FOFFSET_LOCKED) {
549                                 fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
550                                 msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
551                                     "vnread offlock", 0);
552                         }
553                         fp->f_vnread_flags |= FOFFSET_LOCKED;
554                         uio->uio_offset = fp->f_offset;
555                 }
556                 if (fp->f_advice != NULL &&
557                     uio->uio_offset >= fp->f_advice->fa_start &&
558                     uio->uio_offset + uio->uio_resid <= fp->f_advice->fa_end)
559                         advice = fp->f_advice->fa_advice;
560                 mtx_unlock(mtxp);
561         }
562         vn_lock(vp, LK_SHARED | LK_RETRY);
563
564         switch (advice) {
565         case POSIX_FADV_NORMAL:
566         case POSIX_FADV_SEQUENTIAL:
567         case POSIX_FADV_NOREUSE:
568                 ioflag |= sequential_heuristic(uio, fp);
569                 break;
570         case POSIX_FADV_RANDOM:
571                 /* Disable read-ahead for random I/O. */
572                 break;
573         }
574         offset = uio->uio_offset;
575
576 #ifdef MAC
577         error = mac_vnode_check_read(active_cred, fp->f_cred, vp);
578         if (error == 0)
579 #endif
580                 error = VOP_READ(vp, uio, ioflag, fp->f_cred);
581         if ((flags & FOF_OFFSET) == 0) {
582                 fp->f_offset = uio->uio_offset;
583                 mtx_lock(mtxp);
584                 if (fp->f_vnread_flags & FOFFSET_LOCK_WAITING)
585                         wakeup(&fp->f_vnread_flags);
586                 fp->f_vnread_flags = 0;
587                 mtx_unlock(mtxp);
588         }
589         fp->f_nextoff = uio->uio_offset;
590         VOP_UNLOCK(vp, 0);
591         if (error == 0 && advice == POSIX_FADV_NOREUSE &&
592             offset != uio->uio_offset)
593                 error = VOP_ADVISE(vp, offset, uio->uio_offset - 1,
594                     POSIX_FADV_DONTNEED);
595         VFS_UNLOCK_GIANT(vfslocked);
596         return (error);
597 }
598
599 /*
600  * File table vnode write routine.
601  */
602 static int
603 vn_write(fp, uio, active_cred, flags, td)
604         struct file *fp;
605         struct uio *uio;
606         struct ucred *active_cred;
607         int flags;
608         struct thread *td;
609 {
610         struct vnode *vp;
611         struct mount *mp;
612         int error, ioflag, lock_flags;
613         struct mtx *mtxp;
614         int advice, vfslocked;
615
616         KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
617             uio->uio_td, td));
618         vp = fp->f_vnode;
619         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
620         if (vp->v_type == VREG)
621                 bwillwrite();
622         ioflag = IO_UNIT;
623         if (vp->v_type == VREG && (fp->f_flag & O_APPEND))
624                 ioflag |= IO_APPEND;
625         if (fp->f_flag & FNONBLOCK)
626                 ioflag |= IO_NDELAY;
627         if (fp->f_flag & O_DIRECT)
628                 ioflag |= IO_DIRECT;
629         if ((fp->f_flag & O_FSYNC) ||
630             (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
631                 ioflag |= IO_SYNC;
632         mp = NULL;
633         if (vp->v_type != VCHR &&
634             (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
635                 goto unlock;
636  
637         if ((MNT_SHARED_WRITES(mp) ||
638             ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) &&
639             (flags & FOF_OFFSET) != 0) {
640                 lock_flags = LK_SHARED;
641         } else {
642                 lock_flags = LK_EXCLUSIVE;
643         }
644
645         vn_lock(vp, lock_flags | LK_RETRY);
646         if ((flags & FOF_OFFSET) == 0)
647                 uio->uio_offset = fp->f_offset;
648         advice = POSIX_FADV_NORMAL;
649         if (fp->f_advice != NULL) {
650                 mtxp = mtx_pool_find(mtxpool_sleep, fp);
651                 mtx_lock(mtxp);
652                 if (fp->f_advice != NULL &&
653                     uio->uio_offset >= fp->f_advice->fa_start &&
654                     uio->uio_offset + uio->uio_resid <= fp->f_advice->fa_end)
655                         advice = fp->f_advice->fa_advice;
656                 mtx_unlock(mtxp);
657         }
658         switch (advice) {
659         case POSIX_FADV_NORMAL:
660         case POSIX_FADV_SEQUENTIAL:
661                 ioflag |= sequential_heuristic(uio, fp);
662                 break;
663         case POSIX_FADV_RANDOM:
664                 /* XXX: Is this correct? */
665                 break;
666         case POSIX_FADV_NOREUSE:
667                 /*
668                  * Request the underlying FS to discard the buffers
669                  * and pages after the I/O is complete.
670                  */
671                 ioflag |= IO_DIRECT;
672                 break;
673         }
674
675 #ifdef MAC
676         error = mac_vnode_check_write(active_cred, fp->f_cred, vp);
677         if (error == 0)
678 #endif
679                 error = VOP_WRITE(vp, uio, ioflag, fp->f_cred);
680         if ((flags & FOF_OFFSET) == 0)
681                 fp->f_offset = uio->uio_offset;
682         fp->f_nextoff = uio->uio_offset;
683         VOP_UNLOCK(vp, 0);
684         if (vp->v_type != VCHR)
685                 vn_finished_write(mp);
686 unlock:
687         VFS_UNLOCK_GIANT(vfslocked);
688         return (error);
689 }
690
691 /*
692  * File table truncate routine.
693  */
694 static int
695 vn_truncate(fp, length, active_cred, td)
696         struct file *fp;
697         off_t length;
698         struct ucred *active_cred;
699         struct thread *td;
700 {
701         struct vattr vattr;
702         struct mount *mp;
703         struct vnode *vp;
704         int vfslocked;
705         int error;
706
707         vp = fp->f_vnode;
708         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
709         error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
710         if (error) {
711                 VFS_UNLOCK_GIANT(vfslocked);
712                 return (error);
713         }
714         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
715         if (vp->v_type == VDIR) {
716                 error = EISDIR;
717                 goto out;
718         }
719 #ifdef MAC
720         error = mac_vnode_check_write(active_cred, fp->f_cred, vp);
721         if (error)
722                 goto out;
723 #endif
724         error = vn_writechk(vp);
725         if (error == 0) {
726                 VATTR_NULL(&vattr);
727                 vattr.va_size = length;
728                 error = VOP_SETATTR(vp, &vattr, fp->f_cred);
729         }
730 out:
731         VOP_UNLOCK(vp, 0);
732         vn_finished_write(mp);
733         VFS_UNLOCK_GIANT(vfslocked);
734         return (error);
735 }
736
737 /*
738  * File table vnode stat routine.
739  */
740 static int
741 vn_statfile(fp, sb, active_cred, td)
742         struct file *fp;
743         struct stat *sb;
744         struct ucred *active_cred;
745         struct thread *td;
746 {
747         struct vnode *vp = fp->f_vnode;
748         int vfslocked;
749         int error;
750
751         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
752         vn_lock(vp, LK_SHARED | LK_RETRY);
753         error = vn_stat(vp, sb, active_cred, fp->f_cred, td);
754         VOP_UNLOCK(vp, 0);
755         VFS_UNLOCK_GIANT(vfslocked);
756
757         return (error);
758 }
759
760 /*
761  * Stat a vnode; implementation for the stat syscall
762  */
763 int
764 vn_stat(vp, sb, active_cred, file_cred, td)
765         struct vnode *vp;
766         register struct stat *sb;
767         struct ucred *active_cred;
768         struct ucred *file_cred;
769         struct thread *td;
770 {
771         struct vattr vattr;
772         register struct vattr *vap;
773         int error;
774         u_short mode;
775
776 #ifdef MAC
777         error = mac_vnode_check_stat(active_cred, file_cred, vp);
778         if (error)
779                 return (error);
780 #endif
781
782         vap = &vattr;
783
784         /*
785          * Initialize defaults for new and unusual fields, so that file
786          * systems which don't support these fields don't need to know
787          * about them.
788          */
789         vap->va_birthtime.tv_sec = -1;
790         vap->va_birthtime.tv_nsec = 0;
791         vap->va_fsid = VNOVAL;
792         vap->va_rdev = NODEV;
793
794         error = VOP_GETATTR(vp, vap, active_cred);
795         if (error)
796                 return (error);
797
798         /*
799          * Zero the spare stat fields
800          */
801         bzero(sb, sizeof *sb);
802
803         /*
804          * Copy from vattr table
805          */
806         if (vap->va_fsid != VNOVAL)
807                 sb->st_dev = vap->va_fsid;
808         else
809                 sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0];
810         sb->st_ino = vap->va_fileid;
811         mode = vap->va_mode;
812         switch (vap->va_type) {
813         case VREG:
814                 mode |= S_IFREG;
815                 break;
816         case VDIR:
817                 mode |= S_IFDIR;
818                 break;
819         case VBLK:
820                 mode |= S_IFBLK;
821                 break;
822         case VCHR:
823                 mode |= S_IFCHR;
824                 break;
825         case VLNK:
826                 mode |= S_IFLNK;
827                 break;
828         case VSOCK:
829                 mode |= S_IFSOCK;
830                 break;
831         case VFIFO:
832                 mode |= S_IFIFO;
833                 break;
834         default:
835                 return (EBADF);
836         };
837         sb->st_mode = mode;
838         sb->st_nlink = vap->va_nlink;
839         sb->st_uid = vap->va_uid;
840         sb->st_gid = vap->va_gid;
841         sb->st_rdev = vap->va_rdev;
842         if (vap->va_size > OFF_MAX)
843                 return (EOVERFLOW);
844         sb->st_size = vap->va_size;
845         sb->st_atim = vap->va_atime;
846         sb->st_mtim = vap->va_mtime;
847         sb->st_ctim = vap->va_ctime;
848         sb->st_birthtim = vap->va_birthtime;
849
850         /*
851          * According to www.opengroup.org, the meaning of st_blksize is 
852          *   "a filesystem-specific preferred I/O block size for this 
853          *    object.  In some filesystem types, this may vary from file
854          *    to file"
855          * Use miminum/default of PAGE_SIZE (e.g. for VCHR).
856          */
857
858         sb->st_blksize = max(PAGE_SIZE, vap->va_blocksize);
859         
860         sb->st_flags = vap->va_flags;
861         if (priv_check(td, PRIV_VFS_GENERATION))
862                 sb->st_gen = 0;
863         else
864                 sb->st_gen = vap->va_gen;
865
866         sb->st_blocks = vap->va_bytes / S_BLKSIZE;
867         return (0);
868 }
869
870 /*
871  * File table vnode ioctl routine.
872  */
873 static int
874 vn_ioctl(fp, com, data, active_cred, td)
875         struct file *fp;
876         u_long com;
877         void *data;
878         struct ucred *active_cred;
879         struct thread *td;
880 {
881         struct vnode *vp = fp->f_vnode;
882         struct vattr vattr;
883         int vfslocked;
884         int error;
885
886         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
887         error = ENOTTY;
888         switch (vp->v_type) {
889         case VREG:
890         case VDIR:
891                 if (com == FIONREAD) {
892                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
893                         error = VOP_GETATTR(vp, &vattr, active_cred);
894                         VOP_UNLOCK(vp, 0);
895                         if (!error)
896                                 *(int *)data = vattr.va_size - fp->f_offset;
897                 }
898                 if (com == FIONBIO || com == FIOASYNC)  /* XXX */
899                         error = 0;
900                 else
901                         error = VOP_IOCTL(vp, com, data, fp->f_flag,
902                             active_cred, td);
903                 break;
904
905         default:
906                 break;
907         }
908         VFS_UNLOCK_GIANT(vfslocked);
909         return (error);
910 }
911
912 /*
913  * File table vnode poll routine.
914  */
915 static int
916 vn_poll(fp, events, active_cred, td)
917         struct file *fp;
918         int events;
919         struct ucred *active_cred;
920         struct thread *td;
921 {
922         struct vnode *vp;
923         int vfslocked;
924         int error;
925
926         vp = fp->f_vnode;
927         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
928 #ifdef MAC
929         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
930         error = mac_vnode_check_poll(active_cred, fp->f_cred, vp);
931         VOP_UNLOCK(vp, 0);
932         if (!error)
933 #endif
934
935         error = VOP_POLL(vp, events, fp->f_cred, td);
936         VFS_UNLOCK_GIANT(vfslocked);
937         return (error);
938 }
939
940 /*
941  * Acquire the requested lock and then check for validity.  LK_RETRY
942  * permits vn_lock to return doomed vnodes.
943  */
944 int
945 _vn_lock(struct vnode *vp, int flags, char *file, int line)
946 {
947         int error;
948
949         VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
950             ("vn_lock called with no locktype."));
951         do {
952 #ifdef DEBUG_VFS_LOCKS
953                 KASSERT(vp->v_holdcnt != 0,
954                     ("vn_lock %p: zero hold count", vp));
955 #endif
956                 error = VOP_LOCK1(vp, flags, file, line);
957                 flags &= ~LK_INTERLOCK; /* Interlock is always dropped. */
958                 KASSERT((flags & LK_RETRY) == 0 || error == 0,
959                     ("LK_RETRY set with incompatible flags (0x%x) or an error occured (%d)",
960                     flags, error));
961                 /*
962                  * Callers specify LK_RETRY if they wish to get dead vnodes.
963                  * If RETRY is not set, we return ENOENT instead.
964                  */
965                 if (error == 0 && vp->v_iflag & VI_DOOMED &&
966                     (flags & LK_RETRY) == 0) {
967                         VOP_UNLOCK(vp, 0);
968                         error = ENOENT;
969                         break;
970                 }
971         } while (flags & LK_RETRY && error != 0);
972         return (error);
973 }
974
975 /*
976  * File table vnode close routine.
977  */
978 static int
979 vn_closefile(fp, td)
980         struct file *fp;
981         struct thread *td;
982 {
983         struct vnode *vp;
984         struct flock lf;
985         int vfslocked;
986         int error;
987
988         vp = fp->f_vnode;
989
990         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
991         if (fp->f_type == DTYPE_VNODE && fp->f_flag & FHASLOCK) {
992                 lf.l_whence = SEEK_SET;
993                 lf.l_start = 0;
994                 lf.l_len = 0;
995                 lf.l_type = F_UNLCK;
996                 (void) VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, F_FLOCK);
997         }
998
999         fp->f_ops = &badfileops;
1000
1001         error = vn_close(vp, fp->f_flag, fp->f_cred, td);
1002         VFS_UNLOCK_GIANT(vfslocked);
1003         return (error);
1004 }
1005
1006 /*
1007  * Preparing to start a filesystem write operation. If the operation is
1008  * permitted, then we bump the count of operations in progress and
1009  * proceed. If a suspend request is in progress, we wait until the
1010  * suspension is over, and then proceed.
1011  */
1012 int
1013 vn_start_write(vp, mpp, flags)
1014         struct vnode *vp;
1015         struct mount **mpp;
1016         int flags;
1017 {
1018         struct mount *mp;
1019         int error;
1020
1021         error = 0;
1022         /*
1023          * If a vnode is provided, get and return the mount point that
1024          * to which it will write.
1025          */
1026         if (vp != NULL) {
1027                 if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
1028                         *mpp = NULL;
1029                         if (error != EOPNOTSUPP)
1030                                 return (error);
1031                         return (0);
1032                 }
1033         }
1034         if ((mp = *mpp) == NULL)
1035                 return (0);
1036
1037         /*
1038          * VOP_GETWRITEMOUNT() returns with the mp refcount held through
1039          * a vfs_ref().
1040          * As long as a vnode is not provided we need to acquire a
1041          * refcount for the provided mountpoint too, in order to
1042          * emulate a vfs_ref().
1043          */
1044         MNT_ILOCK(mp);
1045         if (vp == NULL)
1046                 MNT_REF(mp);
1047
1048         /*
1049          * Check on status of suspension.
1050          */
1051         if ((curthread->td_pflags & TDP_IGNSUSP) == 0 ||
1052             mp->mnt_susp_owner != curthread) {
1053                 while ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
1054                         if (flags & V_NOWAIT) {
1055                                 error = EWOULDBLOCK;
1056                                 goto unlock;
1057                         }
1058                         error = msleep(&mp->mnt_flag, MNT_MTX(mp),
1059                             (PUSER - 1) | (flags & PCATCH), "suspfs", 0);
1060                         if (error)
1061                                 goto unlock;
1062                 }
1063         }
1064         if (flags & V_XSLEEP)
1065                 goto unlock;
1066         mp->mnt_writeopcount++;
1067 unlock:
1068         if (error != 0 || (flags & V_XSLEEP) != 0)
1069                 MNT_REL(mp);
1070         MNT_IUNLOCK(mp);
1071         return (error);
1072 }
1073
1074 /*
1075  * Secondary suspension. Used by operations such as vop_inactive
1076  * routines that are needed by the higher level functions. These
1077  * are allowed to proceed until all the higher level functions have
1078  * completed (indicated by mnt_writeopcount dropping to zero). At that
1079  * time, these operations are halted until the suspension is over.
1080  */
1081 int
1082 vn_start_secondary_write(vp, mpp, flags)
1083         struct vnode *vp;
1084         struct mount **mpp;
1085         int flags;
1086 {
1087         struct mount *mp;
1088         int error;
1089
1090  retry:
1091         if (vp != NULL) {
1092                 if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
1093                         *mpp = NULL;
1094                         if (error != EOPNOTSUPP)
1095                                 return (error);
1096                         return (0);
1097                 }
1098         }
1099         /*
1100          * If we are not suspended or have not yet reached suspended
1101          * mode, then let the operation proceed.
1102          */
1103         if ((mp = *mpp) == NULL)
1104                 return (0);
1105
1106         /*
1107          * VOP_GETWRITEMOUNT() returns with the mp refcount held through
1108          * a vfs_ref().
1109          * As long as a vnode is not provided we need to acquire a
1110          * refcount for the provided mountpoint too, in order to
1111          * emulate a vfs_ref().
1112          */
1113         MNT_ILOCK(mp);
1114         if (vp == NULL)
1115                 MNT_REF(mp);
1116         if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
1117                 mp->mnt_secondary_writes++;
1118                 mp->mnt_secondary_accwrites++;
1119                 MNT_IUNLOCK(mp);
1120                 return (0);
1121         }
1122         if (flags & V_NOWAIT) {
1123                 MNT_REL(mp);
1124                 MNT_IUNLOCK(mp);
1125                 return (EWOULDBLOCK);
1126         }
1127         /*
1128          * Wait for the suspension to finish.
1129          */
1130         error = msleep(&mp->mnt_flag, MNT_MTX(mp),
1131                        (PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
1132         vfs_rel(mp);
1133         if (error == 0)
1134                 goto retry;
1135         return (error);
1136 }
1137
1138 /*
1139  * Filesystem write operation has completed. If we are suspending and this
1140  * operation is the last one, notify the suspender that the suspension is
1141  * now in effect.
1142  */
1143 void
1144 vn_finished_write(mp)
1145         struct mount *mp;
1146 {
1147         if (mp == NULL)
1148                 return;
1149         MNT_ILOCK(mp);
1150         MNT_REL(mp);
1151         mp->mnt_writeopcount--;
1152         if (mp->mnt_writeopcount < 0)
1153                 panic("vn_finished_write: neg cnt");
1154         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
1155             mp->mnt_writeopcount <= 0)
1156                 wakeup(&mp->mnt_writeopcount);
1157         MNT_IUNLOCK(mp);
1158 }
1159
1160
1161 /*
1162  * Filesystem secondary write operation has completed. If we are
1163  * suspending and this operation is the last one, notify the suspender
1164  * that the suspension is now in effect.
1165  */
1166 void
1167 vn_finished_secondary_write(mp)
1168         struct mount *mp;
1169 {
1170         if (mp == NULL)
1171                 return;
1172         MNT_ILOCK(mp);
1173         MNT_REL(mp);
1174         mp->mnt_secondary_writes--;
1175         if (mp->mnt_secondary_writes < 0)
1176                 panic("vn_finished_secondary_write: neg cnt");
1177         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
1178             mp->mnt_secondary_writes <= 0)
1179                 wakeup(&mp->mnt_secondary_writes);
1180         MNT_IUNLOCK(mp);
1181 }
1182
1183
1184
1185 /*
1186  * Request a filesystem to suspend write operations.
1187  */
1188 int
1189 vfs_write_suspend(mp)
1190         struct mount *mp;
1191 {
1192         int error;
1193
1194         MNT_ILOCK(mp);
1195         if (mp->mnt_susp_owner == curthread) {
1196                 MNT_IUNLOCK(mp);
1197                 return (EALREADY);
1198         }
1199         while (mp->mnt_kern_flag & MNTK_SUSPEND)
1200                 msleep(&mp->mnt_flag, MNT_MTX(mp), PUSER - 1, "wsuspfs", 0);
1201         mp->mnt_kern_flag |= MNTK_SUSPEND;
1202         mp->mnt_susp_owner = curthread;
1203         if (mp->mnt_writeopcount > 0)
1204                 (void) msleep(&mp->mnt_writeopcount, 
1205                     MNT_MTX(mp), (PUSER - 1)|PDROP, "suspwt", 0);
1206         else
1207                 MNT_IUNLOCK(mp);
1208         if ((error = VFS_SYNC(mp, MNT_SUSPEND)) != 0)
1209                 vfs_write_resume(mp);
1210         return (error);
1211 }
1212
1213 /*
1214  * Request a filesystem to resume write operations.
1215  */
1216 void
1217 vfs_write_resume(mp)
1218         struct mount *mp;
1219 {
1220
1221         MNT_ILOCK(mp);
1222         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
1223                 KASSERT(mp->mnt_susp_owner == curthread, ("mnt_susp_owner"));
1224                 mp->mnt_kern_flag &= ~(MNTK_SUSPEND | MNTK_SUSPEND2 |
1225                                        MNTK_SUSPENDED);
1226                 mp->mnt_susp_owner = NULL;
1227                 wakeup(&mp->mnt_writeopcount);
1228                 wakeup(&mp->mnt_flag);
1229                 curthread->td_pflags &= ~TDP_IGNSUSP;
1230                 MNT_IUNLOCK(mp);
1231                 VFS_SUSP_CLEAN(mp);
1232         } else
1233                 MNT_IUNLOCK(mp);
1234 }
1235
1236 /*
1237  * Implement kqueues for files by translating it to vnode operation.
1238  */
1239 static int
1240 vn_kqfilter(struct file *fp, struct knote *kn)
1241 {
1242         int vfslocked;
1243         int error;
1244
1245         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
1246         error = VOP_KQFILTER(fp->f_vnode, kn);
1247         VFS_UNLOCK_GIANT(vfslocked);
1248
1249         return error;
1250 }
1251
1252 /*
1253  * Simplified in-kernel wrapper calls for extended attribute access.
1254  * Both calls pass in a NULL credential, authorizing as "kernel" access.
1255  * Set IO_NODELOCKED in ioflg if the vnode is already locked.
1256  */
1257 int
1258 vn_extattr_get(struct vnode *vp, int ioflg, int attrnamespace,
1259     const char *attrname, int *buflen, char *buf, struct thread *td)
1260 {
1261         struct uio      auio;
1262         struct iovec    iov;
1263         int     error;
1264
1265         iov.iov_len = *buflen;
1266         iov.iov_base = buf;
1267
1268         auio.uio_iov = &iov;
1269         auio.uio_iovcnt = 1;
1270         auio.uio_rw = UIO_READ;
1271         auio.uio_segflg = UIO_SYSSPACE;
1272         auio.uio_td = td;
1273         auio.uio_offset = 0;
1274         auio.uio_resid = *buflen;
1275
1276         if ((ioflg & IO_NODELOCKED) == 0)
1277                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1278
1279         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1280
1281         /* authorize attribute retrieval as kernel */
1282         error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, NULL, NULL,
1283             td);
1284
1285         if ((ioflg & IO_NODELOCKED) == 0)
1286                 VOP_UNLOCK(vp, 0);
1287
1288         if (error == 0) {
1289                 *buflen = *buflen - auio.uio_resid;
1290         }
1291
1292         return (error);
1293 }
1294
1295 /*
1296  * XXX failure mode if partially written?
1297  */
1298 int
1299 vn_extattr_set(struct vnode *vp, int ioflg, int attrnamespace,
1300     const char *attrname, int buflen, char *buf, struct thread *td)
1301 {
1302         struct uio      auio;
1303         struct iovec    iov;
1304         struct mount    *mp;
1305         int     error;
1306
1307         iov.iov_len = buflen;
1308         iov.iov_base = buf;
1309
1310         auio.uio_iov = &iov;
1311         auio.uio_iovcnt = 1;
1312         auio.uio_rw = UIO_WRITE;
1313         auio.uio_segflg = UIO_SYSSPACE;
1314         auio.uio_td = td;
1315         auio.uio_offset = 0;
1316         auio.uio_resid = buflen;
1317
1318         if ((ioflg & IO_NODELOCKED) == 0) {
1319                 if ((error = vn_start_write(vp, &mp, V_WAIT)) != 0)
1320                         return (error);
1321                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1322         }
1323
1324         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1325
1326         /* authorize attribute setting as kernel */
1327         error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, NULL, td);
1328
1329         if ((ioflg & IO_NODELOCKED) == 0) {
1330                 vn_finished_write(mp);
1331                 VOP_UNLOCK(vp, 0);
1332         }
1333
1334         return (error);
1335 }
1336
1337 int
1338 vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
1339     const char *attrname, struct thread *td)
1340 {
1341         struct mount    *mp;
1342         int     error;
1343
1344         if ((ioflg & IO_NODELOCKED) == 0) {
1345                 if ((error = vn_start_write(vp, &mp, V_WAIT)) != 0)
1346                         return (error);
1347                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1348         }
1349
1350         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1351
1352         /* authorize attribute removal as kernel */
1353         error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, NULL, td);
1354         if (error == EOPNOTSUPP)
1355                 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
1356                     NULL, td);
1357
1358         if ((ioflg & IO_NODELOCKED) == 0) {
1359                 vn_finished_write(mp);
1360                 VOP_UNLOCK(vp, 0);
1361         }
1362
1363         return (error);
1364 }
1365
1366 int
1367 vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp)
1368 {
1369         struct mount *mp;
1370         int ltype, error;
1371
1372         mp = vp->v_mount;
1373         ltype = VOP_ISLOCKED(vp);
1374         KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
1375             ("vn_vget_ino: vp not locked"));
1376         error = vfs_busy(mp, MBF_NOWAIT);
1377         if (error != 0) {
1378                 vfs_ref(mp);
1379                 VOP_UNLOCK(vp, 0);
1380                 error = vfs_busy(mp, 0);
1381                 vn_lock(vp, ltype | LK_RETRY);
1382                 vfs_rel(mp);
1383                 if (error != 0)
1384                         return (ENOENT);
1385                 if (vp->v_iflag & VI_DOOMED) {
1386                         vfs_unbusy(mp);
1387                         return (ENOENT);
1388                 }
1389         }
1390         VOP_UNLOCK(vp, 0);
1391         error = VFS_VGET(mp, ino, lkflags, rvp);
1392         vfs_unbusy(mp);
1393         vn_lock(vp, ltype | LK_RETRY);
1394         if (vp->v_iflag & VI_DOOMED) {
1395                 if (error == 0)
1396                         vput(*rvp);
1397                 error = ENOENT;
1398         }
1399         return (error);
1400 }
1401
1402 int
1403 vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
1404     const struct thread *td)
1405 {
1406
1407         if (vp->v_type != VREG || td == NULL)
1408                 return (0);
1409         PROC_LOCK(td->td_proc);
1410         if ((uoff_t)uio->uio_offset + uio->uio_resid >
1411             lim_cur(td->td_proc, RLIMIT_FSIZE)) {
1412                 kern_psignal(td->td_proc, SIGXFSZ);
1413                 PROC_UNLOCK(td->td_proc);
1414                 return (EFBIG);
1415         }
1416         PROC_UNLOCK(td->td_proc);
1417         return (0);
1418 }
1419
1420 int
1421 vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
1422     struct thread *td)
1423 {
1424         struct vnode *vp;
1425         int error, vfslocked;
1426
1427         vp = fp->f_vnode;
1428         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1429 #ifdef AUDIT
1430         vn_lock(vp, LK_SHARED | LK_RETRY);
1431         AUDIT_ARG_VNODE1(vp);
1432         VOP_UNLOCK(vp, 0);
1433 #endif
1434         error = setfmode(td, active_cred, vp, mode);
1435         VFS_UNLOCK_GIANT(vfslocked);
1436         return (error);
1437 }
1438
1439 int
1440 vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
1441     struct thread *td)
1442 {
1443         struct vnode *vp;
1444         int error, vfslocked;
1445
1446         vp = fp->f_vnode;
1447         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1448 #ifdef AUDIT
1449         vn_lock(vp, LK_SHARED | LK_RETRY);
1450         AUDIT_ARG_VNODE1(vp);
1451         VOP_UNLOCK(vp, 0);
1452 #endif
1453         error = setfown(td, active_cred, vp, uid, gid);
1454         VFS_UNLOCK_GIANT(vfslocked);
1455         return (error);
1456 }
1457
1458 void
1459 vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
1460 {
1461         vm_object_t object;
1462
1463         if ((object = vp->v_object) == NULL)
1464                 return;
1465         VM_OBJECT_LOCK(object);
1466         vm_object_page_remove(object, start, end, 0);
1467         VM_OBJECT_UNLOCK(object);
1468 }