]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/kern/vfs_vnops.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.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         *flagp = fmode;
251         ASSERT_VOP_LOCKED(vp, "vn_open_cred");
252         if (!mpsafe)
253                 VFS_UNLOCK_GIANT(vfslocked);
254         return (0);
255 bad:
256         NDFREE(ndp, NDF_ONLY_PNBUF);
257         vput(vp);
258         VFS_UNLOCK_GIANT(vfslocked);
259         *flagp = fmode;
260         ndp->ni_vp = NULL;
261         return (error);
262 }
263
264 /*
265  * Check for write permissions on the specified vnode.
266  * Prototype text segments cannot be written.
267  */
268 int
269 vn_writechk(vp)
270         register struct vnode *vp;
271 {
272
273         ASSERT_VOP_LOCKED(vp, "vn_writechk");
274         /*
275          * If there's shared text associated with
276          * the vnode, try to free it up once.  If
277          * we fail, we can't allow writing.
278          */
279         if (vp->v_vflag & VV_TEXT)
280                 return (ETXTBSY);
281
282         return (0);
283 }
284
285 /*
286  * Vnode close call
287  */
288 int
289 vn_close(vp, flags, file_cred, td)
290         register struct vnode *vp;
291         int flags;
292         struct ucred *file_cred;
293         struct thread *td;
294 {
295         struct mount *mp;
296         int error, lock_flags;
297
298         if (!(flags & FWRITE) && vp->v_mount != NULL &&
299             vp->v_mount->mnt_kern_flag & MNTK_EXTENDED_SHARED)
300                 lock_flags = LK_SHARED;
301         else
302                 lock_flags = LK_EXCLUSIVE;
303
304         VFS_ASSERT_GIANT(vp->v_mount);
305
306         vn_start_write(vp, &mp, V_WAIT);
307         vn_lock(vp, lock_flags | LK_RETRY);
308         if (flags & FWRITE) {
309                 VNASSERT(vp->v_writecount > 0, vp, 
310                     ("vn_close: negative writecount"));
311                 vp->v_writecount--;
312         }
313         error = VOP_CLOSE(vp, flags, file_cred, td);
314         vput(vp);
315         vn_finished_write(mp);
316         return (error);
317 }
318
319 /*
320  * Heuristic to detect sequential operation.
321  */
322 static int
323 sequential_heuristic(struct uio *uio, struct file *fp)
324 {
325
326         if (atomic_load_acq_int(&(fp->f_flag)) & FRDAHEAD)
327                 return (fp->f_seqcount << IO_SEQSHIFT);
328
329         /*
330          * Offset 0 is handled specially.  open() sets f_seqcount to 1 so
331          * that the first I/O is normally considered to be slightly
332          * sequential.  Seeking to offset 0 doesn't change sequentiality
333          * unless previous seeks have reduced f_seqcount to 0, in which
334          * case offset 0 is not special.
335          */
336         if ((uio->uio_offset == 0 && fp->f_seqcount > 0) ||
337             uio->uio_offset == fp->f_nextoff) {
338                 /*
339                  * f_seqcount is in units of fixed-size blocks so that it
340                  * depends mainly on the amount of sequential I/O and not
341                  * much on the number of sequential I/O's.  The fixed size
342                  * of 16384 is hard-coded here since it is (not quite) just
343                  * a magic size that works well here.  This size is more
344                  * closely related to the best I/O size for real disks than
345                  * to any block size used by software.
346                  */
347                 fp->f_seqcount += howmany(uio->uio_resid, 16384);
348                 if (fp->f_seqcount > IO_SEQMAX)
349                         fp->f_seqcount = IO_SEQMAX;
350                 return (fp->f_seqcount << IO_SEQSHIFT);
351         }
352
353         /* Not sequential.  Quickly draw-down sequentiality. */
354         if (fp->f_seqcount > 1)
355                 fp->f_seqcount = 1;
356         else
357                 fp->f_seqcount = 0;
358         return (0);
359 }
360
361 /*
362  * Package up an I/O request on a vnode into a uio and do it.
363  */
364 int
365 vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred,
366     aresid, td)
367         enum uio_rw rw;
368         struct vnode *vp;
369         void *base;
370         int len;
371         off_t offset;
372         enum uio_seg segflg;
373         int ioflg;
374         struct ucred *active_cred;
375         struct ucred *file_cred;
376         int *aresid;
377         struct thread *td;
378 {
379         struct uio auio;
380         struct iovec aiov;
381         struct mount *mp;
382         struct ucred *cred;
383         int error, lock_flags;
384
385         VFS_ASSERT_GIANT(vp->v_mount);
386
387         if ((ioflg & IO_NODELOCKED) == 0) {
388                 mp = NULL;
389                 if (rw == UIO_WRITE) { 
390                         if (vp->v_type != VCHR &&
391                             (error = vn_start_write(vp, &mp, V_WAIT | PCATCH))
392                             != 0)
393                                 return (error);
394                         if (MNT_SHARED_WRITES(mp) ||
395                             ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) {
396                                 lock_flags = LK_SHARED;
397                         } else {
398                                 lock_flags = LK_EXCLUSIVE;
399                         }
400                         vn_lock(vp, lock_flags | LK_RETRY);
401                 } else
402                         vn_lock(vp, LK_SHARED | LK_RETRY);
403
404         }
405         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
406         auio.uio_iov = &aiov;
407         auio.uio_iovcnt = 1;
408         aiov.iov_base = base;
409         aiov.iov_len = len;
410         auio.uio_resid = len;
411         auio.uio_offset = offset;
412         auio.uio_segflg = segflg;
413         auio.uio_rw = rw;
414         auio.uio_td = td;
415         error = 0;
416 #ifdef MAC
417         if ((ioflg & IO_NOMACCHECK) == 0) {
418                 if (rw == UIO_READ)
419                         error = mac_vnode_check_read(active_cred, file_cred,
420                             vp);
421                 else
422                         error = mac_vnode_check_write(active_cred, file_cred,
423                             vp);
424         }
425 #endif
426         if (error == 0) {
427                 if (file_cred)
428                         cred = file_cred;
429                 else
430                         cred = active_cred;
431                 if (rw == UIO_READ)
432                         error = VOP_READ(vp, &auio, ioflg, cred);
433                 else
434                         error = VOP_WRITE(vp, &auio, ioflg, cred);
435         }
436         if (aresid)
437                 *aresid = auio.uio_resid;
438         else
439                 if (auio.uio_resid && error == 0)
440                         error = EIO;
441         if ((ioflg & IO_NODELOCKED) == 0) {
442                 if (rw == UIO_WRITE && vp->v_type != VCHR)
443                         vn_finished_write(mp);
444                 VOP_UNLOCK(vp, 0);
445         }
446         return (error);
447 }
448
449 /*
450  * Package up an I/O request on a vnode into a uio and do it.  The I/O
451  * request is split up into smaller chunks and we try to avoid saturating
452  * the buffer cache while potentially holding a vnode locked, so we 
453  * check bwillwrite() before calling vn_rdwr().  We also call kern_yield()
454  * to give other processes a chance to lock the vnode (either other processes
455  * core'ing the same binary, or unrelated processes scanning the directory).
456  */
457 int
458 vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, active_cred,
459     file_cred, aresid, td)
460         enum uio_rw rw;
461         struct vnode *vp;
462         void *base;
463         size_t len;
464         off_t offset;
465         enum uio_seg segflg;
466         int ioflg;
467         struct ucred *active_cred;
468         struct ucred *file_cred;
469         size_t *aresid;
470         struct thread *td;
471 {
472         int error = 0;
473         int iaresid;
474
475         VFS_ASSERT_GIANT(vp->v_mount);
476
477         do {
478                 int chunk;
479
480                 /*
481                  * Force `offset' to a multiple of MAXBSIZE except possibly
482                  * for the first chunk, so that filesystems only need to
483                  * write full blocks except possibly for the first and last
484                  * chunks.
485                  */
486                 chunk = MAXBSIZE - (uoff_t)offset % MAXBSIZE;
487
488                 if (chunk > len)
489                         chunk = len;
490                 if (rw != UIO_READ && vp->v_type == VREG)
491                         bwillwrite();
492                 iaresid = 0;
493                 error = vn_rdwr(rw, vp, base, chunk, offset, segflg,
494                     ioflg, active_cred, file_cred, &iaresid, td);
495                 len -= chunk;   /* aresid calc already includes length */
496                 if (error)
497                         break;
498                 offset += chunk;
499                 base = (char *)base + chunk;
500                 kern_yield(PRI_USER);
501         } while (len);
502         if (aresid)
503                 *aresid = len + iaresid;
504         return (error);
505 }
506
507 /*
508  * File table vnode read routine.
509  */
510 static int
511 vn_read(fp, uio, active_cred, flags, td)
512         struct file *fp;
513         struct uio *uio;
514         struct ucred *active_cred;
515         int flags;
516         struct thread *td;
517 {
518         struct vnode *vp;
519         int error, ioflag;
520         struct mtx *mtxp;
521         int vfslocked;
522
523         KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
524             uio->uio_td, td));
525         mtxp = NULL;
526         vp = fp->f_vnode;
527         ioflag = 0;
528         if (fp->f_flag & FNONBLOCK)
529                 ioflag |= IO_NDELAY;
530         if (fp->f_flag & O_DIRECT)
531                 ioflag |= IO_DIRECT;
532         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
533         /*
534          * According to McKusick the vn lock was protecting f_offset here.
535          * It is now protected by the FOFFSET_LOCKED flag.
536          */
537         if ((flags & FOF_OFFSET) == 0) {
538                 mtxp = mtx_pool_find(mtxpool_sleep, fp);
539                 mtx_lock(mtxp);
540                 while(fp->f_vnread_flags & FOFFSET_LOCKED) {
541                         fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
542                         msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
543                             "vnread offlock", 0);
544                 }
545                 fp->f_vnread_flags |= FOFFSET_LOCKED;
546                 mtx_unlock(mtxp);
547                 vn_lock(vp, LK_SHARED | LK_RETRY);
548                 uio->uio_offset = fp->f_offset;
549         } else
550                 vn_lock(vp, LK_SHARED | LK_RETRY);
551
552         ioflag |= sequential_heuristic(uio, fp);
553
554 #ifdef MAC
555         error = mac_vnode_check_read(active_cred, fp->f_cred, vp);
556         if (error == 0)
557 #endif
558                 error = VOP_READ(vp, uio, ioflag, fp->f_cred);
559         if ((flags & FOF_OFFSET) == 0) {
560                 fp->f_offset = uio->uio_offset;
561                 mtx_lock(mtxp);
562                 if (fp->f_vnread_flags & FOFFSET_LOCK_WAITING)
563                         wakeup(&fp->f_vnread_flags);
564                 fp->f_vnread_flags = 0;
565                 mtx_unlock(mtxp);
566         }
567         fp->f_nextoff = uio->uio_offset;
568         VOP_UNLOCK(vp, 0);
569         VFS_UNLOCK_GIANT(vfslocked);
570         return (error);
571 }
572
573 /*
574  * File table vnode write routine.
575  */
576 static int
577 vn_write(fp, uio, active_cred, flags, td)
578         struct file *fp;
579         struct uio *uio;
580         struct ucred *active_cred;
581         int flags;
582         struct thread *td;
583 {
584         struct vnode *vp;
585         struct mount *mp;
586         int error, ioflag, lock_flags;
587         int vfslocked;
588
589         KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
590             uio->uio_td, td));
591         vp = fp->f_vnode;
592         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
593         if (vp->v_type == VREG)
594                 bwillwrite();
595         ioflag = IO_UNIT;
596         if (vp->v_type == VREG && (fp->f_flag & O_APPEND))
597                 ioflag |= IO_APPEND;
598         if (fp->f_flag & FNONBLOCK)
599                 ioflag |= IO_NDELAY;
600         if (fp->f_flag & O_DIRECT)
601                 ioflag |= IO_DIRECT;
602         if ((fp->f_flag & O_FSYNC) ||
603             (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
604                 ioflag |= IO_SYNC;
605         mp = NULL;
606         if (vp->v_type != VCHR &&
607             (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
608                 goto unlock;
609  
610         if ((MNT_SHARED_WRITES(mp) ||
611             ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) &&
612             (flags & FOF_OFFSET) != 0) {
613                 lock_flags = LK_SHARED;
614         } else {
615                 lock_flags = LK_EXCLUSIVE;
616         }
617
618         vn_lock(vp, lock_flags | LK_RETRY);
619         if ((flags & FOF_OFFSET) == 0)
620                 uio->uio_offset = fp->f_offset;
621         ioflag |= sequential_heuristic(uio, fp);
622 #ifdef MAC
623         error = mac_vnode_check_write(active_cred, fp->f_cred, vp);
624         if (error == 0)
625 #endif
626                 error = VOP_WRITE(vp, uio, ioflag, fp->f_cred);
627         if ((flags & FOF_OFFSET) == 0)
628                 fp->f_offset = uio->uio_offset;
629         fp->f_nextoff = uio->uio_offset;
630         VOP_UNLOCK(vp, 0);
631         if (vp->v_type != VCHR)
632                 vn_finished_write(mp);
633 unlock:
634         VFS_UNLOCK_GIANT(vfslocked);
635         return (error);
636 }
637
638 /*
639  * File table truncate routine.
640  */
641 static int
642 vn_truncate(fp, length, active_cred, td)
643         struct file *fp;
644         off_t length;
645         struct ucred *active_cred;
646         struct thread *td;
647 {
648         struct vattr vattr;
649         struct mount *mp;
650         struct vnode *vp;
651         int vfslocked;
652         int error;
653
654         vp = fp->f_vnode;
655         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
656         error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
657         if (error) {
658                 VFS_UNLOCK_GIANT(vfslocked);
659                 return (error);
660         }
661         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
662         if (vp->v_type == VDIR) {
663                 error = EISDIR;
664                 goto out;
665         }
666 #ifdef MAC
667         error = mac_vnode_check_write(active_cred, fp->f_cred, vp);
668         if (error)
669                 goto out;
670 #endif
671         error = vn_writechk(vp);
672         if (error == 0) {
673                 VATTR_NULL(&vattr);
674                 vattr.va_size = length;
675                 error = VOP_SETATTR(vp, &vattr, fp->f_cred);
676         }
677 out:
678         VOP_UNLOCK(vp, 0);
679         vn_finished_write(mp);
680         VFS_UNLOCK_GIANT(vfslocked);
681         return (error);
682 }
683
684 /*
685  * File table vnode stat routine.
686  */
687 static int
688 vn_statfile(fp, sb, active_cred, td)
689         struct file *fp;
690         struct stat *sb;
691         struct ucred *active_cred;
692         struct thread *td;
693 {
694         struct vnode *vp = fp->f_vnode;
695         int vfslocked;
696         int error;
697
698         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
699         vn_lock(vp, LK_SHARED | LK_RETRY);
700         error = vn_stat(vp, sb, active_cred, fp->f_cred, td);
701         VOP_UNLOCK(vp, 0);
702         VFS_UNLOCK_GIANT(vfslocked);
703
704         return (error);
705 }
706
707 /*
708  * Stat a vnode; implementation for the stat syscall
709  */
710 int
711 vn_stat(vp, sb, active_cred, file_cred, td)
712         struct vnode *vp;
713         register struct stat *sb;
714         struct ucred *active_cred;
715         struct ucred *file_cred;
716         struct thread *td;
717 {
718         struct vattr vattr;
719         register struct vattr *vap;
720         int error;
721         u_short mode;
722
723 #ifdef MAC
724         error = mac_vnode_check_stat(active_cred, file_cred, vp);
725         if (error)
726                 return (error);
727 #endif
728
729         vap = &vattr;
730
731         /*
732          * Initialize defaults for new and unusual fields, so that file
733          * systems which don't support these fields don't need to know
734          * about them.
735          */
736         vap->va_birthtime.tv_sec = -1;
737         vap->va_birthtime.tv_nsec = 0;
738         vap->va_fsid = VNOVAL;
739         vap->va_rdev = NODEV;
740
741         error = VOP_GETATTR(vp, vap, active_cred);
742         if (error)
743                 return (error);
744
745         /*
746          * Zero the spare stat fields
747          */
748         bzero(sb, sizeof *sb);
749
750         /*
751          * Copy from vattr table
752          */
753         if (vap->va_fsid != VNOVAL)
754                 sb->st_dev = vap->va_fsid;
755         else
756                 sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0];
757         sb->st_ino = vap->va_fileid;
758         mode = vap->va_mode;
759         switch (vap->va_type) {
760         case VREG:
761                 mode |= S_IFREG;
762                 break;
763         case VDIR:
764                 mode |= S_IFDIR;
765                 break;
766         case VBLK:
767                 mode |= S_IFBLK;
768                 break;
769         case VCHR:
770                 mode |= S_IFCHR;
771                 break;
772         case VLNK:
773                 mode |= S_IFLNK;
774                 break;
775         case VSOCK:
776                 mode |= S_IFSOCK;
777                 break;
778         case VFIFO:
779                 mode |= S_IFIFO;
780                 break;
781         default:
782                 return (EBADF);
783         };
784         sb->st_mode = mode;
785         sb->st_nlink = vap->va_nlink;
786         sb->st_uid = vap->va_uid;
787         sb->st_gid = vap->va_gid;
788         sb->st_rdev = vap->va_rdev;
789         if (vap->va_size > OFF_MAX)
790                 return (EOVERFLOW);
791         sb->st_size = vap->va_size;
792         sb->st_atim = vap->va_atime;
793         sb->st_mtim = vap->va_mtime;
794         sb->st_ctim = vap->va_ctime;
795         sb->st_birthtim = vap->va_birthtime;
796
797         /*
798          * According to www.opengroup.org, the meaning of st_blksize is 
799          *   "a filesystem-specific preferred I/O block size for this 
800          *    object.  In some filesystem types, this may vary from file
801          *    to file"
802          * Use miminum/default of PAGE_SIZE (e.g. for VCHR).
803          */
804
805         sb->st_blksize = max(PAGE_SIZE, vap->va_blocksize);
806         
807         sb->st_flags = vap->va_flags;
808         if (priv_check(td, PRIV_VFS_GENERATION))
809                 sb->st_gen = 0;
810         else
811                 sb->st_gen = vap->va_gen;
812
813         sb->st_blocks = vap->va_bytes / S_BLKSIZE;
814         return (0);
815 }
816
817 /*
818  * File table vnode ioctl routine.
819  */
820 static int
821 vn_ioctl(fp, com, data, active_cred, td)
822         struct file *fp;
823         u_long com;
824         void *data;
825         struct ucred *active_cred;
826         struct thread *td;
827 {
828         struct vnode *vp = fp->f_vnode;
829         struct vattr vattr;
830         int vfslocked;
831         int error;
832
833         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
834         error = ENOTTY;
835         switch (vp->v_type) {
836         case VREG:
837         case VDIR:
838                 if (com == FIONREAD) {
839                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
840                         error = VOP_GETATTR(vp, &vattr, active_cred);
841                         VOP_UNLOCK(vp, 0);
842                         if (!error)
843                                 *(int *)data = vattr.va_size - fp->f_offset;
844                 }
845                 if (com == FIONBIO || com == FIOASYNC)  /* XXX */
846                         error = 0;
847                 else
848                         error = VOP_IOCTL(vp, com, data, fp->f_flag,
849                             active_cred, td);
850                 break;
851
852         default:
853                 break;
854         }
855         VFS_UNLOCK_GIANT(vfslocked);
856         return (error);
857 }
858
859 /*
860  * File table vnode poll routine.
861  */
862 static int
863 vn_poll(fp, events, active_cred, td)
864         struct file *fp;
865         int events;
866         struct ucred *active_cred;
867         struct thread *td;
868 {
869         struct vnode *vp;
870         int vfslocked;
871         int error;
872
873         vp = fp->f_vnode;
874         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
875 #ifdef MAC
876         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
877         error = mac_vnode_check_poll(active_cred, fp->f_cred, vp);
878         VOP_UNLOCK(vp, 0);
879         if (!error)
880 #endif
881
882         error = VOP_POLL(vp, events, fp->f_cred, td);
883         VFS_UNLOCK_GIANT(vfslocked);
884         return (error);
885 }
886
887 /*
888  * Acquire the requested lock and then check for validity.  LK_RETRY
889  * permits vn_lock to return doomed vnodes.
890  */
891 int
892 _vn_lock(struct vnode *vp, int flags, char *file, int line)
893 {
894         int error;
895
896         VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
897             ("vn_lock called with no locktype."));
898         do {
899 #ifdef DEBUG_VFS_LOCKS
900                 KASSERT(vp->v_holdcnt != 0,
901                     ("vn_lock %p: zero hold count", vp));
902 #endif
903                 error = VOP_LOCK1(vp, flags, file, line);
904                 flags &= ~LK_INTERLOCK; /* Interlock is always dropped. */
905                 KASSERT((flags & LK_RETRY) == 0 || error == 0,
906                     ("LK_RETRY set with incompatible flags (0x%x) or an error occured (%d)",
907                     flags, error));
908                 /*
909                  * Callers specify LK_RETRY if they wish to get dead vnodes.
910                  * If RETRY is not set, we return ENOENT instead.
911                  */
912                 if (error == 0 && vp->v_iflag & VI_DOOMED &&
913                     (flags & LK_RETRY) == 0) {
914                         VOP_UNLOCK(vp, 0);
915                         error = ENOENT;
916                         break;
917                 }
918         } while (flags & LK_RETRY && error != 0);
919         return (error);
920 }
921
922 /*
923  * File table vnode close routine.
924  */
925 static int
926 vn_closefile(fp, td)
927         struct file *fp;
928         struct thread *td;
929 {
930         struct vnode *vp;
931         struct flock lf;
932         int vfslocked;
933         int error;
934
935         vp = fp->f_vnode;
936
937         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
938         if (fp->f_type == DTYPE_VNODE && fp->f_flag & FHASLOCK) {
939                 lf.l_whence = SEEK_SET;
940                 lf.l_start = 0;
941                 lf.l_len = 0;
942                 lf.l_type = F_UNLCK;
943                 (void) VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, F_FLOCK);
944         }
945
946         fp->f_ops = &badfileops;
947
948         error = vn_close(vp, fp->f_flag, fp->f_cred, td);
949         VFS_UNLOCK_GIANT(vfslocked);
950         return (error);
951 }
952
953 /*
954  * Preparing to start a filesystem write operation. If the operation is
955  * permitted, then we bump the count of operations in progress and
956  * proceed. If a suspend request is in progress, we wait until the
957  * suspension is over, and then proceed.
958  */
959 int
960 vn_start_write(vp, mpp, flags)
961         struct vnode *vp;
962         struct mount **mpp;
963         int flags;
964 {
965         struct mount *mp;
966         int error;
967
968         error = 0;
969         /*
970          * If a vnode is provided, get and return the mount point that
971          * to which it will write.
972          */
973         if (vp != NULL) {
974                 if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
975                         *mpp = NULL;
976                         if (error != EOPNOTSUPP)
977                                 return (error);
978                         return (0);
979                 }
980         }
981         if ((mp = *mpp) == NULL)
982                 return (0);
983
984         /*
985          * VOP_GETWRITEMOUNT() returns with the mp refcount held through
986          * a vfs_ref().
987          * As long as a vnode is not provided we need to acquire a
988          * refcount for the provided mountpoint too, in order to
989          * emulate a vfs_ref().
990          */
991         MNT_ILOCK(mp);
992         if (vp == NULL)
993                 MNT_REF(mp);
994
995         /*
996          * Check on status of suspension.
997          */
998         if ((curthread->td_pflags & TDP_IGNSUSP) == 0 ||
999             mp->mnt_susp_owner != curthread) {
1000                 while ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
1001                         if (flags & V_NOWAIT) {
1002                                 error = EWOULDBLOCK;
1003                                 goto unlock;
1004                         }
1005                         error = msleep(&mp->mnt_flag, MNT_MTX(mp),
1006                             (PUSER - 1) | (flags & PCATCH), "suspfs", 0);
1007                         if (error)
1008                                 goto unlock;
1009                 }
1010         }
1011         if (flags & V_XSLEEP)
1012                 goto unlock;
1013         mp->mnt_writeopcount++;
1014 unlock:
1015         if (error != 0 || (flags & V_XSLEEP) != 0)
1016                 MNT_REL(mp);
1017         MNT_IUNLOCK(mp);
1018         return (error);
1019 }
1020
1021 /*
1022  * Secondary suspension. Used by operations such as vop_inactive
1023  * routines that are needed by the higher level functions. These
1024  * are allowed to proceed until all the higher level functions have
1025  * completed (indicated by mnt_writeopcount dropping to zero). At that
1026  * time, these operations are halted until the suspension is over.
1027  */
1028 int
1029 vn_start_secondary_write(vp, mpp, flags)
1030         struct vnode *vp;
1031         struct mount **mpp;
1032         int flags;
1033 {
1034         struct mount *mp;
1035         int error;
1036
1037  retry:
1038         if (vp != NULL) {
1039                 if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
1040                         *mpp = NULL;
1041                         if (error != EOPNOTSUPP)
1042                                 return (error);
1043                         return (0);
1044                 }
1045         }
1046         /*
1047          * If we are not suspended or have not yet reached suspended
1048          * mode, then let the operation proceed.
1049          */
1050         if ((mp = *mpp) == NULL)
1051                 return (0);
1052
1053         /*
1054          * VOP_GETWRITEMOUNT() returns with the mp refcount held through
1055          * a vfs_ref().
1056          * As long as a vnode is not provided we need to acquire a
1057          * refcount for the provided mountpoint too, in order to
1058          * emulate a vfs_ref().
1059          */
1060         MNT_ILOCK(mp);
1061         if (vp == NULL)
1062                 MNT_REF(mp);
1063         if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
1064                 mp->mnt_secondary_writes++;
1065                 mp->mnt_secondary_accwrites++;
1066                 MNT_IUNLOCK(mp);
1067                 return (0);
1068         }
1069         if (flags & V_NOWAIT) {
1070                 MNT_REL(mp);
1071                 MNT_IUNLOCK(mp);
1072                 return (EWOULDBLOCK);
1073         }
1074         /*
1075          * Wait for the suspension to finish.
1076          */
1077         error = msleep(&mp->mnt_flag, MNT_MTX(mp),
1078                        (PUSER - 1) | (flags & PCATCH) | PDROP, "suspfs", 0);
1079         vfs_rel(mp);
1080         if (error == 0)
1081                 goto retry;
1082         return (error);
1083 }
1084
1085 /*
1086  * Filesystem write operation has completed. If we are suspending and this
1087  * operation is the last one, notify the suspender that the suspension is
1088  * now in effect.
1089  */
1090 void
1091 vn_finished_write(mp)
1092         struct mount *mp;
1093 {
1094         if (mp == NULL)
1095                 return;
1096         MNT_ILOCK(mp);
1097         MNT_REL(mp);
1098         mp->mnt_writeopcount--;
1099         if (mp->mnt_writeopcount < 0)
1100                 panic("vn_finished_write: neg cnt");
1101         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
1102             mp->mnt_writeopcount <= 0)
1103                 wakeup(&mp->mnt_writeopcount);
1104         MNT_IUNLOCK(mp);
1105 }
1106
1107
1108 /*
1109  * Filesystem secondary write operation has completed. If we are
1110  * suspending and this operation is the last one, notify the suspender
1111  * that the suspension is now in effect.
1112  */
1113 void
1114 vn_finished_secondary_write(mp)
1115         struct mount *mp;
1116 {
1117         if (mp == NULL)
1118                 return;
1119         MNT_ILOCK(mp);
1120         MNT_REL(mp);
1121         mp->mnt_secondary_writes--;
1122         if (mp->mnt_secondary_writes < 0)
1123                 panic("vn_finished_secondary_write: neg cnt");
1124         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0 &&
1125             mp->mnt_secondary_writes <= 0)
1126                 wakeup(&mp->mnt_secondary_writes);
1127         MNT_IUNLOCK(mp);
1128 }
1129
1130
1131
1132 /*
1133  * Request a filesystem to suspend write operations.
1134  */
1135 int
1136 vfs_write_suspend(mp)
1137         struct mount *mp;
1138 {
1139         int error;
1140
1141         MNT_ILOCK(mp);
1142         if (mp->mnt_susp_owner == curthread) {
1143                 MNT_IUNLOCK(mp);
1144                 return (EALREADY);
1145         }
1146         while (mp->mnt_kern_flag & MNTK_SUSPEND)
1147                 msleep(&mp->mnt_flag, MNT_MTX(mp), PUSER - 1, "wsuspfs", 0);
1148         mp->mnt_kern_flag |= MNTK_SUSPEND;
1149         mp->mnt_susp_owner = curthread;
1150         if (mp->mnt_writeopcount > 0)
1151                 (void) msleep(&mp->mnt_writeopcount, 
1152                     MNT_MTX(mp), (PUSER - 1)|PDROP, "suspwt", 0);
1153         else
1154                 MNT_IUNLOCK(mp);
1155         if ((error = VFS_SYNC(mp, MNT_SUSPEND)) != 0)
1156                 vfs_write_resume(mp);
1157         return (error);
1158 }
1159
1160 /*
1161  * Request a filesystem to resume write operations.
1162  */
1163 void
1164 vfs_write_resume(mp)
1165         struct mount *mp;
1166 {
1167
1168         MNT_ILOCK(mp);
1169         if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
1170                 KASSERT(mp->mnt_susp_owner == curthread, ("mnt_susp_owner"));
1171                 mp->mnt_kern_flag &= ~(MNTK_SUSPEND | MNTK_SUSPEND2 |
1172                                        MNTK_SUSPENDED);
1173                 mp->mnt_susp_owner = NULL;
1174                 wakeup(&mp->mnt_writeopcount);
1175                 wakeup(&mp->mnt_flag);
1176                 curthread->td_pflags &= ~TDP_IGNSUSP;
1177                 MNT_IUNLOCK(mp);
1178                 VFS_SUSP_CLEAN(mp);
1179         } else
1180                 MNT_IUNLOCK(mp);
1181 }
1182
1183 /*
1184  * Implement kqueues for files by translating it to vnode operation.
1185  */
1186 static int
1187 vn_kqfilter(struct file *fp, struct knote *kn)
1188 {
1189         int vfslocked;
1190         int error;
1191
1192         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
1193         error = VOP_KQFILTER(fp->f_vnode, kn);
1194         VFS_UNLOCK_GIANT(vfslocked);
1195
1196         return error;
1197 }
1198
1199 /*
1200  * Simplified in-kernel wrapper calls for extended attribute access.
1201  * Both calls pass in a NULL credential, authorizing as "kernel" access.
1202  * Set IO_NODELOCKED in ioflg if the vnode is already locked.
1203  */
1204 int
1205 vn_extattr_get(struct vnode *vp, int ioflg, int attrnamespace,
1206     const char *attrname, int *buflen, char *buf, struct thread *td)
1207 {
1208         struct uio      auio;
1209         struct iovec    iov;
1210         int     error;
1211
1212         iov.iov_len = *buflen;
1213         iov.iov_base = buf;
1214
1215         auio.uio_iov = &iov;
1216         auio.uio_iovcnt = 1;
1217         auio.uio_rw = UIO_READ;
1218         auio.uio_segflg = UIO_SYSSPACE;
1219         auio.uio_td = td;
1220         auio.uio_offset = 0;
1221         auio.uio_resid = *buflen;
1222
1223         if ((ioflg & IO_NODELOCKED) == 0)
1224                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1225
1226         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1227
1228         /* authorize attribute retrieval as kernel */
1229         error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, NULL, NULL,
1230             td);
1231
1232         if ((ioflg & IO_NODELOCKED) == 0)
1233                 VOP_UNLOCK(vp, 0);
1234
1235         if (error == 0) {
1236                 *buflen = *buflen - auio.uio_resid;
1237         }
1238
1239         return (error);
1240 }
1241
1242 /*
1243  * XXX failure mode if partially written?
1244  */
1245 int
1246 vn_extattr_set(struct vnode *vp, int ioflg, int attrnamespace,
1247     const char *attrname, int buflen, char *buf, struct thread *td)
1248 {
1249         struct uio      auio;
1250         struct iovec    iov;
1251         struct mount    *mp;
1252         int     error;
1253
1254         iov.iov_len = buflen;
1255         iov.iov_base = buf;
1256
1257         auio.uio_iov = &iov;
1258         auio.uio_iovcnt = 1;
1259         auio.uio_rw = UIO_WRITE;
1260         auio.uio_segflg = UIO_SYSSPACE;
1261         auio.uio_td = td;
1262         auio.uio_offset = 0;
1263         auio.uio_resid = buflen;
1264
1265         if ((ioflg & IO_NODELOCKED) == 0) {
1266                 if ((error = vn_start_write(vp, &mp, V_WAIT)) != 0)
1267                         return (error);
1268                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1269         }
1270
1271         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1272
1273         /* authorize attribute setting as kernel */
1274         error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, NULL, td);
1275
1276         if ((ioflg & IO_NODELOCKED) == 0) {
1277                 vn_finished_write(mp);
1278                 VOP_UNLOCK(vp, 0);
1279         }
1280
1281         return (error);
1282 }
1283
1284 int
1285 vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
1286     const char *attrname, struct thread *td)
1287 {
1288         struct mount    *mp;
1289         int     error;
1290
1291         if ((ioflg & IO_NODELOCKED) == 0) {
1292                 if ((error = vn_start_write(vp, &mp, V_WAIT)) != 0)
1293                         return (error);
1294                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1295         }
1296
1297         ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
1298
1299         /* authorize attribute removal as kernel */
1300         error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, NULL, td);
1301         if (error == EOPNOTSUPP)
1302                 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
1303                     NULL, td);
1304
1305         if ((ioflg & IO_NODELOCKED) == 0) {
1306                 vn_finished_write(mp);
1307                 VOP_UNLOCK(vp, 0);
1308         }
1309
1310         return (error);
1311 }
1312
1313 int
1314 vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp)
1315 {
1316         struct mount *mp;
1317         int ltype, error;
1318
1319         mp = vp->v_mount;
1320         ltype = VOP_ISLOCKED(vp);
1321         KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
1322             ("vn_vget_ino: vp not locked"));
1323         error = vfs_busy(mp, MBF_NOWAIT);
1324         if (error != 0) {
1325                 vfs_ref(mp);
1326                 VOP_UNLOCK(vp, 0);
1327                 error = vfs_busy(mp, 0);
1328                 vn_lock(vp, ltype | LK_RETRY);
1329                 vfs_rel(mp);
1330                 if (error != 0)
1331                         return (ENOENT);
1332                 if (vp->v_iflag & VI_DOOMED) {
1333                         vfs_unbusy(mp);
1334                         return (ENOENT);
1335                 }
1336         }
1337         VOP_UNLOCK(vp, 0);
1338         error = VFS_VGET(mp, ino, lkflags, rvp);
1339         vfs_unbusy(mp);
1340         vn_lock(vp, ltype | LK_RETRY);
1341         if (vp->v_iflag & VI_DOOMED) {
1342                 if (error == 0)
1343                         vput(*rvp);
1344                 error = ENOENT;
1345         }
1346         return (error);
1347 }
1348
1349 int
1350 vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
1351     const struct thread *td)
1352 {
1353
1354         if (vp->v_type != VREG || td == NULL)
1355                 return (0);
1356         PROC_LOCK(td->td_proc);
1357         if ((uoff_t)uio->uio_offset + uio->uio_resid >
1358             lim_cur(td->td_proc, RLIMIT_FSIZE)) {
1359                 kern_psignal(td->td_proc, SIGXFSZ);
1360                 PROC_UNLOCK(td->td_proc);
1361                 return (EFBIG);
1362         }
1363         PROC_UNLOCK(td->td_proc);
1364         return (0);
1365 }
1366
1367 int
1368 vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
1369     struct thread *td)
1370 {
1371         struct vnode *vp;
1372         int error, vfslocked;
1373
1374         vp = fp->f_vnode;
1375         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1376 #ifdef AUDIT
1377         vn_lock(vp, LK_SHARED | LK_RETRY);
1378         AUDIT_ARG_VNODE1(vp);
1379         VOP_UNLOCK(vp, 0);
1380 #endif
1381         error = setfmode(td, active_cred, vp, mode);
1382         VFS_UNLOCK_GIANT(vfslocked);
1383         return (error);
1384 }
1385
1386 int
1387 vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
1388     struct thread *td)
1389 {
1390         struct vnode *vp;
1391         int error, vfslocked;
1392
1393         vp = fp->f_vnode;
1394         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1395 #ifdef AUDIT
1396         vn_lock(vp, LK_SHARED | LK_RETRY);
1397         AUDIT_ARG_VNODE1(vp);
1398         VOP_UNLOCK(vp, 0);
1399 #endif
1400         error = setfown(td, active_cred, vp, uid, gid);
1401         VFS_UNLOCK_GIANT(vfslocked);
1402         return (error);
1403 }
1404
1405 void
1406 vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
1407 {
1408         vm_object_t object;
1409
1410         if ((object = vp->v_object) == NULL)
1411                 return;
1412         VM_OBJECT_LOCK(object);
1413         vm_object_page_remove(object, start, end, 0);
1414         VM_OBJECT_UNLOCK(object);
1415 }