Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/bio_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,11 @@ static void __on_bio_read_complete(struct bio *bio, int err)
#ifndef HAVE_BVEC_ITER
//#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
for (i = 0; i < bio->bi_vcnt; i++) {
bio->bi_io_vec[i].bv_len = PAGE_SIZE;
if (map && (i + 1) * PAGE_SIZE > map->size) {
bio->bi_io_vec[i].bv_len = map->size - i * PAGE_SIZE;
} else {
bio->bi_io_vec[i].bv_len = PAGE_SIZE;
}
bio->bi_io_vec[i].bv_offset = 0;
}
#endif
Expand Down Expand Up @@ -695,13 +699,14 @@ void bio_free_clone(struct bio *bio)
*/
int bio_make_read_clone(struct bio_set *bs, struct tracing_params *tp,
struct bio *orig_bio, sector_t sect, unsigned int pages,
struct bio **bio_out, unsigned int *bytes_added)
unsigned int tail, struct bio **bio_out, unsigned int *bytes_added)
{
int ret;
struct bio *new_bio;
struct page *pg;
unsigned int i;
unsigned int bytes;
unsigned int actual_size = PAGE_SIZE;
unsigned int total = 0;
#ifdef BIO_MAX_PAGES
unsigned int actual_pages =
Expand Down Expand Up @@ -758,9 +763,12 @@ int bio_make_read_clone(struct bio_set *bs, struct tracing_params *tp,
goto error;
}

if (i == pages - 1 && tail != 0)
actual_size = PAGE_SIZE - tail;

// add the page to the bio
bytes = bio_add_page(new_bio, pg, PAGE_SIZE, 0);
if (bytes != PAGE_SIZE) {
bytes = bio_add_page(new_bio, pg, actual_size, 0);
if (bytes != actual_size) {
__free_page(pg);
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/bio_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void bio_free_clone(struct bio *bio);

int bio_make_read_clone(struct bio_set *bs, struct tracing_params *tp,
struct bio *orig_bio, sector_t sect, unsigned int pages,
struct bio **bio_out, unsigned int *bytes_added);
unsigned int tail, struct bio **bio_out, unsigned int *bytes_added);

#ifdef HAVE_BIO_ENDIO_INT
void dattobd_bio_endio(struct bio *bio, int err);
Expand Down
2 changes: 1 addition & 1 deletion src/cow_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <stdint.h>
#endif

#define COW_SECTION_SIZE 4096
#define COW_SECTION_SIZE PAGE_SIZE

#define cow_write_filler_mapping(cm, pos) __cow_write_mapping(cm, pos, 1)
extern const unsigned long dattobd_cow_ext_buf_size;
Expand Down
7 changes: 4 additions & 3 deletions src/snap_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ int snap_handle_write_bio(const struct snap_device *dev, struct bio *bio)
{
int ret;
char *data;
char *block_data;
sector_t start_block, end_block = SECTOR_TO_BLOCK(bio_sector(bio));
struct bio_vec *bvec;
#ifdef HAVE_BVEC_ITER_ALL
Expand All @@ -266,10 +267,10 @@ int snap_handle_write_bio(const struct snap_device *dev, struct bio *bio)
// map the page into kernel space
data = kmap(bvec->bv_page);

// loop through the blocks in the page
for (; start_block < end_block; start_block++) {
block_data = data + bvec->bv_offset;
for (; start_block < end_block; start_block++, block_data += COW_BLOCK_SIZE) {
// pass the block to the cow manager to be handled
ret = cow_write_current(dev->sd_cow, start_block, data);
ret = cow_write_current(dev->sd_cow, start_block, block_data);
if (ret) {
LOG_ERROR(ret,"memory demands %llu, memory saved before crash %llu",number_of_blocks*COW_BLOCK_SIZE,saved_blocks*COW_BLOCK_SIZE);
kunmap(bvec->bv_page);
Expand Down
10 changes: 6 additions & 4 deletions src/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static int snap_trace_bio(struct snap_device *dev, struct bio *bio)
struct bio *new_bio = NULL;
struct tracing_params *tp = NULL;
sector_t start_sect, end_sect;
unsigned int bytes, pages;
unsigned int bytes, pages, tail;

// if we don't need to cow this bio just call the real mrf normally
if (!bio_needs_cow(bio, dev->sd_cow_inode) || tracer_read_fail_state(dev))
Expand All @@ -144,7 +144,9 @@ static int snap_trace_bio(struct snap_device *dev, struct bio *bio)
dev->sd_sect_off,
SECTORS_PER_BLOCK) +
dev->sd_sect_off;
pages = (end_sect - start_sect) / SECTORS_PER_PAGE;

pages = ROUND_UP(end_sect - start_sect, SECTORS_PER_PAGE) / SECTORS_PER_PAGE;
tail = pages * PAGE_SIZE - (end_sect - start_sect) * SECTOR_SIZE;

// allocate tracing_params struct to hold all pointers we will need
// across contexts
Expand All @@ -164,7 +166,7 @@ static int snap_trace_bio(struct snap_device *dev, struct bio *bio)
// allocate and populate read bio clone. This bio may not have all the
// pages we need due to queue restrictions
ret = bio_make_read_clone(dev_bioset(dev), tp, bio, start_sect, pages,
&new_bio, &bytes);
tail, &new_bio, &bytes);
if (ret)
goto error;

Expand All @@ -188,7 +190,7 @@ static int snap_trace_bio(struct snap_device *dev, struct bio *bio)

// if our bio didn't cover the entire clone we must keep creating bios
// until we have
if (bytes / PAGE_SIZE < pages) {
if (bytes < (end_sect - start_sect) * SECTOR_SIZE) {
start_sect += bytes / SECTOR_SIZE;
pages -= bytes / PAGE_SIZE;
continue;
Expand Down