2005-04-17 02:20:36 +04:00
/*
* Copyright 2000 by Hans Reiser , licensing governed by reiserfs / README
*/
# include <linux/time.h>
2012-03-17 09:16:43 +04:00
# include "reiserfs.h"
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/*
* this contains item handlers for old item types : sd , direct ,
* indirect , directory
*/
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/*
* and where are the comments ? how about saying where we can find an
* explanation of each item handler method ? - Hans
*/
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/* stat data functions */
2005-07-13 07:21:28 +04:00
static int sd_bytes_number ( struct item_head * ih , int block_size )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void sd_decrement_key ( struct cpu_key * key )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
key - > on_disk_key . k_objectid - - ;
set_cpu_key_k_type ( key , TYPE_ANY ) ;
2007-04-12 10:28:44 +04:00
set_cpu_key_k_offset ( key , ( loff_t ) ( ~ 0ULL > > 1 ) ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_is_left_mergeable ( struct reiserfs_key * key , unsigned long bsize )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void sd_print_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
printk ( " \t mode | size | nlinks | first direct | mtime \n " ) ;
if ( stat_data_v1 ( ih ) ) {
struct stat_data_v1 * sd = ( struct stat_data_v1 * ) item ;
2005-04-17 02:20:36 +04:00
2018-08-22 07:59:30 +03:00
printk ( " \t 0%-6o | %6u | %2u | %d | %u \n " , sd_v1_mode ( sd ) ,
2005-07-13 07:21:28 +04:00
sd_v1_size ( sd ) , sd_v1_nlink ( sd ) ,
sd_v1_first_direct_byte ( sd ) ,
2018-08-22 07:59:30 +03:00
sd_v1_mtime ( sd ) ) ;
2005-07-13 07:21:28 +04:00
} else {
struct stat_data * sd = ( struct stat_data * ) item ;
2005-04-17 02:20:36 +04:00
2018-08-22 07:59:30 +03:00
printk ( " \t 0%-6o | %6llu | %2u | %d | %u \n " , sd_v2_mode ( sd ) ,
2005-07-13 07:21:28 +04:00
( unsigned long long ) sd_v2_size ( sd ) , sd_v2_nlink ( sd ) ,
2018-08-22 07:59:30 +03:00
sd_v2_rdev ( sd ) , sd_v2_mtime ( sd ) ) ;
2005-07-13 07:21:28 +04:00
}
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void sd_check_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
/* unused */
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_create_vi ( struct virtual_node * vn ,
struct virtual_item * vi ,
int is_affected , int insert_size )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
vi - > vi_index = TYPE_STAT_DATA ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_check_left ( struct virtual_item * vi , int free ,
int start_skip , int end_skip )
2005-04-17 02:20:36 +04:00
{
2006-10-04 01:36:38 +04:00
BUG_ON ( start_skip | | end_skip ) ;
2005-07-13 07:21:28 +04:00
return - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_check_right ( struct virtual_item * vi , int free )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_part_size ( struct virtual_item * vi , int first , int count )
2005-04-17 02:20:36 +04:00
{
2006-10-04 01:36:38 +04:00
BUG_ON ( count ) ;
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sd_unit_num ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return vi - > vi_item_len - IH_SIZE ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void sd_print_vi ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " reiserfs-16100 " ,
" STATDATA, index %d, type 0x%x, %h " ,
2005-07-13 07:21:28 +04:00
vi - > vi_index , vi - > vi_type , vi - > vi_ih ) ;
2005-04-17 02:20:36 +04:00
}
static struct item_operations stat_data_ops = {
2005-07-13 07:21:28 +04:00
. bytes_number = sd_bytes_number ,
. decrement_key = sd_decrement_key ,
. is_left_mergeable = sd_is_left_mergeable ,
. print_item = sd_print_item ,
. check_item = sd_check_item ,
. create_vi = sd_create_vi ,
. check_left = sd_check_left ,
. check_right = sd_check_right ,
. part_size = sd_part_size ,
. unit_num = sd_unit_num ,
. print_vi = sd_print_vi
2005-04-17 02:20:36 +04:00
} ;
2014-04-23 18:00:36 +04:00
/* direct item functions */
2005-07-13 07:21:28 +04:00
static int direct_bytes_number ( struct item_head * ih , int block_size )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return ih_item_len ( ih ) ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/* FIXME: this should probably switch to indirect as well */
2005-07-13 07:21:28 +04:00
static void direct_decrement_key ( struct cpu_key * key )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
cpu_key_k_offset_dec ( key ) ;
if ( cpu_key_k_offset ( key ) = = 0 )
set_cpu_key_k_type ( key , TYPE_STAT_DATA ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_is_left_mergeable ( struct reiserfs_key * key ,
unsigned long bsize )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int version = le_key_version ( key ) ;
return ( ( le_key_k_offset ( version , key ) & ( bsize - 1 ) ) ! = 1 ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void direct_print_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int j = 0 ;
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/* return; */
2005-07-13 07:21:28 +04:00
printk ( " \" " ) ;
while ( j < ih_item_len ( ih ) )
printk ( " %c " , item [ j + + ] ) ;
printk ( " \" \n " ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void direct_check_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
/* unused */
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_create_vi ( struct virtual_node * vn ,
struct virtual_item * vi ,
int is_affected , int insert_size )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
vi - > vi_index = TYPE_DIRECT ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_check_left ( struct virtual_item * vi , int free ,
int start_skip , int end_skip )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int bytes ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
bytes = free - free % 8 ;
return bytes ? : - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_check_right ( struct virtual_item * vi , int free )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return direct_check_left ( vi , free , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_part_size ( struct virtual_item * vi , int first , int count )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return count ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direct_unit_num ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return vi - > vi_item_len - IH_SIZE ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void direct_print_vi ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " reiserfs-16101 " ,
" DIRECT, index %d, type 0x%x, %h " ,
2005-07-13 07:21:28 +04:00
vi - > vi_index , vi - > vi_type , vi - > vi_ih ) ;
2005-04-17 02:20:36 +04:00
}
static struct item_operations direct_ops = {
2005-07-13 07:21:28 +04:00
. bytes_number = direct_bytes_number ,
. decrement_key = direct_decrement_key ,
. is_left_mergeable = direct_is_left_mergeable ,
. print_item = direct_print_item ,
. check_item = direct_check_item ,
. create_vi = direct_create_vi ,
. check_left = direct_check_left ,
. check_right = direct_check_right ,
. part_size = direct_part_size ,
. unit_num = direct_unit_num ,
. print_vi = direct_print_vi
2005-04-17 02:20:36 +04:00
} ;
2014-04-23 18:00:36 +04:00
/* indirect item functions */
2005-07-13 07:21:28 +04:00
static int indirect_bytes_number ( struct item_head * ih , int block_size )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
return ih_item_len ( ih ) / UNFM_P_SIZE * block_size ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/* decrease offset, if it becomes 0, change type to stat data */
2005-07-13 07:21:28 +04:00
static void indirect_decrement_key ( struct cpu_key * key )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
cpu_key_k_offset_dec ( key ) ;
if ( cpu_key_k_offset ( key ) = = 0 )
set_cpu_key_k_type ( key , TYPE_STAT_DATA ) ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/* if it is not first item of the body, then it is mergeable */
2005-07-13 07:21:28 +04:00
static int indirect_is_left_mergeable ( struct reiserfs_key * key ,
unsigned long bsize )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int version = le_key_version ( key ) ;
return ( le_key_k_offset ( version , key ) ! = 1 ) ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/* printing of indirect item */
2005-07-13 07:21:28 +04:00
static void start_new_sequence ( __u32 * start , int * len , __u32 new )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
* start = new ;
* len = 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int sequence_finished ( __u32 start , int * len , __u32 new )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( start = = INT_MAX )
return 1 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( start = = 0 & & new = = 0 ) {
( * len ) + + ;
return 0 ;
}
if ( start ! = 0 & & ( start + * len ) = = new ) {
( * len ) + + ;
return 0 ;
}
return 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void print_sequence ( __u32 start , int len )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( start = = INT_MAX )
return ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( len = = 1 )
printk ( " %d " , start ) ;
else
printk ( " %d(%d) " , start , len ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void indirect_print_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int j ;
__le32 * unp ;
__u32 prev = INT_MAX ;
2006-03-25 14:07:54 +03:00
int num = 0 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
unp = ( __le32 * ) item ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( ih_item_len ( ih ) % UNFM_P_SIZE )
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " reiserfs-16102 " , " invalid item len " ) ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
printk ( " %d pointers \n [ " , ( int ) I_UNFM_NUM ( ih ) ) ;
for ( j = 0 ; j < I_UNFM_NUM ( ih ) ; j + + ) {
if ( sequence_finished ( prev , & num , get_block_num ( unp , j ) ) ) {
print_sequence ( prev , num ) ;
start_new_sequence ( & prev , & num , get_block_num ( unp , j ) ) ;
}
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
print_sequence ( prev , num ) ;
printk ( " ] \n " ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void indirect_check_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
/* unused */
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int indirect_create_vi ( struct virtual_node * vn ,
struct virtual_item * vi ,
int is_affected , int insert_size )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
vi - > vi_index = TYPE_INDIRECT ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int indirect_check_left ( struct virtual_item * vi , int free ,
int start_skip , int end_skip )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int bytes ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
bytes = free - free % UNFM_P_SIZE ;
return bytes ? : - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int indirect_check_right ( struct virtual_item * vi , int free )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
return indirect_check_left ( vi , free , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/*
* return size in bytes of ' units ' units . If first = = 0 - calculate
* from the head ( left ) , otherwise - from tail ( right )
*/
2005-07-13 07:21:28 +04:00
static int indirect_part_size ( struct virtual_item * vi , int first , int units )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
/* unit of indirect item is byte (yet) */
2005-07-13 07:21:28 +04:00
return units ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int indirect_unit_num ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2014-04-23 18:00:36 +04:00
/* unit of indirect item is byte (yet) */
2005-07-13 07:21:28 +04:00
return vi - > vi_item_len - IH_SIZE ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void indirect_print_vi ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " reiserfs-16103 " ,
" INDIRECT, index %d, type 0x%x, %h " ,
2005-07-13 07:21:28 +04:00
vi - > vi_index , vi - > vi_type , vi - > vi_ih ) ;
2005-04-17 02:20:36 +04:00
}
static struct item_operations indirect_ops = {
2005-07-13 07:21:28 +04:00
. bytes_number = indirect_bytes_number ,
. decrement_key = indirect_decrement_key ,
. is_left_mergeable = indirect_is_left_mergeable ,
. print_item = indirect_print_item ,
. check_item = indirect_check_item ,
. create_vi = indirect_create_vi ,
. check_left = indirect_check_left ,
. check_right = indirect_check_right ,
. part_size = indirect_part_size ,
. unit_num = indirect_unit_num ,
. print_vi = indirect_print_vi
2005-04-17 02:20:36 +04:00
} ;
2014-04-23 18:00:36 +04:00
/* direntry functions */
2005-07-13 07:21:28 +04:00
static int direntry_bytes_number ( struct item_head * ih , int block_size )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " vs-16090 " ,
2005-07-13 07:21:28 +04:00
" bytes number is asked for direntry " ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void direntry_decrement_key ( struct cpu_key * key )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
cpu_key_k_offset_dec ( key ) ;
if ( cpu_key_k_offset ( key ) = = 0 )
set_cpu_key_k_type ( key , TYPE_STAT_DATA ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direntry_is_left_mergeable ( struct reiserfs_key * key ,
unsigned long bsize )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( le32_to_cpu ( key - > u . k_offset_v1 . k_offset ) = = DOT_OFFSET )
return 0 ;
return 1 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
}
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
static void direntry_print_item ( struct item_head * ih , char * item )
{
int i ;
int namelen ;
struct reiserfs_de_head * deh ;
char * name ;
static char namebuf [ 80 ] ;
printk ( " \n # %-15s%-30s%-15s%-15s%-15s \n " , " Name " ,
" Key of pointed object " , " Hash " , " Gen number " , " Status " ) ;
deh = ( struct reiserfs_de_head * ) item ;
2014-04-23 18:00:35 +04:00
for ( i = 0 ; i < ih_entry_count ( ih ) ; i + + , deh + + ) {
2005-07-13 07:21:28 +04:00
namelen =
( i ? ( deh_location ( deh - 1 ) ) : ih_item_len ( ih ) ) -
deh_location ( deh ) ;
name = item + deh_location ( deh ) ;
if ( name [ namelen - 1 ] = = 0 )
namelen = strlen ( name ) ;
namebuf [ 0 ] = ' " ' ;
if ( namelen > sizeof ( namebuf ) - 3 ) {
strncpy ( namebuf + 1 , name , sizeof ( namebuf ) - 3 ) ;
namebuf [ sizeof ( namebuf ) - 2 ] = ' " ' ;
namebuf [ sizeof ( namebuf ) - 1 ] = 0 ;
} else {
memcpy ( namebuf + 1 , name , namelen ) ;
namebuf [ namelen + 1 ] = ' " ' ;
namebuf [ namelen + 2 ] = 0 ;
}
2014-08-09 01:21:10 +04:00
printk ( " %d: %-15s%-15d%-15d%-15lld%-15lld(%s) \n " ,
2005-07-13 07:21:28 +04:00
i , namebuf ,
deh_dir_id ( deh ) , deh_objectid ( deh ) ,
GET_HASH_VALUE ( deh_offset ( deh ) ) ,
GET_GENERATION_NUMBER ( ( deh_offset ( deh ) ) ) ,
( de_hidden ( deh ) ) ? " HIDDEN " : " VISIBLE " ) ;
2005-04-17 02:20:36 +04:00
}
}
2005-07-13 07:21:28 +04:00
static void direntry_check_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int i ;
struct reiserfs_de_head * deh ;
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/* unused */
2005-07-13 07:21:28 +04:00
deh = ( struct reiserfs_de_head * ) item ;
2014-04-23 18:00:35 +04:00
for ( i = 0 ; i < ih_entry_count ( ih ) ; i + + , deh + + ) {
2005-07-13 07:21:28 +04:00
;
}
2005-04-17 02:20:36 +04:00
}
# define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
/*
* function returns old entry number in directory item in real node
2014-04-23 18:00:36 +04:00
* using new entry number in virtual item in virtual node
*/
2005-07-13 07:21:28 +04:00
static inline int old_entry_num ( int is_affected , int virtual_entry_num ,
int pos_in_item , int mode )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
if ( mode = = M_INSERT | | mode = = M_DELETE )
return virtual_entry_num ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( ! is_affected )
/* cut or paste is applied to another item */
return virtual_entry_num ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( virtual_entry_num < pos_in_item )
return virtual_entry_num ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( mode = = M_CUT )
return virtual_entry_num + 1 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
RFALSE ( mode ! = M_PASTE | | virtual_entry_num = = 0 ,
" vs-8015: old_entry_num: mode must be M_PASTE (mode = \' %c \' " ,
mode ) ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
return virtual_entry_num - 1 ;
}
2005-04-17 02:20:36 +04:00
2014-04-23 18:00:36 +04:00
/*
* Create an array of sizes of directory entries for virtual
* item . Return space used by an item . FIXME : no control over
* consuming of space used by this item handler
*/
2005-07-13 07:21:28 +04:00
static int direntry_create_vi ( struct virtual_node * vn ,
struct virtual_item * vi ,
int is_affected , int insert_size )
{
struct direntry_uarea * dir_u = vi - > vi_uarea ;
int i , j ;
int size = sizeof ( struct direntry_uarea ) ;
struct reiserfs_de_head * deh ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
vi - > vi_index = TYPE_DIRENTRY ;
2006-10-04 01:36:38 +04:00
BUG_ON ( ! ( vi - > vi_ih ) | | ! vi - > vi_item ) ;
2005-07-13 07:21:28 +04:00
dir_u - > flags = 0 ;
if ( le_ih_k_offset ( vi - > vi_ih ) = = DOT_OFFSET )
dir_u - > flags | = DIRENTRY_VI_FIRST_DIRENTRY_ITEM ;
deh = ( struct reiserfs_de_head * ) ( vi - > vi_item ) ;
/* virtual directory item have this amount of entry after */
dir_u - > entry_count = ih_entry_count ( vi - > vi_ih ) +
( ( is_affected ) ? ( ( vn - > vn_mode = = M_CUT ) ? - 1 :
( vn - > vn_mode = = M_PASTE ? 1 : 0 ) ) : 0 ) ;
for ( i = 0 ; i < dir_u - > entry_count ; i + + ) {
j = old_entry_num ( is_affected , i , vn - > vn_pos_in_item ,
vn - > vn_mode ) ;
dir_u - > entry_sizes [ i ] =
2014-04-23 18:00:42 +04:00
( j ? deh_location ( & deh [ j - 1 ] ) : ih_item_len ( vi - > vi_ih ) ) -
deh_location ( & deh [ j ] ) + DEH_SIZE ;
2005-07-13 07:21:28 +04:00
}
size + = ( dir_u - > entry_count * sizeof ( short ) ) ;
/* set size of pasted entry */
if ( is_affected & & vn - > vn_mode = = M_PASTE )
dir_u - > entry_sizes [ vn - > vn_pos_in_item ] = insert_size ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_REISERFS_CHECK
2005-07-13 07:21:28 +04:00
/* compare total size of entries with item length */
{
int k , l ;
l = 0 ;
for ( k = 0 ; k < dir_u - > entry_count ; k + + )
l + = dir_u - > entry_sizes [ k ] ;
if ( l + IH_SIZE ! = vi - > vi_item_len +
( ( is_affected
& & ( vn - > vn_mode = = M_PASTE
| | vn - > vn_mode = = M_CUT ) ) ? insert_size : 0 ) ) {
2009-03-30 22:02:25 +04:00
reiserfs_panic ( NULL , " vs-8025 " , " (mode==%c, "
" insert_size==%d), invalid length of "
" directory item " ,
2005-07-13 07:21:28 +04:00
vn - > vn_mode , insert_size ) ;
}
2005-04-17 02:20:36 +04:00
}
# endif
2005-07-13 07:21:28 +04:00
return size ;
2005-04-17 02:20:36 +04:00
}
2014-04-23 18:00:36 +04:00
/*
* return number of entries which may fit into specified amount of
* free space , or - 1 if free space is not enough even for 1 entry
*/
2005-07-13 07:21:28 +04:00
static int direntry_check_left ( struct virtual_item * vi , int free ,
int start_skip , int end_skip )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int i ;
int entries = 0 ;
struct direntry_uarea * dir_u = vi - > vi_uarea ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
for ( i = start_skip ; i < dir_u - > entry_count - end_skip ; i + + ) {
2014-04-23 18:00:36 +04:00
/* i-th entry doesn't fit into the remaining free space */
2005-07-13 07:21:28 +04:00
if ( dir_u - > entry_sizes [ i ] > free )
break ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
free - = dir_u - > entry_sizes [ i ] ;
entries + + ;
}
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
if ( entries = = dir_u - > entry_count ) {
2009-03-30 22:02:25 +04:00
reiserfs_panic ( NULL , " item_ops-1 " ,
" free space %d, entry_count %d " , free ,
2005-07-13 07:21:28 +04:00
dir_u - > entry_count ) ;
}
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
/* "." and ".." can not be separated from each other */
if ( start_skip = = 0 & & ( dir_u - > flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM )
& & entries < 2 )
entries = 0 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
return entries ? : - 1 ;
}
static int direntry_check_right ( struct virtual_item * vi , int free )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int i ;
int entries = 0 ;
struct direntry_uarea * dir_u = vi - > vi_uarea ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
for ( i = dir_u - > entry_count - 1 ; i > = 0 ; i - - ) {
2014-04-23 18:00:36 +04:00
/* i-th entry doesn't fit into the remaining free space */
2005-07-13 07:21:28 +04:00
if ( dir_u - > entry_sizes [ i ] > free )
break ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
free - = dir_u - > entry_sizes [ i ] ;
entries + + ;
}
2006-10-04 01:36:38 +04:00
BUG_ON ( entries = = dir_u - > entry_count ) ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
/* "." and ".." can not be separated from each other */
if ( ( dir_u - > flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM )
& & entries > dir_u - > entry_count - 2 )
entries = dir_u - > entry_count - 2 ;
return entries ? : - 1 ;
}
2005-04-17 02:20:36 +04:00
/* sum of entry sizes between from-th and to-th entries including both edges */
2005-07-13 07:21:28 +04:00
static int direntry_part_size ( struct virtual_item * vi , int first , int count )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int i , retval ;
int from , to ;
struct direntry_uarea * dir_u = vi - > vi_uarea ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
retval = 0 ;
if ( first = = 0 )
from = 0 ;
else
from = dir_u - > entry_count - count ;
to = from + count - 1 ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
for ( i = from ; i < = to ; i + + )
retval + = dir_u - > entry_sizes [ i ] ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
return retval ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int direntry_unit_num ( struct virtual_item * vi )
{
struct direntry_uarea * dir_u = vi - > vi_uarea ;
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
return dir_u - > entry_count ;
}
2005-04-17 02:20:36 +04:00
2005-07-13 07:21:28 +04:00
static void direntry_print_vi ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2005-07-13 07:21:28 +04:00
int i ;
struct direntry_uarea * dir_u = vi - > vi_uarea ;
2005-04-17 02:20:36 +04:00
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " reiserfs-16104 " ,
" DIRENTRY, index %d, type 0x%x, %h, flags 0x%x " ,
2005-07-13 07:21:28 +04:00
vi - > vi_index , vi - > vi_type , vi - > vi_ih , dir_u - > flags ) ;
printk ( " %d entries: " , dir_u - > entry_count ) ;
for ( i = 0 ; i < dir_u - > entry_count ; i + + )
printk ( " %d " , dir_u - > entry_sizes [ i ] ) ;
printk ( " \n " ) ;
2005-04-17 02:20:36 +04:00
}
static struct item_operations direntry_ops = {
2005-07-13 07:21:28 +04:00
. bytes_number = direntry_bytes_number ,
. decrement_key = direntry_decrement_key ,
. is_left_mergeable = direntry_is_left_mergeable ,
. print_item = direntry_print_item ,
. check_item = direntry_check_item ,
. create_vi = direntry_create_vi ,
. check_left = direntry_check_left ,
. check_right = direntry_check_right ,
. part_size = direntry_part_size ,
. unit_num = direntry_unit_num ,
. print_vi = direntry_print_vi
2005-04-17 02:20:36 +04:00
} ;
2014-04-23 18:00:36 +04:00
/* Error catching functions to catch errors caused by incorrect item types. */
2005-07-13 07:21:28 +04:00
static int errcatch_bytes_number ( struct item_head * ih , int block_size )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16001 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void errcatch_decrement_key ( struct cpu_key * key )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16002 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_is_left_mergeable ( struct reiserfs_key * key ,
unsigned long bsize )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16003 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void errcatch_print_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16004 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void errcatch_check_item ( struct item_head * ih , char * item )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16005 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_create_vi ( struct virtual_node * vn ,
struct virtual_item * vi ,
int is_affected , int insert_size )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16006 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2014-04-23 18:00:36 +04:00
/*
* We might return - 1 here as well , but it won ' t help as
* create_virtual_node ( ) from where this operation is called
* from is of return type void .
*/
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_check_left ( struct virtual_item * vi , int free ,
int start_skip , int end_skip )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16007 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_check_right ( struct virtual_item * vi , int free )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16008 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return - 1 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_part_size ( struct virtual_item * vi , int first , int count )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16009 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static int errcatch_unit_num ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16010 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-07-13 07:21:28 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-07-13 07:21:28 +04:00
static void errcatch_print_vi ( struct virtual_item * vi )
2005-04-17 02:20:36 +04:00
{
2009-03-30 22:02:21 +04:00
reiserfs_warning ( NULL , " green-16011 " ,
" Invalid item type observed, run fsck ASAP " ) ;
2005-04-17 02:20:36 +04:00
}
static struct item_operations errcatch_ops = {
2017-05-09 01:56:08 +03:00
. bytes_number = errcatch_bytes_number ,
. decrement_key = errcatch_decrement_key ,
. is_left_mergeable = errcatch_is_left_mergeable ,
. print_item = errcatch_print_item ,
. check_item = errcatch_check_item ,
. create_vi = errcatch_create_vi ,
. check_left = errcatch_check_left ,
. check_right = errcatch_check_right ,
. part_size = errcatch_part_size ,
. unit_num = errcatch_unit_num ,
. print_vi = errcatch_print_vi
2005-04-17 02:20:36 +04:00
} ;
# if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
2005-07-13 03:19:30 +04:00
# error Item types must use disk-format assigned values.
2005-04-17 02:20:36 +04:00
# endif
2005-07-13 07:21:28 +04:00
struct item_operations * item_ops [ TYPE_ANY + 1 ] = {
& stat_data_ops ,
& indirect_ops ,
& direct_ops ,
& direntry_ops ,
NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ,
& errcatch_ops /* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
2005-04-17 02:20:36 +04:00
} ;