2018-04-03 19:23:33 +02:00
// SPDX-License-Identifier: GPL-2.0
2013-09-19 16:07:01 -04:00
/*
* Copyright ( C ) 2013 Fusion IO . All rights reserved .
*/
# include <linux/slab.h>
# include "btrfs-tests.h"
# include "../ctree.h"
# include "../extent_io.h"
# include "../disk-io.h"
2016-06-01 19:18:25 +08:00
static int test_btrfs_split_item ( u32 sectorsize , u32 nodesize )
2013-09-19 16:07:01 -04:00
{
2016-06-20 14:14:09 -04:00
struct btrfs_fs_info * fs_info ;
struct btrfs_path * path = NULL ;
struct btrfs_root * root = NULL ;
2013-09-19 16:07:01 -04:00
struct extent_buffer * eb ;
struct btrfs_item * item ;
char * value = " mary had a little lamb " ;
char * split1 = " mary had a little " ;
char * split2 = " lamb " ;
char * split3 = " mary " ;
char * split4 = " had a little " ;
char buf [ 32 ] ;
struct btrfs_key key ;
u32 value_len = strlen ( value ) ;
int ret = 0 ;
2018-05-17 00:00:44 +02:00
test_msg ( " running btrfs_split_item tests " ) ;
2013-09-19 16:07:01 -04:00
2016-06-15 09:22:56 -04:00
fs_info = btrfs_alloc_dummy_fs_info ( nodesize , sectorsize ) ;
2016-06-20 14:14:09 -04:00
if ( ! fs_info ) {
2019-03-15 17:28:46 +01:00
test_std_err ( TEST_ALLOC_FS_INFO ) ;
2016-06-20 14:14:09 -04:00
return - ENOMEM ;
}
2016-06-15 09:22:56 -04:00
root = btrfs_alloc_dummy_root ( fs_info ) ;
2013-09-19 16:07:01 -04:00
if ( IS_ERR ( root ) ) {
2019-03-15 17:28:46 +01:00
test_std_err ( TEST_ALLOC_ROOT ) ;
2016-06-20 14:14:09 -04:00
ret = PTR_ERR ( root ) ;
goto out ;
2013-09-19 16:07:01 -04:00
}
path = btrfs_alloc_path ( ) ;
if ( ! path ) {
2019-03-15 17:28:46 +01:00
test_std_err ( TEST_ALLOC_PATH ) ;
2016-06-20 14:14:09 -04:00
ret = - ENOMEM ;
goto out ;
2013-09-19 16:07:01 -04:00
}
2016-06-15 09:22:56 -04:00
path - > nodes [ 0 ] = eb = alloc_dummy_extent_buffer ( fs_info , nodesize ) ;
2013-09-19 16:07:01 -04:00
if ( ! eb ) {
2019-03-15 17:28:46 +01:00
test_std_err ( TEST_ALLOC_EXTENT_BUFFER ) ;
2013-09-19 16:07:01 -04:00
ret = - ENOMEM ;
goto out ;
}
path - > slots [ 0 ] = 0 ;
key . objectid = 0 ;
key . type = BTRFS_EXTENT_CSUM_KEY ;
key . offset = 0 ;
2020-09-01 17:39:59 +03:00
setup_items_for_insert ( root , path , & key , & value_len , 1 ) ;
2013-09-19 16:07:01 -04:00
item = btrfs_item_nr ( 0 ) ;
write_extent_buffer ( eb , value , btrfs_item_ptr_offset ( eb , 0 ) ,
value_len ) ;
key . offset = 3 ;
/*
* Passing NULL trans here should be safe because we have plenty of
* space in this leaf to split the item without having to split the
* leaf .
*/
ret = btrfs_split_item ( NULL , root , path , & key , 17 ) ;
if ( ret ) {
2018-05-17 00:00:42 +02:00
test_err ( " split item failed %d " , ret ) ;
2013-09-19 16:07:01 -04:00
goto out ;
}
/*
* Read the first slot , it should have the original key and contain only
* ' mary had a little '
*/
btrfs_item_key_to_cpu ( eb , & key , 0 ) ;
if ( key . objectid ! = 0 | | key . type ! = BTRFS_EXTENT_CSUM_KEY | |
key . offset ! = 0 ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid key at slot 0 " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
item = btrfs_item_nr ( 0 ) ;
if ( btrfs_item_size ( eb , item ) ! = strlen ( split1 ) ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid len in the first split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
read_extent_buffer ( eb , buf , btrfs_item_ptr_offset ( eb , 0 ) ,
strlen ( split1 ) ) ;
if ( memcmp ( buf , split1 , strlen ( split1 ) ) ) {
2018-05-17 00:00:42 +02:00
test_err (
" data in the buffer doesn't match what it should in the first split have='%.*s' want '%s' " ,
2013-09-19 16:07:01 -04:00
( int ) strlen ( split1 ) , buf , split1 ) ;
ret = - EINVAL ;
goto out ;
}
btrfs_item_key_to_cpu ( eb , & key , 1 ) ;
if ( key . objectid ! = 0 | | key . type ! = BTRFS_EXTENT_CSUM_KEY | |
key . offset ! = 3 ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid key at slot 1 " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
item = btrfs_item_nr ( 1 ) ;
if ( btrfs_item_size ( eb , item ) ! = strlen ( split2 ) ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid len in the second split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
read_extent_buffer ( eb , buf , btrfs_item_ptr_offset ( eb , 1 ) ,
strlen ( split2 ) ) ;
if ( memcmp ( buf , split2 , strlen ( split2 ) ) ) {
2018-05-17 00:00:42 +02:00
test_err (
" data in the buffer doesn't match what it should in the second split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
key . offset = 1 ;
/* Do it again so we test memmoving the other items in the leaf */
ret = btrfs_split_item ( NULL , root , path , & key , 4 ) ;
if ( ret ) {
2018-05-17 00:00:42 +02:00
test_err ( " second split item failed %d " , ret ) ;
2013-09-19 16:07:01 -04:00
goto out ;
}
btrfs_item_key_to_cpu ( eb , & key , 0 ) ;
if ( key . objectid ! = 0 | | key . type ! = BTRFS_EXTENT_CSUM_KEY | |
key . offset ! = 0 ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid key at slot 0 " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
item = btrfs_item_nr ( 0 ) ;
if ( btrfs_item_size ( eb , item ) ! = strlen ( split3 ) ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid len in the first split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
read_extent_buffer ( eb , buf , btrfs_item_ptr_offset ( eb , 0 ) ,
strlen ( split3 ) ) ;
if ( memcmp ( buf , split3 , strlen ( split3 ) ) ) {
2018-05-17 00:00:42 +02:00
test_err (
" data in the buffer doesn't match what it should in the third split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
btrfs_item_key_to_cpu ( eb , & key , 1 ) ;
if ( key . objectid ! = 0 | | key . type ! = BTRFS_EXTENT_CSUM_KEY | |
key . offset ! = 1 ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid key at slot 1 " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
item = btrfs_item_nr ( 1 ) ;
if ( btrfs_item_size ( eb , item ) ! = strlen ( split4 ) ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid len in the second split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
read_extent_buffer ( eb , buf , btrfs_item_ptr_offset ( eb , 1 ) ,
strlen ( split4 ) ) ;
if ( memcmp ( buf , split4 , strlen ( split4 ) ) ) {
2018-05-17 00:00:42 +02:00
test_err (
" data in the buffer doesn't match what it should in the fourth split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
btrfs_item_key_to_cpu ( eb , & key , 2 ) ;
if ( key . objectid ! = 0 | | key . type ! = BTRFS_EXTENT_CSUM_KEY | |
key . offset ! = 3 ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid key at slot 2 " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
item = btrfs_item_nr ( 2 ) ;
if ( btrfs_item_size ( eb , item ) ! = strlen ( split2 ) ) {
2018-05-17 00:00:42 +02:00
test_err ( " invalid len in the second split " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
read_extent_buffer ( eb , buf , btrfs_item_ptr_offset ( eb , 2 ) ,
strlen ( split2 ) ) ;
if ( memcmp ( buf , split2 , strlen ( split2 ) ) ) {
2018-05-17 00:00:42 +02:00
test_err (
" data in the buffer doesn't match what it should in the last chunk " ) ;
2013-09-19 16:07:01 -04:00
ret = - EINVAL ;
goto out ;
}
out :
btrfs_free_path ( path ) ;
2016-06-20 14:14:09 -04:00
btrfs_free_dummy_root ( root ) ;
btrfs_free_dummy_fs_info ( fs_info ) ;
2013-09-19 16:07:01 -04:00
return ret ;
}
2016-06-01 19:18:25 +08:00
int btrfs_test_extent_buffer_operations ( u32 sectorsize , u32 nodesize )
2013-09-19 16:07:01 -04:00
{
2018-05-17 00:00:44 +02:00
test_msg ( " running extent buffer operation tests " ) ;
2016-06-01 19:18:25 +08:00
return test_btrfs_split_item ( sectorsize , nodesize ) ;
2013-09-19 16:07:01 -04:00
}