Annotation of src/sys/miscfs/genfs/genfs_vnops.c, Revision 1.164.6.2
1.164.6.1 mjf 1: /* $NetBSD$ */
1.164 ad 2:
3: /*-
4: * Copyright (c) 2008 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26: * POSSIBILITY OF SUCH DAMAGE.
27: */
1.6 fvdl 28:
29: /*
30: * Copyright (c) 1982, 1986, 1989, 1993
31: * The Regents of the University of California. All rights reserved.
32: *
33: * Redistribution and use in source and binary forms, with or without
34: * modification, are permitted provided that the following conditions
35: * are met:
36: * 1. Redistributions of source code must retain the above copyright
37: * notice, this list of conditions and the following disclaimer.
38: * 2. Redistributions in binary form must reproduce the above copyright
39: * notice, this list of conditions and the following disclaimer in the
40: * documentation and/or other materials provided with the distribution.
1.81 agc 41: * 3. Neither the name of the University nor the names of its contributors
1.6 fvdl 42: * may be used to endorse or promote products derived from this software
43: * without specific prior written permission.
44: *
45: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55: * SUCH DAMAGE.
56: *
57: */
1.40 lukem 58:
59: #include <sys/cdefs.h>
1.164.6.1 mjf 60: __KERNEL_RCSID(0, "$NetBSD$");
1.8 thorpej 61:
1.1 mycroft 62: #include <sys/param.h>
63: #include <sys/systm.h>
1.6 fvdl 64: #include <sys/proc.h>
1.1 mycroft 65: #include <sys/kernel.h>
66: #include <sys/mount.h>
67: #include <sys/namei.h>
68: #include <sys/vnode.h>
1.13 wrstuden 69: #include <sys/fcntl.h>
1.135 yamt 70: #include <sys/kmem.h>
1.3 mycroft 71: #include <sys/poll.h>
1.37 chs 72: #include <sys/mman.h>
1.66 jdolecek 73: #include <sys/file.h>
1.125 elad 74: #include <sys/kauth.h>
1.1 mycroft 75:
76: #include <miscfs/genfs/genfs.h>
1.37 chs 77: #include <miscfs/genfs/genfs_node.h>
1.6 fvdl 78: #include <miscfs/specfs/specdev.h>
1.1 mycroft 79:
1.21 chs 80: #include <uvm/uvm.h>
81: #include <uvm/uvm_pager.h>
82:
1.70 christos 83: static void filt_genfsdetach(struct knote *);
84: static int filt_genfsread(struct knote *, long);
85: static int filt_genfsvnode(struct knote *, long);
86:
1.1 mycroft 87: int
1.53 enami 88: genfs_poll(void *v)
1.1 mycroft 89: {
1.3 mycroft 90: struct vop_poll_args /* {
1.1 mycroft 91: struct vnode *a_vp;
1.3 mycroft 92: int a_events;
1.116 christos 93: struct lwp *a_l;
1.1 mycroft 94: } */ *ap = v;
95:
1.3 mycroft 96: return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1.1 mycroft 97: }
98:
99: int
1.53 enami 100: genfs_seek(void *v)
1.4 kleink 101: {
102: struct vop_seek_args /* {
103: struct vnode *a_vp;
104: off_t a_oldoff;
105: off_t a_newoff;
1.125 elad 106: kauth_cred_t cred;
1.4 kleink 107: } */ *ap = v;
108:
109: if (ap->a_newoff < 0)
110: return (EINVAL);
111:
112: return (0);
113: }
114:
115: int
1.53 enami 116: genfs_abortop(void *v)
1.1 mycroft 117: {
118: struct vop_abortop_args /* {
119: struct vnode *a_dvp;
120: struct componentname *a_cnp;
121: } */ *ap = v;
1.53 enami 122:
1.1 mycroft 123: if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
1.19 thorpej 124: PNBUF_PUT(ap->a_cnp->cn_pnbuf);
1.1 mycroft 125: return (0);
1.13 wrstuden 126: }
127:
128: int
1.53 enami 129: genfs_fcntl(void *v)
1.13 wrstuden 130: {
131: struct vop_fcntl_args /* {
132: struct vnode *a_vp;
133: u_int a_command;
1.150 christos 134: void *a_data;
1.13 wrstuden 135: int a_fflag;
1.125 elad 136: kauth_cred_t a_cred;
1.116 christos 137: struct lwp *a_l;
1.13 wrstuden 138: } */ *ap = v;
139:
140: if (ap->a_command == F_SETFL)
141: return (0);
142: else
143: return (EOPNOTSUPP);
1.1 mycroft 144: }
145:
146: /*ARGSUSED*/
147: int
1.138 christos 148: genfs_badop(void *v)
1.1 mycroft 149: {
150:
151: panic("genfs: bad op");
152: }
153:
154: /*ARGSUSED*/
155: int
1.138 christos 156: genfs_nullop(void *v)
1.1 mycroft 157: {
158:
159: return (0);
1.10 kleink 160: }
161:
162: /*ARGSUSED*/
163: int
1.138 christos 164: genfs_einval(void *v)
1.10 kleink 165: {
166:
167: return (EINVAL);
1.1 mycroft 168: }
169:
1.12 wrstuden 170: /*
1.74 jdolecek 171: * Called when an fs doesn't support a particular vop.
172: * This takes care to vrele, vput, or vunlock passed in vnodes.
1.12 wrstuden 173: */
174: int
1.75 jdolecek 175: genfs_eopnotsupp(void *v)
1.12 wrstuden 176: {
177: struct vop_generic_args /*
178: struct vnodeop_desc *a_desc;
1.53 enami 179: / * other random data follows, presumably * /
1.12 wrstuden 180: } */ *ap = v;
181: struct vnodeop_desc *desc = ap->a_desc;
1.74 jdolecek 182: struct vnode *vp, *vp_last = NULL;
1.12 wrstuden 183: int flags, i, j, offset;
184:
185: flags = desc->vdesc_flags;
186: for (i = 0; i < VDESC_MAX_VPS; flags >>=1, i++) {
187: if ((offset = desc->vdesc_vp_offsets[i]) == VDESC_NO_OFFSET)
188: break; /* stop at end of list */
189: if ((j = flags & VDESC_VP0_WILLPUT)) {
1.53 enami 190: vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap);
1.74 jdolecek 191:
192: /* Skip if NULL */
193: if (!vp)
194: continue;
195:
1.12 wrstuden 196: switch (j) {
197: case VDESC_VP0_WILLPUT:
1.74 jdolecek 198: /* Check for dvp == vp cases */
199: if (vp == vp_last)
200: vrele(vp);
201: else {
202: vput(vp);
203: vp_last = vp;
204: }
1.12 wrstuden 205: break;
206: case VDESC_VP0_WILLUNLOCK:
207: VOP_UNLOCK(vp, 0);
208: break;
209: case VDESC_VP0_WILLRELE:
210: vrele(vp);
211: break;
212: }
213: }
214: }
215:
216: return (EOPNOTSUPP);
217: }
218:
1.1 mycroft 219: /*ARGSUSED*/
220: int
1.138 christos 221: genfs_ebadf(void *v)
1.1 mycroft 222: {
223:
224: return (EBADF);
1.9 matthias 225: }
226:
227: /* ARGSUSED */
228: int
1.138 christos 229: genfs_enoioctl(void *v)
1.9 matthias 230: {
231:
1.51 atatat 232: return (EPASSTHROUGH);
1.6 fvdl 233: }
234:
235:
236: /*
1.15 fvdl 237: * Eliminate all activity associated with the requested vnode
1.6 fvdl 238: * and with all vnodes aliased to the requested vnode.
239: */
240: int
1.53 enami 241: genfs_revoke(void *v)
1.6 fvdl 242: {
243: struct vop_revoke_args /* {
244: struct vnode *a_vp;
245: int a_flags;
246: } */ *ap = v;
247:
248: #ifdef DIAGNOSTIC
249: if ((ap->a_flags & REVOKEALL) == 0)
250: panic("genfs_revoke: not revokeall");
251: #endif
1.161 ad 252: vrevoke(ap->a_vp);
1.6 fvdl 253: return (0);
254: }
255:
256: /*
1.12 wrstuden 257: * Lock the node.
1.6 fvdl 258: */
259: int
1.53 enami 260: genfs_lock(void *v)
1.6 fvdl 261: {
262: struct vop_lock_args /* {
263: struct vnode *a_vp;
264: int a_flags;
265: } */ *ap = v;
266: struct vnode *vp = ap->a_vp;
1.163 ad 267: int flags = ap->a_flags;
1.6 fvdl 268:
1.163 ad 269: if ((flags & LK_INTERLOCK) != 0) {
270: flags &= ~LK_INTERLOCK;
271: mutex_exit(&vp->v_interlock);
272: }
273:
274: return (vlockmgr(vp->v_vnlock, flags));
1.6 fvdl 275: }
276:
277: /*
1.12 wrstuden 278: * Unlock the node.
1.6 fvdl 279: */
280: int
1.53 enami 281: genfs_unlock(void *v)
1.6 fvdl 282: {
283: struct vop_unlock_args /* {
284: struct vnode *a_vp;
285: int a_flags;
286: } */ *ap = v;
287: struct vnode *vp = ap->a_vp;
288:
1.163 ad 289: KASSERT(ap->a_flags == 0);
290:
291: return (vlockmgr(vp->v_vnlock, LK_RELEASE));
1.6 fvdl 292: }
293:
294: /*
1.12 wrstuden 295: * Return whether or not the node is locked.
1.6 fvdl 296: */
297: int
1.53 enami 298: genfs_islocked(void *v)
1.6 fvdl 299: {
300: struct vop_islocked_args /* {
301: struct vnode *a_vp;
302: } */ *ap = v;
303: struct vnode *vp = ap->a_vp;
304:
1.163 ad 305: return (vlockstatus(vp->v_vnlock));
1.12 wrstuden 306: }
307:
308: /*
309: * Stubs to use when there is no locking to be done on the underlying object.
310: */
311: int
1.53 enami 312: genfs_nolock(void *v)
1.12 wrstuden 313: {
314: struct vop_lock_args /* {
315: struct vnode *a_vp;
316: int a_flags;
1.116 christos 317: struct lwp *a_l;
1.12 wrstuden 318: } */ *ap = v;
319:
320: /*
321: * Since we are not using the lock manager, we must clear
322: * the interlock here.
323: */
324: if (ap->a_flags & LK_INTERLOCK)
1.160 ad 325: mutex_exit(&ap->a_vp->v_interlock);
1.12 wrstuden 326: return (0);
327: }
328:
329: int
1.138 christos 330: genfs_nounlock(void *v)
1.12 wrstuden 331: {
1.53 enami 332:
1.12 wrstuden 333: return (0);
334: }
335:
336: int
1.138 christos 337: genfs_noislocked(void *v)
1.12 wrstuden 338: {
1.53 enami 339:
1.12 wrstuden 340: return (0);
1.8 thorpej 341: }
342:
1.34 chs 343: int
1.138 christos 344: genfs_mmap(void *v)
1.34 chs 345: {
1.53 enami 346:
347: return (0);
1.21 chs 348: }
349:
1.37 chs 350: void
1.98 yamt 351: genfs_node_init(struct vnode *vp, const struct genfs_ops *ops)
1.37 chs 352: {
353: struct genfs_node *gp = VTOG(vp);
354:
1.146 ad 355: rw_init(&gp->g_glock);
1.37 chs 356: gp->g_op = ops;
357: }
358:
359: void
1.147 ad 360: genfs_node_destroy(struct vnode *vp)
361: {
362: struct genfs_node *gp = VTOG(vp);
363:
364: rw_destroy(&gp->g_glock);
365: }
366:
367: void
1.138 christos 368: genfs_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
1.21 chs 369: {
370: int bsize;
371:
1.37 chs 372: bsize = 1 << vp->v_mount->mnt_fs_bshift;
373: *eobp = (size + bsize - 1) & ~(bsize - 1);
1.43 chs 374: }
375:
1.66 jdolecek 376: static void
377: filt_genfsdetach(struct knote *kn)
378: {
379: struct vnode *vp = (struct vnode *)kn->kn_hook;
380:
1.164 ad 381: mutex_enter(&vp->v_interlock);
1.66 jdolecek 382: SLIST_REMOVE(&vp->v_klist, kn, knote, kn_selnext);
1.164 ad 383: mutex_exit(&vp->v_interlock);
1.66 jdolecek 384: }
385:
386: static int
387: filt_genfsread(struct knote *kn, long hint)
388: {
389: struct vnode *vp = (struct vnode *)kn->kn_hook;
1.164 ad 390: int rv;
1.66 jdolecek 391:
392: /*
393: * filesystem is gone, so set the EOF flag and schedule
394: * the knote for deletion.
395: */
1.164 ad 396: switch (hint) {
397: case NOTE_REVOKE:
398: KASSERT(mutex_owned(&vp->v_interlock));
1.66 jdolecek 399: kn->kn_flags |= (EV_EOF | EV_ONESHOT);
400: return (1);
1.164 ad 401: case 0:
402: mutex_enter(&vp->v_interlock);
1.164.6.1 mjf 403: kn->kn_data = vp->v_size - ((file_t *)kn->kn_obj)->f_offset;
1.164 ad 404: rv = (kn->kn_data != 0);
405: mutex_exit(&vp->v_interlock);
406: return rv;
407: default:
408: KASSERT(mutex_owned(&vp->v_interlock));
1.164.6.1 mjf 409: kn->kn_data = vp->v_size - ((file_t *)kn->kn_obj)->f_offset;
1.164 ad 410: return (kn->kn_data != 0);
1.66 jdolecek 411: }
412: }
413:
414: static int
415: filt_genfsvnode(struct knote *kn, long hint)
416: {
1.164 ad 417: struct vnode *vp = (struct vnode *)kn->kn_hook;
418: int fflags;
1.66 jdolecek 419:
1.164 ad 420: switch (hint) {
421: case NOTE_REVOKE:
422: KASSERT(mutex_owned(&vp->v_interlock));
1.66 jdolecek 423: kn->kn_flags |= EV_EOF;
1.164 ad 424: if ((kn->kn_sfflags & hint) != 0)
425: kn->kn_fflags |= hint;
1.66 jdolecek 426: return (1);
1.164 ad 427: case 0:
428: mutex_enter(&vp->v_interlock);
429: fflags = kn->kn_fflags;
430: mutex_exit(&vp->v_interlock);
431: break;
432: default:
433: KASSERT(mutex_owned(&vp->v_interlock));
434: if ((kn->kn_sfflags & hint) != 0)
435: kn->kn_fflags |= hint;
436: fflags = kn->kn_fflags;
437: break;
1.66 jdolecek 438: }
1.164 ad 439:
1.164.6.1 mjf 440: return (fflags != 0);
1.66 jdolecek 441: }
442:
1.96 perry 443: static const struct filterops genfsread_filtops =
1.66 jdolecek 444: { 1, NULL, filt_genfsdetach, filt_genfsread };
1.96 perry 445: static const struct filterops genfsvnode_filtops =
1.66 jdolecek 446: { 1, NULL, filt_genfsdetach, filt_genfsvnode };
447:
448: int
449: genfs_kqfilter(void *v)
450: {
451: struct vop_kqfilter_args /* {
452: struct vnode *a_vp;
453: struct knote *a_kn;
454: } */ *ap = v;
455: struct vnode *vp;
456: struct knote *kn;
457:
458: vp = ap->a_vp;
459: kn = ap->a_kn;
460: switch (kn->kn_filter) {
461: case EVFILT_READ:
462: kn->kn_fop = &genfsread_filtops;
463: break;
464: case EVFILT_VNODE:
465: kn->kn_fop = &genfsvnode_filtops;
466: break;
467: default:
1.159 pooka 468: return (EINVAL);
1.66 jdolecek 469: }
470:
471: kn->kn_hook = vp;
472:
1.164 ad 473: mutex_enter(&vp->v_interlock);
1.66 jdolecek 474: SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext);
1.164 ad 475: mutex_exit(&vp->v_interlock);
1.66 jdolecek 476:
477: return (0);
1.1 mycroft 478: }
1.136 yamt 479:
480: void
481: genfs_node_wrlock(struct vnode *vp)
482: {
483: struct genfs_node *gp = VTOG(vp);
484:
1.146 ad 485: rw_enter(&gp->g_glock, RW_WRITER);
1.136 yamt 486: }
487:
488: void
489: genfs_node_rdlock(struct vnode *vp)
490: {
491: struct genfs_node *gp = VTOG(vp);
492:
1.146 ad 493: rw_enter(&gp->g_glock, RW_READER);
1.136 yamt 494: }
495:
496: void
497: genfs_node_unlock(struct vnode *vp)
498: {
499: struct genfs_node *gp = VTOG(vp);
500:
1.146 ad 501: rw_exit(&gp->g_glock);
1.136 yamt 502: }
CVSweb <webmaster@jp.NetBSD.org>