-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
8,860 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/* | ||
* Squashfs - a compressed read only filesystem for Linux | ||
* | ||
* Copyright (c) 2016-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2, | ||
* or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* zstd_wrapper.c | ||
*/ | ||
|
||
#include <linux/zstd.h> | ||
|
||
#include "squashfs_fs.h" | ||
#include "squashfs_fs_sb.h" | ||
#include "squashfs.h" | ||
#include "decompressor.h" | ||
#include "page_actor.h" | ||
|
||
struct workspace { | ||
void *mem; | ||
size_t mem_size; | ||
size_t window_size; | ||
}; | ||
|
||
static void *zstd_init(struct squashfs_sb_info *msblk, void *buff) | ||
{ | ||
struct workspace *wksp = kmalloc(sizeof(*wksp), GFP_KERNEL); | ||
|
||
if (wksp == NULL) | ||
goto failed; | ||
wksp->window_size = max_t(size_t, | ||
msblk->block_size, SQUASHFS_METADATA_SIZE); | ||
wksp->mem_size = ZSTD_DStreamWorkspaceBound(wksp->window_size); | ||
wksp->mem = vmalloc(wksp->mem_size); | ||
if (wksp->mem == NULL) | ||
goto failed; | ||
|
||
return wksp; | ||
|
||
failed: | ||
ERROR("Failed to allocate zstd workspace\n"); | ||
kfree(wksp); | ||
return ERR_PTR(-ENOMEM); | ||
} | ||
|
||
|
||
static void zstd_free(void *strm) | ||
{ | ||
struct workspace *wksp = strm; | ||
|
||
if (wksp) | ||
vfree(wksp->mem); | ||
kfree(wksp); | ||
} | ||
|
||
|
||
static int zstd_uncompress(struct squashfs_sb_info *msblk, void *strm, | ||
char **bh, int b, int offset, int length, | ||
struct squashfs_page_actor *output) | ||
{ | ||
struct workspace *wksp = strm; | ||
ZSTD_DStream *stream; | ||
size_t total_out = 0; | ||
size_t zstd_err; | ||
int k = 0; | ||
ZSTD_inBuffer in_buf = { NULL, 0, 0 }; | ||
ZSTD_outBuffer out_buf = { NULL, 0, 0 }; | ||
|
||
stream = ZSTD_initDStream(wksp->window_size, wksp->mem, wksp->mem_size); | ||
|
||
if (!stream) { | ||
ERROR("Failed to initialize zstd decompressor\n"); | ||
goto out; | ||
} | ||
|
||
out_buf.size = PAGE_SIZE; | ||
out_buf.dst = squashfs_first_page(output); | ||
|
||
do { | ||
if (in_buf.pos == in_buf.size && k < b) { | ||
int avail = min(length, msblk->devblksize - offset); | ||
|
||
length -= avail; | ||
in_buf.src = bh[k] + offset; | ||
in_buf.size = avail; | ||
in_buf.pos = 0; | ||
offset = 0; | ||
} | ||
|
||
if (out_buf.pos == out_buf.size) { | ||
out_buf.dst = squashfs_next_page(output); | ||
if (out_buf.dst == NULL) { | ||
/* Shouldn't run out of pages | ||
* before stream is done. | ||
*/ | ||
squashfs_finish_page(output); | ||
goto out; | ||
} | ||
out_buf.pos = 0; | ||
out_buf.size = PAGE_SIZE; | ||
} | ||
|
||
total_out -= out_buf.pos; | ||
zstd_err = ZSTD_decompressStream(stream, &out_buf, &in_buf); | ||
total_out += out_buf.pos; /* add the additional data produced */ | ||
|
||
if (in_buf.pos == in_buf.size && k < b) | ||
kfree(bh[k++]); | ||
} while (zstd_err != 0 && !ZSTD_isError(zstd_err)); | ||
|
||
squashfs_finish_page(output); | ||
|
||
if (ZSTD_isError(zstd_err)) { | ||
ERROR("zstd decompression error: %d\n", | ||
(int)ZSTD_getErrorCode(zstd_err)); | ||
goto out; | ||
} | ||
|
||
if (k < b) | ||
goto out; | ||
|
||
return (int)total_out; | ||
|
||
out: | ||
for (; k < b; k++) | ||
kfree(bh[k]); | ||
|
||
return -EIO; | ||
} | ||
|
||
const struct squashfs_decompressor squashfs_zstd_comp_ops = { | ||
.init = zstd_init, | ||
.free = zstd_free, | ||
.decompress = zstd_uncompress, | ||
.id = ZSTD_COMPRESSION, | ||
.name = "zstd", | ||
.supported = 1 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.