Skip to content

Commit

Permalink
Merge branch 'misc-4.10' into for-chris-4.10-20161130
Browse files Browse the repository at this point in the history
  • Loading branch information
David Sterba committed Nov 30, 2016
2 parents e5517c2 + 1d57ee9 commit 515bdc4
Show file tree
Hide file tree
Showing 33 changed files with 782 additions and 827 deletions.
32 changes: 12 additions & 20 deletions fs/btrfs/check-integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,7 +1539,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len,
struct btrfs_device *device;

length = len;
ret = btrfs_map_block(state->root->fs_info, READ,
ret = btrfs_map_block(state->root->fs_info, BTRFS_MAP_READ,
bytenr, &length, &multi, mirror_num);

if (ret) {
Expand Down Expand Up @@ -2819,10 +2819,11 @@ static void __btrfsic_submit_bio(struct bio *bio)
* btrfsic_mount(), this might return NULL */
dev_state = btrfsic_dev_state_lookup(bio->bi_bdev);
if (NULL != dev_state &&
(bio_op(bio) == REQ_OP_WRITE) && NULL != bio->bi_io_vec) {
(bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) {
unsigned int i;
u64 dev_bytenr;
u64 cur_bytenr;
struct bio_vec *bvec;
int bio_is_patched;
char **mapped_datav;

Expand All @@ -2840,32 +2841,23 @@ static void __btrfsic_submit_bio(struct bio *bio)
if (!mapped_datav)
goto leave;
cur_bytenr = dev_bytenr;
for (i = 0; i < bio->bi_vcnt; i++) {
BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_SIZE);
mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page);
if (!mapped_datav[i]) {
while (i > 0) {
i--;
kunmap(bio->bi_io_vec[i].bv_page);
}
kfree(mapped_datav);
goto leave;
}

bio_for_each_segment_all(bvec, bio, i) {
BUG_ON(bvec->bv_len != PAGE_SIZE);
mapped_datav[i] = kmap(bvec->bv_page);

if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE)
pr_info("#%u: bytenr=%llu, len=%u, offset=%u\n",
i, cur_bytenr, bio->bi_io_vec[i].bv_len,
bio->bi_io_vec[i].bv_offset);
cur_bytenr += bio->bi_io_vec[i].bv_len;
i, cur_bytenr, bvec->bv_len, bvec->bv_offset);
cur_bytenr += bvec->bv_len;
}
btrfsic_process_written_block(dev_state, dev_bytenr,
mapped_datav, bio->bi_vcnt,
bio, &bio_is_patched,
NULL, bio->bi_opf);
while (i > 0) {
i--;
kunmap(bio->bi_io_vec[i].bv_page);
}
bio_for_each_segment_all(bvec, bio, i)
kunmap(bvec->bv_page);
kfree(mapped_datav);
} else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) {
if (dev_state->state->print_mask &
Expand Down
142 changes: 53 additions & 89 deletions fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ struct compressed_bio {
u32 sums;
};

static int btrfs_decompress_biovec(int type, struct page **pages_in,
u64 disk_start, struct bio_vec *bvec,
int vcnt, size_t srclen);
static int btrfs_decompress_bio(int type, struct page **pages_in,
u64 disk_start, struct bio *orig_bio,
size_t srclen);

static inline int compressed_bio_size(struct btrfs_root *root,
unsigned long disk_size)
Expand Down Expand Up @@ -120,7 +120,7 @@ static int check_compressed_csum(struct inode *inode,

kaddr = kmap_atomic(page);
csum = btrfs_csum_data(kaddr, csum, PAGE_SIZE);
btrfs_csum_final(csum, (char *)&csum);
btrfs_csum_final(csum, (u8 *)&csum);
kunmap_atomic(kaddr);

if (csum != *cb_sum) {
Expand Down Expand Up @@ -175,11 +175,10 @@ static void end_compressed_bio_read(struct bio *bio)
/* ok, we're the last bio for this extent, lets start
* the decompression.
*/
ret = btrfs_decompress_biovec(cb->compress_type,
ret = btrfs_decompress_bio(cb->compress_type,
cb->compressed_pages,
cb->start,
cb->orig_bio->bi_io_vec,
cb->orig_bio->bi_vcnt,
cb->orig_bio,
cb->compressed_len);
csum_failed:
if (ret)
Expand Down Expand Up @@ -446,6 +445,13 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
return 0;
}

static u64 bio_end_offset(struct bio *bio)
{
struct bio_vec *last = &bio->bi_io_vec[bio->bi_vcnt - 1];

return page_offset(last->bv_page) + last->bv_len + last->bv_offset;
}

static noinline int add_ra_bio_pages(struct inode *inode,
u64 compressed_end,
struct compressed_bio *cb)
Expand All @@ -464,8 +470,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
u64 end;
int misses = 0;

page = cb->orig_bio->bi_io_vec[cb->orig_bio->bi_vcnt - 1].bv_page;
last_offset = (page_offset(page) + PAGE_SIZE);
last_offset = bio_end_offset(cb->orig_bio);
em_tree = &BTRFS_I(inode)->extent_tree;
tree = &BTRFS_I(inode)->io_tree;

Expand Down Expand Up @@ -563,7 +568,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
*
* bio->bi_iter.bi_sector points to the compressed extent on disk
* bio->bi_io_vec points to all of the inode pages
* bio->bi_vcnt is a count of pages
*
* After the compressed pages are read, we copy the bytes into the
* bio we were passed and then call the bio end_io calls
Expand All @@ -575,7 +579,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
struct extent_map_tree *em_tree;
struct compressed_bio *cb;
struct btrfs_root *root = BTRFS_I(inode)->root;
unsigned long uncompressed_len = bio->bi_vcnt * PAGE_SIZE;
unsigned long compressed_len;
unsigned long nr_pages;
unsigned long pg_index;
Expand Down Expand Up @@ -620,7 +623,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
free_extent_map(em);
em = NULL;

cb->len = uncompressed_len;
cb->len = bio->bi_iter.bi_size;
cb->compressed_len = compressed_len;
cb->compress_type = extent_compress_type(bio_flags);
cb->orig_bio = bio;
Expand Down Expand Up @@ -648,8 +651,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
add_ra_bio_pages(inode, em_start + em_len, cb);

/* include any pages we added in add_ra-bio_pages */
uncompressed_len = bio->bi_vcnt * PAGE_SIZE;
cb->len = uncompressed_len;
cb->len = bio->bi_iter.bi_size;

comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS);
if (!comp_bio)
Expand Down Expand Up @@ -959,9 +961,7 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
*
* disk_start is the starting logical offset of this array in the file
*
* bvec is a bio_vec of pages from the file that we want to decompress into
*
* vcnt is the count of pages in the biovec
* orig_bio contains the pages from the file that we want to decompress into
*
* srclen is the number of bytes in pages_in
*
Expand All @@ -970,18 +970,18 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
* be contiguous. They all correspond to the range of bytes covered by
* the compressed extent.
*/
static int btrfs_decompress_biovec(int type, struct page **pages_in,
u64 disk_start, struct bio_vec *bvec,
int vcnt, size_t srclen)
static int btrfs_decompress_bio(int type, struct page **pages_in,
u64 disk_start, struct bio *orig_bio,
size_t srclen)
{
struct list_head *workspace;
int ret;

workspace = find_workspace(type);

ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in,
disk_start,
bvec, vcnt, srclen);
ret = btrfs_compress_op[type-1]->decompress_bio(workspace, pages_in,
disk_start, orig_bio,
srclen);
free_workspace(type, workspace);
return ret;
}
Expand Down Expand Up @@ -1021,23 +1021,21 @@ void btrfs_exit_compress(void)
*/
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
unsigned long total_out, u64 disk_start,
struct bio_vec *bvec, int vcnt,
unsigned long *pg_index,
unsigned long *pg_offset)
struct bio *bio)
{
unsigned long buf_offset;
unsigned long current_buf_start;
unsigned long start_byte;
unsigned long working_bytes = total_out - buf_start;
unsigned long bytes;
char *kaddr;
struct page *page_out = bvec[*pg_index].bv_page;
struct bio_vec bvec = bio_iter_iovec(bio, bio->bi_iter);

/*
* start byte is the first byte of the page we're currently
* copying into relative to the start of the compressed data.
*/
start_byte = page_offset(page_out) - disk_start;
start_byte = page_offset(bvec.bv_page) - disk_start;

/* we haven't yet hit data corresponding to this page */
if (total_out <= start_byte)
Expand All @@ -1057,80 +1055,46 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,

/* copy bytes from the working buffer into the pages */
while (working_bytes > 0) {
bytes = min(PAGE_SIZE - *pg_offset,
PAGE_SIZE - buf_offset);
bytes = min_t(unsigned long, bvec.bv_len,
PAGE_SIZE - buf_offset);
bytes = min(bytes, working_bytes);
kaddr = kmap_atomic(page_out);
memcpy(kaddr + *pg_offset, buf + buf_offset, bytes);

kaddr = kmap_atomic(bvec.bv_page);
memcpy(kaddr + bvec.bv_offset, buf + buf_offset, bytes);
kunmap_atomic(kaddr);
flush_dcache_page(page_out);
flush_dcache_page(bvec.bv_page);

*pg_offset += bytes;
buf_offset += bytes;
working_bytes -= bytes;
current_buf_start += bytes;

/* check if we need to pick another page */
if (*pg_offset == PAGE_SIZE) {
(*pg_index)++;
if (*pg_index >= vcnt)
return 0;
bio_advance(bio, bytes);
if (!bio->bi_iter.bi_size)
return 0;
bvec = bio_iter_iovec(bio, bio->bi_iter);

page_out = bvec[*pg_index].bv_page;
*pg_offset = 0;
start_byte = page_offset(page_out) - disk_start;
start_byte = page_offset(bvec.bv_page) - disk_start;

/*
* make sure our new page is covered by this
* working buffer
*/
if (total_out <= start_byte)
return 1;
/*
* make sure our new page is covered by this
* working buffer
*/
if (total_out <= start_byte)
return 1;

/*
* the next page in the biovec might not be adjacent
* to the last page, but it might still be found
* inside this working buffer. bump our offset pointer
*/
if (total_out > start_byte &&
current_buf_start < start_byte) {
buf_offset = start_byte - buf_start;
working_bytes = total_out - start_byte;
current_buf_start = buf_start + buf_offset;
}
/*
* the next page in the biovec might not be adjacent
* to the last page, but it might still be found
* inside this working buffer. bump our offset pointer
*/
if (total_out > start_byte &&
current_buf_start < start_byte) {
buf_offset = start_byte - buf_start;
working_bytes = total_out - start_byte;
current_buf_start = buf_start + buf_offset;
}
}

return 1;
}

/*
* When uncompressing data, we need to make sure and zero any parts of
* the biovec that were not filled in by the decompression code. pg_index
* and pg_offset indicate the last page and the last offset of that page
* that have been filled in. This will zero everything remaining in the
* biovec.
*/
void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt,
unsigned long pg_index,
unsigned long pg_offset)
{
while (pg_index < vcnt) {
struct page *page = bvec[pg_index].bv_page;
unsigned long off = bvec[pg_index].bv_offset;
unsigned long len = bvec[pg_index].bv_len;

if (pg_offset < off)
pg_offset = off;
if (pg_offset < off + len) {
unsigned long bytes = off + len - pg_offset;
char *kaddr;

kaddr = kmap_atomic(page);
memset(kaddr + pg_offset, 0, bytes);
kunmap_atomic(kaddr);
}
pg_index++;
pg_offset = 0;
}
}
12 changes: 3 additions & 9 deletions fs/btrfs/compression.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
unsigned long start_byte, size_t srclen, size_t destlen);
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
unsigned long total_out, u64 disk_start,
struct bio_vec *bvec, int vcnt,
unsigned long *pg_index,
unsigned long *pg_offset);
struct bio *bio);

int btrfs_submit_compressed_write(struct inode *inode, u64 start,
unsigned long len, u64 disk_start,
Expand All @@ -45,9 +43,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
unsigned long nr_pages);
int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
int mirror_num, unsigned long bio_flags);
void btrfs_clear_biovec_end(struct bio_vec *bvec, int vcnt,
unsigned long pg_index,
unsigned long pg_offset);

enum btrfs_compression_type {
BTRFS_COMPRESS_NONE = 0,
Expand All @@ -72,11 +67,10 @@ struct btrfs_compress_op {
unsigned long *total_out,
unsigned long max_out);

int (*decompress_biovec)(struct list_head *workspace,
int (*decompress_bio)(struct list_head *workspace,
struct page **pages_in,
u64 disk_start,
struct bio_vec *bvec,
int vcnt,
struct bio *orig_bio,
size_t srclen);

int (*decompress)(struct list_head *workspace,
Expand Down
Loading

0 comments on commit 515bdc4

Please sign in to comment.