From 7d4b6a2eeab335774ea5031745ca29c1268a6761 Mon Sep 17 00:00:00 2001 From: Bart Hakvoort Date: Sun, 22 Jan 2006 00:07:27 +0000 Subject: [PATCH] :sector_to_unit() and use it in several places fixed errors with * implemented Utils::sector_to_unit() and use it in several places * (finally) fixed errors with ntfsresizing (had a lot to do with difference between MB and MiB) * resizing of reiserfs now shows more detailed feedback * support for TebiByte (TiB) unit --- ChangeLog | 8 ++++ include/Utils.h | 23 ++++++++++-- src/Dialog_Base_Partition.cc | 8 ++-- src/Dialog_Partition_New.cc | 8 ++-- src/Dialog_Partition_Resize_Move.cc | 21 ++++++----- src/GParted_Core.cc | 17 +++++---- src/Operation.cc | 20 ++++++---- src/Partition.cc | 4 +- src/Utils.cc | 58 ++++++++++++++++++++++------- src/ext2.cc | 5 ++- src/ext3.cc | 3 +- src/ntfs.cc | 8 ++-- src/reiserfs.cc | 20 ++++++++-- 13 files changed, 141 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index eef3798a..82c695b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-01-22 Bart Hakvoort + + * implemented Utils::sector_to_unit() and use it in several places + * (finally) fixed errors with ntfsresizing (had a lot to do with + difference between MB and MiB) + * resizing of reiserfs now shows more detailed feedback + * support for TebiByte (TiB) unit + 2006-01-21 Bart Hakvoort * changed KB/MB/GB/TB to KiB/MiB/GiB/TiB after reading http://www.iec.ch/zone/si/si_bytes.htm diff --git a/include/Utils.h b/include/Utils.h index aff5a68f..cfcd5639 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -37,7 +37,11 @@ namespace GParted typedef long long Sector; -#define MEGABYTE 2048 //try it: 2048 * 512 / 1024 /1024 == 1 :P +//sizeunits defined in sectors of 512 bytes.. +#define KIBIBYTE 2 +#define MEBIBYTE 2048 +#define GIBIBYTE 2097152 +#define TEBIBYTE 2147483648U enum FILESYSTEM { @@ -64,6 +68,17 @@ enum FILESYSTEM FS_UNUSED = 18 }; +enum SIZE_UNIT +{ + UNIT_SECTOR = 0, + UNIT_BYTE = 1, + + UNIT_KIB = 2, + UNIT_MIB = 3, + UNIT_GIB = 4, + UNIT_TIB = 5, +}; + //struct to store filesysteminformation struct FS { @@ -85,7 +100,7 @@ struct FS int MIN ; int MAX ; - FS( ) + FS() { read = create = grow = shrink = move = check = copy = NONE; MIN = MAX = 0 ; @@ -96,8 +111,7 @@ struct FS class Utils { public: - static long Round( double double_value ) ; - static long Sector_To_MB( Sector sectors ) ; + static Sector Round( double double_value ) ; static Gtk::Label * mk_label( const Glib::ustring & text, bool use_markup = true, bool align_left = true, @@ -115,6 +129,7 @@ public: const Glib::ustring & data = "" ) ; static bool unmount( const Glib::ustring & node, const Glib::ustring & mountpoint, Glib::ustring & error ) ; static Glib::ustring format_size( Sector size ) ; + static double sector_to_unit( Sector sectors, SIZE_UNIT size_unit ) ; }; diff --git a/src/Dialog_Base_Partition.cc b/src/Dialog_Base_Partition.cc index dc896d77..2eb9a012 100644 --- a/src/Dialog_Base_Partition.cc +++ b/src/Dialog_Base_Partition.cc @@ -112,10 +112,10 @@ void Dialog_Base_Partition::Set_Resizer( bool extended ) Partition Dialog_Base_Partition::Get_New_Partition( ) { if ( ORIG_BEFORE != spinbutton_before .get_value_as_int( ) ) - selected_partition .sector_start = START + spinbutton_before .get_value_as_int( ) * MEGABYTE ; + selected_partition .sector_start = START + spinbutton_before .get_value_as_int( ) * MEBIBYTE ; if ( ORIG_AFTER != spinbutton_after .get_value_as_int( ) ) - selected_partition .sector_end = selected_partition .sector_start + spinbutton_size .get_value_as_int( ) * MEGABYTE ; + selected_partition .sector_end = selected_partition .sector_start + spinbutton_size .get_value_as_int( ) * MEBIBYTE ; //due to loss of precision during calcs from Sector -> MiB and back, it is possible the new partition thinks it's bigger then it can be. Here we solve this. if ( selected_partition .sector_start < START ) @@ -124,9 +124,9 @@ Partition Dialog_Base_Partition::Get_New_Partition( ) selected_partition .sector_end = START + total_length ; //grow a bit into small freespace ( < 1MB ) - if ( (selected_partition .sector_start - START) < MEGABYTE ) + if ( (selected_partition .sector_start - START) < MEBIBYTE ) selected_partition .sector_start = START ; - if ( ( START + total_length - selected_partition .sector_end ) < MEGABYTE ) + if ( ( START + total_length - selected_partition .sector_end ) < MEBIBYTE ) selected_partition .sector_end = START + total_length ; //set new value of unused.. diff --git a/src/Dialog_Partition_New.cc b/src/Dialog_Partition_New.cc index 3262f244..87d6159f 100644 --- a/src/Dialog_Partition_New.cc +++ b/src/Dialog_Partition_New.cc @@ -130,8 +130,8 @@ Partition Dialog_Partition_New::Get_New_Partition() default : part_type = GParted::TYPE_UNALLOCATED ; } - new_start = START + (Sector) (spinbutton_before .get_value( ) * MEGABYTE) ; - new_end = new_start + (Sector) (spinbutton_size .get_value( ) * MEGABYTE) ; + new_start = START + (Sector) (spinbutton_before .get_value( ) * MEBIBYTE) ; + new_end = new_start + (Sector) (spinbutton_size .get_value( ) * MEBIBYTE) ; /* due to loss of precision during calcs from Sector -> MiB and back, it is possible the new * partition thinks it's bigger then it can be. Here we try to solve this.*/ @@ -149,9 +149,9 @@ Partition Dialog_Partition_New::Get_New_Partition() selected_partition .inside_extended, false) ; //grow new partition a bit if freespaces are < 1 MiB - if ( (part_temp.sector_start - selected_partition.sector_start) < MEGABYTE ) + if ( (part_temp.sector_start - selected_partition.sector_start) < MEBIBYTE ) part_temp.sector_start = selected_partition.sector_start ; - if ( (selected_partition.sector_end - part_temp.sector_end) < MEGABYTE ) + if ( (selected_partition.sector_end - part_temp.sector_end) < MEBIBYTE ) part_temp.sector_end = selected_partition.sector_end ; //if new is extended... diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc index f9eb1908..890d9849 100644 --- a/src/Dialog_Partition_Resize_Move.cc +++ b/src/Dialog_Partition_Resize_Move.cc @@ -99,7 +99,7 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector set_size_limits( Utils::Round( fs .MIN / MB_PER_PIXEL ), Utils::Round( fs .MAX / MB_PER_PIXEL ) +1 ) ; @@ -171,7 +171,7 @@ void Dialog_Partition_Resize_Move::Resize_Move_Extended( const std::vector & devices ) temp_device .sectors = lp_device ->bios_geom .sectors ; temp_device .cylinders = lp_device ->bios_geom .cylinders ; temp_device .length = temp_device .heads * temp_device .sectors * temp_device .cylinders ; - temp_device .cylsize = Utils::Sector_To_MB( temp_device .heads * temp_device .sectors ) ; + temp_device .cylsize = Utils::Round( Utils::sector_to_unit( + temp_device .heads * temp_device .sectors, GParted::UNIT_MIB ) ) ; //make sure cylsize is at least 1 MiB if ( temp_device .cylsize < 1 ) @@ -440,7 +441,7 @@ void GParted_Core::insert_unallocated( const Glib::ustring & device_path, std::v } //start <---> first partition start - if ( (partitions .front( ) .sector_start - start) >= MEGABYTE ) + if ( (partitions .front( ) .sector_start - start) >= MEBIBYTE ) { partition_temp .sector_start = start ; partition_temp .sector_end = partitions .front( ) .sector_start -1 ; @@ -450,7 +451,7 @@ void GParted_Core::insert_unallocated( const Glib::ustring & device_path, std::v //look for gaps in between for ( unsigned int t =0 ; t < partitions .size( ) -1 ; t++ ) - if ( ( partitions[ t +1 ] .sector_start - partitions[ t ] .sector_end ) >= MEGABYTE ) + if ( ( partitions[ t +1 ] .sector_start - partitions[ t ] .sector_end ) >= MEBIBYTE ) { partition_temp .sector_start = partitions[ t ] .sector_end +1 ; partition_temp .sector_end = partitions[ t +1 ] .sector_start -1 ; @@ -459,7 +460,7 @@ void GParted_Core::insert_unallocated( const Glib::ustring & device_path, std::v } //last partition end <---> end - if ( (end - partitions .back( ) .sector_end ) >= MEGABYTE ) + if ( (end - partitions .back( ) .sector_end ) >= MEBIBYTE ) { partition_temp .sector_start = partitions .back( ) .sector_end +1 ; partition_temp .sector_end = end ; @@ -748,9 +749,9 @@ int GParted_Core::create_empty_partition( Partition & new_partition, if ( constraint ) { if ( copy ) - constraint ->min_size = new_partition .sector_end - new_partition .sector_start ; + constraint ->min_size = new_partition .get_length() ; - if ( ped_disk_add_partition( lp_disk, c_part, constraint ) && commit( ) ) + if ( ped_disk_add_partition( lp_disk, c_part, constraint ) && commit() ) { new_partition .partition = ped_partition_get_path( c_part ) ; new_partition .partition_number = c_part ->num ; @@ -761,7 +762,7 @@ int GParted_Core::create_empty_partition( Partition & new_partition, } - close_device_and_disk( ) ; + close_device_and_disk() ; } if ( new_partition .type == GParted::TYPE_EXTENDED || @@ -820,7 +821,7 @@ bool GParted_Core::resize_container_partition( const Partition & partition_old, if ( constraint ) { if ( ped_disk_set_partition_geom( lp_disk, lp_partition, constraint, partition_new .sector_start, partition_new .sector_end ) ) - return_value = commit( ) ; + return_value = commit() ; ped_constraint_destroy( constraint ); } diff --git a/src/Operation.cc b/src/Operation.cc index ccfb4500..d3bbb6c5 100644 --- a/src/Operation.cc +++ b/src/Operation.cc @@ -86,18 +86,22 @@ Glib::ustring Operation::Get_String( ) case RESIZE_MOVE: //if startsector has changed >= 1 MiB we consider it a move diff = std::abs( partition_new .sector_start - partition_original .sector_start ) ; - if ( diff >= MEGABYTE ) + if ( diff >= MEBIBYTE ) { if ( partition_new .sector_start > partition_original .sector_start ) - temp = String::ucompose( _("Move %1 forward by %2 MiB"), partition_new.partition, Utils::Sector_To_MB( diff ) ) ; + temp = String::ucompose( _("Move %1 forward by %2 MiB"), + partition_new.partition, + Utils::Round( Utils::sector_to_unit( diff, GParted::UNIT_MIB ) ) ) ; else - temp = String::ucompose( _("Move %1 backward by %2 MiB"), partition_new.partition, Utils::Sector_To_MB( diff ) ) ; + temp = String::ucompose( _("Move %1 backward by %2 MiB"), + partition_new.partition, + Utils::Round( Utils::sector_to_unit( diff, GParted::UNIT_MIB ) ) ) ; } //check if size has changed ( we only consider changes >= 1 MiB ) diff = std::abs( (partition_original .sector_end - partition_original .sector_start) - (partition_new .sector_end - partition_new .sector_start) ) ; - if ( diff >= MEGABYTE ) + if ( diff >= MEBIBYTE ) { if ( temp .empty( ) ) temp = String::ucompose( _("Resize %1 from %2 MiB to %3 MiB"), @@ -127,7 +131,7 @@ Glib::ustring Operation::Get_String( ) return String::ucompose( _("Copy %1 to %2 (start at %3 MiB)"), partition_new .partition, device .path, - Utils::Sector_To_MB( partition_new .sector_start ) ) ; + Utils::Round( Utils::sector_to_unit( partition_new .sector_start, GParted::UNIT_MIB ) ) ) ; default : return ""; @@ -167,7 +171,7 @@ void Operation::Insert_Unallocated( std::vector & partitions, Sector } //start <---> first partition start - if ( (partitions .front( ) .sector_start - start) >= MEGABYTE ) + if ( (partitions .front( ) .sector_start - start) >= MEBIBYTE ) { UNALLOCATED .sector_start = start ; UNALLOCATED .sector_end = partitions .front( ) .sector_start -1 ; @@ -177,7 +181,7 @@ void Operation::Insert_Unallocated( std::vector & partitions, Sector //look for gaps in between for ( unsigned int t =0 ; t < partitions .size( ) -1 ; t++ ) - if ( ( partitions[ t +1 ] .sector_start - partitions[ t ] .sector_end ) >= MEGABYTE ) + if ( ( partitions[ t +1 ] .sector_start - partitions[ t ] .sector_end ) >= MEBIBYTE ) { UNALLOCATED .sector_start = partitions[ t ] .sector_end +1 ; UNALLOCATED .sector_end = partitions[ t +1 ] .sector_start -1 ; @@ -186,7 +190,7 @@ void Operation::Insert_Unallocated( std::vector & partitions, Sector } //last partition end <---> end - if ( (end - partitions .back( ) .sector_end ) >= MEGABYTE ) + if ( (end - partitions .back( ) .sector_end ) >= MEBIBYTE ) { UNALLOCATED .sector_start = partitions .back( ) .sector_end +1 ; UNALLOCATED .sector_end = end ; diff --git a/src/Partition.cc b/src/Partition.cc index bd420b54..e8834759 100644 --- a/src/Partition.cc +++ b/src/Partition.cc @@ -93,12 +93,12 @@ void Partition::Update_Number( int new_number ) long Partition::Get_Length_MB() const { - return Utils::Sector_To_MB( sector_end - sector_start ) ; + return Utils::Round( Utils::sector_to_unit( get_length(), GParted::UNIT_MIB ) ) ; } long Partition::Get_Used_MB() const { - return Utils::Sector_To_MB( this ->sectors_used ) ; + return Utils::Round( Utils::sector_to_unit( sectors_used, GParted::UNIT_MIB ) ) ; } long Partition::Get_Unused_MB() const diff --git a/src/Utils.cc b/src/Utils.cc index 41cd0ca8..09311c98 100644 --- a/src/Utils.cc +++ b/src/Utils.cc @@ -22,18 +22,12 @@ #include #include - namespace GParted { -long Utils::Round( double double_value ) +Sector Utils::Round( double double_value ) { - return static_cast( double_value + 0.5 ) ; -} - -long Utils::Sector_To_MB( Sector sectors ) -{ - return Round( sectors * 0.000488281250 ) ; // that's what 512/1024/1024 gives you :) + return static_cast( double_value + 0.5 ) ; } Gtk::Label * Utils::mk_label( const Glib::ustring & text, bool use_markup, bool align_left, bool wrap, const Glib::ustring & text_color ) @@ -241,20 +235,58 @@ bool Utils::unmount( const Glib::ustring & node, const Glib::ustring & mountpoin Glib::ustring Utils::format_size( Sector size ) { - size *= 512 ; std::stringstream ss ; //ss .imbue( std::locale( "" ) ) ; see #157871 ss << std::setiosflags( std::ios::fixed ) << std::setprecision( 2 ) ; - if ( size < 1073741824 ) + if ( size < KIBIBYTE ) { - ss << static_cast( size / 1048567.0 ) ; + ss << sector_to_unit( size, UNIT_BYTE ) ; + return String::ucompose( _("%1 B"), ss .str() ) ; + } + else if ( size < MEBIBYTE ) + { + ss << sector_to_unit( size, UNIT_KIB ) ; + return String::ucompose( _("%1 KiB"), ss .str() ) ; + } + else if ( size < GIBIBYTE ) + { + ss << sector_to_unit( size, UNIT_MIB ) ; return String::ucompose( _("%1 MiB"), ss .str() ) ; } + else if ( size < TEBIBYTE ) + { + ss << sector_to_unit( size, UNIT_GIB ) ; + return String::ucompose( _("%1 GiB"), ss .str() ) ; + } else { - ss << static_cast( size / 1073741824.0 ) ; - return String::ucompose( _("%1 GiB"), ss .str() ) ; + ss << sector_to_unit( size, UNIT_TIB ) ; + return String::ucompose( _("%1 TiB"), ss .str() ) ; + } +} + +double Utils::sector_to_unit( Sector sectors, SIZE_UNIT size_unit ) +{ + /* NOTE: this could have been done more efficient by using static numbers. + * However, the performancegain would be unnoticable and this way its easier to read/debug + */ + switch ( size_unit ) + { + case UNIT_BYTE : + return sectors * 512 ; + + case UNIT_KIB : + return sector_to_unit( sectors, UNIT_BYTE ) / 1024 ; + case UNIT_MIB : + return sector_to_unit( sectors, UNIT_KIB ) / 1024 ; + case UNIT_GIB : + return sector_to_unit( sectors, UNIT_MIB ) / 1024 ; + case UNIT_TIB : + return sector_to_unit( sectors, UNIT_GIB ) / 1024 ; + + default: + return sectors ; } } diff --git a/src/ext2.cc b/src/ext2.cc index 8ddfa0f3..42d2fa32 100644 --- a/src/ext2.cc +++ b/src/ext2.cc @@ -111,9 +111,10 @@ bool ext2::Resize( const Partition & partition_new, argv .clear() ; argv .push_back( "resize2fs" ) ; argv .push_back( partition_new .partition ) ; - + if ( ! fill_partition ) - argv .push_back( Utils::num_to_str( partition_new .Get_Length_MB() - cylinder_size, true ) + "M" ) ; + argv .push_back( Utils::num_to_str( Utils::Round( Utils::sector_to_unit( + partition_new .get_length(), GParted::UNIT_MIB ) ) - cylinder_size, true ) + "M" ) ; if ( ! execute_command( argv, operation_details .back() .sub_details ) ) { diff --git a/src/ext3.cc b/src/ext3.cc index 43fde2dc..362d9663 100644 --- a/src/ext3.cc +++ b/src/ext3.cc @@ -114,7 +114,8 @@ bool ext3::Resize( const Partition & partition_new, argv .push_back( partition_new .partition ) ; if ( ! fill_partition ) - argv .push_back( Utils::num_to_str( partition_new .Get_Length_MB() - cylinder_size, true ) + "M" ) ; + argv .push_back( Utils::num_to_str( Utils::Round( Utils::sector_to_unit( + partition_new .get_length(), GParted::UNIT_MIB ) ) - cylinder_size, true ) + "M" ) ; if ( ! execute_command( argv, operation_details .back() .sub_details ) ) { diff --git a/src/ntfs.cc b/src/ntfs.cc index 9031e60a..753d8e94 100644 --- a/src/ntfs.cc +++ b/src/ntfs.cc @@ -112,7 +112,10 @@ bool ntfs::Resize( const Partition & partition_new, Glib::ustring str_temp = "echo y | ntfsresize -P --force " + partition_new .partition ; if ( ! fill_partition ) - str_temp += " -s " + Utils::num_to_str( partition_new .Get_Length_MB() - cylinder_size, true ) + "M" ; + { + str_temp += " -s " ; + str_temp += Utils::num_to_str( Utils::Round( Utils::sector_to_unit( partition_new .get_length(), GParted::UNIT_BYTE ) ), true ) ; + } //simulation.. operation_details .back() .sub_details .push_back( OperationDetails( _("run simulation") ) ) ; @@ -129,8 +132,7 @@ bool ntfs::Resize( const Partition & partition_new, operation_details .back() .sub_details .push_back( OperationDetails( operation_details .back() .description ) ) ; - argv .erase( argv .end() ) ; - argv .push_back( str_temp ) ; + argv .back() = str_temp ; if ( ! execute_command( argv, operation_details .back() .sub_details .back() .sub_details ) ) { operation_details .back() .sub_details .back() .status = OperationDetails::SUCCES ; diff --git a/src/reiserfs.cc b/src/reiserfs.cc index 6492c64b..e2b8e3b0 100644 --- a/src/reiserfs.cc +++ b/src/reiserfs.cc @@ -107,7 +107,7 @@ bool reiserfs::Create( const Partition & new_partition, std::vector & operation_details, bool fill_partition ) -{//FIXME implement use of execute_command() for improved feedback +{ if ( fill_partition ) operation_details .push_back( OperationDetails( _("grow filesystem to fill the partition") ) ) ; else @@ -116,9 +116,23 @@ bool reiserfs::Resize( const Partition & partition_new, Glib::ustring str_temp = "echo y | resize_reiserfs " + partition_new .partition ; if ( ! fill_partition ) - str_temp += " -s " + Utils::num_to_str( partition_new .Get_Length_MB( ) - cylinder_size, true ) + "M" ; + { + /* FIXME:i need to find a better solution for this 'cylinder problem' + * till then we do it the 'dirty way' + * (this only matters while shrinking a filesystem, so maybe we should solve this + * in the resizedialog...) + */ + long bytes = Utils::Round( Utils::sector_to_unit( cylinder_size * MEBIBYTE, GParted::UNIT_BYTE ) ) ; + + str_temp += " -s " ; + str_temp += Utils::num_to_str( Utils::Round( Utils::sector_to_unit( partition_new .get_length(), GParted::UNIT_BYTE ) ) - bytes, true ) ; + } - if ( ! Execute_Command( str_temp ) ) + argv .clear() ; + argv .push_back( "sh" ) ; + argv .push_back( "-c" ) ; + argv .push_back( str_temp ) ; + if ( ! execute_command( argv, operation_details .back() .sub_details ) ) { operation_details .back() .status = OperationDetails::SUCCES ; return true ;