Deleted Added
sdiff udiff text old ( 107832 ) new ( 107953 )
full compact
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the

--- 18 unchanged lines hidden (view full) ---

27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $FreeBSD: head/sys/geom/geom_slice.c 107832 2002-12-13 21:31:13Z phk $
36 */
37
38
39#include <sys/param.h>
40#include <sys/stdint.h>
41#ifndef _KERNEL
42#include <stdio.h>
43#include <unistd.h>

--- 33 unchanged lines hidden (view full) ---

77 M_WAITOK | M_ZERO);
78 gsp->nslice = nslice;
79 return (gsp);
80}
81
82static int
83g_slice_access(struct g_provider *pp, int dr, int dw, int de)
84{
85 int error, i;
86 struct g_geom *gp;
87 struct g_consumer *cp;
88 struct g_provider *pp2;
89 struct g_slicer *gsp;
90 struct g_slice *gsl, *gsl2;
91
92 gp = pp->geom;
93 cp = LIST_FIRST(&gp->consumer);
94 KASSERT (cp != NULL, ("g_slice_access but no consumer"));
95 gsp = gp->softc;
96 gsl = &gsp->slices[pp->index];
97 for (i = 0; i < gsp->nslice; i++) {
98 gsl2 = &gsp->slices[i];
99 if (gsl2->length == 0)
100 continue;
101 if (i == pp->index)
102 continue;
103 if (gsl->offset + gsl->length <= gsl2->offset)
104 continue;
105 if (gsl2->offset + gsl2->length <= gsl->offset)
106 continue;
107 /* overlap */
108 pp2 = gsl2->provider;
109 if ((pp->acw + dw) > 0 && pp2->ace > 0)

--- 14 unchanged lines hidden (view full) ---

124void
125g_slice_finish_hot(struct bio *bp)
126{
127 struct bio *bp2;
128 struct g_geom *gp;
129 struct g_consumer *cp;
130 struct g_slicer *gsp;
131 struct g_slice *gsl;
132 int index;
133
134 KASSERT(bp->bio_to != NULL, ("NULL bio_to in g_slice_finish_hot(%p)", bp));
135 KASSERT(bp->bio_from != NULL, ("NULL bio_from in g_slice_finish_hot(%p)", bp));
136 gp = bp->bio_to->geom;
137 gsp = gp->softc;
138 cp = LIST_FIRST(&gp->consumer);
139 KASSERT(cp != NULL, ("NULL consumer in g_slice_finish_hot(%p)", bp));
140 index = bp->bio_to->index;
141 gsl = &gsp->slices[index];
142
143 bp2 = g_clone_bio(bp);
144 if (bp2 == NULL) {
145 g_io_deliver(bp, ENOMEM);
146 return;
147 }
148 if (bp2->bio_offset + bp2->bio_length > gsl->length)
149 bp2->bio_length = gsl->length - bp2->bio_offset;

--- 7 unchanged lines hidden (view full) ---

157g_slice_start(struct bio *bp)
158{
159 struct bio *bp2;
160 struct g_provider *pp;
161 struct g_geom *gp;
162 struct g_consumer *cp;
163 struct g_slicer *gsp;
164 struct g_slice *gsl, *gmp;
165 int index, error;
166 u_int m_index;
167 off_t t;
168
169 pp = bp->bio_to;
170 gp = pp->geom;
171 gsp = gp->softc;
172 cp = LIST_FIRST(&gp->consumer);
173 index = pp->index;
174 gsl = &gsp->slices[index];
175 switch(bp->bio_cmd) {
176 case BIO_READ:
177 case BIO_WRITE:
178 case BIO_DELETE:
179 if (bp->bio_offset > gsl->length) {
180 g_io_deliver(bp, EINVAL); /* XXX: EWHAT ? */
181 return;
182 }

--- 45 unchanged lines hidden (view full) ---

228 g_handleattr_off_t(bp, "GEOM::frontstuff", t);
229 return;
230 }
231#ifdef _KERNEL
232 if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) {
233 struct g_kerneldump *gkd;
234
235 gkd = (struct g_kerneldump *)bp->bio_data;
236 gkd->offset += gsp->slices[index].offset;
237 if (gkd->length > gsp->slices[index].length)
238 gkd->length = gsp->slices[index].length;
239 /* now, pass it on downwards... */
240 }
241#endif
242 bp2 = g_clone_bio(bp);
243 if (bp2 == NULL) {
244 g_io_deliver(bp, ENOMEM);
245 return;
246 }
247 bp2->bio_done = g_std_done;
248 g_io_request(bp2, cp);
249 break;
250 default:
251 g_io_deliver(bp, EOPNOTSUPP);
252 return;
253 }
254}
255
256void
257g_slice_dumpconf(struct sbuf *sb, char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp)
258{
259 struct g_slicer *gsp;
260
261 gsp = gp->softc;
262 if (indent == NULL) {
263 sbuf_printf(sb, " i %u", pp->index);
264 sbuf_printf(sb, " o %ju",
265 (uintmax_t)gsp->slices[pp->index].offset);

--- 12 unchanged lines hidden (view full) ---

278 sbuf_printf(sb, "%s<offset>%ju</offset>\n", indent,
279 (uintmax_t)gsp->slices[pp->index].offset);
280 sbuf_printf(sb, "%s<secoffset>%ju</secoffset>\n", indent,
281 (uintmax_t)gsp->slices[pp->index].offset / 512);
282 }
283}
284
285int
286g_slice_config(struct g_geom *gp, u_int index, int how, off_t offset, off_t length, u_int sectorsize, char *fmt, ...)
287{
288 struct g_provider *pp;
289 struct g_slicer *gsp;
290 struct g_slice *gsl;
291 va_list ap;
292 struct sbuf *sb;
293 int error, acc;
294
295 g_trace(G_T_TOPOLOGY, "g_slice_config(%s, %d, %d)",
296 gp->name, index, how);
297 g_topology_assert();
298 gsp = gp->softc;
299 error = 0;
300 if (index >= gsp->nslice)
301 return(EINVAL);
302 gsl = &gsp->slices[index];
303 pp = gsl->provider;
304 if (pp != NULL)
305 acc = pp->acr + pp->acw + pp->ace;
306 else
307 acc = 0;
308 if (acc != 0 && how != G_SLICE_CONFIG_FORCE) {
309 if (length < gsl->length)
310 return(EBUSY);

--- 28 unchanged lines hidden (view full) ---

339 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
340 sbuf_vprintf(sb, fmt, ap);
341 sbuf_finish(sb);
342 pp = g_new_providerf(gp, sbuf_data(sb));
343 if (bootverbose)
344 printf("GEOM: Configure %s, start %jd length %jd end %jd\n",
345 pp->name, (intmax_t)offset, (intmax_t)length,
346 (intmax_t)(offset + length - 1));
347 pp->index = index;
348 pp->mediasize = gsl->length;
349 pp->sectorsize = gsl->sectorsize;
350 gsl->provider = pp;
351 gsp->nprovider++;
352 g_error_provider(pp, 0);
353 sbuf_delete(sb);
354 return(0);
355}
356
357int
358g_slice_conf_hot(struct g_geom *gp, u_int index, off_t offset, off_t length)
359{
360 struct g_slicer *gsp;
361 struct g_slice *gsl, *gsl2;
362
363 g_trace(G_T_TOPOLOGY, "g_slice_conf_hot()");
364 g_topology_assert();
365 gsp = gp->softc;
366 gsl = gsp->hot;
367 if(index >= gsp->nhot) {
368 gsl2 = g_malloc((index + 1) * sizeof *gsl2, M_WAITOK | M_ZERO);
369 if (gsp->hot != NULL)
370 bcopy(gsp->hot, gsl2, gsp->nhot * sizeof *gsl2);
371 gsp->hot = gsl2;
372 if (gsp->hot != NULL)
373 g_free(gsl);
374 gsl = gsl2;
375 gsp->nhot = index + 1;
376 }
377 if (bootverbose)
378 printf("GEOM: Add %s hot[%d] start %jd length %jd end %jd\n",
379 gp->name, index, (intmax_t)offset, (intmax_t)length,
380 (intmax_t)(offset + length - 1));
381 gsl[index].offset = offset;
382 gsl[index].length = length;
383 return (0);
384}
385
386struct g_provider *
387g_slice_addslice(struct g_geom *gp, int index, off_t offset, off_t length, u_int sectorsize, char *fmt, ...)
388{
389 struct g_provider *pp;
390 struct g_slicer *gsp;
391 va_list ap;
392 struct sbuf *sb;
393
394 g_trace(G_T_TOPOLOGY, "g_slice_addslice()");
395 g_topology_assert();
396 gsp = gp->softc;
397 va_start(ap, fmt);
398 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
399 sbuf_vprintf(sb, fmt, ap);
400 sbuf_finish(sb);
401 pp = g_new_providerf(gp, sbuf_data(sb));
402
403 pp->index = index;
404 gsp->slices[index].length = length;
405 gsp->slices[index].offset = offset;
406 gsp->slices[index].provider = pp;
407 gsp->slices[index].sectorsize = sectorsize;
408 pp->mediasize = gsp->slices[index].length;
409 pp->sectorsize = gsp->slices[index].sectorsize;
410 sbuf_delete(sb);
411 if (bootverbose)
412 printf("GEOM: Add %s, start %jd length %jd end %jd\n",
413 pp->name, (intmax_t)offset, (intmax_t)length,
414 (intmax_t)(offset + length - 1));
415 return(pp);
416}
417

--- 63 unchanged lines hidden ---