Deleted Added
full compact
g_uncompress.c (256281) g_uncompress.c (266220)
1/*-
2 * Copyright (c) 2010-2012 Aleksandr Rybalko
3 * Copyright (c) 2004 Max Khon
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

29 * GEOM UNCOMPRESS module - simple decompression module for use with read-only
30 * copressed images maked by mkuzip(8) or mkulzma(8) utilities.
31 *
32 * To enable module in kernel config, put this line:
33 * device geom_uncompress
34 */
35
36#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2010-2012 Aleksandr Rybalko
3 * Copyright (c) 2004 Max Khon
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

29 * GEOM UNCOMPRESS module - simple decompression module for use with read-only
30 * copressed images maked by mkuzip(8) or mkulzma(8) utilities.
31 *
32 * To enable module in kernel config, put this line:
33 * device geom_uncompress
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: stable/10/sys/geom/uncompress/g_uncompress.c 239790 2012-08-28 19:28:31Z ed $");
37__FBSDID("$FreeBSD: stable/10/sys/geom/uncompress/g_uncompress.c 266220 2014-05-16 14:28:55Z loos $");
38
39#include <sys/param.h>
40#include <sys/bio.h>
41#include <sys/endian.h>
42#include <sys/errno.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>

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

111{
112
113 if (gp != NULL) {
114 printf("%s: %d requests, %d cached\n",
115 gp->name, sc->req_total, sc->req_cached);
116 }
117 if (sc->offsets != NULL) {
118 free(sc->offsets, M_GEOM_UNCOMPRESS);
38
39#include <sys/param.h>
40#include <sys/bio.h>
41#include <sys/endian.h>
42#include <sys/errno.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>

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

111{
112
113 if (gp != NULL) {
114 printf("%s: %d requests, %d cached\n",
115 gp->name, sc->req_total, sc->req_cached);
116 }
117 if (sc->offsets != NULL) {
118 free(sc->offsets, M_GEOM_UNCOMPRESS);
119 sc->offsets = 0;
119 sc->offsets = NULL;
120 }
121
122 switch (sc->type) {
123 case GEOM_ULZMA:
124 if (sc->b) {
125 free(sc->b, M_GEOM_UNCOMPRESS);
126 sc->b = 0;
127 }

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

145}
146
147static void *
148z_alloc(void *nil, u_int type, u_int size)
149{
150 void *ptr;
151
152 ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
120 }
121
122 switch (sc->type) {
123 case GEOM_ULZMA:
124 if (sc->b) {
125 free(sc->b, M_GEOM_UNCOMPRESS);
126 sc->b = 0;
127 }

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

145}
146
147static void *
148z_alloc(void *nil, u_int type, u_int size)
149{
150 void *ptr;
151
152 ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
153
153 return (ptr);
154}
155
156static void
157z_free(void *nil, void *ptr)
158{
159
160 free(ptr, M_GEOM_UNCOMPRESS);
161}
162
163static void
164g_uncompress_done(struct bio *bp)
165{
166 struct g_uncompress_softc *sc;
167 struct g_provider *pp, *pp2;
168 struct g_consumer *cp;
169 struct g_geom *gp;
170 struct bio *bp2;
171 uint32_t start_blk, i;
154 return (ptr);
155}
156
157static void
158z_free(void *nil, void *ptr)
159{
160
161 free(ptr, M_GEOM_UNCOMPRESS);
162}
163
164static void
165g_uncompress_done(struct bio *bp)
166{
167 struct g_uncompress_softc *sc;
168 struct g_provider *pp, *pp2;
169 struct g_consumer *cp;
170 struct g_geom *gp;
171 struct bio *bp2;
172 uint32_t start_blk, i;
172 off_t pos, upos;
173 off_t iolen, pos, upos;
173 size_t bsize;
174 int err;
175
176 err = 0;
177 bp2 = bp->bio_parent;
178 pp = bp2->bio_to;
179 gp = pp->geom;
180 cp = LIST_FIRST(&gp->consumer);

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

205 * = sc->offsets[1] % 4 = 1020 % 4 = 0
206 */
207
208 /*
209 * Uncompress data.
210 */
211 start_blk = bp2->bio_offset / sc->blksz;
212 bsize = pp2->sectorsize;
174 size_t bsize;
175 int err;
176
177 err = 0;
178 bp2 = bp->bio_parent;
179 pp = bp2->bio_to;
180 gp = pp->geom;
181 cp = LIST_FIRST(&gp->consumer);

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

206 * = sc->offsets[1] % 4 = 1020 % 4 = 0
207 */
208
209 /*
210 * Uncompress data.
211 */
212 start_blk = bp2->bio_offset / sc->blksz;
213 bsize = pp2->sectorsize;
214 iolen = bp->bio_completed;
213 pos = sc->offsets[start_blk] % bsize;
214 upos = 0;
215
215 pos = sc->offsets[start_blk] % bsize;
216 upos = 0;
217
216 DPRINTF(("%s: done: bio_length %lld bio_completed %lld start_blk %d, "
217 "pos %lld, upos %lld (%lld, %d, %d)\n",
218 gp->name, bp->bio_length, bp->bio_completed, start_blk, pos, upos,
219 bp2->bio_offset, sc->blksz, bsize));
218 DPRINTF(("%s: done: bio_length %jd bio_completed %jd start_blk %d, "
219 "pos %jd, upos %jd (%jd, %d, %zu)\n",
220 gp->name, (intmax_t)bp->bio_length, (intmax_t)bp->bio_completed,
221 start_blk, (intmax_t)pos, (intmax_t)upos,
222 (intmax_t)bp2->bio_offset, sc->blksz, bsize));
220
221 for (i = start_blk; upos < bp2->bio_length; i++) {
223
224 for (i = start_blk; upos < bp2->bio_length; i++) {
222 off_t len, dlen, ulen, uoff;
225 off_t len, ulen, uoff;
223
224 uoff = i == start_blk ? bp2->bio_offset % sc->blksz : 0;
225 ulen = MIN(sc->blksz - uoff, bp2->bio_length - upos);
226
227 uoff = i == start_blk ? bp2->bio_offset % sc->blksz : 0;
228 ulen = MIN(sc->blksz - uoff, bp2->bio_length - upos);
226 dlen = len = sc->offsets[i + 1] - sc->offsets[i];
229 len = sc->offsets[i + 1] - sc->offsets[i];
227
230
228 DPRINTF(("%s: done: inflate block %d, start %lld, end %lld "
229 "len %lld\n",
230 gp->name, i, sc->offsets[i], sc->offsets[i + 1], len));
231 DPRINTF((
232 "%s: done: inflate block %d, start %ju, end %ju len %jd\n",
233 gp->name, i, (uintmax_t)sc->offsets[i],
234 (uintmax_t)sc->offsets[i + 1], (intmax_t)len));
231
232 if (len == 0) {
233 /* All zero block: no cache update */
234 bzero(bp2->bio_data + upos, ulen);
235 upos += ulen;
236 bp2->bio_completed += ulen;
237 continue;
238 }
235
236 if (len == 0) {
237 /* All zero block: no cache update */
238 bzero(bp2->bio_data + upos, ulen);
239 upos += ulen;
240 bp2->bio_completed += ulen;
241 continue;
242 }
239
243 if (len > iolen) {
244 DPRINTF(("%s: done: early termination: len (%jd) > "
245 "iolen (%jd)\n",
246 gp->name, (intmax_t)len, (intmax_t)iolen));
247 break;
248 }
240 mtx_lock(&sc->last_mtx);
241
242#ifdef GEOM_UNCOMPRESS_DEBUG
243 if (g_debugflags & 32)
249 mtx_lock(&sc->last_mtx);
250
251#ifdef GEOM_UNCOMPRESS_DEBUG
252 if (g_debugflags & 32)
244 hexdump(bp->bio_data + pos, dlen, 0, 0);
253 hexdump(bp->bio_data + pos, len, 0, 0);
245#endif
246
247 switch (sc->type) {
248 case GEOM_ULZMA:
249 sc->b->in = bp->bio_data + pos;
250 sc->b->out = sc->last_buf;
251 sc->b->in_pos = sc->b->out_pos = 0;
254#endif
255
256 switch (sc->type) {
257 case GEOM_ULZMA:
258 sc->b->in = bp->bio_data + pos;
259 sc->b->out = sc->last_buf;
260 sc->b->in_pos = sc->b->out_pos = 0;
252 sc->b->in_size = dlen;
261 sc->b->in_size = len;
253 sc->b->out_size = (size_t)-1;
254
255 err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
256 1 : 0;
257 /* TODO decoder recovery, if needed */
258 break;
259 case GEOM_UZIP:
260 sc->zs->next_in = bp->bio_data + pos;
262 sc->b->out_size = (size_t)-1;
263
264 err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
265 1 : 0;
266 /* TODO decoder recovery, if needed */
267 break;
268 case GEOM_UZIP:
269 sc->zs->next_in = bp->bio_data + pos;
261 sc->zs->avail_in = dlen;
270 sc->zs->avail_in = len;
262 sc->zs->next_out = sc->last_buf;
263 sc->zs->avail_out = sc->blksz;
264
265 err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
266 1 : 0;
271 sc->zs->next_out = sc->last_buf;
272 sc->zs->avail_out = sc->blksz;
273
274 err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
275 1 : 0;
267 if ((err) && (inflateReset(sc->zs) != Z_OK))
276 if ((err) || (inflateReset(sc->zs) != Z_OK))
268 printf("%s: UZIP decoder reset failed\n",
269 gp->name);
270 break;
271 }
272
273 if (err) {
274 sc->last_blk = -1;
275 mtx_unlock(&sc->last_mtx);

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

285#endif
286
287 sc->last_blk = i;
288 DPRINTF(("%s: done: inflated \n", gp->name));
289 memcpy(bp2->bio_data + upos, sc->last_buf + uoff, ulen);
290 mtx_unlock(&sc->last_mtx);
291
292 pos += len;
277 printf("%s: UZIP decoder reset failed\n",
278 gp->name);
279 break;
280 }
281
282 if (err) {
283 sc->last_blk = -1;
284 mtx_unlock(&sc->last_mtx);

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

294#endif
295
296 sc->last_blk = i;
297 DPRINTF(("%s: done: inflated \n", gp->name));
298 memcpy(bp2->bio_data + upos, sc->last_buf + uoff, ulen);
299 mtx_unlock(&sc->last_mtx);
300
301 pos += len;
302 iolen -= len;
293 upos += ulen;
294 bp2->bio_completed += ulen;
295 }
296
297done:
298 /*
299 * Finish processing the request.
300 */
303 upos += ulen;
304 bp2->bio_completed += ulen;
305 }
306
307done:
308 /*
309 * Finish processing the request.
310 */
301 DPRINTF(("%s: done: (%d, %lld, %ld)\n",
302 gp->name, bp2->bio_error, bp2->bio_completed, bp2->bio_resid));
311 DPRINTF(("%s: done: (%d, %jd, %ld)\n",
312 gp->name, bp2->bio_error, (intmax_t)bp2->bio_completed,
313 bp2->bio_resid));
303 free(bp->bio_data, M_GEOM_UNCOMPRESS);
304 g_destroy_bio(bp);
305 g_io_deliver(bp2, bp2->bio_error);
306}
307
308static void
309g_uncompress_start(struct bio *bp)
310{
311 struct g_uncompress_softc *sc;
312 struct g_provider *pp, *pp2;
313 struct g_consumer *cp;
314 struct g_geom *gp;
315 struct bio *bp2;
316 uint32_t start_blk, end_blk;
317 size_t bsize;
318
314 free(bp->bio_data, M_GEOM_UNCOMPRESS);
315 g_destroy_bio(bp);
316 g_io_deliver(bp2, bp2->bio_error);
317}
318
319static void
320g_uncompress_start(struct bio *bp)
321{
322 struct g_uncompress_softc *sc;
323 struct g_provider *pp, *pp2;
324 struct g_consumer *cp;
325 struct g_geom *gp;
326 struct bio *bp2;
327 uint32_t start_blk, end_blk;
328 size_t bsize;
329
319
320 pp = bp->bio_to;
321 gp = pp->geom;
330 pp = bp->bio_to;
331 gp = pp->geom;
322 DPRINTF(("%s: start (%s) to %s off=%lld len=%lld\n", gp->name,
323 (bp->bio_cmd==BIO_READ) ? "BIO_READ" : "BIO_WRITE*",
324 pp->name, bp->bio_offset, bp->bio_length));
332 DPRINTF(("%s: start (%d:%s) to %s off=%jd len=%jd\n",
333 gp->name, bp->bio_cmd,
334 (bp->bio_cmd == BIO_READ) ? "BIO_READ" : "NOTSUPPORTED",
335 pp->name, (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length));
325
326 if (bp->bio_cmd != BIO_READ) {
327 g_io_deliver(bp, EOPNOTSUPP);
328 return;
329 }
330
331 cp = LIST_FIRST(&gp->consumer);
332 pp2 = cp->provider;
333 sc = gp->softc;
334
335 start_blk = bp->bio_offset / sc->blksz;
336 end_blk = howmany(bp->bio_offset + bp->bio_length, sc->blksz);
336
337 if (bp->bio_cmd != BIO_READ) {
338 g_io_deliver(bp, EOPNOTSUPP);
339 return;
340 }
341
342 cp = LIST_FIRST(&gp->consumer);
343 pp2 = cp->provider;
344 sc = gp->softc;
345
346 start_blk = bp->bio_offset / sc->blksz;
347 end_blk = howmany(bp->bio_offset + bp->bio_length, sc->blksz);
337 KASSERT(start_blk < sc->nblocks,
338 ("start_blk out of range"));
339 KASSERT(end_blk <= sc->nblocks,
340 ("end_blk out of range"));
348 KASSERT(start_blk < sc->nblocks, ("start_blk out of range"));
349 KASSERT(end_blk <= sc->nblocks, ("end_blk out of range"));
341
342 sc->req_total++;
343 if (start_blk + 1 == end_blk) {
344 mtx_lock(&sc->last_mtx);
345 if (start_blk == sc->last_blk) {
346 off_t uoff;
347
348 uoff = bp->bio_offset % sc->blksz;
349 KASSERT(bp->bio_length <= sc->blksz - uoff,
350 ("cached data error"));
351 memcpy(bp->bio_data, sc->last_buf + uoff,
352 bp->bio_length);
353 sc->req_cached++;
354 mtx_unlock(&sc->last_mtx);
355
350
351 sc->req_total++;
352 if (start_blk + 1 == end_blk) {
353 mtx_lock(&sc->last_mtx);
354 if (start_blk == sc->last_blk) {
355 off_t uoff;
356
357 uoff = bp->bio_offset % sc->blksz;
358 KASSERT(bp->bio_length <= sc->blksz - uoff,
359 ("cached data error"));
360 memcpy(bp->bio_data, sc->last_buf + uoff,
361 bp->bio_length);
362 sc->req_cached++;
363 mtx_unlock(&sc->last_mtx);
364
356 DPRINTF(("%s: start: cached 0 + %lld, "
357 "%lld + 0 + %lld\n",
358 gp->name, bp->bio_length, uoff, bp->bio_length));
365 DPRINTF(("%s: start: cached 0 + %jd, %jd + 0 + %jd\n",
366 gp->name, (intmax_t)bp->bio_length, (intmax_t)uoff,
367 (intmax_t)bp->bio_length));
359 bp->bio_completed = bp->bio_length;
360 g_io_deliver(bp, 0);
361 return;
362 }
363 mtx_unlock(&sc->last_mtx);
364 }
365
366 bp2 = g_clone_bio(bp);
367 if (bp2 == NULL) {
368 g_io_deliver(bp, ENOMEM);
369 return;
370 }
368 bp->bio_completed = bp->bio_length;
369 g_io_deliver(bp, 0);
370 return;
371 }
372 mtx_unlock(&sc->last_mtx);
373 }
374
375 bp2 = g_clone_bio(bp);
376 if (bp2 == NULL) {
377 g_io_deliver(bp, ENOMEM);
378 return;
379 }
371 DPRINTF(("%s: start (%d..%d), %s: %d + %llu, %s: %d + %llu\n",
380 DPRINTF(("%s: start (%d..%d), %s: %d + %jd, %s: %d + %jd\n",
372 gp->name, start_blk, end_blk,
381 gp->name, start_blk, end_blk,
373 pp->name, pp->sectorsize, pp->mediasize,
374 pp2->name, pp2->sectorsize, pp2->mediasize));
375
382 pp->name, pp->sectorsize, (intmax_t)pp->mediasize,
383 pp2->name, pp2->sectorsize, (intmax_t)pp2->mediasize));
376 bsize = pp2->sectorsize;
384 bsize = pp2->sectorsize;
377
378 bp2->bio_done = g_uncompress_done;
385 bp2->bio_done = g_uncompress_done;
379 bp2->bio_offset = rounddown(sc->offsets[start_blk],bsize);
380 bp2->bio_length = roundup(sc->offsets[end_blk],bsize) -
381 bp2->bio_offset;
382 bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
386 bp2->bio_offset = rounddown(sc->offsets[start_blk], bsize);
387 while (1) {
388 bp2->bio_length = roundup(sc->offsets[end_blk], bsize) -
389 bp2->bio_offset;
390 if (bp2->bio_length < MAXPHYS)
391 break;
383
392
384 DPRINTF(("%s: start %lld + %lld -> %lld + %lld -> %lld + %lld\n",
393 end_blk--;
394 DPRINTF((
395 "%s: bio_length (%jd) > MAXPHYS: lowering end_blk to %u\n",
396 gp->name, (intmax_t)bp2->bio_length, end_blk));
397 }
398 DPRINTF(("%s: start %jd + %jd -> %ju + %ju -> %jd + %jd\n",
385 gp->name,
399 gp->name,
386 bp->bio_offset, bp->bio_length,
387 sc->offsets[start_blk],
388 sc->offsets[end_blk] - sc->offsets[start_blk],
389 bp2->bio_offset, bp2->bio_length));
390
400 (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length,
401 (uintmax_t)sc->offsets[start_blk],
402 (uintmax_t)sc->offsets[end_blk] - sc->offsets[start_blk],
403 (intmax_t)bp2->bio_offset, (intmax_t)bp2->bio_length));
404 bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
391 if (bp2->bio_data == NULL) {
392 g_destroy_bio(bp2);
393 g_io_deliver(bp, ENOMEM);
394 return;
395 }
396
397 g_io_request(bp2, cp);
398 DPRINTF(("%s: start ok\n", gp->name));
399}
400
401static void
402g_uncompress_orphan(struct g_consumer *cp)
403{
404 struct g_geom *gp;
405
405 if (bp2->bio_data == NULL) {
406 g_destroy_bio(bp2);
407 g_io_deliver(bp, ENOMEM);
408 return;
409 }
410
411 g_io_request(bp2, cp);
412 DPRINTF(("%s: start ok\n", gp->name));
413}
414
415static void
416g_uncompress_orphan(struct g_consumer *cp)
417{
418 struct g_geom *gp;
419
406 g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp,
407 cp->provider->name);
420 g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->provider->name);
408 g_topology_assert();
409
410 gp = cp->geom;
411 g_uncompress_softc_free(gp->softc, gp);
412 gp->softc = NULL;
413 g_wither_geom(gp, ENXIO);
414}
415

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

446static struct g_geom *
447g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags)
448{
449 struct cloop_header *header;
450 struct g_uncompress_softc *sc;
451 struct g_provider *pp2;
452 struct g_consumer *cp;
453 struct g_geom *gp;
421 g_topology_assert();
422
423 gp = cp->geom;
424 g_uncompress_softc_free(gp->softc, gp);
425 gp->softc = NULL;
426 g_wither_geom(gp, ENXIO);
427}
428

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

459static struct g_geom *
460g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags)
461{
462 struct cloop_header *header;
463 struct g_uncompress_softc *sc;
464 struct g_provider *pp2;
465 struct g_consumer *cp;
466 struct g_geom *gp;
454 uint32_t i, total_offsets, offsets_read, type;
467 uint32_t i, total_offsets, type;
455 uint8_t *buf;
456 int error;
457
458 g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
459 g_topology_assert();
460
461 /* Skip providers that are already open for writing. */
462 if (pp->acw > 0)

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

479 return (NULL);
480 }
481 g_topology_unlock();
482
483 /*
484 * Read cloop header, look for CLOOP magic, perform
485 * other validity checks.
486 */
468 uint8_t *buf;
469 int error;
470
471 g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
472 g_topology_assert();
473
474 /* Skip providers that are already open for writing. */
475 if (pp->acw > 0)

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

492 return (NULL);
493 }
494 g_topology_unlock();
495
496 /*
497 * Read cloop header, look for CLOOP magic, perform
498 * other validity checks.
499 */
487 DPRINTF(("%s: media sectorsize %u, mediasize %lld\n",
488 gp->name, pp->sectorsize, pp->mediasize));
489
500 DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
501 gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
490 i = roundup(sizeof(struct cloop_header), pp->sectorsize);
491 buf = g_read_data(cp, 0, i, NULL);
492 if (buf == NULL)
493 goto err;
502 i = roundup(sizeof(struct cloop_header), pp->sectorsize);
503 buf = g_read_data(cp, 0, i, NULL);
504 if (buf == NULL)
505 goto err;
494
495 header = (struct cloop_header *) buf;
496 if (strncmp(header->magic, CLOOP_MAGIC_START,
506 header = (struct cloop_header *) buf;
507 if (strncmp(header->magic, CLOOP_MAGIC_START,
497 sizeof(CLOOP_MAGIC_START) - 1) != 0) {
508 sizeof(CLOOP_MAGIC_START) - 1) != 0) {
498 DPRINTF(("%s: no CLOOP magic\n", gp->name));
499 goto err;
500 }
501
502 switch (header->magic[0x0b]) {
503 case 'L':
504 type = GEOM_ULZMA;
505 if (header->magic[0x0c] < GEOM_ULZMA_MAJVER) {

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

541 }
542 total_offsets = sc->nblocks + 1;
543 if (sizeof(struct cloop_header) +
544 total_offsets * sizeof(uint64_t) > pp->mediasize) {
545 printf("%s: media too small for %u blocks\n",
546 gp->name, sc->nblocks);
547 goto err;
548 }
509 DPRINTF(("%s: no CLOOP magic\n", gp->name));
510 goto err;
511 }
512
513 switch (header->magic[0x0b]) {
514 case 'L':
515 type = GEOM_ULZMA;
516 if (header->magic[0x0c] < GEOM_ULZMA_MAJVER) {

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

552 }
553 total_offsets = sc->nblocks + 1;
554 if (sizeof(struct cloop_header) +
555 total_offsets * sizeof(uint64_t) > pp->mediasize) {
556 printf("%s: media too small for %u blocks\n",
557 gp->name, sc->nblocks);
558 goto err;
559 }
549 sc->offsets = malloc(
550 total_offsets * sizeof(uint64_t), M_GEOM_UNCOMPRESS, M_WAITOK);
551 offsets_read = MIN(total_offsets,
552 (pp->sectorsize - sizeof(*header)) / sizeof(uint64_t));
553 for (i = 0; i < offsets_read; i++)
554 sc->offsets[i] = be64toh(((uint64_t *) (header + 1))[i]);
555 DPRINTF(("%s: %u offsets in the first sector\n",
556 gp->name, offsets_read));
557
558 free(buf, M_GEOM);
560 free(buf, M_GEOM);
561
559 i = roundup((sizeof(struct cloop_header) +
562 i = roundup((sizeof(struct cloop_header) +
560 total_offsets * sizeof(uint64_t)),pp->sectorsize);
563 total_offsets * sizeof(uint64_t)), pp->sectorsize);
561 buf = g_read_data(cp, 0, i, NULL);
562 if (buf == NULL)
563 goto err;
564 buf = g_read_data(cp, 0, i, NULL);
565 if (buf == NULL)
566 goto err;
567 sc->offsets = malloc(total_offsets * sizeof(uint64_t),
568 M_GEOM_UNCOMPRESS, M_WAITOK);
564 for (i = 0; i <= total_offsets; i++) {
565 sc->offsets[i] = be64toh(((uint64_t *)
566 (buf+sizeof(struct cloop_header)))[i]);
567 }
569 for (i = 0; i <= total_offsets; i++) {
570 sc->offsets[i] = be64toh(((uint64_t *)
571 (buf+sizeof(struct cloop_header)))[i]);
572 }
573 free(buf, M_GEOM);
568 DPRINTF(("%s: done reading offsets\n", gp->name));
569 mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
570 sc->last_blk = -1;
571 sc->last_buf = malloc(sc->blksz, M_GEOM_UNCOMPRESS, M_WAITOK);
572 sc->req_total = 0;
573 sc->req_cached = 0;
574
575 switch (sc->type) {

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

594 pp2 = g_new_providerf(gp, "%s", gp->name);
595 pp2->sectorsize = 512;
596 pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
597 if (pp->stripesize > 0) {
598 pp2->stripesize = pp->stripesize;
599 pp2->stripeoffset = pp->stripeoffset;
600 }
601 g_error_provider(pp2, 0);
574 DPRINTF(("%s: done reading offsets\n", gp->name));
575 mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
576 sc->last_blk = -1;
577 sc->last_buf = malloc(sc->blksz, M_GEOM_UNCOMPRESS, M_WAITOK);
578 sc->req_total = 0;
579 sc->req_cached = 0;
580
581 switch (sc->type) {

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

600 pp2 = g_new_providerf(gp, "%s", gp->name);
601 pp2->sectorsize = 512;
602 pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
603 if (pp->stripesize > 0) {
604 pp2->stripesize = pp->stripesize;
605 pp2->stripeoffset = pp->stripeoffset;
606 }
607 g_error_provider(pp2, 0);
602 free(buf, M_GEOM);
603 g_access(cp, -1, 0, 0);
604
608 g_access(cp, -1, 0, 0);
609
605 DPRINTF(("%s: taste ok (%d, %lld), (%d, %d), %x\n",
610 DPRINTF(("%s: taste ok (%d, %jd), (%d, %d), %x\n",
606 gp->name,
611 gp->name,
607 pp2->sectorsize, pp2->mediasize,
612 pp2->sectorsize, (intmax_t)pp2->mediasize,
608 pp2->stripeoffset, pp2->stripesize, pp2->flags));
613 pp2->stripeoffset, pp2->stripesize, pp2->flags));
609 printf("%s: %u x %u blocks\n",
610 gp->name, sc->nblocks, sc->blksz);
614 printf("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz);
611 return (gp);
612
613err:
614 g_topology_lock();
615 g_access(cp, -1, 0, 0);
616 if (buf != NULL)
617 free(buf, M_GEOM);
618 if (gp->softc != NULL) {
619 g_uncompress_softc_free(gp->softc, NULL);
620 gp->softc = NULL;
621 }
622 g_detach(cp);
623 g_destroy_consumer(cp);
624 g_destroy_geom(gp);
615 return (gp);
616
617err:
618 g_topology_lock();
619 g_access(cp, -1, 0, 0);
620 if (buf != NULL)
621 free(buf, M_GEOM);
622 if (gp->softc != NULL) {
623 g_uncompress_softc_free(gp->softc, NULL);
624 gp->softc = NULL;
625 }
626 g_detach(cp);
627 g_destroy_consumer(cp);
628 g_destroy_geom(gp);
629
625 return (NULL);
626}
627
628static int
629g_uncompress_destroy_geom(struct gctl_req *req, struct g_class *mp,
630 struct g_geom *gp)
631{
632 struct g_provider *pp;

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

643 pp = LIST_FIRST(&gp->provider);
644 KASSERT(pp != NULL, ("NULL provider"));
645 if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)
646 return (EBUSY);
647
648 g_uncompress_softc_free(gp->softc, gp);
649 gp->softc = NULL;
650 g_wither_geom(gp, ENXIO);
630 return (NULL);
631}
632
633static int
634g_uncompress_destroy_geom(struct gctl_req *req, struct g_class *mp,
635 struct g_geom *gp)
636{
637 struct g_provider *pp;

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

648 pp = LIST_FIRST(&gp->provider);
649 KASSERT(pp != NULL, ("NULL provider"));
650 if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)
651 return (EBUSY);
652
653 g_uncompress_softc_free(gp->softc, gp);
654 gp->softc = NULL;
655 g_wither_geom(gp, ENXIO);
656
651 return (0);
652}
653
654static struct g_class g_uncompress_class = {
655 .name = UNCOMPRESS_CLASS_NAME,
656 .version = G_VERSION,
657 .taste = g_uncompress_taste,
658 .destroy_geom = g_uncompress_destroy_geom,
659
660 .start = g_uncompress_start,
661 .orphan = g_uncompress_orphan,
662 .access = g_uncompress_access,
663 .spoiled = g_uncompress_spoiled,
664};
665
666DECLARE_GEOM_CLASS(g_uncompress_class, g_uncompress);
657 return (0);
658}
659
660static struct g_class g_uncompress_class = {
661 .name = UNCOMPRESS_CLASS_NAME,
662 .version = G_VERSION,
663 .taste = g_uncompress_taste,
664 .destroy_geom = g_uncompress_destroy_geom,
665
666 .start = g_uncompress_start,
667 .orphan = g_uncompress_orphan,
668 .access = g_uncompress_access,
669 .spoiled = g_uncompress_spoiled,
670};
671
672DECLARE_GEOM_CLASS(g_uncompress_class, g_uncompress);
667
673MODULE_DEPEND(g_uncompress, zlib, 1, 1, 1);