Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/fs/devfs/devfs_vnops.c
39534 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2000-2004
5
* Poul-Henning Kamp. All rights reserved.
6
* Copyright (c) 1989, 1992-1993, 1995
7
* The Regents of the University of California. All rights reserved.
8
*
9
* This code is derived from software donated to Berkeley by
10
* Jan-Simon Pendry.
11
*
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
14
* are met:
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions and the following disclaimer.
17
* 2. Neither the name of the University nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
* From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43
33
*/
34
35
/*
36
* TODO:
37
* mkdir: want it ?
38
*/
39
40
#include <sys/param.h>
41
#include <sys/systm.h>
42
#include <sys/conf.h>
43
#include <sys/dirent.h>
44
#include <sys/eventhandler.h>
45
#include <sys/fcntl.h>
46
#include <sys/file.h>
47
#include <sys/filedesc.h>
48
#include <sys/filio.h>
49
#include <sys/jail.h>
50
#include <sys/kernel.h>
51
#include <sys/limits.h>
52
#include <sys/lock.h>
53
#include <sys/malloc.h>
54
#include <sys/mman.h>
55
#include <sys/mount.h>
56
#include <sys/namei.h>
57
#include <sys/priv.h>
58
#include <sys/proc.h>
59
#include <sys/stat.h>
60
#include <sys/sx.h>
61
#include <sys/sysctl.h>
62
#include <sys/time.h>
63
#include <sys/ttycom.h>
64
#include <sys/unistd.h>
65
#include <sys/vnode.h>
66
67
static struct vop_vector devfs_vnodeops;
68
static struct vop_vector devfs_specops;
69
static const struct fileops devfs_ops_f;
70
71
#include <fs/devfs/devfs.h>
72
#include <fs/devfs/devfs_int.h>
73
74
#include <security/mac/mac_framework.h>
75
76
#include <vm/vm.h>
77
#include <vm/vm_extern.h>
78
#include <vm/vm_object.h>
79
80
static MALLOC_DEFINE(M_CDEVPDATA, "DEVFSP", "Metainfo for cdev-fp data");
81
82
struct mtx devfs_de_interlock;
83
MTX_SYSINIT(devfs_de_interlock, &devfs_de_interlock, "devfs interlock", MTX_DEF);
84
struct mtx cdevpriv_mtx;
85
MTX_SYSINIT(cdevpriv_mtx, &cdevpriv_mtx, "cdevpriv lock", MTX_DEF);
86
87
SYSCTL_DECL(_vfs_devfs);
88
89
static int devfs_dotimes;
90
SYSCTL_INT(_vfs_devfs, OID_AUTO, dotimes, CTLFLAG_RW,
91
&devfs_dotimes, 0, "Update timestamps on DEVFS with default precision");
92
93
/*
94
* Update devfs node timestamp. Note that updates are unlocked and
95
* stat(2) could see partially updated times.
96
*/
97
static void
98
devfs_timestamp(struct timespec *tsp)
99
{
100
time_t ts;
101
102
if (devfs_dotimes) {
103
vfs_timestamp(tsp);
104
} else {
105
ts = time_second;
106
if (tsp->tv_sec != ts) {
107
tsp->tv_sec = ts;
108
tsp->tv_nsec = 0;
109
}
110
}
111
}
112
113
static int
114
devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp,
115
int *ref)
116
{
117
*dswp = devvn_refthread(fp->f_vnode, devp, ref);
118
if (*dswp == NULL || *devp != fp->f_data) {
119
if (*dswp != NULL)
120
dev_relthread(*devp, *ref);
121
return (ENXIO);
122
}
123
KASSERT((*devp)->si_refcount > 0,
124
("devfs: un-referenced struct cdev *(%s)", devtoname(*devp)));
125
if (*dswp == NULL)
126
return (ENXIO);
127
curthread->td_fpop = fp;
128
return (0);
129
}
130
131
int
132
devfs_get_cdevpriv(void **datap)
133
{
134
struct file *fp;
135
struct cdev_privdata *p;
136
int error;
137
138
fp = curthread->td_fpop;
139
if (fp == NULL)
140
return (EBADF);
141
p = fp->f_cdevpriv;
142
if (p != NULL) {
143
error = 0;
144
*datap = p->cdpd_data;
145
} else
146
error = ENOENT;
147
return (error);
148
}
149
150
int
151
devfs_set_cdevpriv(void *priv, d_priv_dtor_t *priv_dtr)
152
{
153
struct file *fp;
154
struct cdev_priv *cdp;
155
struct cdev_privdata *p;
156
int error;
157
158
fp = curthread->td_fpop;
159
if (fp == NULL)
160
return (ENOENT);
161
cdp = cdev2priv((struct cdev *)fp->f_data);
162
p = malloc(sizeof(struct cdev_privdata), M_CDEVPDATA, M_WAITOK);
163
p->cdpd_data = priv;
164
p->cdpd_dtr = priv_dtr;
165
p->cdpd_fp = fp;
166
mtx_lock(&cdevpriv_mtx);
167
if (fp->f_cdevpriv == NULL) {
168
LIST_INSERT_HEAD(&cdp->cdp_fdpriv, p, cdpd_list);
169
fp->f_cdevpriv = p;
170
mtx_unlock(&cdevpriv_mtx);
171
error = 0;
172
} else {
173
mtx_unlock(&cdevpriv_mtx);
174
free(p, M_CDEVPDATA);
175
error = EBUSY;
176
}
177
return (error);
178
}
179
180
int
181
devfs_foreach_cdevpriv(struct cdev *dev, int (*cb)(void *data, void *arg),
182
void *arg)
183
{
184
struct cdev_priv *cdp;
185
struct cdev_privdata *p;
186
int error;
187
188
cdp = cdev2priv(dev);
189
error = 0;
190
mtx_lock(&cdevpriv_mtx);
191
LIST_FOREACH(p, &cdp->cdp_fdpriv, cdpd_list) {
192
error = cb(p->cdpd_data, arg);
193
if (error != 0)
194
break;
195
}
196
mtx_unlock(&cdevpriv_mtx);
197
return (error);
198
}
199
200
void
201
devfs_destroy_cdevpriv(struct cdev_privdata *p)
202
{
203
204
mtx_assert(&cdevpriv_mtx, MA_OWNED);
205
KASSERT(p->cdpd_fp->f_cdevpriv == p,
206
("devfs_destoy_cdevpriv %p != %p", p->cdpd_fp->f_cdevpriv, p));
207
p->cdpd_fp->f_cdevpriv = NULL;
208
LIST_REMOVE(p, cdpd_list);
209
mtx_unlock(&cdevpriv_mtx);
210
(p->cdpd_dtr)(p->cdpd_data);
211
free(p, M_CDEVPDATA);
212
}
213
214
static void
215
devfs_fpdrop(struct file *fp)
216
{
217
struct cdev_privdata *p;
218
219
mtx_lock(&cdevpriv_mtx);
220
if ((p = fp->f_cdevpriv) == NULL) {
221
mtx_unlock(&cdevpriv_mtx);
222
return;
223
}
224
devfs_destroy_cdevpriv(p);
225
}
226
227
void
228
devfs_clear_cdevpriv(void)
229
{
230
struct file *fp;
231
232
fp = curthread->td_fpop;
233
if (fp == NULL)
234
return;
235
devfs_fpdrop(fp);
236
}
237
238
static void
239
devfs_usecount_add(struct vnode *vp)
240
{
241
struct devfs_dirent *de;
242
struct cdev *dev;
243
244
mtx_lock(&devfs_de_interlock);
245
VI_LOCK(vp);
246
VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp);
247
if (VN_IS_DOOMED(vp)) {
248
goto out_unlock;
249
}
250
251
de = vp->v_data;
252
dev = vp->v_rdev;
253
MPASS(de != NULL);
254
MPASS(dev != NULL);
255
dev->si_usecount++;
256
de->de_usecount++;
257
out_unlock:
258
VI_UNLOCK(vp);
259
mtx_unlock(&devfs_de_interlock);
260
}
261
262
static void
263
devfs_usecount_subl(struct vnode *vp)
264
{
265
struct devfs_dirent *de;
266
struct cdev *dev;
267
268
mtx_assert(&devfs_de_interlock, MA_OWNED);
269
ASSERT_VI_LOCKED(vp, __func__);
270
VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp);
271
272
de = vp->v_data;
273
dev = vp->v_rdev;
274
if (de == NULL)
275
return;
276
if (dev == NULL) {
277
MPASS(de->de_usecount == 0);
278
return;
279
}
280
if (dev->si_usecount < de->de_usecount)
281
panic("%s: si_usecount underflow for dev %p "
282
"(has %ld, dirent has %d)\n",
283
__func__, dev, dev->si_usecount, de->de_usecount);
284
if (VN_IS_DOOMED(vp)) {
285
dev->si_usecount -= de->de_usecount;
286
de->de_usecount = 0;
287
} else {
288
if (de->de_usecount == 0)
289
panic("%s: de_usecount underflow for dev %p\n",
290
__func__, dev);
291
dev->si_usecount--;
292
de->de_usecount--;
293
}
294
}
295
296
static void
297
devfs_usecount_sub(struct vnode *vp)
298
{
299
300
mtx_lock(&devfs_de_interlock);
301
VI_LOCK(vp);
302
devfs_usecount_subl(vp);
303
VI_UNLOCK(vp);
304
mtx_unlock(&devfs_de_interlock);
305
}
306
307
static int
308
devfs_usecountl(struct vnode *vp)
309
{
310
311
VNPASS(vp->v_type == VCHR, vp);
312
mtx_assert(&devfs_de_interlock, MA_OWNED);
313
ASSERT_VI_LOCKED(vp, __func__);
314
return (vp->v_rdev->si_usecount);
315
}
316
317
int
318
devfs_usecount(struct vnode *vp)
319
{
320
int count;
321
322
VNPASS(vp->v_type == VCHR, vp);
323
mtx_lock(&devfs_de_interlock);
324
VI_LOCK(vp);
325
count = devfs_usecountl(vp);
326
VI_UNLOCK(vp);
327
mtx_unlock(&devfs_de_interlock);
328
return (count);
329
}
330
331
void
332
devfs_ctty_ref(struct vnode *vp)
333
{
334
335
vrefact(vp);
336
devfs_usecount_add(vp);
337
}
338
339
void
340
devfs_ctty_unref(struct vnode *vp)
341
{
342
343
devfs_usecount_sub(vp);
344
vrele(vp);
345
}
346
347
/*
348
* On success devfs_populate_vp() returns with dmp->dm_lock held.
349
*/
350
static int
351
devfs_populate_vp(struct vnode *vp)
352
{
353
struct devfs_dirent *de;
354
struct devfs_mount *dmp;
355
int locked;
356
357
ASSERT_VOP_LOCKED(vp, "devfs_populate_vp");
358
359
dmp = VFSTODEVFS(vp->v_mount);
360
if (!devfs_populate_needed(dmp)) {
361
sx_xlock(&dmp->dm_lock);
362
goto out_nopopulate;
363
}
364
365
locked = VOP_ISLOCKED(vp);
366
367
sx_xlock(&dmp->dm_lock);
368
DEVFS_DMP_HOLD(dmp);
369
370
/* Can't call devfs_populate() with the vnode lock held. */
371
VOP_UNLOCK(vp);
372
devfs_populate(dmp);
373
374
sx_xunlock(&dmp->dm_lock);
375
vn_lock(vp, locked | LK_RETRY);
376
sx_xlock(&dmp->dm_lock);
377
if (DEVFS_DMP_DROP(dmp)) {
378
sx_xunlock(&dmp->dm_lock);
379
devfs_unmount_final(dmp);
380
return (ERESTART);
381
}
382
out_nopopulate:
383
if (VN_IS_DOOMED(vp)) {
384
sx_xunlock(&dmp->dm_lock);
385
return (ERESTART);
386
}
387
de = vp->v_data;
388
KASSERT(de != NULL,
389
("devfs_populate_vp: vp->v_data == NULL but vnode not doomed"));
390
if ((de->de_flags & DE_DOOMED) != 0) {
391
sx_xunlock(&dmp->dm_lock);
392
return (ERESTART);
393
}
394
395
return (0);
396
}
397
398
static int
399
devfs_vptocnp(struct vop_vptocnp_args *ap)
400
{
401
struct vnode *vp = ap->a_vp;
402
struct vnode **dvp = ap->a_vpp;
403
struct devfs_mount *dmp;
404
char *buf = ap->a_buf;
405
size_t *buflen = ap->a_buflen;
406
struct devfs_dirent *dd, *de;
407
int i, error;
408
409
dmp = VFSTODEVFS(vp->v_mount);
410
411
error = devfs_populate_vp(vp);
412
if (error != 0)
413
return (error);
414
415
if (vp->v_type != VCHR && vp->v_type != VDIR) {
416
error = ENOENT;
417
goto finished;
418
}
419
420
dd = vp->v_data;
421
if (vp->v_type == VDIR && dd == dmp->dm_rootdir) {
422
*dvp = vp;
423
vref(*dvp);
424
goto finished;
425
}
426
427
i = *buflen;
428
i -= dd->de_dirent->d_namlen;
429
if (i < 0) {
430
error = ENOMEM;
431
goto finished;
432
}
433
bcopy(dd->de_dirent->d_name, buf + i, dd->de_dirent->d_namlen);
434
*buflen = i;
435
de = devfs_parent_dirent(dd);
436
if (de == NULL) {
437
error = ENOENT;
438
goto finished;
439
}
440
mtx_lock(&devfs_de_interlock);
441
*dvp = de->de_vnode;
442
if (*dvp != NULL) {
443
VI_LOCK(*dvp);
444
mtx_unlock(&devfs_de_interlock);
445
vholdl(*dvp);
446
VI_UNLOCK(*dvp);
447
vref(*dvp);
448
vdrop(*dvp);
449
} else {
450
mtx_unlock(&devfs_de_interlock);
451
error = ENOENT;
452
}
453
finished:
454
sx_xunlock(&dmp->dm_lock);
455
return (error);
456
}
457
458
/*
459
* Construct the fully qualified path name relative to the mountpoint.
460
* If a NULL cnp is provided, no '/' is appended to the resulting path.
461
*/
462
char *
463
devfs_fqpn(char *buf, struct devfs_mount *dmp, struct devfs_dirent *dd,
464
struct componentname *cnp)
465
{
466
int i;
467
struct devfs_dirent *de;
468
469
sx_assert(&dmp->dm_lock, SA_LOCKED);
470
471
i = SPECNAMELEN;
472
buf[i] = '\0';
473
if (cnp != NULL)
474
i -= cnp->cn_namelen;
475
if (i < 0)
476
return (NULL);
477
if (cnp != NULL)
478
bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen);
479
de = dd;
480
while (de != dmp->dm_rootdir) {
481
if (cnp != NULL || i < SPECNAMELEN) {
482
i--;
483
if (i < 0)
484
return (NULL);
485
buf[i] = '/';
486
}
487
i -= de->de_dirent->d_namlen;
488
if (i < 0)
489
return (NULL);
490
bcopy(de->de_dirent->d_name, buf + i,
491
de->de_dirent->d_namlen);
492
de = devfs_parent_dirent(de);
493
if (de == NULL)
494
return (NULL);
495
}
496
return (buf + i);
497
}
498
499
static int
500
devfs_allocv_drop_refs(int drop_dm_lock, struct devfs_mount *dmp,
501
struct devfs_dirent *de)
502
{
503
int not_found;
504
505
not_found = 0;
506
if (de->de_flags & DE_DOOMED)
507
not_found = 1;
508
if (DEVFS_DE_DROP(de)) {
509
KASSERT(not_found == 1, ("DEVFS de dropped but not doomed"));
510
devfs_dirent_free(de);
511
}
512
if (DEVFS_DMP_DROP(dmp)) {
513
KASSERT(not_found == 1,
514
("DEVFS mount struct freed before dirent"));
515
not_found = 2;
516
sx_xunlock(&dmp->dm_lock);
517
devfs_unmount_final(dmp);
518
}
519
if (not_found == 1 || (drop_dm_lock && not_found != 2))
520
sx_unlock(&dmp->dm_lock);
521
return (not_found);
522
}
523
524
/*
525
* devfs_allocv shall be entered with dmp->dm_lock held, and it drops
526
* it on return.
527
*/
528
int
529
devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode,
530
struct vnode **vpp)
531
{
532
int error;
533
struct vnode *vp;
534
struct cdev *dev;
535
struct devfs_mount *dmp;
536
struct cdevsw *dsw;
537
enum vgetstate vs;
538
539
dmp = VFSTODEVFS(mp);
540
if (de->de_flags & DE_DOOMED) {
541
sx_xunlock(&dmp->dm_lock);
542
return (ENOENT);
543
}
544
loop:
545
DEVFS_DE_HOLD(de);
546
DEVFS_DMP_HOLD(dmp);
547
mtx_lock(&devfs_de_interlock);
548
vp = de->de_vnode;
549
if (vp != NULL) {
550
vs = vget_prep(vp);
551
mtx_unlock(&devfs_de_interlock);
552
sx_xunlock(&dmp->dm_lock);
553
vget_finish(vp, lockmode | LK_RETRY, vs);
554
sx_xlock(&dmp->dm_lock);
555
if (devfs_allocv_drop_refs(0, dmp, de)) {
556
vput(vp);
557
return (ENOENT);
558
} else if (VN_IS_DOOMED(vp)) {
559
mtx_lock(&devfs_de_interlock);
560
if (de->de_vnode == vp) {
561
de->de_vnode = NULL;
562
vp->v_data = NULL;
563
}
564
mtx_unlock(&devfs_de_interlock);
565
vput(vp);
566
goto loop;
567
}
568
sx_xunlock(&dmp->dm_lock);
569
*vpp = vp;
570
return (0);
571
}
572
mtx_unlock(&devfs_de_interlock);
573
if (de->de_dirent->d_type == DT_CHR) {
574
if (!(de->de_cdp->cdp_flags & CDP_ACTIVE)) {
575
devfs_allocv_drop_refs(1, dmp, de);
576
return (ENOENT);
577
}
578
dev = &de->de_cdp->cdp_c;
579
} else {
580
dev = NULL;
581
}
582
error = getnewvnode("devfs", mp, &devfs_vnodeops, &vp);
583
if (error != 0) {
584
devfs_allocv_drop_refs(1, dmp, de);
585
printf("devfs_allocv: failed to allocate new vnode\n");
586
return (error);
587
}
588
589
if (de->de_dirent->d_type == DT_CHR) {
590
vp->v_type = VCHR;
591
VI_LOCK(vp);
592
dev_lock();
593
dev_refl(dev);
594
/* XXX: v_rdev should be protect by vnode lock */
595
vp->v_rdev = dev;
596
VNPASS(vp->v_usecount == 1, vp);
597
/* Special casing of ttys for deadfs. Probably redundant. */
598
dsw = dev->si_devsw;
599
if (dsw != NULL && (dsw->d_flags & D_TTY) != 0)
600
vp->v_vflag |= VV_ISTTY;
601
dev_unlock();
602
VI_UNLOCK(vp);
603
if ((dev->si_flags & SI_ETERNAL) != 0)
604
vp->v_vflag |= VV_ETERNALDEV;
605
vp->v_op = &devfs_specops;
606
} else if (de->de_dirent->d_type == DT_DIR) {
607
vp->v_type = VDIR;
608
} else if (de->de_dirent->d_type == DT_LNK) {
609
vp->v_type = VLNK;
610
} else {
611
vp->v_type = VBAD;
612
}
613
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOWITNESS);
614
VN_LOCK_ASHARE(vp);
615
mtx_lock(&devfs_de_interlock);
616
vp->v_data = de;
617
de->de_vnode = vp;
618
mtx_unlock(&devfs_de_interlock);
619
error = insmntque1(vp, mp);
620
if (error != 0) {
621
mtx_lock(&devfs_de_interlock);
622
vp->v_data = NULL;
623
de->de_vnode = NULL;
624
mtx_unlock(&devfs_de_interlock);
625
vgone(vp);
626
vput(vp);
627
(void) devfs_allocv_drop_refs(1, dmp, de);
628
return (error);
629
}
630
if (devfs_allocv_drop_refs(0, dmp, de)) {
631
vgone(vp);
632
vput(vp);
633
return (ENOENT);
634
}
635
#ifdef MAC
636
mac_devfs_vnode_associate(mp, de, vp);
637
#endif
638
sx_xunlock(&dmp->dm_lock);
639
vn_set_state(vp, VSTATE_CONSTRUCTED);
640
*vpp = vp;
641
return (0);
642
}
643
644
static int
645
devfs_access(struct vop_access_args *ap)
646
{
647
struct vnode *vp = ap->a_vp;
648
struct devfs_dirent *de;
649
struct proc *p;
650
int error;
651
652
de = vp->v_data;
653
if (vp->v_type == VDIR)
654
de = de->de_dir;
655
656
error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
657
ap->a_accmode, ap->a_cred);
658
if (error == 0)
659
return (0);
660
if (error != EACCES)
661
return (error);
662
p = ap->a_td->td_proc;
663
/* We do, however, allow access to the controlling terminal */
664
PROC_LOCK(p);
665
if (!(p->p_flag & P_CONTROLT)) {
666
PROC_UNLOCK(p);
667
return (error);
668
}
669
if (p->p_session->s_ttydp == de->de_cdp)
670
error = 0;
671
PROC_UNLOCK(p);
672
return (error);
673
}
674
675
_Static_assert(((FMASK | FCNTLFLAGS) & (FLASTCLOSE | FREVOKE)) == 0,
676
"devfs-only flag reuse failed");
677
678
static int
679
devfs_close(struct vop_close_args *ap)
680
{
681
struct vnode *vp = ap->a_vp, *oldvp;
682
struct thread *td = ap->a_td;
683
struct proc *p;
684
struct cdev *dev = vp->v_rdev;
685
struct cdevsw *dsw;
686
struct devfs_dirent *de = vp->v_data;
687
int dflags, error, ref, vp_locked;
688
689
/*
690
* XXX: Don't call d_close() if we were called because of
691
* XXX: insmntque() failure.
692
*/
693
if (vp->v_data == NULL)
694
return (0);
695
696
/*
697
* Hack: a tty device that is a controlling terminal
698
* has a reference from the session structure.
699
* We cannot easily tell that a character device is
700
* a controlling terminal, unless it is the closing
701
* process' controlling terminal. In that case,
702
* if the reference count is 2 (this last descriptor
703
* plus the session), release the reference from the session.
704
*/
705
if (de->de_usecount == 2 && td != NULL) {
706
p = td->td_proc;
707
PROC_LOCK(p);
708
if (vp == p->p_session->s_ttyvp) {
709
PROC_UNLOCK(p);
710
oldvp = NULL;
711
sx_xlock(&proctree_lock);
712
if (vp == p->p_session->s_ttyvp) {
713
SESS_LOCK(p->p_session);
714
mtx_lock(&devfs_de_interlock);
715
VI_LOCK(vp);
716
if (devfs_usecountl(vp) == 2 && !VN_IS_DOOMED(vp)) {
717
p->p_session->s_ttyvp = NULL;
718
p->p_session->s_ttydp = NULL;
719
oldvp = vp;
720
}
721
VI_UNLOCK(vp);
722
mtx_unlock(&devfs_de_interlock);
723
SESS_UNLOCK(p->p_session);
724
}
725
sx_xunlock(&proctree_lock);
726
if (oldvp != NULL)
727
devfs_ctty_unref(oldvp);
728
} else
729
PROC_UNLOCK(p);
730
}
731
/*
732
* We do not want to really close the device if it
733
* is still in use unless we are trying to close it
734
* forcibly. Since every use (buffer, vnode, swap, cmap)
735
* holds a reference to the vnode, and because we mark
736
* any other vnodes that alias this device, when the
737
* sum of the reference counts on all the aliased
738
* vnodes descends to one, we are on last close.
739
*/
740
dsw = dev_refthread(dev, &ref);
741
if (dsw == NULL)
742
return (ENXIO);
743
dflags = 0;
744
mtx_lock(&devfs_de_interlock);
745
VI_LOCK(vp);
746
if (devfs_usecountl(vp) == 1)
747
dflags |= FLASTCLOSE;
748
devfs_usecount_subl(vp);
749
mtx_unlock(&devfs_de_interlock);
750
if (VN_IS_DOOMED(vp)) {
751
/* Forced close. */
752
dflags |= FREVOKE | FNONBLOCK;
753
} else if (dsw->d_flags & D_TRACKCLOSE) {
754
/* Keep device updated on status. */
755
} else if ((dflags & FLASTCLOSE) == 0) {
756
VI_UNLOCK(vp);
757
dev_relthread(dev, ref);
758
return (0);
759
}
760
vholdnz(vp);
761
VI_UNLOCK(vp);
762
vp_locked = VOP_ISLOCKED(vp);
763
VOP_UNLOCK(vp);
764
KASSERT(dev->si_refcount > 0,
765
("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
766
error = dsw->d_close(dev, ap->a_fflag | dflags, S_IFCHR, td);
767
dev_relthread(dev, ref);
768
vn_lock(vp, vp_locked | LK_RETRY);
769
vdrop(vp);
770
return (error);
771
}
772
773
static int
774
devfs_close_f(struct file *fp, struct thread *td)
775
{
776
int error;
777
struct file *fpop;
778
779
/*
780
* NB: td may be NULL if this descriptor is closed due to
781
* garbage collection from a closed UNIX domain socket.
782
*/
783
fpop = curthread->td_fpop;
784
curthread->td_fpop = fp;
785
error = vnops.fo_close(fp, td);
786
curthread->td_fpop = fpop;
787
788
/*
789
* The f_cdevpriv cannot be assigned non-NULL value while we
790
* are destroying the file.
791
*/
792
if (fp->f_cdevpriv != NULL)
793
devfs_fpdrop(fp);
794
return (error);
795
}
796
797
static int
798
devfs_getattr(struct vop_getattr_args *ap)
799
{
800
struct vnode *vp = ap->a_vp;
801
struct vattr *vap = ap->a_vap;
802
struct devfs_dirent *de;
803
struct devfs_mount *dmp;
804
struct cdev *dev;
805
struct timeval boottime;
806
int error;
807
808
error = devfs_populate_vp(vp);
809
if (error != 0)
810
return (error);
811
812
dmp = VFSTODEVFS(vp->v_mount);
813
sx_xunlock(&dmp->dm_lock);
814
815
de = vp->v_data;
816
KASSERT(de != NULL, ("Null dirent in devfs_getattr vp=%p", vp));
817
if (vp->v_type == VDIR) {
818
de = de->de_dir;
819
KASSERT(de != NULL,
820
("Null dir dirent in devfs_getattr vp=%p", vp));
821
}
822
vap->va_uid = de->de_uid;
823
vap->va_gid = de->de_gid;
824
vap->va_mode = de->de_mode;
825
if (vp->v_type == VLNK)
826
vap->va_size = strlen(de->de_symlink);
827
else if (vp->v_type == VDIR)
828
vap->va_size = vap->va_bytes = DEV_BSIZE;
829
else
830
vap->va_size = 0;
831
if (vp->v_type != VDIR)
832
vap->va_bytes = 0;
833
vap->va_blocksize = DEV_BSIZE;
834
vap->va_type = vp->v_type;
835
836
getboottime(&boottime);
837
#define fix(aa) \
838
do { \
839
if ((aa).tv_sec <= 3600) { \
840
(aa).tv_sec = boottime.tv_sec; \
841
(aa).tv_nsec = boottime.tv_usec * 1000; \
842
} \
843
} while (0)
844
845
if (vp->v_type != VCHR) {
846
fix(de->de_atime);
847
vap->va_atime = de->de_atime;
848
fix(de->de_mtime);
849
vap->va_mtime = de->de_mtime;
850
fix(de->de_ctime);
851
vap->va_ctime = de->de_ctime;
852
} else {
853
dev = vp->v_rdev;
854
fix(dev->si_atime);
855
vap->va_atime = dev->si_atime;
856
fix(dev->si_mtime);
857
vap->va_mtime = dev->si_mtime;
858
fix(dev->si_ctime);
859
vap->va_ctime = dev->si_ctime;
860
861
vap->va_rdev = cdev2priv(dev)->cdp_inode;
862
}
863
vap->va_gen = 0;
864
vap->va_flags = 0;
865
vap->va_filerev = 0;
866
vap->va_nlink = de->de_links;
867
vap->va_fileid = de->de_inode;
868
869
return (error);
870
}
871
872
/* ARGSUSED */
873
static int
874
devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td)
875
{
876
struct file *fpop;
877
int error;
878
879
fpop = td->td_fpop;
880
td->td_fpop = fp;
881
error = vnops.fo_ioctl(fp, com, data, cred, td);
882
td->td_fpop = fpop;
883
return (error);
884
}
885
886
void *
887
fiodgname_buf_get_ptr(void *fgnp, u_long com)
888
{
889
union {
890
struct fiodgname_arg fgn;
891
#ifdef COMPAT_FREEBSD32
892
struct fiodgname_arg32 fgn32;
893
#endif
894
} *fgnup;
895
896
fgnup = fgnp;
897
switch (com) {
898
case FIODGNAME:
899
return (fgnup->fgn.buf);
900
#ifdef COMPAT_FREEBSD32
901
case FIODGNAME_32:
902
return ((void *)(uintptr_t)fgnup->fgn32.buf);
903
#endif
904
default:
905
panic("Unhandled ioctl command %ld", com);
906
}
907
}
908
909
static int
910
devfs_ioctl(struct vop_ioctl_args *ap)
911
{
912
struct fiodgname_arg *fgn;
913
struct vnode *vpold, *vp;
914
struct cdevsw *dsw;
915
struct thread *td;
916
struct session *sess;
917
struct cdev *dev;
918
int error, ref, i;
919
const char *p;
920
u_long com;
921
922
vp = ap->a_vp;
923
com = ap->a_command;
924
td = ap->a_td;
925
926
dsw = devvn_refthread(vp, &dev, &ref);
927
if (dsw == NULL)
928
return (ENXIO);
929
KASSERT(dev->si_refcount > 0,
930
("devfs: un-referenced struct cdev *(%s)", devtoname(dev)));
931
932
switch (com) {
933
case FIODTYPE:
934
*(int *)ap->a_data = dsw->d_flags & D_TYPEMASK;
935
error = 0;
936
break;
937
case FIODGNAME:
938
#ifdef COMPAT_FREEBSD32
939
case FIODGNAME_32:
940
#endif
941
fgn = ap->a_data;
942
p = devtoname(dev);
943
i = strlen(p) + 1;
944
if (i > fgn->len)
945
error = EINVAL;
946
else
947
error = copyout(p, fiodgname_buf_get_ptr(fgn, com), i);
948
break;
949
default:
950
error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td);
951
}
952
953
dev_relthread(dev, ref);
954
if (error == ENOIOCTL)
955
error = ENOTTY;
956
957
if (error == 0 && com == TIOCSCTTY) {
958
/*
959
* Do nothing if reassigning same control tty, or if the
960
* control tty has already disappeared. If it disappeared,
961
* it's because we were racing with TIOCNOTTY. TIOCNOTTY
962
* already took care of releasing the old vnode and we have
963
* nothing left to do.
964
*/
965
sx_slock(&proctree_lock);
966
sess = td->td_proc->p_session;
967
if (sess->s_ttyvp == vp || sess->s_ttyp == NULL) {
968
sx_sunlock(&proctree_lock);
969
return (0);
970
}
971
972
devfs_ctty_ref(vp);
973
SESS_LOCK(sess);
974
vpold = sess->s_ttyvp;
975
sess->s_ttyvp = vp;
976
sess->s_ttydp = cdev2priv(dev);
977
SESS_UNLOCK(sess);
978
979
sx_sunlock(&proctree_lock);
980
981
/* Get rid of reference to old control tty */
982
if (vpold)
983
devfs_ctty_unref(vpold);
984
}
985
return (error);
986
}
987
988
/* ARGSUSED */
989
static int
990
devfs_kqfilter_f(struct file *fp, struct knote *kn)
991
{
992
struct cdev *dev;
993
struct cdevsw *dsw;
994
int error, ref;
995
struct file *fpop;
996
struct thread *td;
997
998
td = curthread;
999
fpop = td->td_fpop;
1000
error = devfs_fp_check(fp, &dev, &dsw, &ref);
1001
if (error)
1002
return (error);
1003
error = dsw->d_kqfilter(dev, kn);
1004
td->td_fpop = fpop;
1005
dev_relthread(dev, ref);
1006
return (error);
1007
}
1008
1009
static inline int
1010
devfs_prison_check(struct devfs_dirent *de, struct thread *td)
1011
{
1012
struct cdev_priv *cdp;
1013
struct ucred *dcr;
1014
struct proc *p;
1015
int error;
1016
1017
cdp = de->de_cdp;
1018
if (cdp == NULL)
1019
return (0);
1020
dcr = cdp->cdp_c.si_cred;
1021
if (dcr == NULL)
1022
return (0);
1023
1024
error = prison_check(td->td_ucred, dcr);
1025
if (error == 0)
1026
return (0);
1027
/* We do, however, allow access to the controlling terminal */
1028
p = td->td_proc;
1029
PROC_LOCK(p);
1030
if (!(p->p_flag & P_CONTROLT)) {
1031
PROC_UNLOCK(p);
1032
return (error);
1033
}
1034
if (p->p_session->s_ttydp == cdp)
1035
error = 0;
1036
PROC_UNLOCK(p);
1037
return (error);
1038
}
1039
1040
static int
1041
devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
1042
{
1043
struct componentname *cnp;
1044
struct vnode *dvp, **vpp;
1045
struct thread *td;
1046
struct devfs_dirent *de, *dd;
1047
struct devfs_dirent **dde;
1048
struct devfs_mount *dmp;
1049
struct mount *mp;
1050
struct cdev *cdev;
1051
int error, flags, nameiop, dvplocked;
1052
char specname[SPECNAMELEN + 1], *pname;
1053
1054
td = curthread;
1055
cnp = ap->a_cnp;
1056
vpp = ap->a_vpp;
1057
dvp = ap->a_dvp;
1058
pname = cnp->cn_nameptr;
1059
flags = cnp->cn_flags;
1060
nameiop = cnp->cn_nameiop;
1061
mp = dvp->v_mount;
1062
dmp = VFSTODEVFS(mp);
1063
dd = dvp->v_data;
1064
*vpp = NULL;
1065
1066
if ((flags & ISLASTCN) && nameiop == RENAME)
1067
return (EOPNOTSUPP);
1068
1069
if (dvp->v_type != VDIR)
1070
return (ENOTDIR);
1071
1072
if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT))
1073
return (EIO);
1074
1075
error = vn_dir_check_exec(dvp, cnp);
1076
if (error != 0)
1077
return (error);
1078
1079
if (cnp->cn_namelen == 1 && *pname == '.') {
1080
if ((flags & ISLASTCN) && nameiop != LOOKUP)
1081
return (EINVAL);
1082
*vpp = dvp;
1083
vref(dvp);
1084
return (0);
1085
}
1086
1087
if (flags & ISDOTDOT) {
1088
if ((flags & ISLASTCN) && nameiop != LOOKUP)
1089
return (EINVAL);
1090
de = devfs_parent_dirent(dd);
1091
if (de == NULL)
1092
return (ENOENT);
1093
dvplocked = VOP_ISLOCKED(dvp);
1094
VOP_UNLOCK(dvp);
1095
error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK,
1096
vpp);
1097
*dm_unlock = 0;
1098
vn_lock(dvp, dvplocked | LK_RETRY);
1099
return (error);
1100
}
1101
1102
dd = dvp->v_data;
1103
de = devfs_find(dd, cnp->cn_nameptr, cnp->cn_namelen, 0);
1104
while (de == NULL) { /* While(...) so we can use break */
1105
1106
if (nameiop == DELETE)
1107
return (ENOENT);
1108
1109
/*
1110
* OK, we didn't have an entry for the name we were asked for
1111
* so we try to see if anybody can create it on demand.
1112
*/
1113
pname = devfs_fqpn(specname, dmp, dd, cnp);
1114
if (pname == NULL)
1115
break;
1116
1117
cdev = NULL;
1118
DEVFS_DMP_HOLD(dmp);
1119
sx_xunlock(&dmp->dm_lock);
1120
EVENTHANDLER_INVOKE(dev_clone,
1121
td->td_ucred, pname, strlen(pname), &cdev);
1122
1123
if (cdev == NULL)
1124
sx_xlock(&dmp->dm_lock);
1125
else if (devfs_populate_vp(dvp) != 0) {
1126
*dm_unlock = 0;
1127
sx_xlock(&dmp->dm_lock);
1128
if (DEVFS_DMP_DROP(dmp)) {
1129
sx_xunlock(&dmp->dm_lock);
1130
devfs_unmount_final(dmp);
1131
} else
1132
sx_xunlock(&dmp->dm_lock);
1133
dev_rel(cdev);
1134
return (ENOENT);
1135
}
1136
if (DEVFS_DMP_DROP(dmp)) {
1137
*dm_unlock = 0;
1138
sx_xunlock(&dmp->dm_lock);
1139
devfs_unmount_final(dmp);
1140
if (cdev != NULL)
1141
dev_rel(cdev);
1142
return (ENOENT);
1143
}
1144
1145
if (cdev == NULL)
1146
break;
1147
1148
dev_lock();
1149
dde = &cdev2priv(cdev)->cdp_dirents[dmp->dm_idx];
1150
if (dde != NULL && *dde != NULL)
1151
de = *dde;
1152
dev_unlock();
1153
dev_rel(cdev);
1154
break;
1155
}
1156
1157
if (de == NULL || de->de_flags & DE_WHITEOUT) {
1158
if ((nameiop == CREATE || nameiop == RENAME) &&
1159
(flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
1160
return (EJUSTRETURN);
1161
}
1162
return (ENOENT);
1163
}
1164
1165
if (devfs_prison_check(de, td))
1166
return (ENOENT);
1167
1168
if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
1169
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
1170
if (error)
1171
return (error);
1172
if (*vpp == dvp) {
1173
vref(dvp);
1174
*vpp = dvp;
1175
return (0);
1176
}
1177
}
1178
error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp);
1179
*dm_unlock = 0;
1180
return (error);
1181
}
1182
1183
static int
1184
devfs_lookup(struct vop_lookup_args *ap)
1185
{
1186
int j;
1187
struct devfs_mount *dmp;
1188
int dm_unlock;
1189
1190
if (devfs_populate_vp(ap->a_dvp) != 0)
1191
return (ENOTDIR);
1192
1193
dmp = VFSTODEVFS(ap->a_dvp->v_mount);
1194
dm_unlock = 1;
1195
j = devfs_lookupx(ap, &dm_unlock);
1196
if (dm_unlock == 1)
1197
sx_xunlock(&dmp->dm_lock);
1198
return (j);
1199
}
1200
1201
static int
1202
devfs_mknod(struct vop_mknod_args *ap)
1203
{
1204
struct componentname *cnp;
1205
struct vnode *dvp, **vpp;
1206
struct devfs_dirent *dd, *de;
1207
struct devfs_mount *dmp;
1208
int error;
1209
1210
/*
1211
* The only type of node we should be creating here is a
1212
* character device, for anything else return EOPNOTSUPP.
1213
*/
1214
if (ap->a_vap->va_type != VCHR)
1215
return (EOPNOTSUPP);
1216
dvp = ap->a_dvp;
1217
dmp = VFSTODEVFS(dvp->v_mount);
1218
1219
cnp = ap->a_cnp;
1220
vpp = ap->a_vpp;
1221
dd = dvp->v_data;
1222
1223
error = ENOENT;
1224
sx_xlock(&dmp->dm_lock);
1225
TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
1226
if (cnp->cn_namelen != de->de_dirent->d_namlen)
1227
continue;
1228
if (de->de_dirent->d_type == DT_CHR &&
1229
(de->de_cdp->cdp_flags & CDP_ACTIVE) == 0)
1230
continue;
1231
if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
1232
de->de_dirent->d_namlen) != 0)
1233
continue;
1234
if (de->de_flags & DE_WHITEOUT)
1235
break;
1236
goto notfound;
1237
}
1238
if (de == NULL)
1239
goto notfound;
1240
de->de_flags &= ~DE_WHITEOUT;
1241
error = devfs_allocv(de, dvp->v_mount, LK_EXCLUSIVE, vpp);
1242
return (error);
1243
notfound:
1244
sx_xunlock(&dmp->dm_lock);
1245
return (error);
1246
}
1247
1248
/* ARGSUSED */
1249
static int
1250
devfs_open(struct vop_open_args *ap)
1251
{
1252
struct thread *td = ap->a_td;
1253
struct vnode *vp = ap->a_vp;
1254
struct cdev *dev = vp->v_rdev;
1255
struct file *fp = ap->a_fp;
1256
int error, ref, vlocked;
1257
struct cdevsw *dsw;
1258
struct file *fpop;
1259
1260
if (vp->v_type == VBLK)
1261
return (ENXIO);
1262
1263
if (dev == NULL)
1264
return (ENXIO);
1265
1266
/* Make this field valid before any I/O in d_open. */
1267
if (dev->si_iosize_max == 0)
1268
dev->si_iosize_max = DFLTPHYS;
1269
1270
dsw = dev_refthread(dev, &ref);
1271
if (dsw == NULL)
1272
return (ENXIO);
1273
if (fp == NULL && dsw->d_fdopen != NULL) {
1274
dev_relthread(dev, ref);
1275
return (ENXIO);
1276
}
1277
1278
if (vp->v_type == VCHR)
1279
devfs_usecount_add(vp);
1280
1281
vlocked = VOP_ISLOCKED(vp);
1282
VOP_UNLOCK(vp);
1283
1284
fpop = td->td_fpop;
1285
td->td_fpop = fp;
1286
if (fp != NULL) {
1287
fp->f_data = dev;
1288
fp->f_vnode = vp;
1289
}
1290
if (dsw->d_fdopen != NULL)
1291
error = dsw->d_fdopen(dev, ap->a_mode, td, fp);
1292
else
1293
error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
1294
/* Clean up any cdevpriv upon error. */
1295
if (error != 0)
1296
devfs_clear_cdevpriv();
1297
td->td_fpop = fpop;
1298
1299
vn_lock(vp, vlocked | LK_RETRY);
1300
if (error != 0 && vp->v_type == VCHR)
1301
devfs_usecount_sub(vp);
1302
1303
dev_relthread(dev, ref);
1304
if (error != 0) {
1305
if (error == ERESTART)
1306
error = EINTR;
1307
return (error);
1308
}
1309
1310
#if 0 /* /dev/console */
1311
KASSERT(fp != NULL, ("Could not vnode bypass device on NULL fp"));
1312
#else
1313
if (fp == NULL)
1314
return (error);
1315
#endif
1316
if (fp->f_ops == &badfileops)
1317
finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f);
1318
return (error);
1319
}
1320
1321
static int
1322
devfs_pathconf(struct vop_pathconf_args *ap)
1323
{
1324
1325
switch (ap->a_name) {
1326
case _PC_FILESIZEBITS:
1327
*ap->a_retval = 64;
1328
return (0);
1329
case _PC_NAME_MAX:
1330
*ap->a_retval = NAME_MAX;
1331
return (0);
1332
case _PC_LINK_MAX:
1333
*ap->a_retval = INT_MAX;
1334
return (0);
1335
case _PC_SYMLINK_MAX:
1336
*ap->a_retval = MAXPATHLEN;
1337
return (0);
1338
case _PC_MAX_CANON:
1339
if (ap->a_vp->v_vflag & VV_ISTTY) {
1340
*ap->a_retval = MAX_CANON;
1341
return (0);
1342
}
1343
return (EINVAL);
1344
case _PC_MAX_INPUT:
1345
if (ap->a_vp->v_vflag & VV_ISTTY) {
1346
*ap->a_retval = MAX_INPUT;
1347
return (0);
1348
}
1349
return (EINVAL);
1350
case _PC_VDISABLE:
1351
if (ap->a_vp->v_vflag & VV_ISTTY) {
1352
*ap->a_retval = _POSIX_VDISABLE;
1353
return (0);
1354
}
1355
return (EINVAL);
1356
case _PC_MAC_PRESENT:
1357
#ifdef MAC
1358
/*
1359
* If MAC is enabled, devfs automatically supports
1360
* trivial non-persistent label storage.
1361
*/
1362
*ap->a_retval = 1;
1363
#else
1364
*ap->a_retval = 0;
1365
#endif
1366
return (0);
1367
case _PC_CHOWN_RESTRICTED:
1368
*ap->a_retval = 1;
1369
return (0);
1370
default:
1371
return (vop_stdpathconf(ap));
1372
}
1373
/* NOTREACHED */
1374
}
1375
1376
/* ARGSUSED */
1377
static int
1378
devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
1379
{
1380
struct cdev *dev;
1381
struct cdevsw *dsw;
1382
int error, ref;
1383
struct file *fpop;
1384
1385
fpop = td->td_fpop;
1386
error = devfs_fp_check(fp, &dev, &dsw, &ref);
1387
if (error != 0) {
1388
error = vnops.fo_poll(fp, events, cred, td);
1389
return (error);
1390
}
1391
error = dsw->d_poll(dev, events, td);
1392
td->td_fpop = fpop;
1393
dev_relthread(dev, ref);
1394
return(error);
1395
}
1396
1397
/*
1398
* Print out the contents of a special device vnode.
1399
*/
1400
static int
1401
devfs_print(struct vop_print_args *ap)
1402
{
1403
1404
printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev));
1405
return (0);
1406
}
1407
1408
static int
1409
devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
1410
int flags, struct thread *td)
1411
{
1412
struct cdev *dev;
1413
int ioflag, error, ref;
1414
ssize_t resid;
1415
struct cdevsw *dsw;
1416
struct file *fpop;
1417
1418
if (uio->uio_resid > DEVFS_IOSIZE_MAX)
1419
return (EINVAL);
1420
fpop = td->td_fpop;
1421
error = devfs_fp_check(fp, &dev, &dsw, &ref);
1422
if (error != 0) {
1423
error = vnops.fo_read(fp, uio, cred, flags, td);
1424
return (error);
1425
}
1426
resid = uio->uio_resid;
1427
ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT);
1428
if (ioflag & O_DIRECT)
1429
ioflag |= IO_DIRECT;
1430
1431
foffset_lock_uio(fp, uio, flags | FOF_NOLOCK);
1432
error = dsw->d_read(dev, uio, ioflag);
1433
if (uio->uio_resid != resid || (error == 0 && resid != 0))
1434
devfs_timestamp(&dev->si_atime);
1435
td->td_fpop = fpop;
1436
dev_relthread(dev, ref);
1437
1438
foffset_unlock_uio(fp, uio, flags | FOF_NOLOCK | FOF_NEXTOFF_R);
1439
return (error);
1440
}
1441
1442
static int
1443
devfs_readdir(struct vop_readdir_args *ap)
1444
{
1445
int error;
1446
struct uio *uio;
1447
struct dirent *dp;
1448
struct devfs_dirent *dd;
1449
struct devfs_dirent *de;
1450
struct devfs_mount *dmp;
1451
off_t off;
1452
int *tmp_ncookies = NULL;
1453
ssize_t startresid;
1454
1455
if (ap->a_vp->v_type != VDIR)
1456
return (ENOTDIR);
1457
1458
uio = ap->a_uio;
1459
if (uio->uio_offset < 0)
1460
return (EINVAL);
1461
1462
/*
1463
* XXX: This is a temporary hack to get around this filesystem not
1464
* supporting cookies. We store the location of the ncookies pointer
1465
* in a temporary variable before calling vfs_subr.c:vfs_read_dirent()
1466
* and set the number of cookies to 0. We then set the pointer to
1467
* NULL so that vfs_read_dirent doesn't try to call realloc() on
1468
* ap->a_cookies. Later in this function, we restore the ap->a_ncookies
1469
* pointer to its original location before returning to the caller.
1470
*/
1471
if (ap->a_ncookies != NULL) {
1472
tmp_ncookies = ap->a_ncookies;
1473
*ap->a_ncookies = 0;
1474
ap->a_ncookies = NULL;
1475
}
1476
1477
dmp = VFSTODEVFS(ap->a_vp->v_mount);
1478
if (devfs_populate_vp(ap->a_vp) != 0) {
1479
if (tmp_ncookies != NULL)
1480
ap->a_ncookies = tmp_ncookies;
1481
return (EIO);
1482
}
1483
error = 0;
1484
de = ap->a_vp->v_data;
1485
off = 0;
1486
startresid = uio->uio_resid;
1487
TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
1488
KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
1489
if (dd->de_flags & (DE_COVERED | DE_WHITEOUT))
1490
continue;
1491
if (devfs_prison_check(dd, uio->uio_td))
1492
continue;
1493
if (dd->de_dirent->d_type == DT_DIR)
1494
de = dd->de_dir;
1495
else
1496
de = dd;
1497
dp = dd->de_dirent;
1498
MPASS(dp->d_reclen == GENERIC_DIRSIZ(dp));
1499
if (dp->d_reclen > uio->uio_resid) {
1500
/* Nothing was copied out, return EINVAL. */
1501
if (uio->uio_resid == startresid)
1502
error = EINVAL;
1503
/* Otherwise stop. */
1504
break;
1505
}
1506
dp->d_fileno = de->de_inode;
1507
/* NOTE: d_off is the offset for the *next* entry. */
1508
dp->d_off = off + dp->d_reclen;
1509
if (off >= uio->uio_offset) {
1510
error = vfs_read_dirent(ap, dp, off);
1511
if (error)
1512
break;
1513
}
1514
off += dp->d_reclen;
1515
}
1516
sx_xunlock(&dmp->dm_lock);
1517
uio->uio_offset = off;
1518
1519
/*
1520
* Restore ap->a_ncookies if it wasn't originally NULL in the first
1521
* place.
1522
*/
1523
if (tmp_ncookies != NULL)
1524
ap->a_ncookies = tmp_ncookies;
1525
if (dd == NULL && error == 0 && ap->a_eofflag != NULL)
1526
*ap->a_eofflag = 1;
1527
1528
return (error);
1529
}
1530
1531
static int
1532
devfs_readlink(struct vop_readlink_args *ap)
1533
{
1534
struct devfs_dirent *de;
1535
1536
de = ap->a_vp->v_data;
1537
return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio));
1538
}
1539
1540
static void
1541
devfs_reclaiml(struct vnode *vp)
1542
{
1543
struct devfs_dirent *de;
1544
1545
mtx_assert(&devfs_de_interlock, MA_OWNED);
1546
de = vp->v_data;
1547
if (de != NULL) {
1548
MPASS(de->de_usecount == 0);
1549
de->de_vnode = NULL;
1550
vp->v_data = NULL;
1551
}
1552
}
1553
1554
static int
1555
devfs_reclaim(struct vop_reclaim_args *ap)
1556
{
1557
struct vnode *vp;
1558
1559
vp = ap->a_vp;
1560
mtx_lock(&devfs_de_interlock);
1561
devfs_reclaiml(vp);
1562
mtx_unlock(&devfs_de_interlock);
1563
return (0);
1564
}
1565
1566
static int
1567
devfs_reclaim_vchr(struct vop_reclaim_args *ap)
1568
{
1569
struct vnode *vp;
1570
struct cdev *dev;
1571
1572
vp = ap->a_vp;
1573
MPASS(vp->v_type == VCHR);
1574
1575
mtx_lock(&devfs_de_interlock);
1576
VI_LOCK(vp);
1577
devfs_usecount_subl(vp);
1578
devfs_reclaiml(vp);
1579
mtx_unlock(&devfs_de_interlock);
1580
dev_lock();
1581
dev = vp->v_rdev;
1582
vp->v_rdev = NULL;
1583
dev_unlock();
1584
VI_UNLOCK(vp);
1585
if (dev != NULL)
1586
dev_rel(dev);
1587
return (0);
1588
}
1589
1590
static int
1591
devfs_remove(struct vop_remove_args *ap)
1592
{
1593
struct vnode *dvp = ap->a_dvp;
1594
struct vnode *vp = ap->a_vp;
1595
struct devfs_dirent *dd;
1596
struct devfs_dirent *de, *de_covered;
1597
struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
1598
1599
ASSERT_VOP_ELOCKED(dvp, "devfs_remove");
1600
ASSERT_VOP_ELOCKED(vp, "devfs_remove");
1601
1602
sx_xlock(&dmp->dm_lock);
1603
dd = ap->a_dvp->v_data;
1604
de = vp->v_data;
1605
if (de->de_cdp == NULL) {
1606
TAILQ_REMOVE(&dd->de_dlist, de, de_list);
1607
if (de->de_dirent->d_type == DT_LNK) {
1608
de_covered = devfs_find(dd, de->de_dirent->d_name,
1609
de->de_dirent->d_namlen, 0);
1610
if (de_covered != NULL)
1611
de_covered->de_flags &= ~DE_COVERED;
1612
}
1613
/* We need to unlock dvp because devfs_delete() may lock it. */
1614
VOP_UNLOCK(vp);
1615
if (dvp != vp)
1616
VOP_UNLOCK(dvp);
1617
devfs_delete(dmp, de, 0);
1618
sx_xunlock(&dmp->dm_lock);
1619
if (dvp != vp)
1620
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1621
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1622
} else {
1623
de->de_flags |= DE_WHITEOUT;
1624
sx_xunlock(&dmp->dm_lock);
1625
}
1626
return (0);
1627
}
1628
1629
/*
1630
* Revoke is called on a tty when a terminal session ends. The vnode
1631
* is orphaned by setting v_op to deadfs so we need to let go of it
1632
* as well so that we create a new one next time around.
1633
*
1634
*/
1635
static int
1636
devfs_revoke(struct vop_revoke_args *ap)
1637
{
1638
struct vnode *vp = ap->a_vp, *vp2;
1639
struct cdev *dev;
1640
struct cdev_priv *cdp;
1641
struct devfs_dirent *de;
1642
enum vgetstate vs;
1643
u_int i;
1644
1645
KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
1646
1647
dev = vp->v_rdev;
1648
cdp = cdev2priv(dev);
1649
1650
dev_lock();
1651
cdp->cdp_inuse++;
1652
dev_unlock();
1653
1654
vhold(vp);
1655
vgone(vp);
1656
vdrop(vp);
1657
1658
VOP_UNLOCK(vp);
1659
loop:
1660
for (;;) {
1661
mtx_lock(&devfs_de_interlock);
1662
dev_lock();
1663
vp2 = NULL;
1664
for (i = 0; i <= cdp->cdp_maxdirent; i++) {
1665
de = cdp->cdp_dirents[i];
1666
if (de == NULL)
1667
continue;
1668
1669
vp2 = de->de_vnode;
1670
if (vp2 != NULL) {
1671
dev_unlock();
1672
vs = vget_prep(vp2);
1673
mtx_unlock(&devfs_de_interlock);
1674
if (vget_finish(vp2, LK_EXCLUSIVE, vs) != 0)
1675
goto loop;
1676
vhold(vp2);
1677
vgone(vp2);
1678
vdrop(vp2);
1679
vput(vp2);
1680
break;
1681
}
1682
}
1683
if (vp2 != NULL) {
1684
continue;
1685
}
1686
dev_unlock();
1687
mtx_unlock(&devfs_de_interlock);
1688
break;
1689
}
1690
dev_lock();
1691
cdp->cdp_inuse--;
1692
if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) {
1693
KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) != 0,
1694
("%s: cdp %p (%s) not on active list",
1695
__func__, cdp, dev->si_name));
1696
cdp->cdp_flags &= ~CDP_ON_ACTIVE_LIST;
1697
TAILQ_REMOVE(&cdevp_list, cdp, cdp_list);
1698
dev_unlock();
1699
dev_rel(&cdp->cdp_c);
1700
} else
1701
dev_unlock();
1702
1703
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1704
return (0);
1705
}
1706
1707
static int
1708
devfs_rioctl(struct vop_ioctl_args *ap)
1709
{
1710
struct vnode *vp;
1711
struct devfs_mount *dmp;
1712
int error;
1713
1714
vp = ap->a_vp;
1715
vn_lock(vp, LK_SHARED | LK_RETRY);
1716
if (VN_IS_DOOMED(vp)) {
1717
VOP_UNLOCK(vp);
1718
return (EBADF);
1719
}
1720
dmp = VFSTODEVFS(vp->v_mount);
1721
sx_xlock(&dmp->dm_lock);
1722
VOP_UNLOCK(vp);
1723
DEVFS_DMP_HOLD(dmp);
1724
devfs_populate(dmp);
1725
if (DEVFS_DMP_DROP(dmp)) {
1726
sx_xunlock(&dmp->dm_lock);
1727
devfs_unmount_final(dmp);
1728
return (ENOENT);
1729
}
1730
error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td);
1731
sx_xunlock(&dmp->dm_lock);
1732
return (error);
1733
}
1734
1735
static int
1736
devfs_rread(struct vop_read_args *ap)
1737
{
1738
1739
if (ap->a_vp->v_type != VDIR)
1740
return (EINVAL);
1741
return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL));
1742
}
1743
1744
static int
1745
devfs_setattr(struct vop_setattr_args *ap)
1746
{
1747
struct devfs_dirent *de;
1748
struct vattr *vap;
1749
struct vnode *vp;
1750
struct thread *td;
1751
int c, error;
1752
uid_t uid;
1753
gid_t gid;
1754
1755
vap = ap->a_vap;
1756
vp = ap->a_vp;
1757
td = curthread;
1758
if ((vap->va_type != VNON) ||
1759
(vap->va_nlink != VNOVAL) ||
1760
(vap->va_fsid != VNOVAL) ||
1761
(vap->va_fileid != VNOVAL) ||
1762
(vap->va_blocksize != VNOVAL) ||
1763
(vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1764
(vap->va_rdev != VNOVAL) ||
1765
((int)vap->va_bytes != VNOVAL) ||
1766
(vap->va_gen != VNOVAL)) {
1767
return (EINVAL);
1768
}
1769
1770
error = devfs_populate_vp(vp);
1771
if (error != 0)
1772
return (error);
1773
1774
de = vp->v_data;
1775
if (vp->v_type == VDIR)
1776
de = de->de_dir;
1777
1778
c = 0;
1779
if (vap->va_uid == (uid_t)VNOVAL)
1780
uid = de->de_uid;
1781
else
1782
uid = vap->va_uid;
1783
if (vap->va_gid == (gid_t)VNOVAL)
1784
gid = de->de_gid;
1785
else
1786
gid = vap->va_gid;
1787
if (uid != de->de_uid || gid != de->de_gid) {
1788
if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
1789
(gid != de->de_gid && !groupmember(gid, ap->a_cred))) {
1790
error = priv_check(td, PRIV_VFS_CHOWN);
1791
if (error != 0)
1792
goto ret;
1793
}
1794
de->de_uid = uid;
1795
de->de_gid = gid;
1796
c = 1;
1797
}
1798
1799
if (vap->va_mode != (mode_t)VNOVAL) {
1800
if (ap->a_cred->cr_uid != de->de_uid) {
1801
error = priv_check(td, PRIV_VFS_ADMIN);
1802
if (error != 0)
1803
goto ret;
1804
}
1805
de->de_mode = vap->va_mode;
1806
c = 1;
1807
}
1808
1809
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1810
error = vn_utimes_perm(vp, vap, ap->a_cred, td);
1811
if (error != 0)
1812
goto ret;
1813
if (vap->va_atime.tv_sec != VNOVAL) {
1814
if (vp->v_type == VCHR)
1815
vp->v_rdev->si_atime = vap->va_atime;
1816
else
1817
de->de_atime = vap->va_atime;
1818
}
1819
if (vap->va_mtime.tv_sec != VNOVAL) {
1820
if (vp->v_type == VCHR)
1821
vp->v_rdev->si_mtime = vap->va_mtime;
1822
else
1823
de->de_mtime = vap->va_mtime;
1824
}
1825
c = 1;
1826
}
1827
1828
if (c) {
1829
if (vp->v_type == VCHR)
1830
vfs_timestamp(&vp->v_rdev->si_ctime);
1831
else
1832
vfs_timestamp(&de->de_mtime);
1833
}
1834
1835
ret:
1836
sx_xunlock(&VFSTODEVFS(vp->v_mount)->dm_lock);
1837
return (error);
1838
}
1839
1840
#ifdef MAC
1841
static int
1842
devfs_setlabel(struct vop_setlabel_args *ap)
1843
{
1844
struct vnode *vp;
1845
struct devfs_dirent *de;
1846
1847
vp = ap->a_vp;
1848
de = vp->v_data;
1849
1850
mac_vnode_relabel(ap->a_cred, vp, ap->a_label);
1851
mac_devfs_update(vp->v_mount, de, vp);
1852
1853
return (0);
1854
}
1855
#endif
1856
1857
static int
1858
devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred)
1859
{
1860
1861
return (vnops.fo_stat(fp, sb, cred));
1862
}
1863
1864
static int
1865
devfs_symlink(struct vop_symlink_args *ap)
1866
{
1867
int i, error;
1868
struct devfs_dirent *dd;
1869
struct devfs_dirent *de, *de_covered, *de_dotdot;
1870
struct devfs_mount *dmp;
1871
1872
error = priv_check(curthread, PRIV_DEVFS_SYMLINK);
1873
if (error)
1874
return(error);
1875
dmp = VFSTODEVFS(ap->a_dvp->v_mount);
1876
if (devfs_populate_vp(ap->a_dvp) != 0)
1877
return (ENOENT);
1878
1879
dd = ap->a_dvp->v_data;
1880
de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
1881
de->de_flags = DE_USER;
1882
de->de_uid = 0;
1883
de->de_gid = 0;
1884
de->de_mode = 0755;
1885
de->de_inode = alloc_unr(devfs_inos);
1886
de->de_dir = dd;
1887
de->de_dirent->d_type = DT_LNK;
1888
i = strlen(ap->a_target) + 1;
1889
de->de_symlink = malloc(i, M_DEVFS, M_WAITOK);
1890
bcopy(ap->a_target, de->de_symlink, i);
1891
#ifdef MAC
1892
mac_devfs_create_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de);
1893
#endif
1894
de_covered = devfs_find(dd, de->de_dirent->d_name,
1895
de->de_dirent->d_namlen, 0);
1896
if (de_covered != NULL) {
1897
if ((de_covered->de_flags & DE_USER) != 0) {
1898
devfs_delete(dmp, de, DEVFS_DEL_NORECURSE);
1899
sx_xunlock(&dmp->dm_lock);
1900
return (EEXIST);
1901
}
1902
KASSERT((de_covered->de_flags & DE_COVERED) == 0,
1903
("devfs_symlink: entry %p already covered", de_covered));
1904
de_covered->de_flags |= DE_COVERED;
1905
}
1906
1907
de_dotdot = TAILQ_FIRST(&dd->de_dlist); /* "." */
1908
de_dotdot = TAILQ_NEXT(de_dotdot, de_list); /* ".." */
1909
TAILQ_INSERT_AFTER(&dd->de_dlist, de_dotdot, de, de_list);
1910
devfs_dir_ref_de(dmp, dd);
1911
devfs_rules_apply(dmp, de);
1912
1913
return (devfs_allocv(de, ap->a_dvp->v_mount, LK_EXCLUSIVE, ap->a_vpp));
1914
}
1915
1916
static int
1917
devfs_truncate_f(struct file *fp, off_t length, struct ucred *cred, struct thread *td)
1918
{
1919
1920
return (vnops.fo_truncate(fp, length, cred, td));
1921
}
1922
1923
static int
1924
devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
1925
int flags, struct thread *td)
1926
{
1927
struct cdev *dev;
1928
int error, ioflag, ref;
1929
ssize_t resid;
1930
struct cdevsw *dsw;
1931
struct file *fpop;
1932
1933
if (uio->uio_resid > DEVFS_IOSIZE_MAX)
1934
return (EINVAL);
1935
fpop = td->td_fpop;
1936
error = devfs_fp_check(fp, &dev, &dsw, &ref);
1937
if (error != 0) {
1938
error = vnops.fo_write(fp, uio, cred, flags, td);
1939
return (error);
1940
}
1941
KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
1942
ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC);
1943
if (ioflag & O_DIRECT)
1944
ioflag |= IO_DIRECT;
1945
foffset_lock_uio(fp, uio, flags | FOF_NOLOCK);
1946
1947
resid = uio->uio_resid;
1948
1949
error = dsw->d_write(dev, uio, ioflag);
1950
if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
1951
devfs_timestamp(&dev->si_ctime);
1952
dev->si_mtime = dev->si_ctime;
1953
}
1954
td->td_fpop = fpop;
1955
dev_relthread(dev, ref);
1956
1957
foffset_unlock_uio(fp, uio, flags | FOF_NOLOCK | FOF_NEXTOFF_W);
1958
return (error);
1959
}
1960
1961
static int
1962
devfs_mmap_f(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
1963
vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
1964
struct thread *td)
1965
{
1966
struct cdev *dev;
1967
struct cdevsw *dsw;
1968
struct mount *mp;
1969
struct vnode *vp;
1970
struct file *fpop;
1971
vm_object_t object;
1972
vm_prot_t maxprot;
1973
int error, ref;
1974
1975
vp = fp->f_vnode;
1976
1977
/*
1978
* Ensure that file and memory protections are
1979
* compatible.
1980
*/
1981
mp = vp->v_mount;
1982
if (mp != NULL && (mp->mnt_flag & MNT_NOEXEC) != 0) {
1983
maxprot = VM_PROT_NONE;
1984
if ((prot & VM_PROT_EXECUTE) != 0)
1985
return (EACCES);
1986
} else
1987
maxprot = VM_PROT_EXECUTE;
1988
if ((fp->f_flag & FREAD) != 0)
1989
maxprot |= VM_PROT_READ;
1990
else if ((prot & VM_PROT_READ) != 0)
1991
return (EACCES);
1992
1993
/*
1994
* If we are sharing potential changes via MAP_SHARED and we
1995
* are trying to get write permission although we opened it
1996
* without asking for it, bail out.
1997
*
1998
* Note that most character devices always share mappings.
1999
* The one exception is that D_MMAP_ANON devices
2000
* (i.e. /dev/zero) permit private writable mappings.
2001
*
2002
* Rely on vm_mmap_cdev() to fail invalid MAP_PRIVATE requests
2003
* as well as updating maxprot to permit writing for
2004
* D_MMAP_ANON devices rather than doing that here.
2005
*/
2006
if ((flags & MAP_SHARED) != 0) {
2007
if ((fp->f_flag & FWRITE) != 0)
2008
maxprot |= VM_PROT_WRITE;
2009
else if ((prot & VM_PROT_WRITE) != 0)
2010
return (EACCES);
2011
}
2012
maxprot &= cap_maxprot;
2013
2014
fpop = td->td_fpop;
2015
error = devfs_fp_check(fp, &dev, &dsw, &ref);
2016
if (error != 0)
2017
return (error);
2018
2019
error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, dev, dsw, &foff,
2020
&object);
2021
td->td_fpop = fpop;
2022
dev_relthread(dev, ref);
2023
if (error != 0)
2024
return (error);
2025
2026
error = vm_mmap_object(map, addr, size, prot, maxprot, flags, object,
2027
foff, FALSE, td);
2028
if (error != 0)
2029
vm_object_deallocate(object);
2030
return (error);
2031
}
2032
2033
dev_t
2034
dev2udev(struct cdev *x)
2035
{
2036
if (x == NULL)
2037
return (NODEV);
2038
return (cdev2priv(x)->cdp_inode);
2039
}
2040
2041
static int
2042
devfs_cmp_f(struct file *fp1, struct file *fp2, struct thread *td)
2043
{
2044
if (fp2->f_type != DTYPE_VNODE || fp2->f_ops != &devfs_ops_f)
2045
return (3);
2046
return (kcmp_cmp((uintptr_t)fp1->f_data, (uintptr_t)fp2->f_data));
2047
}
2048
2049
static const struct fileops devfs_ops_f = {
2050
.fo_read = devfs_read_f,
2051
.fo_write = devfs_write_f,
2052
.fo_truncate = devfs_truncate_f,
2053
.fo_ioctl = devfs_ioctl_f,
2054
.fo_poll = devfs_poll_f,
2055
.fo_kqfilter = devfs_kqfilter_f,
2056
.fo_stat = devfs_stat_f,
2057
.fo_close = devfs_close_f,
2058
.fo_chmod = vn_chmod,
2059
.fo_chown = vn_chown,
2060
.fo_sendfile = vn_sendfile,
2061
.fo_seek = vn_seek,
2062
.fo_fill_kinfo = vn_fill_kinfo,
2063
.fo_mmap = devfs_mmap_f,
2064
.fo_cmp = devfs_cmp_f,
2065
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
2066
};
2067
2068
/* Vops for non-CHR vnodes in /dev. */
2069
static struct vop_vector devfs_vnodeops = {
2070
.vop_default = &default_vnodeops,
2071
2072
.vop_access = devfs_access,
2073
.vop_getattr = devfs_getattr,
2074
.vop_ioctl = devfs_rioctl,
2075
.vop_lookup = devfs_lookup,
2076
.vop_mknod = devfs_mknod,
2077
.vop_pathconf = devfs_pathconf,
2078
.vop_read = devfs_rread,
2079
.vop_readdir = devfs_readdir,
2080
.vop_readlink = devfs_readlink,
2081
.vop_reclaim = devfs_reclaim,
2082
.vop_remove = devfs_remove,
2083
.vop_revoke = devfs_revoke,
2084
.vop_setattr = devfs_setattr,
2085
#ifdef MAC
2086
.vop_setlabel = devfs_setlabel,
2087
#endif
2088
.vop_symlink = devfs_symlink,
2089
.vop_vptocnp = devfs_vptocnp,
2090
.vop_lock1 = vop_lock,
2091
.vop_unlock = vop_unlock,
2092
.vop_islocked = vop_islocked,
2093
.vop_add_writecount = vop_stdadd_writecount_nomsync,
2094
};
2095
VFS_VOP_VECTOR_REGISTER(devfs_vnodeops);
2096
2097
/* Vops for VCHR vnodes in /dev. */
2098
static struct vop_vector devfs_specops = {
2099
.vop_default = &default_vnodeops,
2100
2101
.vop_access = devfs_access,
2102
.vop_bmap = VOP_PANIC,
2103
.vop_close = devfs_close,
2104
.vop_create = VOP_PANIC,
2105
.vop_fsync = vop_stdfsync,
2106
.vop_getattr = devfs_getattr,
2107
.vop_ioctl = devfs_ioctl,
2108
.vop_link = VOP_PANIC,
2109
.vop_mkdir = VOP_PANIC,
2110
.vop_mknod = VOP_PANIC,
2111
.vop_open = devfs_open,
2112
.vop_pathconf = devfs_pathconf,
2113
.vop_poll = dead_poll,
2114
.vop_print = devfs_print,
2115
.vop_read = dead_read,
2116
.vop_readdir = VOP_PANIC,
2117
.vop_readlink = VOP_PANIC,
2118
.vop_reallocblks = VOP_PANIC,
2119
.vop_reclaim = devfs_reclaim_vchr,
2120
.vop_remove = devfs_remove,
2121
.vop_rename = VOP_PANIC,
2122
.vop_revoke = devfs_revoke,
2123
.vop_rmdir = VOP_PANIC,
2124
.vop_setattr = devfs_setattr,
2125
#ifdef MAC
2126
.vop_setlabel = devfs_setlabel,
2127
#endif
2128
.vop_strategy = VOP_PANIC,
2129
.vop_symlink = VOP_PANIC,
2130
.vop_vptocnp = devfs_vptocnp,
2131
.vop_write = dead_write,
2132
.vop_lock1 = vop_lock,
2133
.vop_unlock = vop_unlock,
2134
.vop_islocked = vop_islocked,
2135
.vop_add_writecount = vop_stdadd_writecount_nomsync,
2136
};
2137
VFS_VOP_VECTOR_REGISTER(devfs_specops);
2138
2139
/*
2140
* Our calling convention to the device drivers used to be that we passed
2141
* vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_
2142
* flags instead since that's what open(), close() and ioctl() takes and
2143
* we don't really want vnode.h in device drivers.
2144
* We solved the source compatibility by redefining some vnode flags to
2145
* be the same as the fcntl ones and by sending down the bitwise OR of
2146
* the respective fcntl/vnode flags. These CTASSERTS make sure nobody
2147
* pulls the rug out under this.
2148
*/
2149
CTASSERT(O_NONBLOCK == IO_NDELAY);
2150
CTASSERT(O_FSYNC == IO_SYNC);
2151
2152