Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 374851
b: refs/heads/master
c: e4100d9
h: refs/heads/master
i:
  374849: f8f2636
  374847: 1ecfc74
v: v3
  • Loading branch information
Miao Xie authored and Josef Bacik committed May 6, 2013
1 parent c2893f2 commit ecfedec
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 09a2a8f96e3009273bed1833b3f210e2c68728a5
refs/heads/master: e4100d987b2437596ebcf11809022b79507f3db1
58 changes: 58 additions & 0 deletions trunk/fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,64 @@ int set_state_private(struct extent_io_tree *tree, u64 start, u64 private)
return ret;
}

void extent_cache_csums_dio(struct extent_io_tree *tree, u64 start, u32 csums[],
int count)
{
struct rb_node *node;
struct extent_state *state;

spin_lock(&tree->lock);
/*
* this search will find all the extents that end after
* our range starts.
*/
node = tree_search(tree, start);
BUG_ON(!node);

state = rb_entry(node, struct extent_state, rb_node);
BUG_ON(state->start != start);

while (count) {
state->private = *csums++;
count--;
state = next_state(state);
}
spin_unlock(&tree->lock);
}

static inline u64 __btrfs_get_bio_offset(struct bio *bio, int bio_index)
{
struct bio_vec *bvec = bio->bi_io_vec + bio_index;

return page_offset(bvec->bv_page) + bvec->bv_offset;
}

void extent_cache_csums(struct extent_io_tree *tree, struct bio *bio, int bio_index,
u32 csums[], int count)
{
struct rb_node *node;
struct extent_state *state = NULL;
u64 start;

spin_lock(&tree->lock);
do {
start = __btrfs_get_bio_offset(bio, bio_index);
if (state == NULL || state->start != start) {
node = tree_search(tree, start);
BUG_ON(!node);

state = rb_entry(node, struct extent_state, rb_node);
BUG_ON(state->start != start);
}
state->private = *csums++;
count--;
bio_index++;

state = next_state(state);
} while (count);
spin_unlock(&tree->lock);
}

int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private)
{
struct rb_node *node;
Expand Down
4 changes: 4 additions & 0 deletions trunk/fs/btrfs/extent_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ int extent_readpages(struct extent_io_tree *tree,
int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
__u64 start, __u64 len, get_extent_t *get_extent);
int set_state_private(struct extent_io_tree *tree, u64 start, u64 private);
void extent_cache_csums_dio(struct extent_io_tree *tree, u64 start, u32 csums[],
int count);
void extent_cache_csums(struct extent_io_tree *tree, struct bio *bio,
int bvec_index, u32 csums[], int count);
int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private);
void set_page_extent_mapped(struct page *page);

Expand Down
49 changes: 30 additions & 19 deletions trunk/fs/btrfs/file-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
struct inode *inode, struct bio *bio,
u64 logical_offset, u32 *dst, int dio)
{
u32 sum;
u32 sum[16];
int len;
struct bio_vec *bvec = bio->bi_io_vec;
int bio_index = 0;
u64 offset = 0;
Expand All @@ -186,7 +187,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
u64 disk_bytenr;
u32 diff;
u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
int ret;
int count;
struct btrfs_path *path;
struct btrfs_csum_item *item = NULL;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
Expand Down Expand Up @@ -214,10 +215,12 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
if (dio)
offset = logical_offset;
while (bio_index < bio->bi_vcnt) {
len = min_t(int, ARRAY_SIZE(sum), bio->bi_vcnt - bio_index);
if (!dio)
offset = page_offset(bvec->bv_page) + bvec->bv_offset;
ret = btrfs_find_ordered_sum(inode, offset, disk_bytenr, &sum);
if (ret == 0)
count = btrfs_find_ordered_sum(inode, offset, disk_bytenr, sum,
len);
if (count)
goto found;

if (!item || disk_bytenr < item_start_offset ||
Expand All @@ -230,10 +233,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
item = btrfs_lookup_csum(NULL, root->fs_info->csum_root,
path, disk_bytenr, 0);
if (IS_ERR(item)) {
ret = PTR_ERR(item);
if (ret == -ENOENT || ret == -EFBIG)
ret = 0;
sum = 0;
count = 1;
sum[0] = 0;
if (BTRFS_I(inode)->root->root_key.objectid ==
BTRFS_DATA_RELOC_TREE_OBJECTID) {
set_extent_bits(io_tree, offset,
Expand Down Expand Up @@ -269,19 +270,29 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
diff = disk_bytenr - item_start_offset;
diff = diff / root->sectorsize;
diff = diff * csum_size;

read_extent_buffer(path->nodes[0], &sum,
count = min_t(int, len, (item_last_offset - disk_bytenr) >>
inode->i_sb->s_blocksize_bits);
read_extent_buffer(path->nodes[0], sum,
((unsigned long)item) + diff,
csum_size);
csum_size * count);
found:
if (dst)
*dst++ = sum;
else
set_state_private(io_tree, offset, sum);
disk_bytenr += bvec->bv_len;
offset += bvec->bv_len;
bio_index++;
bvec++;
if (dst) {
memcpy(dst, sum, count * csum_size);
dst += count;
} else {
if (dio)
extent_cache_csums_dio(io_tree, offset, sum,
count);
else
extent_cache_csums(io_tree, bio, bio_index, sum,
count);
}
while (count--) {
disk_bytenr += bvec->bv_len;
offset += bvec->bv_len;
bio_index++;
bvec++;
}
}
btrfs_free_path(path);
return 0;
Expand Down
28 changes: 17 additions & 11 deletions trunk/fs/btrfs/ordered-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
* be reclaimed before their checksum is actually put into the btree
*/
int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
u32 *sum)
u32 *sum, int len)
{
struct btrfs_ordered_sum *ordered_sum;
struct btrfs_sector_sum *sector_sums;
Expand All @@ -995,30 +995,36 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
unsigned long num_sectors;
unsigned long i;
u32 sectorsize = BTRFS_I(inode)->root->sectorsize;
int ret = 1;
int index = 0;

ordered = btrfs_lookup_ordered_extent(inode, offset);
if (!ordered)
return 1;
return 0;

spin_lock_irq(&tree->lock);
list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
if (disk_bytenr >= ordered_sum->bytenr) {
num_sectors = ordered_sum->len / sectorsize;
sector_sums = ordered_sum->sums;
for (i = 0; i < num_sectors; i++) {
if (disk_bytenr >= ordered_sum->bytenr &&
disk_bytenr < ordered_sum->bytenr + ordered_sum->len) {
i = (disk_bytenr - ordered_sum->bytenr) >>
inode->i_sb->s_blocksize_bits;
sector_sums = ordered_sum->sums + i;
num_sectors = ordered_sum->len >>
inode->i_sb->s_blocksize_bits;
for (; i < num_sectors; i++) {
if (sector_sums[i].bytenr == disk_bytenr) {
*sum = sector_sums[i].sum;
ret = 0;
goto out;
sum[index] = sector_sums[i].sum;
index++;
if (index == len)
goto out;
disk_bytenr += sectorsize;
}
}
}
}
out:
spin_unlock_irq(&tree->lock);
btrfs_put_ordered_extent(ordered);
return ret;
return index;
}


Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/btrfs/ordered-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode,
u64 len);
int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
struct btrfs_ordered_extent *ordered);
int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum);
int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
u32 *sum, int len);
int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int wait);
void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
Expand Down

0 comments on commit ecfedec

Please sign in to comment.