@ -34,8 +34,7 @@
# define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \
sizeof ( struct btrfs_ordered_sum ) ) / \
sizeof ( struct btrfs_sector_sum ) * \
( r ) - > sectorsize - ( r ) - > sectorsize )
sizeof ( u32 ) * ( r ) - > sectorsize )
int btrfs_insert_file_extent ( struct btrfs_trans_handle * trans ,
struct btrfs_root * root ,
@ -297,7 +296,6 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
struct btrfs_path * path ;
struct extent_buffer * leaf ;
struct btrfs_ordered_sum * sums ;
struct btrfs_sector_sum * sector_sum ;
struct btrfs_csum_item * item ;
LIST_HEAD ( tmplist ) ;
unsigned long offset ;
@ -368,34 +366,28 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
struct btrfs_csum_item ) ;
while ( start < csum_end ) {
size = min_t ( size_t , csum_end - start ,
MAX_ORDERED_SUM_BYTES ( root ) ) ;
MAX_ORDERED_SUM_BYTES ( root ) ) ;
sums = kzalloc ( btrfs_ordered_sum_size ( root , size ) ,
GFP_NOFS ) ;
GFP_NOFS ) ;
if ( ! sums ) {
ret = - ENOMEM ;
goto fail ;
}
sector_sum = sums - > sums ;
sums - > bytenr = start ;
sums - > len = size ;
sums - > len = ( int ) size ;
offset = ( start - key . offset ) > >
root - > fs_info - > sb - > s_blocksize_bits ;
offset * = csum_size ;
size > > = root - > fs_info - > sb - > s_blocksize_bits ;
while ( size > 0 ) {
read_extent_buffer ( path - > nodes [ 0 ] ,
& sector_sum - > sum ,
( ( unsigned long ) item ) +
offset , csum_size ) ;
sector_sum - > bytenr = start ;
size - = root - > sectorsize ;
start + = root - > sectorsize ;
offset + = csum_size ;
sector_sum + + ;
}
read_extent_buffer ( path - > nodes [ 0 ] ,
sums - > sums ,
( ( unsigned long ) item ) + offset ,
csum_size * size ) ;
start + = root - > sectorsize * size ;
list_add_tail ( & sums - > list , & tmplist ) ;
}
path - > slots [ 0 ] + + ;
@ -417,23 +409,20 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
struct bio * bio , u64 file_start , int contig )
{
struct btrfs_ordered_sum * sums ;
struct btrfs_sector_sum * sector_sum ;
struct btrfs_ordered_extent * ordered ;
char * data ;
struct bio_vec * bvec = bio - > bi_io_vec ;
int bio_index = 0 ;
int index ;
unsigned long total_bytes = 0 ;
unsigned long this_sum_bytes = 0 ;
u64 offset ;
u64 disk_bytenr ;
WARN_ON ( bio - > bi_vcnt < = 0 ) ;
sums = kzalloc ( btrfs_ordered_sum_size ( root , bio - > bi_size ) , GFP_NOFS ) ;
if ( ! sums )
return - ENOMEM ;
sector_sum = sums - > sums ;
disk_bytenr = ( u64 ) bio - > bi_sector < < 9 ;
sums - > len = bio - > bi_size ;
INIT_LIST_HEAD ( & sums - > list ) ;
@ -444,7 +433,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
ordered = btrfs_lookup_ordered_extent ( inode , offset ) ;
BUG_ON ( ! ordered ) ; /* Logic error */
sums - > bytenr = ordered - > start ;
sums - > bytenr = ( u64 ) bio - > bi_sector < < 9 ;
index = 0 ;
while ( bio_index < bio - > bi_vcnt ) {
if ( ! contig )
@ -463,28 +453,27 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
sums = kzalloc ( btrfs_ordered_sum_size ( root , bytes_left ) ,
GFP_NOFS ) ;
BUG_ON ( ! sums ) ; /* -ENOMEM */
sector_sum = sums - > sums ;
sums - > len = bytes_left ;
ordered = btrfs_lookup_ordered_extent ( inode , offset ) ;
BUG_ON ( ! ordered ) ; /* Logic error */
sums - > bytenr = ordered - > start ;
sums - > bytenr = ( ( u64 ) bio - > bi_sector < < 9 ) +
total_bytes ;
index = 0 ;
}
data = kmap_atomic ( bvec - > bv_page ) ;
sector_s um - > sum = ~ ( u32 ) 0 ;
sector_s um - > sum = btrfs_csum_data ( data + bvec - > bv_offset ,
sector_s um - > sum ,
bvec - > bv_len ) ;
sums - > sums [ index ] = ~ ( u32 ) 0 ;
sums - > sums [ index ] = btrfs_csum_data ( data + bvec - > bv_offset ,
sums - > sums [ index ] ,
bvec - > bv_len ) ;
kunmap_atomic ( data ) ;
btrfs_csum_final ( sector_sum - > sum ,
( char * ) & sector_sum - > sum ) ;
sector_sum - > bytenr = disk_bytenr ;
btrfs_csum_final ( sums - > sums [ index ] ,
( char * ) ( sums - > sums + index ) ) ;
sector_sum + + ;
bio_index + + ;
index + + ;
total_bytes + = bvec - > bv_len ;
this_sum_bytes + = bvec - > bv_len ;
disk_bytenr + = bvec - > bv_len ;
offset + = bvec - > bv_len ;
bvec + + ;
}
@ -672,62 +661,46 @@ out:
return ret ;
}
static u64 btrfs_sector_sum_left ( struct btrfs_ordered_sum * sums ,
struct btrfs_sector_sum * sector_sum ,
u64 total_bytes , u64 sectorsize )
{
u64 tmp = sectorsize ;
u64 next_sector = sector_sum - > bytenr ;
struct btrfs_sector_sum * next = sector_sum + 1 ;
while ( ( tmp + total_bytes ) < sums - > len ) {
if ( next_sector + sectorsize ! = next - > bytenr )
break ;
tmp + = sectorsize ;
next_sector = next - > bytenr ;
next + + ;
}
return tmp ;
}
int btrfs_csum_file_blocks ( struct btrfs_trans_handle * trans ,
struct btrfs_root * root ,
struct btrfs_ordered_sum * sums )
{
u64 bytenr ;
int ret ;
struct btrfs_key file_key ;
struct btrfs_key found_key ;
u64 next_offset ;
u64 total_bytes = 0 ;
int found_next ;
struct btrfs_path * path ;
struct btrfs_csum_item * item ;
struct btrfs_csum_item * item_end ;
struct extent_buffer * leaf = NULL ;
u64 next_offset ;
u64 total_bytes = 0 ;
u64 csum_offset ;
struct btrfs_sector_sum * sector_sum ;
u64 bytenr ;
u32 nritems ;
u32 ins_size ;
int index = 0 ;
int found_next ;
int ret ;
u16 csum_size = btrfs_super_csum_size ( root - > fs_info - > super_copy ) ;
path = btrfs_alloc_path ( ) ;
if ( ! path )
return - ENOMEM ;
sector_sum = sums - > sums ;
again :
next_offset = ( u64 ) - 1 ;
found_next = 0 ;
bytenr = sums - > bytenr + total_bytes ;
file_key . objectid = BTRFS_EXTENT_CSUM_OBJECTID ;
file_key . offset = sector_sum - > bytenr ;
bytenr = sector_sum - > bytenr ;
file_key . offset = bytenr ;
btrfs_set_key_type ( & file_key , BTRFS_EXTENT_CSUM_KEY ) ;
item = btrfs_lookup_csum ( trans , root , path , sector_sum - > bytenr , 1 ) ;
item = btrfs_lookup_csum ( trans , root , path , bytenr , 1 ) ;
if ( ! IS_ERR ( item ) ) {
leaf = path - > nodes [ 0 ] ;
ret = 0 ;
leaf = path - > nodes [ 0 ] ;
item_end = btrfs_item_ptr ( leaf , path - > slots [ 0 ] ,
struct btrfs_csum_item ) ;
item_end = ( struct btrfs_csum_item * ) ( ( char * ) item_end +
btrfs_item_size_nr ( leaf , path - > slots [ 0 ] ) ) ;
goto found ;
}
ret = PTR_ERR ( item ) ;
@ -807,8 +780,7 @@ again:
free_space = btrfs_leaf_free_space ( root , leaf ) -
sizeof ( struct btrfs_item ) - csum_size ;
tmp = btrfs_sector_sum_left ( sums , sector_sum , total_bytes ,
root - > sectorsize ) ;
tmp = sums - > len - total_bytes ;
tmp > > = root - > fs_info - > sb - > s_blocksize_bits ;
WARN_ON ( tmp < 1 ) ;
@ -822,6 +794,7 @@ again:
diff * = csum_size ;
btrfs_extend_item ( root , path , diff ) ;
ret = 0 ;
goto csum ;
}
@ -831,8 +804,7 @@ insert:
if ( found_next ) {
u64 tmp ;
tmp = btrfs_sector_sum_left ( sums , sector_sum , total_bytes ,
root - > sectorsize ) ;
tmp = sums - > len - total_bytes ;
tmp > > = root - > fs_info - > sb - > s_blocksize_bits ;
tmp = min ( tmp , ( next_offset - file_key . offset ) > >
root - > fs_info - > sb - > s_blocksize_bits ) ;
@ -853,31 +825,25 @@ insert:
WARN_ON ( 1 ) ;
goto fail_unlock ;
}
csum :
leaf = path - > nodes [ 0 ] ;
csum :
item = btrfs_item_ptr ( leaf , path - > slots [ 0 ] , struct btrfs_csum_item ) ;
ret = 0 ;
item_end = ( struct btrfs_csum_item * ) ( ( unsigned char * ) item +
btrfs_item_size_nr ( leaf , path - > slots [ 0 ] ) ) ;
item = ( struct btrfs_csum_item * ) ( ( unsigned char * ) item +
csum_offset * csum_size ) ;
found :
item_end = btrfs_item_ptr ( leaf , path - > slots [ 0 ] , struct btrfs_csum_item ) ;
item_end = ( struct btrfs_csum_item * ) ( ( unsigned char * ) item_end +
btrfs_item_size_nr ( leaf , path - > slots [ 0 ] ) ) ;
next_sector :
write_extent_buffer ( leaf , & sector_sum - > sum , ( unsigned long ) item , csum_size ) ;
total_bytes + = root - > sectorsize ;
sector_sum + + ;
if ( total_bytes < sums - > len ) {
item = ( struct btrfs_csum_item * ) ( ( char * ) item +
csum_size ) ;
if ( item < item_end & & bytenr + PAGE_CACHE_SIZE = =
sector_sum - > bytenr ) {
bytenr = sector_sum - > bytenr ;
goto next_sector ;
}
}
ins_size = ( u32 ) ( sums - > len - total_bytes ) > >
root - > fs_info - > sb - > s_blocksize_bits ;
ins_size * = csum_size ;
ins_size = min_t ( u32 , ( unsigned long ) item_end - ( unsigned long ) item ,
ins_size ) ;
write_extent_buffer ( leaf , sums - > sums + index , ( unsigned long ) item ,
ins_size ) ;
ins_size / = csum_size ;
total_bytes + = ins_size * root - > sectorsize ;
index + = ins_size ;
btrfs_mark_buffer_dirty ( path - > nodes [ 0 ] ) ;
if ( total_bytes < sums - > len ) {