This source file includes following definitions.
- vntblinit
- vfs_busy
- vfs_unbusy
- vfs_isbusy
- vfs_rootmountalloc
- vfs_mountroot
- vfs_getvfs
- vfs_getnewfsid
- makefstype
- vattr_null
- getnewvnode
- insmntque
- bdevvp
- cdevvp
- getdevvp
- checkalias
- vget
- vref
- vputonfreelist
- vput
- vrele
- vhold
- vfs_mount_foreach_vnode
- vflush_vnode
- vflush
- vclean
- vrecycle
- vgone
- vgonel
- vfinddev
- vdevgone
- vcount
- vprint
- printlockedvnodes
- vfs_sysctl
- sysctl_vnode
- vfs_mountedon
- vfs_hang_addrlist
- vfs_free_netcred
- vfs_free_addrlist
- vfs_export
- vfs_export_lookup
- vaccess
- vfs_unmountall
- vfs_shutdown
- vfs_syncwait
- fs_posix_sysctl
- fs_sysctl
- vwaitforio
- vwakeup
- vinvalbuf
- vflushbuf
- bgetvp
- brelvp
- buf_replacevnode
- reassignbuf
- vfs_register
- vfs_unregister
- vn_isdisk
- vfs_buf_print
- vfs_vnode_print
- vfs_mount_print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/proc.h>
47 #include <sys/mount.h>
48 #include <sys/time.h>
49 #include <sys/fcntl.h>
50 #include <sys/kernel.h>
51 #include <sys/vnode.h>
52 #include <sys/stat.h>
53 #include <sys/namei.h>
54 #include <sys/ucred.h>
55 #include <sys/buf.h>
56 #include <sys/errno.h>
57 #include <sys/malloc.h>
58 #include <sys/domain.h>
59 #include <sys/mbuf.h>
60 #include <sys/syscallargs.h>
61 #include <sys/pool.h>
62
63 #include <uvm/uvm_extern.h>
64 #include <sys/sysctl.h>
65
66 #include <miscfs/specfs/specdev.h>
67
68 enum vtype iftovt_tab[16] = {
69 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
70 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
71 };
72
73 int vttoif_tab[9] = {
74 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,
75 S_IFSOCK, S_IFIFO, S_IFMT,
76 };
77
78 int doforce = 1;
79 int prtactive = 0;
80 int suid_clear = 1;
81
82
83
84
85 #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs)
86 #define bufremvn(bp) { \
87 LIST_REMOVE(bp, b_vnbufs); \
88 LIST_NEXT(bp, b_vnbufs) = NOLIST; \
89 }
90
91 struct freelst vnode_hold_list;
92 struct freelst vnode_free_list;
93
94 struct mntlist mountlist;
95
96 void vclean(struct vnode *, int, struct proc *);
97
98 void insmntque(struct vnode *, struct mount *);
99 int getdevvp(dev_t, struct vnode **, enum vtype);
100
101 int vfs_hang_addrlist(struct mount *, struct netexport *,
102 struct export_args *);
103 int vfs_free_netcred(struct radix_node *, void *);
104 void vfs_free_addrlist(struct netexport *);
105 void vputonfreelist(struct vnode *);
106
107 int vflush_vnode(struct vnode *, void *);
108 int maxvnodes;
109
110 #ifdef DEBUG
111 void printlockedvnodes(void);
112 #endif
113
114 struct pool vnode_pool;
115
116
117
118
119 void
120 vntblinit(void)
121 {
122
123 maxvnodes = desiredvnodes;
124 pool_init(&vnode_pool, sizeof(struct vnode), 0, 0, 0, "vnodes",
125 &pool_allocator_nointr);
126 TAILQ_INIT(&vnode_hold_list);
127 TAILQ_INIT(&vnode_free_list);
128 CIRCLEQ_INIT(&mountlist);
129
130
131
132 vn_initialize_syncerd();
133 }
134
135
136
137
138
139
140
141
142 int
143 vfs_busy(struct mount *mp, int flags)
144 {
145 int rwflags = 0;
146
147
148 if (mp->mnt_lock.rwl_name == NULL)
149 rw_init(&mp->mnt_lock, "vfslock");
150
151 if (flags & VB_WRITE)
152 rwflags |= RW_WRITE;
153 else
154 rwflags |= RW_READ;
155
156 if (flags & VB_WAIT)
157 rwflags |= RW_SLEEPFAIL;
158 else
159 rwflags |= RW_NOSLEEP;
160
161 if (rw_enter(&mp->mnt_lock, rwflags))
162 return (EBUSY);
163
164 return (0);
165 }
166
167
168
169
170 void
171 vfs_unbusy(struct mount *mp)
172 {
173 rw_exit(&mp->mnt_lock);
174 }
175
176 int
177 vfs_isbusy(struct mount *mp)
178 {
179 if (RWLOCK_OWNER(&mp->mnt_lock) > 0)
180 return (1);
181 else
182 return (0);
183 }
184
185
186
187
188
189
190
191 int
192 vfs_rootmountalloc(char *fstypename, char *devname, struct mount **mpp)
193 {
194 struct vfsconf *vfsp;
195 struct mount *mp;
196
197 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
198 if (!strcmp(vfsp->vfc_name, fstypename))
199 break;
200 if (vfsp == NULL)
201 return (ENODEV);
202 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK);
203 bzero(mp, sizeof(struct mount));
204 (void)vfs_busy(mp, VB_READ|VB_NOWAIT);
205 LIST_INIT(&mp->mnt_vnodelist);
206 mp->mnt_vfc = vfsp;
207 mp->mnt_op = vfsp->vfc_vfsops;
208 mp->mnt_flag = MNT_RDONLY;
209 mp->mnt_vnodecovered = NULLVP;
210 vfsp->vfc_refcount++;
211 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
212 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
213 mp->mnt_stat.f_mntonname[0] = '/';
214 (void)copystr(devname, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 0);
215 *mpp = mp;
216 return (0);
217 }
218
219
220
221
222
223
224
225 int
226 vfs_mountroot(void)
227 {
228 struct vfsconf *vfsp;
229 int error;
230
231 if (mountroot != NULL)
232 return ((*mountroot)());
233 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
234 if (vfsp->vfc_mountroot == NULL)
235 continue;
236 if ((error = (*vfsp->vfc_mountroot)()) == 0)
237 return (0);
238 printf("%s_mountroot failed: %d\n", vfsp->vfc_name, error);
239 }
240 return (ENODEV);
241 }
242
243
244
245
246 struct mount *
247 vfs_getvfs(fsid_t *fsid)
248 {
249 struct mount *mp;
250
251 CIRCLEQ_FOREACH(mp, &mountlist, mnt_list) {
252 if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
253 mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) {
254 return (mp);
255 }
256 }
257
258 return (NULL);
259 }
260
261
262
263
264
265 void
266 vfs_getnewfsid(struct mount *mp)
267 {
268 static u_short xxxfs_mntid;
269
270 fsid_t tfsid;
271 int mtype;
272
273 mtype = mp->mnt_vfc->vfc_typenum;
274 mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev + mtype, 0);
275 mp->mnt_stat.f_fsid.val[1] = mtype;
276 if (xxxfs_mntid == 0)
277 ++xxxfs_mntid;
278 tfsid.val[0] = makedev(nblkdev + mtype, xxxfs_mntid);
279 tfsid.val[1] = mtype;
280 if (!CIRCLEQ_EMPTY(&mountlist)) {
281 while (vfs_getvfs(&tfsid)) {
282 tfsid.val[0]++;
283 xxxfs_mntid++;
284 }
285 }
286 mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
287 }
288
289
290
291
292
293
294 long
295 makefstype(char *type)
296 {
297 long rv;
298
299 for (rv = 0; *type; type++) {
300 rv <<= 2;
301 rv ^= *type;
302 }
303 return rv;
304 }
305
306
307
308
309 void
310 vattr_null(struct vattr *vap)
311 {
312
313 vap->va_type = VNON;
314
315 vap->va_size = VNOVAL;
316 vap->va_bytes = VNOVAL;
317 vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid =
318 vap->va_fsid = vap->va_fileid =
319 vap->va_blocksize = vap->va_rdev =
320 vap->va_atime.tv_sec = vap->va_atime.tv_nsec =
321 vap->va_mtime.tv_sec = vap->va_mtime.tv_nsec =
322 vap->va_ctime.tv_sec = vap->va_ctime.tv_nsec =
323 vap->va_flags = vap->va_gen = VNOVAL;
324 vap->va_vaflags = 0;
325 }
326
327
328
329
330 extern int (**dead_vnodeop_p)(void *);
331 long numvnodes;
332
333
334
335
336 int
337 getnewvnode(enum vtagtype tag, struct mount *mp, int (**vops)(void *),
338 struct vnode **vpp)
339 {
340 struct proc *p = curproc;
341 struct freelst *listhd;
342 static int toggle;
343 struct vnode *vp;
344 int s;
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 toggle ^= 1;
362 if (numvnodes > 2 * maxvnodes)
363 toggle = 0;
364
365 s = splbio();
366 if ((numvnodes < maxvnodes) ||
367 ((TAILQ_FIRST(listhd = &vnode_free_list) == NULL) &&
368 ((TAILQ_FIRST(listhd = &vnode_hold_list) == NULL) || toggle))) {
369 splx(s);
370 vp = pool_get(&vnode_pool, PR_WAITOK);
371 bzero((char *)vp, sizeof *vp);
372 numvnodes++;
373 } else {
374 for (vp = TAILQ_FIRST(listhd); vp != NULLVP;
375 vp = TAILQ_NEXT(vp, v_freelist)) {
376 if (VOP_ISLOCKED(vp) == 0)
377 break;
378 }
379
380
381
382
383
384 if (vp == NULL) {
385 splx(s);
386 tablefull("vnode");
387 *vpp = 0;
388 return (ENFILE);
389 }
390
391 #ifdef DIAGNOSTIC
392 if (vp->v_usecount) {
393 vprint("free vnode", vp);
394 panic("free vnode isn't");
395 }
396 #endif
397
398 TAILQ_REMOVE(listhd, vp, v_freelist);
399 vp->v_bioflag &= ~VBIOONFREELIST;
400 splx(s);
401
402 if (vp->v_type != VBAD)
403 vgonel(vp, p);
404 #ifdef DIAGNOSTIC
405 if (vp->v_data) {
406 vprint("cleaned vnode", vp);
407 panic("cleaned vnode isn't");
408 }
409 s = splbio();
410 if (vp->v_numoutput)
411 panic("Clean vnode has pending I/O's");
412 splx(s);
413 #endif
414 vp->v_flag = 0;
415 vp->v_socket = 0;
416 }
417 vp->v_type = VNON;
418 cache_purge(vp);
419 vp->v_tag = tag;
420 vp->v_op = vops;
421 insmntque(vp, mp);
422 *vpp = vp;
423 vp->v_usecount = 1;
424 vp->v_data = 0;
425 simple_lock_init(&vp->v_uvm.u_obj.vmobjlock);
426 return (0);
427 }
428
429
430
431
432 void
433 insmntque(struct vnode *vp, struct mount *mp)
434 {
435
436
437
438 if (vp->v_mount != NULL)
439 LIST_REMOVE(vp, v_mntvnodes);
440
441
442
443 if ((vp->v_mount = mp) != NULL)
444 LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
445 }
446
447
448
449
450
451
452 int
453 bdevvp(dev_t dev, struct vnode **vpp)
454 {
455 return (getdevvp(dev, vpp, VBLK));
456 }
457
458
459
460
461
462 int
463 cdevvp(dev_t dev, struct vnode **vpp)
464 {
465 return (getdevvp(dev, vpp, VCHR));
466 }
467
468
469
470
471
472
473 int
474 getdevvp(dev_t dev, struct vnode **vpp, enum vtype type)
475 {
476 struct vnode *vp;
477 struct vnode *nvp;
478 int error;
479
480 if (dev == NODEV) {
481 *vpp = NULLVP;
482 return (0);
483 }
484 error = getnewvnode(VT_NON, NULL, spec_vnodeop_p, &nvp);
485 if (error) {
486 *vpp = NULLVP;
487 return (error);
488 }
489 vp = nvp;
490 vp->v_type = type;
491 if ((nvp = checkalias(vp, dev, NULL)) != 0) {
492 vput(vp);
493 vp = nvp;
494 }
495 *vpp = vp;
496 return (0);
497 }
498
499
500
501
502
503
504
505
506
507 struct vnode *
508 checkalias(struct vnode *nvp, dev_t nvp_rdev, struct mount *mp)
509 {
510 struct proc *p = curproc;
511 struct vnode *vp;
512 struct vnode **vpp;
513
514 if (nvp->v_type != VBLK && nvp->v_type != VCHR)
515 return (NULLVP);
516
517 vpp = &speclisth[SPECHASH(nvp_rdev)];
518 loop:
519 for (vp = *vpp; vp; vp = vp->v_specnext) {
520 if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type) {
521 continue;
522 }
523
524
525
526 if (vp->v_usecount == 0) {
527 vgonel(vp, p);
528 goto loop;
529 }
530 if (vget(vp, LK_EXCLUSIVE, p)) {
531 goto loop;
532 }
533 break;
534 }
535
536
537
538
539 if (vp == NULL || !(vp->v_tag == VT_NON && vp->v_type == VBLK)) {
540 MALLOC(nvp->v_specinfo, struct specinfo *,
541 sizeof(struct specinfo), M_VNODE, M_WAITOK);
542 nvp->v_rdev = nvp_rdev;
543 nvp->v_hashchain = vpp;
544 nvp->v_specnext = *vpp;
545 nvp->v_specmountpoint = NULL;
546 nvp->v_speclockf = NULL;
547 bzero(nvp->v_specbitmap, sizeof(nvp->v_specbitmap));
548 *vpp = nvp;
549 if (vp != NULLVP) {
550 nvp->v_flag |= VALIASED;
551 vp->v_flag |= VALIASED;
552 vput(vp);
553 }
554 return (NULLVP);
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568 VOP_UNLOCK(vp, 0, p);
569 vclean(vp, 0, p);
570 vp->v_op = nvp->v_op;
571 vp->v_tag = nvp->v_tag;
572 nvp->v_type = VNON;
573 insmntque(vp, mp);
574 return (vp);
575 }
576
577
578
579
580
581
582
583
584
585
586 int
587 vget(struct vnode *vp, int flags, struct proc *p)
588 {
589 int error, s, onfreelist;
590
591
592
593
594
595
596
597
598 if (vp->v_flag & VXLOCK) {
599 if (flags & LK_NOWAIT) {
600 return (EBUSY);
601 }
602
603 vp->v_flag |= VXWANT;
604 ltsleep(vp, PINOD | PNORELOCK, "vget", 0, NULL);
605 return (ENOENT);
606 }
607
608 onfreelist = vp->v_bioflag & VBIOONFREELIST;
609 if (vp->v_usecount == 0 && onfreelist) {
610 s = splbio();
611 if (vp->v_holdcnt > 0)
612 TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
613 else
614 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
615 vp->v_bioflag &= ~VBIOONFREELIST;
616 splx(s);
617 }
618
619 vp->v_usecount++;
620 if (flags & LK_TYPE_MASK) {
621 if ((error = vn_lock(vp, flags, p)) != 0) {
622 vp->v_usecount--;
623 if (vp->v_usecount == 0 && onfreelist)
624 vputonfreelist(vp);
625 }
626 return (error);
627 }
628
629 return (0);
630 }
631
632
633
634 void
635 vref(struct vnode *vp)
636 {
637 #ifdef DIAGNOSTIC
638 if (vp->v_usecount == 0)
639 panic("vref used where vget required");
640 #endif
641 vp->v_usecount++;
642 }
643
644 void
645 vputonfreelist(struct vnode *vp)
646 {
647 int s;
648 struct freelst *lst;
649
650 s = splbio();
651 #ifdef DIAGNOSTIC
652 if (vp->v_usecount != 0)
653 panic("Use count is not zero!");
654
655 if (vp->v_bioflag & VBIOONFREELIST) {
656 vprint("vnode already on free list: ", vp);
657 panic("vnode already on free list");
658 }
659 #endif
660
661 vp->v_bioflag |= VBIOONFREELIST;
662
663 if (vp->v_holdcnt > 0)
664 lst = &vnode_hold_list;
665 else
666 lst = &vnode_free_list;
667
668 if (vp->v_type == VBAD)
669 TAILQ_INSERT_HEAD(lst, vp, v_freelist);
670 else
671 TAILQ_INSERT_TAIL(lst, vp, v_freelist);
672
673 splx(s);
674 }
675
676
677
678
679 void
680 vput(struct vnode *vp)
681 {
682 struct proc *p = curproc;
683
684 #ifdef DIAGNOSTIC
685 if (vp == NULL)
686 panic("vput: null vp");
687 #endif
688
689 #ifdef DIAGNOSTIC
690 if (vp->v_usecount == 0) {
691 vprint("vput: bad ref count", vp);
692 panic("vput: ref cnt");
693 }
694 #endif
695 vp->v_usecount--;
696 if (vp->v_usecount > 0) {
697 VOP_UNLOCK(vp, 0, p);
698 return;
699 }
700
701 #ifdef DIAGNOSTIC
702 if (vp->v_writecount != 0) {
703 vprint("vput: bad writecount", vp);
704 panic("vput: v_writecount != 0");
705 }
706 #endif
707
708 VOP_INACTIVE(vp, p);
709
710 if (vp->v_usecount == 0 && !(vp->v_bioflag & VBIOONFREELIST))
711 vputonfreelist(vp);
712 }
713
714
715
716
717
718 void
719 vrele(struct vnode *vp)
720 {
721 struct proc *p = curproc;
722
723 #ifdef DIAGNOSTIC
724 if (vp == NULL)
725 panic("vrele: null vp");
726 #endif
727 #ifdef DIAGNOSTIC
728 if (vp->v_usecount == 0) {
729 vprint("vrele: bad ref count", vp);
730 panic("vrele: ref cnt");
731 }
732 #endif
733 vp->v_usecount--;
734 if (vp->v_usecount > 0) {
735 return;
736 }
737
738 #ifdef DIAGNOSTIC
739 if (vp->v_writecount != 0) {
740 vprint("vrele: bad writecount", vp);
741 panic("vrele: v_writecount != 0");
742 }
743 #endif
744
745 if (vn_lock(vp, LK_EXCLUSIVE, p)) {
746 #ifdef DIAGNOSTIC
747 vprint("vrele: cannot lock", vp);
748 #endif
749 return;
750 }
751
752 VOP_INACTIVE(vp, p);
753
754 if (vp->v_usecount == 0 && !(vp->v_bioflag & VBIOONFREELIST))
755 vputonfreelist(vp);
756 }
757
758 void vhold(struct vnode *vp);
759
760
761
762
763 void
764 vhold(struct vnode *vp)
765 {
766
767
768
769
770 if ((vp->v_bioflag & VBIOONFREELIST) &&
771 vp->v_holdcnt == 0 && vp->v_usecount == 0) {
772 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
773 TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
774 }
775 vp->v_holdcnt++;
776 }
777
778
779
780
781
782
783
784
785
786 #ifdef DEBUG
787 int busyprt = 0;
788 struct ctldebug debug1 = { "busyprt", &busyprt };
789 #endif
790
791 int
792 vfs_mount_foreach_vnode(struct mount *mp,
793 int (*func)(struct vnode *, void *), void *arg) {
794 struct vnode *vp, *nvp;
795 int error = 0;
796
797 loop:
798 for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
799 if (vp->v_mount != mp)
800 goto loop;
801 nvp = LIST_NEXT(vp, v_mntvnodes);
802
803 error = func(vp, arg);
804
805 if (error != 0)
806 break;
807 }
808
809 return (error);
810 }
811
812 struct vflush_args {
813 struct vnode *skipvp;
814 int busy;
815 int flags;
816 };
817
818 int
819 vflush_vnode(struct vnode *vp, void *arg) {
820 struct vflush_args *va = arg;
821 struct proc *p = curproc;
822
823 if (vp == va->skipvp) {
824 return (0);
825 }
826
827 if ((va->flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM)) {
828 return (0);
829 }
830
831
832
833
834
835 if ((va->flags & WRITECLOSE) &&
836 (vp->v_writecount == 0 || vp->v_type != VREG)) {
837 return (0);
838 }
839
840
841
842
843
844 if (vp->v_usecount == 0) {
845 vgonel(vp, p);
846 return (0);
847 }
848
849
850
851
852
853
854 if (va->flags & FORCECLOSE) {
855 if (vp->v_type != VBLK && vp->v_type != VCHR) {
856 vgonel(vp, p);
857 } else {
858 vclean(vp, 0, p);
859 vp->v_op = spec_vnodeop_p;
860 insmntque(vp, (struct mount *)0);
861 }
862 return (0);
863 }
864
865 #ifdef DEBUG
866 if (busyprt)
867 vprint("vflush: busy vnode", vp);
868 #endif
869 va->busy++;
870 return (0);
871 }
872
873 int
874 vflush(struct mount *mp, struct vnode *skipvp, int flags)
875 {
876 struct vflush_args va;
877 va.skipvp = skipvp;
878 va.busy = 0;
879 va.flags = flags;
880
881 vfs_mount_foreach_vnode(mp, vflush_vnode, &va);
882
883 if (va.busy)
884 return (EBUSY);
885 return (0);
886 }
887
888
889
890
891 void
892 vclean(struct vnode *vp, int flags, struct proc *p)
893 {
894 int active;
895
896
897
898
899
900
901
902 if ((active = vp->v_usecount) != 0)
903 vp->v_usecount++;
904
905
906
907
908
909 if (vp->v_flag & VXLOCK)
910 panic("vclean: deadlock");
911 vp->v_flag |= VXLOCK;
912
913
914
915
916
917
918
919 VOP_LOCK(vp, LK_DRAIN, p);
920
921
922
923
924 uvm_vnp_terminate(vp);
925
926
927
928 if (flags & DOCLOSE)
929 vinvalbuf(vp, V_SAVE, NOCRED, p, 0, 0);
930
931
932
933
934
935 if (active) {
936 if (flags & DOCLOSE)
937 VOP_CLOSE(vp, FNONBLOCK, NOCRED, p);
938 VOP_INACTIVE(vp, p);
939 } else {
940
941
942
943
944 VOP_UNLOCK(vp, 0, p);
945 }
946
947
948
949
950 if (VOP_RECLAIM(vp, p))
951 panic("vclean: cannot reclaim");
952 if (active) {
953 vp->v_usecount--;
954 if (vp->v_usecount == 0) {
955 if (vp->v_holdcnt > 0)
956 panic("vclean: not clean");
957 vputonfreelist(vp);
958 }
959 }
960 cache_purge(vp);
961
962
963
964
965 vp->v_op = dead_vnodeop_p;
966 VN_KNOTE(vp, NOTE_REVOKE);
967 vp->v_tag = VT_NON;
968 vp->v_flag &= ~VXLOCK;
969 #ifdef VFSDEBUG
970 vp->v_flag &= ~VLOCKSWORK;
971 #endif
972 if (vp->v_flag & VXWANT) {
973 vp->v_flag &= ~VXWANT;
974 wakeup(vp);
975 }
976 }
977
978
979
980
981 int
982 vrecycle(struct vnode *vp, struct proc *p)
983 {
984 if (vp->v_usecount == 0) {
985 vgonel(vp, p);
986 return (1);
987 }
988 return (0);
989 }
990
991
992
993
994
995 void
996 vgone(struct vnode *vp)
997 {
998 struct proc *p = curproc;
999 vgonel(vp, p);
1000 }
1001
1002
1003
1004
1005 void
1006 vgonel(struct vnode *vp, struct proc *p)
1007 {
1008 struct vnode *vq;
1009 struct vnode *vx;
1010 struct mount *mp;
1011 int flags;
1012
1013
1014
1015
1016
1017 if (vp->v_flag & VXLOCK) {
1018 vp->v_flag |= VXWANT;
1019 ltsleep(vp, PINOD | PNORELOCK, "vgone", 0, NULL);
1020 return;
1021 }
1022
1023
1024
1025
1026 vclean(vp, DOCLOSE, p);
1027
1028
1029
1030 if (vp->v_mount != NULL)
1031 insmntque(vp, (struct mount *)0);
1032
1033
1034
1035
1036 if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_specinfo != 0) {
1037 if (*vp->v_hashchain == vp) {
1038 *vp->v_hashchain = vp->v_specnext;
1039 } else {
1040 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1041 if (vq->v_specnext != vp)
1042 continue;
1043 vq->v_specnext = vp->v_specnext;
1044 break;
1045 }
1046 if (vq == NULL)
1047 panic("missing bdev");
1048 }
1049 if (vp->v_flag & VALIASED) {
1050 vx = NULL;
1051 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1052 if (vq->v_rdev != vp->v_rdev ||
1053 vq->v_type != vp->v_type)
1054 continue;
1055 if (vx)
1056 break;
1057 vx = vq;
1058 }
1059 if (vx == NULL)
1060 panic("missing alias");
1061 if (vq == NULL)
1062 vx->v_flag &= ~VALIASED;
1063 vp->v_flag &= ~VALIASED;
1064 }
1065
1066
1067
1068
1069
1070
1071 mp = vp->v_specmountpoint;
1072 if (mp != NULL) {
1073 if (!vfs_busy(mp, VB_WRITE|VB_WAIT)) {
1074 flags = MNT_FORCE | MNT_DOOMED;
1075 dounmount(mp, flags, p, NULL);
1076 }
1077 }
1078
1079 FREE(vp->v_specinfo, M_VNODE);
1080 vp->v_specinfo = NULL;
1081 }
1082
1083
1084
1085
1086 vp->v_type = VBAD;
1087
1088
1089
1090
1091
1092 if (vp->v_usecount == 0 &&
1093 (vp->v_bioflag & VBIOONFREELIST)) {
1094 int s;
1095
1096 s = splbio();
1097
1098 if (vp->v_holdcnt > 0)
1099 panic("vgonel: not clean");
1100
1101 if (TAILQ_FIRST(&vnode_free_list) != vp) {
1102 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
1103 TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
1104 }
1105 splx(s);
1106 }
1107 }
1108
1109
1110
1111
1112 int
1113 vfinddev(dev_t dev, enum vtype type, struct vnode **vpp)
1114 {
1115 struct vnode *vp;
1116 int rc =0;
1117
1118 for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
1119 if (dev != vp->v_rdev || type != vp->v_type)
1120 continue;
1121 *vpp = vp;
1122 rc = 1;
1123 break;
1124 }
1125 return (rc);
1126 }
1127
1128
1129
1130
1131
1132 void
1133 vdevgone(int maj, int minl, int minh, enum vtype type)
1134 {
1135 struct vnode *vp;
1136 int mn;
1137
1138 for (mn = minl; mn <= minh; mn++)
1139 if (vfinddev(makedev(maj, mn), type, &vp))
1140 VOP_REVOKE(vp, REVOKEALL);
1141 }
1142
1143
1144
1145
1146 int
1147 vcount(struct vnode *vp)
1148 {
1149 struct vnode *vq, *vnext;
1150 int count;
1151
1152 loop:
1153 if ((vp->v_flag & VALIASED) == 0)
1154 return (vp->v_usecount);
1155 for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
1156 vnext = vq->v_specnext;
1157 if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
1158 continue;
1159
1160
1161
1162 if (vq->v_usecount == 0 && vq != vp) {
1163 vgone(vq);
1164 goto loop;
1165 }
1166 count += vq->v_usecount;
1167 }
1168 return (count);
1169 }
1170
1171 #if defined(DEBUG) || defined(DIAGNOSTIC)
1172
1173
1174
1175 static char *typename[] =
1176 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" };
1177
1178 void
1179 vprint(char *label, struct vnode *vp)
1180 {
1181 char buf[64];
1182
1183 if (label != NULL)
1184 printf("%s: ", label);
1185 printf("%p, type %s, use %u, write %u, hold %u,",
1186 vp, typename[vp->v_type], vp->v_usecount, vp->v_writecount,
1187 vp->v_holdcnt);
1188 buf[0] = '\0';
1189 if (vp->v_flag & VROOT)
1190 strlcat(buf, "|VROOT", sizeof buf);
1191 if (vp->v_flag & VTEXT)
1192 strlcat(buf, "|VTEXT", sizeof buf);
1193 if (vp->v_flag & VSYSTEM)
1194 strlcat(buf, "|VSYSTEM", sizeof buf);
1195 if (vp->v_flag & VXLOCK)
1196 strlcat(buf, "|VXLOCK", sizeof buf);
1197 if (vp->v_flag & VXWANT)
1198 strlcat(buf, "|VXWANT", sizeof buf);
1199 if (vp->v_bioflag & VBIOWAIT)
1200 strlcat(buf, "|VBIOWAIT", sizeof buf);
1201 if (vp->v_bioflag & VBIOONFREELIST)
1202 strlcat(buf, "|VBIOONFREELIST", sizeof buf);
1203 if (vp->v_bioflag & VBIOONSYNCLIST)
1204 strlcat(buf, "|VBIOONSYNCLIST", sizeof buf);
1205 if (vp->v_flag & VALIASED)
1206 strlcat(buf, "|VALIASED", sizeof buf);
1207 if (buf[0] != '\0')
1208 printf(" flags (%s)", &buf[1]);
1209 if (vp->v_data == NULL) {
1210 printf("\n");
1211 } else {
1212 printf("\n\t");
1213 VOP_PRINT(vp);
1214 }
1215 }
1216 #endif
1217
1218 #ifdef DEBUG
1219
1220
1221
1222
1223 void
1224 printlockedvnodes(void)
1225 {
1226 struct mount *mp, *nmp;
1227 struct vnode *vp;
1228
1229 printf("Locked vnodes\n");
1230
1231 for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
1232 mp = nmp) {
1233 if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
1234 nmp = CIRCLEQ_NEXT(mp, mnt_list);
1235 continue;
1236 }
1237 LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
1238 if (VOP_ISLOCKED(vp))
1239 vprint((char *)0, vp);
1240 }
1241 nmp = CIRCLEQ_NEXT(mp, mnt_list);
1242 vfs_unbusy(mp);
1243 }
1244
1245 }
1246 #endif
1247
1248
1249
1250
1251 int
1252 vfs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1253 size_t newlen, struct proc *p)
1254 {
1255 struct vfsconf *vfsp, *tmpvfsp;
1256 int ret;
1257
1258
1259 if (namelen < 2)
1260 return (ENOTDIR);
1261
1262 if (name[0] != VFS_GENERIC) {
1263 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
1264 if (vfsp->vfc_typenum == name[0])
1265 break;
1266
1267 if (vfsp == NULL)
1268 return (EOPNOTSUPP);
1269
1270 return ((*vfsp->vfc_vfsops->vfs_sysctl)(&name[1], namelen - 1,
1271 oldp, oldlenp, newp, newlen, p));
1272 }
1273
1274 switch (name[1]) {
1275 case VFS_MAXTYPENUM:
1276 return (sysctl_rdint(oldp, oldlenp, newp, maxvfsconf));
1277
1278 case VFS_CONF:
1279 if (namelen < 3)
1280 return (ENOTDIR);
1281
1282 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
1283 if (vfsp->vfc_typenum == name[2])
1284 break;
1285
1286 if (vfsp == NULL)
1287 return (EOPNOTSUPP);
1288
1289
1290 tmpvfsp = malloc(sizeof(*tmpvfsp), M_TEMP, M_WAITOK);
1291 bcopy(vfsp, tmpvfsp, sizeof(*tmpvfsp));
1292 tmpvfsp->vfc_vfsops = NULL;
1293 tmpvfsp->vfc_mountroot = NULL;
1294 tmpvfsp->vfc_next = NULL;
1295
1296 ret = sysctl_rdstruct(oldp, oldlenp, newp, tmpvfsp,
1297 sizeof(struct vfsconf));
1298
1299 free(tmpvfsp, M_TEMP);
1300 return (ret);
1301 }
1302
1303 return (EOPNOTSUPP);
1304 }
1305
1306 int kinfo_vdebug = 1;
1307 #define KINFO_VNODESLOP 10
1308
1309
1310
1311
1312
1313 int
1314 sysctl_vnode(char *where, size_t *sizep, struct proc *p)
1315 {
1316 struct mount *mp, *nmp;
1317 struct vnode *vp, *nvp;
1318 char *bp = where, *savebp;
1319 char *ewhere;
1320 int error;
1321
1322 if (where == NULL) {
1323 *sizep = (numvnodes + KINFO_VNODESLOP) * sizeof(struct e_vnode);
1324 return (0);
1325 }
1326 ewhere = where + *sizep;
1327
1328 for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
1329 mp = nmp) {
1330 if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
1331 nmp = CIRCLEQ_NEXT(mp, mnt_list);
1332 continue;
1333 }
1334 savebp = bp;
1335 again:
1336 for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL;
1337 vp = nvp) {
1338
1339
1340
1341
1342
1343 if (vp->v_mount != mp) {
1344 if (kinfo_vdebug)
1345 printf("kinfo: vp changed\n");
1346 bp = savebp;
1347 goto again;
1348 }
1349 nvp = LIST_NEXT(vp, v_mntvnodes);
1350 if (bp + sizeof(struct e_vnode) > ewhere) {
1351 *sizep = bp - where;
1352 vfs_unbusy(mp);
1353 return (ENOMEM);
1354 }
1355 if ((error = copyout(&vp,
1356 &((struct e_vnode *)bp)->vptr,
1357 sizeof(struct vnode *))) ||
1358 (error = copyout(vp,
1359 &((struct e_vnode *)bp)->vnode,
1360 sizeof(struct vnode)))) {
1361 vfs_unbusy(mp);
1362 return (error);
1363 }
1364 bp += sizeof(struct e_vnode);
1365 }
1366
1367 nmp = CIRCLEQ_NEXT(mp, mnt_list);
1368 vfs_unbusy(mp);
1369 }
1370
1371 *sizep = bp - where;
1372
1373 return (0);
1374 }
1375
1376
1377
1378
1379 int
1380 vfs_mountedon(struct vnode *vp)
1381 {
1382 struct vnode *vq;
1383 int error = 0;
1384
1385 if (vp->v_specmountpoint != NULL)
1386 return (EBUSY);
1387 if (vp->v_flag & VALIASED) {
1388 for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1389 if (vq->v_rdev != vp->v_rdev ||
1390 vq->v_type != vp->v_type)
1391 continue;
1392 if (vq->v_specmountpoint != NULL) {
1393 error = EBUSY;
1394 break;
1395 }
1396 }
1397 }
1398 return (error);
1399 }
1400
1401
1402
1403
1404
1405 int
1406 vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
1407 struct export_args *argp)
1408 {
1409 struct netcred *np;
1410 struct radix_node_head *rnh;
1411 int i;
1412 struct radix_node *rn;
1413 struct sockaddr *saddr, *smask = 0;
1414 struct domain *dom;
1415 int error;
1416
1417 if (argp->ex_addrlen == 0) {
1418 if (mp->mnt_flag & MNT_DEFEXPORTED)
1419 return (EPERM);
1420 np = &nep->ne_defexported;
1421 np->netc_exflags = argp->ex_flags;
1422 np->netc_anon = argp->ex_anon;
1423 np->netc_anon.cr_ref = 1;
1424 mp->mnt_flag |= MNT_DEFEXPORTED;
1425 return (0);
1426 }
1427 if (argp->ex_addrlen > MLEN || argp->ex_masklen > MLEN ||
1428 argp->ex_addrlen < 0 || argp->ex_masklen < 0)
1429 return (EINVAL);
1430 i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen;
1431 np = (struct netcred *)malloc(i, M_NETADDR, M_WAITOK);
1432 bzero(np, i);
1433 saddr = (struct sockaddr *)(np + 1);
1434 error = copyin(argp->ex_addr, saddr, argp->ex_addrlen);
1435 if (error)
1436 goto out;
1437 if (saddr->sa_len > argp->ex_addrlen)
1438 saddr->sa_len = argp->ex_addrlen;
1439 if (argp->ex_masklen) {
1440 smask = (struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen);
1441 error = copyin(argp->ex_mask, smask, argp->ex_masklen);
1442 if (error)
1443 goto out;
1444 if (smask->sa_len > argp->ex_masklen)
1445 smask->sa_len = argp->ex_masklen;
1446 }
1447 i = saddr->sa_family;
1448 if (i < 0 || i > AF_MAX) {
1449 error = EINVAL;
1450 goto out;
1451 }
1452 if ((rnh = nep->ne_rtable[i]) == 0) {
1453
1454
1455
1456
1457 for (dom = domains; dom; dom = dom->dom_next)
1458 if (dom->dom_family == i && dom->dom_rtattach) {
1459 dom->dom_rtattach((void **)&nep->ne_rtable[i],
1460 dom->dom_rtoffset);
1461 break;
1462 }
1463 if ((rnh = nep->ne_rtable[i]) == 0) {
1464 error = ENOBUFS;
1465 goto out;
1466 }
1467 }
1468 rn = (*rnh->rnh_addaddr)((caddr_t)saddr, (caddr_t)smask, rnh,
1469 np->netc_rnodes);
1470 if (rn == 0 || np != (struct netcred *)rn) {
1471 error = EPERM;
1472 goto out;
1473 }
1474 np->netc_exflags = argp->ex_flags;
1475 np->netc_anon = argp->ex_anon;
1476 np->netc_anon.cr_ref = 1;
1477 return (0);
1478 out:
1479 free(np, M_NETADDR);
1480 return (error);
1481 }
1482
1483
1484 int
1485 vfs_free_netcred(struct radix_node *rn, void *w)
1486 {
1487 struct radix_node_head *rnh = (struct radix_node_head *)w;
1488
1489 (*rnh->rnh_deladdr)(rn->rn_key, rn->rn_mask, rnh, NULL);
1490 free(rn, M_NETADDR);
1491 return (0);
1492 }
1493
1494
1495
1496
1497 void
1498 vfs_free_addrlist(struct netexport *nep)
1499 {
1500 int i;
1501 struct radix_node_head *rnh;
1502
1503 for (i = 0; i <= AF_MAX; i++)
1504 if ((rnh = nep->ne_rtable[i]) != NULL) {
1505 (*rnh->rnh_walktree)(rnh, vfs_free_netcred, rnh);
1506 free(rnh, M_RTABLE);
1507 nep->ne_rtable[i] = 0;
1508 }
1509 }
1510
1511 int
1512 vfs_export(struct mount *mp, struct netexport *nep, struct export_args *argp)
1513 {
1514 int error;
1515
1516 if (argp->ex_flags & MNT_DELEXPORT) {
1517 vfs_free_addrlist(nep);
1518 mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED);
1519 }
1520 if (argp->ex_flags & MNT_EXPORTED) {
1521 if ((error = vfs_hang_addrlist(mp, nep, argp)) != 0)
1522 return (error);
1523 mp->mnt_flag |= MNT_EXPORTED;
1524 }
1525 return (0);
1526 }
1527
1528 struct netcred *
1529 vfs_export_lookup(struct mount *mp, struct netexport *nep, struct mbuf *nam)
1530 {
1531 struct netcred *np;
1532 struct radix_node_head *rnh;
1533 struct sockaddr *saddr;
1534
1535 np = NULL;
1536 if (mp->mnt_flag & MNT_EXPORTED) {
1537
1538
1539
1540 if (nam != NULL) {
1541 saddr = mtod(nam, struct sockaddr *);
1542 rnh = nep->ne_rtable[saddr->sa_family];
1543 if (rnh != NULL) {
1544 np = (struct netcred *)
1545 (*rnh->rnh_matchaddr)((caddr_t)saddr,
1546 rnh);
1547 if (np && np->netc_rnodes->rn_flags & RNF_ROOT)
1548 np = NULL;
1549 }
1550 }
1551
1552
1553
1554 if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED)
1555 np = &nep->ne_defexported;
1556 }
1557 return (np);
1558 }
1559
1560
1561
1562
1563
1564
1565 int
1566 vaccess(mode_t file_mode, uid_t uid, gid_t gid, mode_t acc_mode,
1567 struct ucred *cred)
1568 {
1569 mode_t mask;
1570
1571
1572 if (cred->cr_uid == 0)
1573 return 0;
1574
1575 mask = 0;
1576
1577
1578 if (cred->cr_uid == uid) {
1579 if (acc_mode & VEXEC)
1580 mask |= S_IXUSR;
1581 if (acc_mode & VREAD)
1582 mask |= S_IRUSR;
1583 if (acc_mode & VWRITE)
1584 mask |= S_IWUSR;
1585 return (file_mode & mask) == mask ? 0 : EACCES;
1586 }
1587
1588
1589 if (cred->cr_gid == gid || groupmember(gid, cred)) {
1590 if (acc_mode & VEXEC)
1591 mask |= S_IXGRP;
1592 if (acc_mode & VREAD)
1593 mask |= S_IRGRP;
1594 if (acc_mode & VWRITE)
1595 mask |= S_IWGRP;
1596 return (file_mode & mask) == mask ? 0 : EACCES;
1597 }
1598
1599
1600 if (acc_mode & VEXEC)
1601 mask |= S_IXOTH;
1602 if (acc_mode & VREAD)
1603 mask |= S_IROTH;
1604 if (acc_mode & VWRITE)
1605 mask |= S_IWOTH;
1606 return (file_mode & mask) == mask ? 0 : EACCES;
1607 }
1608
1609
1610
1611
1612
1613
1614 void
1615 vfs_unmountall(void)
1616 {
1617 struct mount *mp, *nmp;
1618 int allerror, error, again = 1;
1619
1620 retry:
1621 allerror = 0;
1622 for (mp = CIRCLEQ_LAST(&mountlist); mp != CIRCLEQ_END(&mountlist);
1623 mp = nmp) {
1624 nmp = CIRCLEQ_PREV(mp, mnt_list);
1625 if ((vfs_busy(mp, VB_WRITE|VB_NOWAIT)) != 0)
1626 continue;
1627 if ((error = dounmount(mp, MNT_FORCE, curproc, NULL)) != 0) {
1628 printf("unmount of %s failed with error %d\n",
1629 mp->mnt_stat.f_mntonname, error);
1630 allerror = 1;
1631 }
1632 }
1633
1634 if (allerror) {
1635 printf("WARNING: some file systems would not unmount\n");
1636 if (again) {
1637 printf("retrying\n");
1638 again = 0;
1639 goto retry;
1640 }
1641 }
1642 }
1643
1644
1645
1646
1647 void
1648 vfs_shutdown(void)
1649 {
1650 #ifdef ACCOUNTING
1651 extern void acct_shutdown(void);
1652
1653 acct_shutdown();
1654 #endif
1655
1656
1657 (void) spl0();
1658
1659 printf("syncing disks... ");
1660
1661 if (panicstr == 0) {
1662
1663 sys_sync(&proc0, (void *)0, (register_t *)0);
1664
1665
1666 vfs_unmountall();
1667 }
1668
1669 if (vfs_syncwait(1))
1670 printf("giving up\n");
1671 else
1672 printf("done\n");
1673 }
1674
1675
1676
1677
1678
1679
1680 int
1681 vfs_syncwait(int verbose)
1682 {
1683 struct buf *bp;
1684 int iter, nbusy, dcount, s;
1685 struct proc *p;
1686
1687 p = curproc? curproc : &proc0;
1688 sys_sync(p, (void *)0, (register_t *)0);
1689
1690
1691 dcount = 10000;
1692 for (iter = 0; iter < 20; iter++) {
1693 nbusy = 0;
1694 LIST_FOREACH(bp, &bufhead, b_list) {
1695 if ((bp->b_flags & (B_BUSY|B_INVAL|B_READ)) == B_BUSY)
1696 nbusy++;
1697
1698
1699
1700
1701
1702 if (bp->b_flags & B_DELWRI) {
1703 s = splbio();
1704 bremfree(bp);
1705 bp->b_flags |= B_BUSY;
1706 splx(s);
1707 nbusy++;
1708 bawrite(bp);
1709 if (dcount-- <= 0) {
1710 if (verbose)
1711 printf("softdep ");
1712 return 1;
1713 }
1714 }
1715 }
1716 if (nbusy == 0)
1717 break;
1718 if (verbose)
1719 printf("%d ", nbusy);
1720 DELAY(40000 * iter);
1721 }
1722
1723 return nbusy;
1724 }
1725
1726
1727
1728
1729 int
1730 fs_posix_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1731 void *newp, size_t newlen, struct proc *p)
1732 {
1733
1734 if (namelen != 1)
1735 return (ENOTDIR);
1736
1737 switch (name[0]) {
1738 case FS_POSIX_SETUID:
1739 if (newp && securelevel > 0)
1740 return (EPERM);
1741 return(sysctl_int(oldp, oldlenp, newp, newlen, &suid_clear));
1742 default:
1743 return (EOPNOTSUPP);
1744 }
1745
1746 }
1747
1748
1749
1750
1751 int
1752 fs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1753 size_t newlen, struct proc *p)
1754 {
1755 sysctlfn *fn;
1756
1757 switch (name[0]) {
1758 case FS_POSIX:
1759 fn = fs_posix_sysctl;
1760 break;
1761 default:
1762 return (EOPNOTSUPP);
1763 }
1764 return (*fn)(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, p);
1765 }
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777 int
1778 vwaitforio(struct vnode *vp, int slpflag, char *wmesg, int timeo)
1779 {
1780 int error = 0;
1781
1782 splassert(IPL_BIO);
1783
1784 while (vp->v_numoutput) {
1785 vp->v_bioflag |= VBIOWAIT;
1786 error = tsleep(&vp->v_numoutput,
1787 slpflag | (PRIBIO + 1), wmesg, timeo);
1788 if (error)
1789 break;
1790 }
1791
1792 return (error);
1793 }
1794
1795
1796
1797
1798
1799
1800 void
1801 vwakeup(struct vnode *vp)
1802 {
1803 splassert(IPL_BIO);
1804
1805 if (vp != NULL) {
1806 if (vp->v_numoutput-- == 0)
1807 panic("vwakeup: neg numoutput");
1808 if ((vp->v_bioflag & VBIOWAIT) && vp->v_numoutput == 0) {
1809 vp->v_bioflag &= ~VBIOWAIT;
1810 wakeup(&vp->v_numoutput);
1811 }
1812 }
1813 }
1814
1815
1816
1817
1818
1819 int
1820 vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, struct proc *p,
1821 int slpflag, int slptimeo)
1822 {
1823 struct buf *bp;
1824 struct buf *nbp, *blist;
1825 int s, error;
1826
1827 #ifdef VFSDEBUG
1828 if ((vp->v_flag & VLOCKSWORK) && !VOP_ISLOCKED(vp))
1829 panic("vinvalbuf(): vp isn't locked");
1830 #endif
1831
1832 if (flags & V_SAVE) {
1833 s = splbio();
1834 vwaitforio(vp, 0, "vinvalbuf", 0);
1835 if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
1836 splx(s);
1837 if ((error = VOP_FSYNC(vp, cred, MNT_WAIT, p)) != 0)
1838 return (error);
1839 s = splbio();
1840 if (vp->v_numoutput > 0 ||
1841 !LIST_EMPTY(&vp->v_dirtyblkhd))
1842 panic("vinvalbuf: dirty bufs");
1843 }
1844 splx(s);
1845 }
1846 loop:
1847 s = splbio();
1848 for (;;) {
1849 if ((blist = LIST_FIRST(&vp->v_cleanblkhd)) &&
1850 (flags & V_SAVEMETA))
1851 while (blist && blist->b_lblkno < 0)
1852 blist = LIST_NEXT(blist, b_vnbufs);
1853 if (blist == NULL &&
1854 (blist = LIST_FIRST(&vp->v_dirtyblkhd)) &&
1855 (flags & V_SAVEMETA))
1856 while (blist && blist->b_lblkno < 0)
1857 blist = LIST_NEXT(blist, b_vnbufs);
1858 if (!blist)
1859 break;
1860
1861 for (bp = blist; bp; bp = nbp) {
1862 nbp = LIST_NEXT(bp, b_vnbufs);
1863 if (flags & V_SAVEMETA && bp->b_lblkno < 0)
1864 continue;
1865 if (bp->b_flags & B_BUSY) {
1866 bp->b_flags |= B_WANTED;
1867 error = tsleep(bp, slpflag | (PRIBIO + 1),
1868 "vinvalbuf", slptimeo);
1869 if (error) {
1870 splx(s);
1871 return (error);
1872 }
1873 break;
1874 }
1875 bremfree(bp);
1876 bp->b_flags |= B_BUSY;
1877
1878
1879
1880
1881
1882 if ((bp->b_flags & B_DELWRI) && (flags & V_SAVE)) {
1883 splx(s);
1884 (void) VOP_BWRITE(bp);
1885 goto loop;
1886 }
1887 bp->b_flags |= B_INVAL;
1888 brelse(bp);
1889 }
1890 }
1891 if (!(flags & V_SAVEMETA) &&
1892 (!LIST_EMPTY(&vp->v_dirtyblkhd) || !LIST_EMPTY(&vp->v_cleanblkhd)))
1893 panic("vinvalbuf: flush failed");
1894 splx(s);
1895 return (0);
1896 }
1897
1898 void
1899 vflushbuf(struct vnode *vp, int sync)
1900 {
1901 struct buf *bp, *nbp;
1902 int s;
1903
1904 loop:
1905 s = splbio();
1906 for (bp = LIST_FIRST(&vp->v_dirtyblkhd);
1907 bp != LIST_END(&vp->v_dirtyblkhd); bp = nbp) {
1908 nbp = LIST_NEXT(bp, b_vnbufs);
1909 if ((bp->b_flags & B_BUSY))
1910 continue;
1911 if ((bp->b_flags & B_DELWRI) == 0)
1912 panic("vflushbuf: not dirty");
1913 bremfree(bp);
1914 bp->b_flags |= B_BUSY;
1915 splx(s);
1916
1917
1918
1919
1920 if (bp->b_vp == vp || sync == 0)
1921 (void) bawrite(bp);
1922 else
1923 (void) bwrite(bp);
1924 goto loop;
1925 }
1926 if (sync == 0) {
1927 splx(s);
1928 return;
1929 }
1930 vwaitforio(vp, 0, "vflushbuf", 0);
1931 if (!LIST_EMPTY(&vp->v_dirtyblkhd)) {
1932 splx(s);
1933 #ifdef DIAGNOSTIC
1934 vprint("vflushbuf: dirty", vp);
1935 #endif
1936 goto loop;
1937 }
1938 splx(s);
1939 }
1940
1941
1942
1943
1944
1945
1946 void
1947 bgetvp(struct vnode *vp, struct buf *bp)
1948 {
1949 splassert(IPL_BIO);
1950
1951
1952 if (bp->b_vp)
1953 panic("bgetvp: not free");
1954 vhold(vp);
1955 bp->b_vp = vp;
1956 if (vp->v_type == VBLK || vp->v_type == VCHR)
1957 bp->b_dev = vp->v_rdev;
1958 else
1959 bp->b_dev = NODEV;
1960
1961
1962
1963 bufinsvn(bp, &vp->v_cleanblkhd);
1964 }
1965
1966
1967
1968
1969
1970
1971 void
1972 brelvp(struct buf *bp)
1973 {
1974 struct vnode *vp;
1975
1976 splassert(IPL_BIO);
1977
1978 if ((vp = bp->b_vp) == (struct vnode *) 0)
1979 panic("brelvp: NULL");
1980
1981
1982
1983 if (LIST_NEXT(bp, b_vnbufs) != NOLIST)
1984 bufremvn(bp);
1985 if ((vp->v_bioflag & VBIOONSYNCLIST) &&
1986 LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
1987 vp->v_bioflag &= ~VBIOONSYNCLIST;
1988 LIST_REMOVE(vp, v_synclist);
1989 }
1990 bp->b_vp = (struct vnode *) 0;
1991
1992 #ifdef DIAGNOSTIC
1993 if (vp->v_holdcnt == 0)
1994 panic("brelvp: holdcnt");
1995 #endif
1996 vp->v_holdcnt--;
1997
1998
1999
2000
2001
2002 if ((vp->v_bioflag & VBIOONFREELIST) &&
2003 vp->v_holdcnt == 0 && vp->v_usecount == 0) {
2004 TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
2005 TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
2006 }
2007 }
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018 void
2019 buf_replacevnode(struct buf *bp, struct vnode *newvp)
2020 {
2021 struct vnode *oldvp = bp->b_vp;
2022
2023 splassert(IPL_BIO);
2024
2025 if (oldvp)
2026 brelvp(bp);
2027
2028 if ((bp->b_flags & (B_READ | B_DONE)) == 0) {
2029 newvp->v_numoutput++;
2030 vwakeup(oldvp);
2031 }
2032
2033 bgetvp(newvp, bp);
2034 bufremvn(bp);
2035 }
2036
2037
2038
2039
2040
2041
2042
2043
2044 void
2045 reassignbuf(struct buf *bp)
2046 {
2047 struct buflists *listheadp;
2048 int delay;
2049 struct vnode *vp = bp->b_vp;
2050
2051 splassert(IPL_BIO);
2052
2053
2054
2055
2056 if (LIST_NEXT(bp, b_vnbufs) != NOLIST)
2057 bufremvn(bp);
2058
2059
2060
2061
2062
2063 if ((bp->b_flags & B_DELWRI) == 0) {
2064 listheadp = &vp->v_cleanblkhd;
2065 if ((vp->v_bioflag & VBIOONSYNCLIST) &&
2066 LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
2067 vp->v_bioflag &= ~VBIOONSYNCLIST;
2068 LIST_REMOVE(vp, v_synclist);
2069 }
2070 } else {
2071 listheadp = &vp->v_dirtyblkhd;
2072 if ((vp->v_bioflag & VBIOONSYNCLIST) == 0) {
2073 switch (vp->v_type) {
2074 case VDIR:
2075 delay = syncdelay / 2;
2076 break;
2077 case VBLK:
2078 if (vp->v_specmountpoint != NULL) {
2079 delay = syncdelay / 3;
2080 break;
2081 }
2082
2083 default:
2084 delay = syncdelay;
2085 }
2086 vn_syncer_add_to_worklist(vp, delay);
2087 }
2088 }
2089 bufinsvn(bp, listheadp);
2090 }
2091
2092 int
2093 vfs_register(struct vfsconf *vfs)
2094 {
2095 struct vfsconf *vfsp;
2096 struct vfsconf **vfspp;
2097
2098 #ifdef DIAGNOSTIC
2099
2100 if (vfs->vfc_refcount != 0)
2101 printf("vfs_register called with vfc_refcount > 0\n");
2102 #endif
2103
2104
2105 for (vfspp = &vfsconf, vfsp = vfsconf; vfsp;
2106 vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next)
2107 if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0)
2108 return (EEXIST);
2109
2110 if (vfs->vfc_typenum > maxvfsconf)
2111 maxvfsconf = vfs->vfc_typenum;
2112
2113 vfs->vfc_next = NULL;
2114
2115
2116 *vfspp = vfs;
2117
2118
2119 if (vfs->vfc_vfsops->vfs_init)
2120 (*(vfs->vfc_vfsops->vfs_init))(vfs);
2121
2122 return 0;
2123 }
2124
2125 int
2126 vfs_unregister(struct vfsconf *vfs)
2127 {
2128 struct vfsconf *vfsp;
2129 struct vfsconf **vfspp;
2130 int maxtypenum;
2131
2132
2133 for (vfspp = &vfsconf, vfsp = vfsconf; vfsp;
2134 vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next) {
2135 if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0)
2136 break;
2137 }
2138
2139 if (!vfsp)
2140 return (ENOENT);
2141
2142 if (vfsp->vfc_refcount)
2143 return (EBUSY);
2144
2145
2146 *vfspp = vfsp->vfc_next;
2147
2148 maxtypenum = 0;
2149
2150 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
2151 if (vfsp->vfc_typenum > maxtypenum)
2152 maxtypenum = vfsp->vfc_typenum;
2153
2154 maxvfsconf = maxtypenum;
2155 return 0;
2156 }
2157
2158
2159
2160
2161 int
2162 vn_isdisk(struct vnode *vp, int *errp)
2163 {
2164 if (vp->v_type != VBLK && vp->v_type != VCHR)
2165 return (0);
2166
2167 return (1);
2168 }
2169
2170 #ifdef DDB
2171 #include <machine/db_machdep.h>
2172 #include <ddb/db_interface.h>
2173 #include <ddb/db_output.h>
2174
2175 void
2176 vfs_buf_print(struct buf *bp, int full, int (*pr)(const char *, ...))
2177 {
2178
2179 (*pr)(" vp %p lblkno 0x%llx blkno 0x%llx dev 0x%x\n"
2180 " proc %p error %d flags %b\n",
2181 bp->b_vp, (int64_t)bp->b_lblkno, (int64_t)bp->b_blkno, bp->b_dev,
2182 bp->b_proc, bp->b_error, bp->b_flags, B_BITS);
2183
2184 (*pr)(" bufsize 0x%lx bcount 0x%lx resid 0x%lx sync 0x%x\n"
2185 " data %p saveaddr %p dep %p iodone %p\n",
2186 bp->b_bufsize, bp->b_bcount, (long)bp->b_resid, bp->b_synctime,
2187 bp->b_data, bp->b_saveaddr, LIST_FIRST(&bp->b_dep), bp->b_iodone);
2188
2189 (*pr)(" dirty {off 0x%x end 0x%x} valid {off 0x%x end 0x%x}\n",
2190 bp->b_dirtyoff, bp->b_dirtyend, bp->b_validoff, bp->b_validend);
2191
2192 #ifdef FFS_SOFTUPDATES
2193 if (full)
2194 softdep_print(bp, full, pr);
2195 #endif
2196 }
2197
2198 const char *vtypes[] = { VTYPE_NAMES };
2199 const char *vtags[] = { VTAG_NAMES };
2200
2201 void
2202 vfs_vnode_print(struct vnode *vp, int full, int (*pr)(const char *, ...))
2203 {
2204
2205 #define NENTS(n) (sizeof n / sizeof(n[0]))
2206 (*pr)("tag %s(%d) type %s(%d) mount %p typedata %p\n",
2207 vp->v_tag > NENTS(vtags)? "<unk>":vtags[vp->v_tag], vp->v_tag,
2208 vp->v_type > NENTS(vtypes)? "<unk>":vtypes[vp->v_type],
2209 vp->v_type, vp->v_mount, vp->v_mountedhere);
2210
2211 (*pr)("data %p usecount %d writecount %ld holdcnt %ld numoutput %d\n",
2212 vp->v_data, vp->v_usecount, vp->v_writecount,
2213 vp->v_holdcnt, vp->v_numoutput);
2214
2215
2216
2217 if (full) {
2218 struct buf *bp;
2219
2220 (*pr)("clean bufs:\n");
2221 LIST_FOREACH(bp, &vp->v_cleanblkhd, b_vnbufs) {
2222 (*pr)(" bp %p\n", bp);
2223 vfs_buf_print(bp, full, pr);
2224 }
2225
2226 (*pr)("dirty bufs:\n");
2227 LIST_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) {
2228 (*pr)(" bp %p\n", bp);
2229 vfs_buf_print(bp, full, pr);
2230 }
2231 }
2232 }
2233
2234 void
2235 vfs_mount_print(struct mount *mp, int full, int (*pr)(const char *, ...))
2236 {
2237 struct vfsconf *vfc = mp->mnt_vfc;
2238 struct vnode *vp;
2239 int cnt = 0;
2240
2241 (*pr)("flags %b\nvnodecovered %p syncer %p data %p\n",
2242 mp->mnt_flag, MNT_BITS,
2243 mp->mnt_vnodecovered, mp->mnt_syncer, mp->mnt_data);
2244
2245 (*pr)("vfsconf: ops %p name \"%s\" num %d ref %d flags 0x%x\n",
2246 vfc->vfc_vfsops, vfc->vfc_name, vfc->vfc_typenum,
2247 vfc->vfc_refcount, vfc->vfc_flags);
2248
2249 (*pr)("statvfs cache: bsize %x iosize %x\nblocks %u free %u avail %u\n",
2250 mp->mnt_stat.f_bsize, mp->mnt_stat.f_iosize, mp->mnt_stat.f_blocks,
2251 mp->mnt_stat.f_bfree, mp->mnt_stat.f_bavail);
2252
2253 (*pr)(" files %u ffiles %u\n", mp->mnt_stat.f_files,
2254 mp->mnt_stat.f_ffree);
2255
2256 (*pr)(" f_fsidx {0x%x, 0x%x} owner %u ctime 0x%x\n",
2257 mp->mnt_stat.f_fsid.val[0], mp->mnt_stat.f_fsid.val[1],
2258 mp->mnt_stat.f_owner, mp->mnt_stat.f_ctime);
2259
2260 (*pr)(" syncwrites %lu asyncwrites = %lu\n",
2261 mp->mnt_stat.f_syncwrites, mp->mnt_stat.f_asyncwrites);
2262
2263 (*pr)(" fstype \"%s\" mnton \"%s\" mntfrom \"%s\"\n",
2264 mp->mnt_stat.f_fstypename, mp->mnt_stat.f_mntonname,
2265 mp->mnt_stat.f_mntfromname);
2266
2267 (*pr)("locked vnodes:");
2268
2269 LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes)
2270 if (VOP_ISLOCKED(vp)) {
2271 if (!LIST_NEXT(vp, v_mntvnodes))
2272 (*pr)(" %p", vp);
2273 else if (!(cnt++ % (72 / (sizeof(void *) * 2 + 4))))
2274 (*pr)("\n\t%p", vp);
2275 else
2276 (*pr)(", %p", vp);
2277 }
2278 (*pr)("\n");
2279
2280 if (full) {
2281 (*pr)("all vnodes:\n\t");
2282
2283 LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes)
2284 if (!LIST_NEXT(vp, v_mntvnodes))
2285 (*pr)(" %p", vp);
2286 else if (!(cnt++ % (72 / (sizeof(void *) * 2 + 4))))
2287 (*pr)(" %p,\n\t", vp);
2288 else
2289 (*pr)(" %p,", vp);
2290 (*pr)("\n", vp);
2291 }
2292 }
2293 #endif