vm_vfs.c revision 1.3.4.2 1 1.3.4.2 skrll /* $NetBSD: vm_vfs.c,v 1.3.4.2 2009/01/19 13:20:27 skrll Exp $ */
2 1.3.4.2 skrll
3 1.3.4.2 skrll /*
4 1.3.4.2 skrll * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
5 1.3.4.2 skrll *
6 1.3.4.2 skrll * Development of this software was supported by the
7 1.3.4.2 skrll * Finnish Cultural Foundation.
8 1.3.4.2 skrll *
9 1.3.4.2 skrll * Redistribution and use in source and binary forms, with or without
10 1.3.4.2 skrll * modification, are permitted provided that the following conditions
11 1.3.4.2 skrll * are met:
12 1.3.4.2 skrll * 1. Redistributions of source code must retain the above copyright
13 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer.
14 1.3.4.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
15 1.3.4.2 skrll * notice, this list of conditions and the following disclaimer in the
16 1.3.4.2 skrll * documentation and/or other materials provided with the distribution.
17 1.3.4.2 skrll *
18 1.3.4.2 skrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 1.3.4.2 skrll * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 1.3.4.2 skrll * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 1.3.4.2 skrll * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 1.3.4.2 skrll * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 1.3.4.2 skrll * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 1.3.4.2 skrll * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 1.3.4.2 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 1.3.4.2 skrll * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 1.3.4.2 skrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.3.4.2 skrll * SUCH DAMAGE.
29 1.3.4.2 skrll */
30 1.3.4.2 skrll
31 1.3.4.2 skrll #include <sys/cdefs.h>
32 1.3.4.2 skrll __KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.3.4.2 2009/01/19 13:20:27 skrll Exp $");
33 1.3.4.2 skrll
34 1.3.4.2 skrll #include <sys/param.h>
35 1.3.4.2 skrll
36 1.3.4.2 skrll #include <sys/buf.h>
37 1.3.4.2 skrll #include <sys/vnode.h>
38 1.3.4.2 skrll
39 1.3.4.2 skrll #include <uvm/uvm.h>
40 1.3.4.2 skrll #include <uvm/uvm_readahead.h>
41 1.3.4.2 skrll
42 1.3.4.2 skrll static int vn_get(struct uvm_object *, voff_t, struct vm_page **,
43 1.3.4.2 skrll int *, int, vm_prot_t, int, int);
44 1.3.4.2 skrll static int vn_put(struct uvm_object *, voff_t, voff_t, int);
45 1.3.4.2 skrll
46 1.3.4.2 skrll const struct uvm_pagerops uvm_vnodeops = {
47 1.3.4.2 skrll .pgo_get = vn_get,
48 1.3.4.2 skrll .pgo_put = vn_put,
49 1.3.4.2 skrll };
50 1.3.4.2 skrll
51 1.3.4.2 skrll /*
52 1.3.4.2 skrll * vnode pager
53 1.3.4.2 skrll */
54 1.3.4.2 skrll
55 1.3.4.2 skrll static int
56 1.3.4.2 skrll vn_get(struct uvm_object *uobj, voff_t off, struct vm_page **pgs,
57 1.3.4.2 skrll int *npages, int centeridx, vm_prot_t access_type,
58 1.3.4.2 skrll int advice, int flags)
59 1.3.4.2 skrll {
60 1.3.4.2 skrll struct vnode *vp = (struct vnode *)uobj;
61 1.3.4.2 skrll
62 1.3.4.2 skrll return VOP_GETPAGES(vp, off, pgs, npages, centeridx, access_type,
63 1.3.4.2 skrll advice, flags);
64 1.3.4.2 skrll }
65 1.3.4.2 skrll
66 1.3.4.2 skrll static int
67 1.3.4.2 skrll vn_put(struct uvm_object *uobj, voff_t offlo, voff_t offhi, int flags)
68 1.3.4.2 skrll {
69 1.3.4.2 skrll struct vnode *vp = (struct vnode *)uobj;
70 1.3.4.2 skrll
71 1.3.4.2 skrll return VOP_PUTPAGES(vp, offlo, offhi, flags);
72 1.3.4.2 skrll }
73 1.3.4.2 skrll
74 1.3.4.2 skrll void
75 1.3.4.2 skrll uvm_aio_biodone1(struct buf *bp)
76 1.3.4.2 skrll {
77 1.3.4.2 skrll
78 1.3.4.2 skrll panic("%s: unimplemented", __func__);
79 1.3.4.2 skrll }
80 1.3.4.2 skrll
81 1.3.4.2 skrll void
82 1.3.4.2 skrll uvm_aio_biodone(struct buf *bp)
83 1.3.4.2 skrll {
84 1.3.4.2 skrll
85 1.3.4.2 skrll uvm_aio_aiodone(bp);
86 1.3.4.2 skrll }
87 1.3.4.2 skrll
88 1.3.4.2 skrll void
89 1.3.4.2 skrll uvm_aio_aiodone(struct buf *bp)
90 1.3.4.2 skrll {
91 1.3.4.2 skrll
92 1.3.4.2 skrll if (((bp->b_flags|bp->b_cflags) & (B_READ|BC_NOCACHE)) == 0 && bioopsp)
93 1.3.4.2 skrll bioopsp->io_pageiodone(bp);
94 1.3.4.2 skrll }
95 1.3.4.2 skrll
96 1.3.4.2 skrll struct uvm_ractx *
97 1.3.4.2 skrll uvm_ra_allocctx()
98 1.3.4.2 skrll {
99 1.3.4.2 skrll
100 1.3.4.2 skrll return NULL;
101 1.3.4.2 skrll }
102 1.3.4.2 skrll
103 1.3.4.2 skrll void
104 1.3.4.2 skrll uvm_ra_freectx(struct uvm_ractx *ra)
105 1.3.4.2 skrll {
106 1.3.4.2 skrll
107 1.3.4.2 skrll return;
108 1.3.4.2 skrll }
109 1.3.4.2 skrll
110 1.3.4.2 skrll bool
111 1.3.4.2 skrll uvn_clean_p(struct uvm_object *uobj)
112 1.3.4.2 skrll {
113 1.3.4.2 skrll struct vnode *vp = (void *)uobj;
114 1.3.4.2 skrll
115 1.3.4.2 skrll return (vp->v_iflag & VI_ONWORKLST) == 0;
116 1.3.4.2 skrll }
117 1.3.4.2 skrll
118 1.3.4.2 skrll void
119 1.3.4.2 skrll uvm_vnp_setsize(struct vnode *vp, voff_t newsize)
120 1.3.4.2 skrll {
121 1.3.4.2 skrll
122 1.3.4.2 skrll mutex_enter(&vp->v_interlock);
123 1.3.4.2 skrll vp->v_size = vp->v_writesize = newsize;
124 1.3.4.2 skrll mutex_exit(&vp->v_interlock);
125 1.3.4.2 skrll }
126 1.3.4.2 skrll
127 1.3.4.2 skrll void
128 1.3.4.2 skrll uvm_vnp_setwritesize(struct vnode *vp, voff_t newsize)
129 1.3.4.2 skrll {
130 1.3.4.2 skrll
131 1.3.4.2 skrll mutex_enter(&vp->v_interlock);
132 1.3.4.2 skrll vp->v_writesize = newsize;
133 1.3.4.2 skrll mutex_exit(&vp->v_interlock);
134 1.3.4.2 skrll }
135 1.3.4.2 skrll
136 1.3.4.2 skrll void
137 1.3.4.2 skrll uvm_vnp_zerorange(struct vnode *vp, off_t off, size_t len)
138 1.3.4.2 skrll {
139 1.3.4.2 skrll struct uvm_object *uobj = &vp->v_uobj;
140 1.3.4.2 skrll struct vm_page **pgs;
141 1.3.4.2 skrll int maxpages = MIN(32, round_page(len) >> PAGE_SHIFT);
142 1.3.4.2 skrll int rv, npages, i;
143 1.3.4.2 skrll
144 1.3.4.2 skrll pgs = kmem_zalloc(maxpages * sizeof(pgs), KM_SLEEP);
145 1.3.4.2 skrll while (len) {
146 1.3.4.2 skrll npages = MIN(maxpages, round_page(len) >> PAGE_SHIFT);
147 1.3.4.2 skrll memset(pgs, 0, npages * sizeof(struct vm_page *));
148 1.3.4.2 skrll mutex_enter(&uobj->vmobjlock);
149 1.3.4.2 skrll rv = uobj->pgops->pgo_get(uobj, off, pgs, &npages, 0, 0, 0, 0);
150 1.3.4.2 skrll KASSERT(npages > 0);
151 1.3.4.2 skrll
152 1.3.4.2 skrll for (i = 0; i < npages; i++) {
153 1.3.4.2 skrll uint8_t *start;
154 1.3.4.2 skrll size_t chunkoff, chunklen;
155 1.3.4.2 skrll
156 1.3.4.2 skrll chunkoff = off & PAGE_MASK;
157 1.3.4.2 skrll chunklen = MIN(PAGE_SIZE - chunkoff, len);
158 1.3.4.2 skrll start = (uint8_t *)pgs[i]->uanon + chunkoff;
159 1.3.4.2 skrll
160 1.3.4.2 skrll memset(start, 0, chunklen);
161 1.3.4.2 skrll pgs[i]->flags &= ~PG_CLEAN;
162 1.3.4.2 skrll
163 1.3.4.2 skrll off += chunklen;
164 1.3.4.2 skrll len -= chunklen;
165 1.3.4.2 skrll }
166 1.3.4.2 skrll uvm_page_unbusy(pgs, npages);
167 1.3.4.2 skrll }
168 1.3.4.2 skrll kmem_free(pgs, maxpages * sizeof(pgs));
169 1.3.4.2 skrll
170 1.3.4.2 skrll return;
171 1.3.4.2 skrll }
172 1.3.4.2 skrll
173 1.3.4.2 skrll /*
174 1.3.4.2 skrll * UBC
175 1.3.4.2 skrll */
176 1.3.4.2 skrll
177 1.3.4.2 skrll /* dumdidumdum */
178 1.3.4.2 skrll #define len2npages(off, len) \
179 1.3.4.2 skrll (((((len) + PAGE_MASK) & ~(PAGE_MASK)) >> PAGE_SHIFT) \
180 1.3.4.2 skrll + (((off & PAGE_MASK) + (len & PAGE_MASK)) > PAGE_SIZE))
181 1.3.4.2 skrll
182 1.3.4.2 skrll int
183 1.3.4.2 skrll ubc_uiomove(struct uvm_object *uobj, struct uio *uio, vsize_t todo,
184 1.3.4.2 skrll int advice, int flags)
185 1.3.4.2 skrll {
186 1.3.4.2 skrll struct vm_page **pgs;
187 1.3.4.2 skrll int npages = len2npages(uio->uio_offset, todo);
188 1.3.4.2 skrll size_t pgalloc;
189 1.3.4.2 skrll int i, rv;
190 1.3.4.2 skrll
191 1.3.4.2 skrll pgalloc = npages * sizeof(pgs);
192 1.3.4.2 skrll pgs = kmem_zalloc(pgalloc, KM_SLEEP);
193 1.3.4.2 skrll
194 1.3.4.2 skrll do {
195 1.3.4.2 skrll mutex_enter(&uobj->vmobjlock);
196 1.3.4.2 skrll rv = uobj->pgops->pgo_get(uobj, uio->uio_offset, pgs, &npages,
197 1.3.4.2 skrll 0, 0, 0, 0);
198 1.3.4.2 skrll if (rv)
199 1.3.4.2 skrll goto out;
200 1.3.4.2 skrll
201 1.3.4.2 skrll for (i = 0; i < npages; i++) {
202 1.3.4.2 skrll size_t xfersize;
203 1.3.4.2 skrll off_t pageoff;
204 1.3.4.2 skrll
205 1.3.4.2 skrll pageoff = uio->uio_offset & PAGE_MASK;
206 1.3.4.2 skrll xfersize = MIN(MIN(todo, PAGE_SIZE), PAGE_SIZE-pageoff);
207 1.3.4.2 skrll uiomove((uint8_t *)pgs[i]->uanon + pageoff,
208 1.3.4.2 skrll xfersize, uio);
209 1.3.4.2 skrll if (uio->uio_rw == UIO_WRITE)
210 1.3.4.2 skrll pgs[i]->flags &= ~PG_CLEAN;
211 1.3.4.2 skrll todo -= xfersize;
212 1.3.4.2 skrll }
213 1.3.4.2 skrll uvm_page_unbusy(pgs, npages);
214 1.3.4.2 skrll } while (todo);
215 1.3.4.2 skrll
216 1.3.4.2 skrll out:
217 1.3.4.2 skrll kmem_free(pgs, pgalloc);
218 1.3.4.2 skrll return rv;
219 1.3.4.2 skrll }
220