Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:ARM
btrfsprogs
0127-btrfs-progs-add-lzo-compression-support-to...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0127-btrfs-progs-add-lzo-compression-support-to-restore.patch of Package btrfsprogs
From 2fe46117d3cde3737a1600195883e63ab4c59a8d Mon Sep 17 00:00:00 2001 From: Josef Bacik <josef@redhat.com> Date: Fri, 2 Dec 2011 10:07:43 -0500 Subject: [PATCH 28/35] btrfs-progs: add lzo compression support to restore This patch simply adds support to decompress lzo compressed extents in restore. Signed-off-by: Josef Bacik <josef@redhat.com> --- Makefile | 2 +- restore.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 548f88c..64de4e6 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ INSTALL = install prefix ?= /usr/local bindir = $(prefix)/bin LIBS=-luuid -RESTORE_LIBS=-lz +RESTORE_LIBS=-lz -llzo2 progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \ btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block \ diff --git a/restore.c b/restore.c index e65746a..6433378 100644 --- a/restore.c +++ b/restore.c @@ -27,6 +27,8 @@ #include <zlib.h> #include <sys/types.h> #include <regex.h> +#include <lzo/lzoconf.h> +#include <lzo/lzo1x.h> #include "kerncompat.h" #include "ctree.h" #include "disk-io.h" @@ -44,8 +46,12 @@ static int verbose = 0; static int ignore_errors = 0; static int overwrite = 0; -static int decompress(char *inbuf, char *outbuf, u64 compress_len, - u64 decompress_len) +#define LZO_LEN 4 +#define PAGE_CACHE_SIZE 4096 +#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3) + +static int decompress_zlib(char *inbuf, char *outbuf, u64 compress_len, + u64 decompress_len) { z_stream strm; int ret; @@ -71,6 +77,73 @@ static int decompress(char *inbuf, char *outbuf, u64 compress_len, (void)inflateEnd(&strm); return 0; } +static inline size_t read_compress_length(unsigned char *buf) +{ + __le32 dlen; + memcpy(&dlen, buf, LZO_LEN); + return le32_to_cpu(dlen); +} + +static int decompress_lzo(unsigned char *inbuf, char *outbuf, u64 compress_len, + u64 *decompress_len) +{ + size_t new_len; + size_t in_len; + size_t out_len = 0; + size_t tot_len; + size_t tot_in; + int ret; + + ret = lzo_init(); + if (ret != LZO_E_OK) { + fprintf(stderr, "lzo init returned %d\n", ret); + return -1; + } + + tot_len = read_compress_length(inbuf); + inbuf += LZO_LEN; + tot_in = LZO_LEN; + + while (tot_in < tot_len) { + in_len = read_compress_length(inbuf); + inbuf += LZO_LEN; + tot_in += LZO_LEN; + + new_len = lzo1x_worst_compress(PAGE_CACHE_SIZE); + ret = lzo1x_decompress_safe((const unsigned char *)inbuf, in_len, + (unsigned char *)outbuf, &new_len, NULL); + if (ret != LZO_E_OK) { + fprintf(stderr, "failed to inflate: %d\n", ret); + return -1; + } + out_len += new_len; + outbuf += new_len; + inbuf += in_len; + tot_in += in_len; + } + + *decompress_len = out_len; + + return 0; +} + +static int decompress(char *inbuf, char *outbuf, u64 compress_len, + u64 *decompress_len, int compress) +{ + switch (compress) { + case BTRFS_COMPRESS_ZLIB: + return decompress_zlib(inbuf, outbuf, compress_len, + *decompress_len); + case BTRFS_COMPRESS_LZO: + return decompress_lzo((unsigned char *)inbuf, outbuf, compress_len, + decompress_len); + default: + break; + } + + fprintf(stderr, "invalid compression type: %d\n", compress); + return -1; +} int next_leaf(struct btrfs_root *root, struct btrfs_path *path) { @@ -133,11 +206,11 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos) struct btrfs_file_extent_item *fi; char buf[4096]; char *outbuf; + u64 ram_size; ssize_t done; unsigned long ptr; int ret; int len; - int ram_size; int compress; fi = btrfs_item_ptr(leaf, path->slots[0], @@ -165,7 +238,7 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos) return -1; } - ret = decompress(buf, outbuf, len, ram_size); + ret = decompress(buf, outbuf, len, &ram_size, compress); if (ret) { free(outbuf); return ret; @@ -174,7 +247,7 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos) done = pwrite(fd, outbuf, ram_size, pos); free(outbuf); if (done < len) { - fprintf(stderr, "Short compressed inline write, wanted %d, " + fprintf(stderr, "Short compressed inline write, wanted %Lu, " "did %zd: %d\n", ram_size, done, errno); return -1; } @@ -196,6 +269,7 @@ static int copy_one_extent(struct btrfs_root *root, int fd, u64 length; u64 size_left; u64 dev_bytenr; + u64 offset; u64 count = 0; int compress; int ret; @@ -207,8 +281,11 @@ static int copy_one_extent(struct btrfs_root *root, int fd, bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi); ram_size = btrfs_file_extent_ram_bytes(leaf, fi); + offset = btrfs_file_extent_offset(leaf, fi); size_left = disk_size; + if (offset) + printf("offset is %Lu\n", offset); /* we found a hole */ if (disk_size == 0) return 0; @@ -282,7 +359,7 @@ again: goto out; } - ret = decompress(inbuf, outbuf, disk_size, ram_size); + ret = decompress(inbuf, outbuf, disk_size, &ram_size, compress); if (ret) { num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, bytenr, length); -- 1.7.6.233.gd79bc
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor