xref: /386bsd/usr/src/kernel/mfs/mfs_vnops.c (revision a2142627)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. 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  *
33  *	@(#)mfs_vnops.c	7.22 (Berkeley) 4/16/91
34  */
35 
36 #include "sys/param.h"
37 #include "sys/file.h"
38 #include "sys/time.h"
39 #include "uio.h"
40 #include "sys/errno.h"	/* for inlines */
41 #include "systm.h"
42 #include "proc.h"
43 #include "buf.h"
44 
45 #include "vnode.h"
46 #include "mfs_node.h"
47 
48 #include "prototypes.h"
49 
50 /*
51  * mfs vnode operations.
52  */
53 struct vnodeops mfs_vnodeops = {
54 	mfs_lookup,		/* lookup */
55 	mfs_create,		/* create */
56 	mfs_mknod,		/* mknod */
57 	mfs_open,		/* open */
58 	mfs_close,		/* close */
59 	mfs_access,		/* access */
60 	mfs_getattr,		/* getattr */
61 	mfs_setattr,		/* setattr */
62 	mfs_read,		/* read */
63 	mfs_write,		/* write */
64 	mfs_ioctl,		/* ioctl */
65 	mfs_select,		/* select */
66 	mfs_mmap,		/* mmap */
67 	mfs_fsync,		/* fsync */
68 	mfs_seek,		/* seek */
69 	mfs_remove,		/* remove */
70 	mfs_link,		/* link */
71 	mfs_rename,		/* rename */
72 	mfs_mkdir,		/* mkdir */
73 	mfs_rmdir,		/* rmdir */
74 	mfs_symlink,		/* symlink */
75 	mfs_readdir,		/* readdir */
76 	mfs_readlink,		/* readlink */
77 	mfs_abortop,		/* abortop */
78 	mfs_inactive,		/* inactive */
79 	mfs_reclaim,		/* reclaim */
80 	mfs_lock,		/* lock */
81 	mfs_unlock,		/* unlock */
82 	mfs_bmap,		/* bmap */
83 	mfs_strategy,		/* strategy */
84 	mfs_print,		/* print */
85 	mfs_islocked,		/* islocked */
86 	mfs_advlock,		/* advlock */
87 };
88 
89 /*
90  * Vnode Operations.
91  *
92  * Open called to allow memory filesystem to initialize and
93  * validate before actual IO. Record our process identifier
94  * so we can tell when we are doing I/O to ourself.
95  */
96 /* ARGSUSED */
mfs_open(vp,mode,cred,p)97 mfs_open(vp, mode, cred, p)
98 	register struct vnode *vp;
99 	int mode;
100 	struct ucred *cred;
101 	struct proc *p;
102 {
103 
104 	if (vp->v_type != VBLK) {
105 		panic("mfs_ioctl not VBLK");
106 		/* NOTREACHED */
107 	}
108 	return (0);
109 }
110 
111 /*
112  * Ioctl operation.
113  */
114 /* ARGSUSED */
115 mfs_ioctl(vp, com, data, fflag, cred, p)
116 	struct vnode *vp;
117 	int com;
118 	caddr_t data;
119 	int fflag;
120 	struct ucred *cred;
121 	struct proc *p;
122 {
123 
124 	return (-1);
125 }
126 
127 /*
128  * Pass I/O requests to the memory filesystem process.
129  */
mfs_strategy(bp)130 mfs_strategy(bp)
131 	register struct buf *bp;
132 {
133 	register struct mfsnode *mfsp;
134 	struct vnode *vp;
135 	struct proc *p = curproc;		/* XXX */
136 
137 	if (spec_find(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
138 		panic("mfs_strategy: bad dev");
139 	mfsp = VTOMFS(vp);
140 	if (mfsp->mfs_pid == p->p_pid) {
141 		mfs_doio(bp, mfsp->mfs_baseoff);
142 	} else {
143 		bp->av_forw = mfsp->mfs_buflist;
144 		mfsp->mfs_buflist = bp;
145 		wakeup((caddr_t)vp);
146 	}
147 	return (0);
148 }
149 
150 /*
151  * Memory file system I/O.
152  *
153  * Trivial since buffer has already been mapping into KVA space.
154  */
mfs_doio(bp,base)155 mfs_doio(bp, base)
156 	register struct buf *bp;
157 	caddr_t base;
158 {
159 	base += (bp->b_blkno << DEV_BSHIFT);
160 	if (bp->b_flags & B_READ)
161 		bp->b_error = copyin(curproc, base, bp->b_un.b_addr, bp->b_bcount);
162 	else
163 		bp->b_error = copyout(curproc, bp->b_un.b_addr, base, bp->b_bcount);
164 	if (bp->b_error)
165 		bp->b_flags |= B_ERROR;
166 	biodone(bp);
167 }
168 
169 /*
170  * This is a noop, simply returning what one has been given.
171  */
172 mfs_bmap(vp, bn, vpp, bnp)
173 	struct vnode *vp;
174 	daddr_t bn;
175 	struct vnode **vpp;
176 	daddr_t *bnp;
177 {
178 
179 	if (vpp != NULL)
180 		*vpp = vp;
181 	if (bnp != NULL)
182 		*bnp = bn;
183 	return (0);
184 }
185 
186 /*
187  * Memory filesystem close routine
188  */
189 /* ARGSUSED */
mfs_close(vp,flag,cred,p)190 mfs_close(vp, flag, cred, p)
191 	register struct vnode *vp;
192 	int flag;
193 	struct ucred *cred;
194 	struct proc *p;
195 {
196 	register struct mfsnode *mfsp = VTOMFS(vp);
197 	register struct buf *bp;
198 
199 	/*
200 	 * Finish any pending I/O requests.
201 	 */
202 	while (bp = mfsp->mfs_buflist) {
203 		mfsp->mfs_buflist = bp->av_forw;
204 		mfs_doio(bp, mfsp->mfs_baseoff);
205 		wakeup((caddr_t)bp);
206 	}
207 	/*
208 	 * On last close of a memory filesystem
209 	 * we must invalidate any in core blocks, so that
210 	 * we can, free up its vnode.
211 	 */
212 	vflushbuf(vp, 0, 0);
213 	if (vinvalbuf(vp, 1))
214 		return (0);
215 	/*
216 	 * There should be no way to have any more uses of this
217 	 * vnode, so if we find any other uses, it is a panic.
218 	 */
219 	if (vp->v_usecount > 1)
220 		printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
221 	if (vp->v_usecount > 1 || mfsp->mfs_buflist)
222 		panic("mfs_close");
223 	/*
224 	 * Send a request to the filesystem server to exit.
225 	 */
226 	mfsp->mfs_buflist = (struct buf *)(-1);
227 	wakeup((caddr_t)vp);
228 	return (0);
229 }
230 
231 /*
232  * Memory filesystem inactive routine
233  */
234 /* ARGSUSED */
235 mfs_inactive(vp, p)
236 	struct vnode *vp;
237 	struct proc *p;
238 {
239 
240 	if (VTOMFS(vp)->mfs_buflist != (struct buf *)(-1))
241 		panic("mfs_inactive: not inactive");
242 	return (0);
243 }
244 
245 /*
246  * Print out the contents of an mfsnode.
247  */
248 mfs_print(vp)
249 	struct vnode *vp;
250 {
251 	register struct mfsnode *mfsp = VTOMFS(vp);
252 
253 	printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid,
254 		mfsp->mfs_baseoff, mfsp->mfs_size);
255 }
256 
257 /*
258  * Block device bad operation
259  */
mfs_badop()260 mfs_badop()
261 {
262 
263 	panic("mfs_badop called\n");
264 	/* NOTREACHED */
265 }
266