Annotation of sys/ufs/mfs/mfs_vnops.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mfs_vnops.c,v 1.28 2007/06/01 23:47:57 deraadt Exp $ */
2: /* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1989, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: * @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94
33: */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/time.h>
38: #include <sys/kernel.h>
39: #include <sys/proc.h>
40: #include <sys/buf.h>
41: #include <sys/vnode.h>
42: #include <sys/malloc.h>
43:
44: #include <miscfs/specfs/specdev.h>
45:
46: #include <machine/vmparam.h>
47:
48: #include <ufs/mfs/mfsnode.h>
49: #include <ufs/mfs/mfs_extern.h>
50:
51: /*
52: * mfs vnode operations.
53: */
54: int (**mfs_vnodeop_p)(void *);
55: struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
56: { &vop_default_desc, vn_default_error },
57: { &vop_lookup_desc, mfs_lookup }, /* lookup */
58: { &vop_create_desc, mfs_create }, /* create */
59: { &vop_mknod_desc, mfs_mknod }, /* mknod */
60: { &vop_open_desc, mfs_open }, /* open */
61: { &vop_close_desc, mfs_close }, /* close */
62: { &vop_access_desc, mfs_access }, /* access */
63: { &vop_getattr_desc, mfs_getattr }, /* getattr */
64: { &vop_setattr_desc, mfs_setattr }, /* setattr */
65: { &vop_read_desc, mfs_read }, /* read */
66: { &vop_write_desc, mfs_write }, /* write */
67: { &vop_ioctl_desc, mfs_ioctl }, /* ioctl */
68: { &vop_poll_desc, mfs_poll }, /* poll */
69: { &vop_revoke_desc, mfs_revoke }, /* revoke */
70: { &vop_fsync_desc, spec_fsync }, /* fsync */
71: { &vop_remove_desc, mfs_remove }, /* remove */
72: { &vop_link_desc, mfs_link }, /* link */
73: { &vop_rename_desc, mfs_rename }, /* rename */
74: { &vop_mkdir_desc, mfs_mkdir }, /* mkdir */
75: { &vop_rmdir_desc, mfs_rmdir }, /* rmdir */
76: { &vop_symlink_desc, mfs_symlink }, /* symlink */
77: { &vop_readdir_desc, mfs_readdir }, /* readdir */
78: { &vop_readlink_desc, mfs_readlink }, /* readlink */
79: { &vop_abortop_desc, mfs_abortop }, /* abortop */
80: { &vop_inactive_desc, mfs_inactive }, /* inactive */
81: { &vop_reclaim_desc, mfs_reclaim }, /* reclaim */
82: { &vop_lock_desc, mfs_lock }, /* lock */
83: { &vop_unlock_desc, mfs_unlock }, /* unlock */
84: { &vop_bmap_desc, mfs_bmap }, /* bmap */
85: { &vop_strategy_desc, mfs_strategy }, /* strategy */
86: { &vop_print_desc, mfs_print }, /* print */
87: { &vop_islocked_desc, mfs_islocked }, /* islocked */
88: { &vop_pathconf_desc, mfs_pathconf }, /* pathconf */
89: { &vop_advlock_desc, mfs_advlock }, /* advlock */
90: { &vop_bwrite_desc, mfs_bwrite }, /* bwrite */
91: { (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
92: };
93: struct vnodeopv_desc mfs_vnodeop_opv_desc =
94: { &mfs_vnodeop_p, mfs_vnodeop_entries };
95:
96: /*
97: * Vnode Operations.
98: *
99: * Open called to allow memory filesystem to initialize and
100: * validate before actual IO. Record our process identifier
101: * so we can tell when we are doing I/O to ourself.
102: */
103: /* ARGSUSED */
104: int
105: mfs_open(void *v)
106: {
107: #ifdef DIAGNOSTIC
108: struct vop_open_args *ap = v;
109:
110: if (ap->a_vp->v_type != VBLK) {
111: panic("mfs_open not VBLK");
112: /* NOTREACHED */
113: }
114: #endif
115: return (0);
116: }
117:
118: /*
119: * Ioctl operation.
120: */
121: /* ARGSUSED */
122: int
123: mfs_ioctl(void *v)
124: {
125: #if 0
126: struct vop_ioctl_args *ap = v;
127: #endif
128:
129: return (ENOTTY);
130: }
131:
132: /*
133: * Pass I/O requests to the memory filesystem process.
134: */
135: int
136: mfs_strategy(void *v)
137: {
138: struct vop_strategy_args *ap = v;
139: struct buf *bp = ap->a_bp;
140: struct mfsnode *mfsp;
141: struct vnode *vp;
142: struct proc *p = curproc;
143: int s;
144:
145: if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
146: panic("mfs_strategy: bad dev");
147:
148: mfsp = VTOMFS(vp);
149: /* check for mini-root access */
150: if (mfsp->mfs_pid == 0) {
151: caddr_t base;
152:
153: base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT);
154: if (bp->b_flags & B_READ)
155: bcopy(base, bp->b_data, bp->b_bcount);
156: else
157: bcopy(bp->b_data, base, bp->b_bcount);
158: s = splbio();
159: biodone(bp);
160: splx(s);
161: } else if (p != NULL && mfsp->mfs_pid == p->p_pid) {
162: mfs_doio(bp, mfsp->mfs_baseoff);
163: } else {
164: bp->b_actf = mfsp->mfs_buflist;
165: mfsp->mfs_buflist = bp;
166: wakeup((caddr_t)vp);
167: }
168: return (0);
169: }
170:
171: /*
172: * Memory file system I/O.
173: *
174: * Trivial on the HP since buffer has already been mapped into KVA space.
175: */
176: void
177: mfs_doio(struct buf *bp, caddr_t base)
178: {
179: int s;
180:
181: base += (bp->b_blkno << DEV_BSHIFT);
182: if (bp->b_flags & B_READ)
183: bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
184: else
185: bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
186: if (bp->b_error)
187: bp->b_flags |= B_ERROR;
188: else
189: bp->b_resid = 0;
190: s = splbio();
191: biodone(bp);
192: splx(s);
193: }
194:
195: /*
196: * This is a noop, simply returning what one has been given.
197: */
198: int
199: mfs_bmap(void *v)
200: {
201: struct vop_bmap_args *ap = v;
202:
203: if (ap->a_vpp != NULL)
204: *ap->a_vpp = ap->a_vp;
205: if (ap->a_bnp != NULL)
206: *ap->a_bnp = ap->a_bn;
207: if (ap->a_runp != NULL)
208: *ap->a_runp = 0;
209:
210: return (0);
211: }
212:
213: /*
214: * Memory filesystem close routine
215: */
216: /* ARGSUSED */
217: int
218: mfs_close(void *v)
219: {
220: struct vop_close_args *ap = v;
221: struct vnode *vp = ap->a_vp;
222: struct mfsnode *mfsp = VTOMFS(vp);
223: struct buf *bp;
224: int error;
225:
226: /*
227: * Finish any pending I/O requests.
228: */
229: while ((bp = mfsp->mfs_buflist) != NULL) {
230: mfsp->mfs_buflist = bp->b_actf;
231: mfs_doio(bp, mfsp->mfs_baseoff);
232: wakeup((caddr_t)bp);
233: }
234: /*
235: * On last close of a memory filesystem
236: * we must invalidate any in core blocks, so that
237: * we can free up its vnode.
238: */
239: if ((error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 0, 0)) != 0)
240: return (error);
241: #ifdef DIAGNOSTIC
242: /*
243: * There should be no way to have any more uses of this
244: * vnode, so if we find any other uses, it is a panic.
245: */
246: if (vp->v_usecount > 1)
247: printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
248: if (mfsp->mfs_buflist)
249: printf("mfs_close: dirty buffers\n");
250: if (vp->v_usecount > 1 || mfsp->mfs_buflist)
251: panic("mfs_close");
252: #endif
253: /*
254: * Send a request to the filesystem server to exit.
255: */
256: mfsp->mfs_buflist = (struct buf *)(-1);
257: wakeup((caddr_t)vp);
258: return (0);
259: }
260:
261: /*
262: * Memory filesystem inactive routine
263: */
264: /* ARGSUSED */
265: int
266: mfs_inactive(void *v)
267: {
268: struct vop_inactive_args *ap = v;
269: #ifdef DIAGNOSTIC
270: struct mfsnode *mfsp = VTOMFS(ap->a_vp);
271:
272: if (mfsp->mfs_buflist && mfsp->mfs_buflist != (struct buf *)(-1))
273: panic("mfs_inactive: not inactive (mfs_buflist %p)",
274: mfsp->mfs_buflist);
275: #endif
276: VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
277: return (0);
278: }
279:
280: /*
281: * Reclaim a memory filesystem devvp so that it can be reused.
282: */
283: int
284: mfs_reclaim(void *v)
285: {
286: struct vop_reclaim_args *ap = v;
287: struct vnode *vp = ap->a_vp;
288:
289: free(vp->v_data, M_MFSNODE);
290: vp->v_data = NULL;
291: return (0);
292: }
293:
294: /*
295: * Print out the contents of an mfsnode.
296: */
297: int
298: mfs_print(void *v)
299: {
300: struct vop_print_args *ap = v;
301: struct mfsnode *mfsp = VTOMFS(ap->a_vp);
302:
303: printf("tag VT_MFS, pid %d, base %p, size %ld\n", mfsp->mfs_pid,
304: mfsp->mfs_baseoff, mfsp->mfs_size);
305: return (0);
306: }
307:
308: /*
309: * Block device bad operation
310: */
311: int
312: mfs_badop(void *v)
313: {
314: panic("mfs_badop called");
315: /* NOTREACHED */
316: }
CVSweb