Line data Source code
1 : /* $OpenBSD: mfs_vnops.c,v 1.51 2018/04/28 03:13:05 visa 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 : #include <sys/mount.h>
44 : #include <sys/specdev.h>
45 :
46 : #include <ufs/mfs/mfsnode.h>
47 : #include <ufs/mfs/mfs_extern.h>
48 :
49 : /* mfs vnode operations. */
50 : struct vops mfs_vops = {
51 : .vop_lookup = mfs_badop,
52 : .vop_create = mfs_badop,
53 : .vop_mknod = mfs_badop,
54 : .vop_open = mfs_open,
55 : .vop_close = mfs_close,
56 : .vop_access = mfs_badop,
57 : .vop_getattr = mfs_badop,
58 : .vop_setattr = mfs_badop,
59 : .vop_read = mfs_badop,
60 : .vop_write = mfs_badop,
61 : .vop_ioctl = mfs_ioctl,
62 : .vop_poll = mfs_badop,
63 : .vop_revoke = mfs_revoke,
64 : .vop_fsync = spec_fsync,
65 : .vop_remove = mfs_badop,
66 : .vop_link = mfs_badop,
67 : .vop_rename = mfs_badop,
68 : .vop_mkdir = mfs_badop,
69 : .vop_rmdir = mfs_badop,
70 : .vop_symlink = mfs_badop,
71 : .vop_readdir = mfs_badop,
72 : .vop_readlink = mfs_badop,
73 : .vop_abortop = mfs_badop,
74 : .vop_inactive = mfs_inactive,
75 : .vop_reclaim = mfs_reclaim,
76 : .vop_lock = vop_generic_lock,
77 : .vop_unlock = vop_generic_unlock,
78 : .vop_bmap = vop_generic_bmap,
79 : .vop_strategy = mfs_strategy,
80 : .vop_print = mfs_print,
81 : .vop_islocked = vop_generic_islocked,
82 : .vop_pathconf = mfs_badop,
83 : .vop_advlock = mfs_badop,
84 : .vop_bwrite = vop_generic_bwrite
85 : };
86 :
87 : /*
88 : * Vnode Operations.
89 : *
90 : * Open called to allow memory filesystem to initialize and
91 : * validate before actual IO. Record our process identifier
92 : * so we can tell when we are doing I/O to ourself.
93 : */
94 : int
95 0 : mfs_open(void *v)
96 : {
97 : #ifdef DIAGNOSTIC
98 0 : struct vop_open_args *ap = v;
99 :
100 0 : if (ap->a_vp->v_type != VBLK) {
101 0 : panic("mfs_open not VBLK");
102 : }
103 : #endif
104 0 : return (0);
105 : }
106 :
107 : /*
108 : * Ioctl operation.
109 : */
110 : int
111 0 : mfs_ioctl(void *v)
112 : {
113 :
114 0 : return (ENOTTY);
115 : }
116 :
117 : /*
118 : * Pass I/O requests to the memory filesystem process.
119 : */
120 : int
121 0 : mfs_strategy(void *v)
122 : {
123 0 : struct vop_strategy_args *ap = v;
124 0 : struct buf *bp = ap->a_bp;
125 : struct mfsnode *mfsp;
126 0 : struct vnode *vp;
127 0 : struct proc *p = curproc;
128 :
129 0 : if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
130 0 : panic("mfs_strategy: bad dev");
131 :
132 0 : mfsp = VTOMFS(vp);
133 0 : if (p != NULL && mfsp->mfs_tid == p->p_tid) {
134 0 : mfs_doio(mfsp, bp);
135 0 : } else {
136 0 : bufq_queue(&mfsp->mfs_bufq, bp);
137 0 : wakeup(vp);
138 : }
139 0 : return (0);
140 0 : }
141 :
142 : /*
143 : * Memory file system I/O.
144 : */
145 : void
146 0 : mfs_doio(struct mfsnode *mfsp, struct buf *bp)
147 : {
148 : caddr_t base;
149 0 : long offset = bp->b_blkno << DEV_BSHIFT;
150 : int s;
151 :
152 0 : if (bp->b_bcount > mfsp->mfs_size - offset)
153 0 : bp->b_bcount = mfsp->mfs_size - offset;
154 :
155 0 : base = mfsp->mfs_baseoff + offset;
156 0 : if (bp->b_flags & B_READ)
157 0 : bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
158 : else
159 0 : bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
160 0 : if (bp->b_error)
161 0 : bp->b_flags |= B_ERROR;
162 : else
163 0 : bp->b_resid = 0;
164 0 : s = splbio();
165 0 : biodone(bp);
166 0 : splx(s);
167 0 : }
168 :
169 : /*
170 : * Memory filesystem close routine
171 : */
172 : int
173 0 : mfs_close(void *v)
174 : {
175 0 : struct vop_close_args *ap = v;
176 0 : struct vnode *vp = ap->a_vp;
177 0 : struct mfsnode *mfsp = VTOMFS(vp);
178 : struct buf *bp;
179 : int error;
180 :
181 : /*
182 : * Finish any pending I/O requests.
183 : */
184 0 : while (1) {
185 0 : bp = bufq_dequeue(&mfsp->mfs_bufq);
186 0 : if (bp == NULL)
187 : break;
188 0 : mfs_doio(mfsp, bp);
189 0 : wakeup(bp);
190 : }
191 :
192 : /*
193 : * On last close of a memory filesystem we must invalidate any in
194 : * core blocks, so that we can free up its vnode.
195 : */
196 0 : if ((error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 0, 0)) != 0)
197 0 : return (error);
198 :
199 : #ifdef DIAGNOSTIC
200 : /*
201 : * There should be no way to have any more buffers on this vnode.
202 : */
203 0 : if (bufq_peek(&mfsp->mfs_bufq))
204 0 : printf("mfs_close: dirty buffers\n");
205 : #endif
206 :
207 : /*
208 : * Send a request to the filesystem server to exit.
209 : */
210 0 : mfsp->mfs_shutdown = 1;
211 0 : wakeup(vp);
212 0 : return (0);
213 0 : }
214 :
215 : /*
216 : * Memory filesystem inactive routine
217 : */
218 : int
219 0 : mfs_inactive(void *v)
220 : {
221 0 : struct vop_inactive_args *ap = v;
222 : #ifdef DIAGNOSTIC
223 0 : struct mfsnode *mfsp = VTOMFS(ap->a_vp);
224 :
225 0 : if (mfsp->mfs_shutdown && bufq_peek(&mfsp->mfs_bufq))
226 0 : panic("mfs_inactive: not inactive");
227 : #endif
228 0 : VOP_UNLOCK(ap->a_vp);
229 0 : return (0);
230 : }
231 :
232 : /*
233 : * Reclaim a memory filesystem devvp so that it can be reused.
234 : */
235 : int
236 0 : mfs_reclaim(void *v)
237 : {
238 0 : struct vop_reclaim_args *ap = v;
239 0 : struct vnode *vp = ap->a_vp;
240 :
241 0 : free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode));
242 0 : vp->v_data = NULL;
243 0 : return (0);
244 : }
245 :
246 : /*
247 : * Print out the contents of an mfsnode.
248 : */
249 : int
250 0 : mfs_print(void *v)
251 : {
252 0 : struct vop_print_args *ap = v;
253 0 : struct mfsnode *mfsp = VTOMFS(ap->a_vp);
254 :
255 0 : printf("tag VT_MFS, tid %d, base %p, size %ld\n", mfsp->mfs_tid,
256 0 : mfsp->mfs_baseoff, mfsp->mfs_size);
257 0 : return (0);
258 : }
259 :
260 : /*
261 : * Block device bad operation
262 : */
263 : int
264 0 : mfs_badop(void *v)
265 : {
266 0 : panic("mfs_badop called");
267 : }
|