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