diff --git a/ChangeLog b/ChangeLog index faaac023..b91b5727 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-07-23 Bart Hakvoort + + * src/Win_GParted.cc: added FIXME: + * include/GParted_Core.h, + src/GParted_Core.cc, + src/fat32.cc: decoupled libparted partition and filesystemresizing. + This resulted in a much more consistent core. This also affected + several other aspects of resizing/moving in a positive way. + 2006-07-20 Bart Hakvoort * src/GParted_Core.cc: FIXME business diff --git a/include/GParted_Core.h b/include/GParted_Core.h index bc727863..f75baae0 100644 --- a/include/GParted_Core.h +++ b/include/GParted_Core.h @@ -93,17 +93,22 @@ private: Partition & partition_new, std::vector & operation_details ) ; bool move_filesystem( const Partition & partition_old, - Partition & partition_new, + const Partition & partition_new, std::vector & operation_details ) ; + bool move_filesystem_using_gparted( const Partition & partition_old, + const Partition & partition_new, + std::vector & operation_details ) ; + bool resize_move_filesystem_using_libparted( const Partition & partition_old, + const Partition & partition_new, + std::vector & operation_details ) ; bool resize( const Device & device, const Partition & partition_old, Partition & partition_new, - std::vector & operation_detail ) ; + std::vector & operation_detail, + bool strict = false ) ; bool resize_move_partition( const Partition & partition_old, - Partition & partition_new, - bool fixed_start, - std::vector & operation_details, - Sector min_size = 0 ) ; + const Partition & partition_new, + std::vector & operation_details ) ; bool resize_filesystem( const Partition & partition_old, const Partition & partition_new, std::vector & operation_details, @@ -111,9 +116,6 @@ private: bool fill_partition = false ) ; bool maximize_filesystem( const Partition & partition, std::vector & operation_details ) ; - bool LP_resize_move_partition_and_filesystem( const Partition & partition_old, - Partition & partition_new, - std::vector & operation_details ) ; bool copy( const Partition & partition_src, Partition & partition_dest, @@ -136,6 +138,10 @@ private: Sector offset_dst, Sector blocksize, Glib::ustring & error_message ) ; + bool calculate_exact_geom( const Partition & partition_old, + Partition & partition_new, + std::vector & operation_details, + bool fixed_start = false ) ; void set_proper_filesystem( const FILESYSTEM & filesystem, Sector cylinder_size = 0 ) ; bool wait_for_node( const Glib::ustring & node ) ; bool erase_filesystem_signatures( const Partition & partition ) ; diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 666a0020..fe3bfe91 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -1072,8 +1072,12 @@ bool GParted_Core::resize_move( const Device & device, Partition & partition_new, std::vector & operation_details ) { - if ( partition_new .sector_start != partition_old .sector_start && - get_fs( partition_old .filesystem ) .move == GParted::FS::GPARTED ) + //extended is a special case.. + if ( partition_old .type == GParted::TYPE_EXTENDED ) + return resize_move_partition( partition_old, partition_new, operation_details ) ; + + //see if we need move or resize.. + if ( partition_new .sector_start != partition_old .sector_start ) return move( device, partition_old, partition_new, operation_details ) ; else return resize( device, partition_old, partition_new, operation_details ) ; @@ -1084,63 +1088,64 @@ bool GParted_Core::move( const Device & device, Partition & partition_new, std::vector & operation_details ) { - if ( partition_new .get_length() > partition_old .get_length() ) + if ( calculate_exact_geom( partition_old, partition_new, operation_details ) ) { - //first do the move - Partition temp = partition_new ; - temp .sector_end = partition_new .sector_start + partition_old .get_length() ; - if ( check_repair( partition_old, operation_details ) && - move_filesystem( partition_old, temp, operation_details ) && - resize_move_partition( partition_old, - temp, - false, - operation_details, - temp .get_length() ) ) + if ( partition_new .get_length() > partition_old .get_length() ) { - //now the partition and the filesystem are moved, we can grow it.. - partition_new .sector_start = temp .sector_start ; - return resize( device, temp, partition_new, operation_details ) ; + //first do the move + Partition temp = partition_new ; + temp .sector_end = partition_new .sector_start + partition_old .get_length() ; + if ( check_repair( partition_old, operation_details ) && + calculate_exact_geom( partition_old, temp, operation_details ) && + move_filesystem( partition_old, temp, operation_details ) && + resize_move_partition( partition_old, + temp, + operation_details ) ) + { + //now the partition and the filesystem are moved, we can grow it.. + partition_new .sector_start = temp .sector_start ; + return resize( device, temp, partition_new, operation_details ) ; + } + + return false ; } - - return false ; - } - else if ( partition_new .get_length() < partition_old .get_length() ) - { - //first shrink the partition - Partition temp = partition_old ; - temp .sector_end = partition_old .sector_start + partition_new .get_length() -1 ; - if ( resize( device, partition_old, temp, operation_details ) ) + else if ( partition_new .get_length() < partition_old .get_length() ) { - //now we can move it - partition_new .sector_end = partition_new .sector_start + temp .get_length() -1 ; - return move_filesystem( temp, partition_new, operation_details ) && - resize_move_partition( temp, + //first shrink the partition + Partition temp = partition_old ; + temp .sector_end = partition_old .sector_start + partition_new .get_length() -1 ; + if ( resize( device, partition_old, temp, operation_details, true ) ) + { + //now we can move it + partition_new .sector_end = partition_new .sector_start + temp .get_length() -1 ; + return calculate_exact_geom( temp, partition_new, operation_details ) && + move_filesystem( temp, partition_new, operation_details ) && + resize_move_partition( temp, + partition_new, + operation_details ) && + check_repair( partition_new, operation_details ) && + maximize_filesystem( partition_new, operation_details ) && + check_repair( partition_new, operation_details ) ; + } + + return false ; + } + else + return check_repair( partition_old, operation_details ) && + move_filesystem( partition_old, partition_new, operation_details ) && + resize_move_partition( partition_old, partition_new, - false, - operation_details, - partition_new .get_length() ) && + operation_details ) && check_repair( partition_new, operation_details ) && maximize_filesystem( partition_new, operation_details ) && check_repair( partition_new, operation_details ) ; - } - - return false ; } - else - return check_repair( partition_old, operation_details ) && - move_filesystem( partition_old, partition_new, operation_details ) && - resize_move_partition( partition_old, - partition_new, - false, - operation_details, - partition_new .get_length() ) && - check_repair( partition_new, operation_details ) && - maximize_filesystem( partition_new, operation_details ) && - check_repair( partition_new, operation_details ) ; + + return false ; } bool GParted_Core::move_filesystem( const Partition & partition_old, - Partition & partition_new, + const Partition & partition_new, std::vector & operation_details ) { if ( partition_new .sector_start < partition_old .sector_start ) @@ -1162,50 +1167,50 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, } bool succes = false ; + switch ( get_fs( partition_old .filesystem ) .move ) + { + case GParted::FS::NONE: + break ; + case GParted::FS::GPARTED: + succes = move_filesystem_using_gparted( partition_old, + partition_new, + operation_details .back() .sub_details ) ; + break ; + case GParted::FS::LIBPARTED: + succes = resize_move_filesystem_using_libparted( partition_old, + partition_new, + operation_details .back() .sub_details ) ; + break ; + case GParted::FS::EXTERNAL: + break ; + } + + operation_details .back() .status = succes ? OperationDetails::SUCCES : OperationDetails::ERROR ; + return succes ; +} + + +bool GParted_Core::move_filesystem_using_gparted( const Partition & partition_old, + const Partition & partition_new, + std::vector & operation_details ) +{ + operation_details .push_back( + OperationDetails( _("using internal algorithm"), OperationDetails::NONE ) ) ; + + bool succes = true ; //FIXME: default to true is too dangerous, just image opening the device fails and this function + //return true. then the partition will be moved and the result would be a disaster. if ( open_device_and_disk( partition_old .device_path ) ) { - //calculate correct geom voor new location (rounded to cylinder) - //we could use the geom set bij snap_to_cylinder, but this one is 100% reliable, while snap_to_cylinder - //exists merely for informative purposes - lp_partition = NULL ; - lp_partition = ped_disk_get_partition_by_sector( - lp_disk, - (partition_old .sector_end + partition_old .sector_start) / 2 ) ; - - if ( lp_partition ) - { - PedConstraint *constraint = NULL ; - constraint = ped_constraint_any( lp_device ) ; - - if ( constraint ) - { - if ( ped_disk_set_partition_geom( lp_disk, - lp_partition, - constraint, - partition_new .sector_start, - partition_new .sector_end ) ) - { - partition_new .sector_start = lp_partition ->geom .start ; - partition_new .sector_end = lp_partition ->geom .end ; - succes = true ; - } - - ped_constraint_destroy( constraint ); - } - } - //we don't need disk anymore.. - close_disk() ; - //do the move.. Sector blocksize = 32 ;//FIXME: write an algorithm to determine the optimal blocksize Glib::ustring error_message ; - if ( succes && ped_device_open( lp_device ) ) + if ( ped_device_open( lp_device ) ) { ped_device_sync( lp_device ) ; //add an empty sub which we will constantly update in the loop - operation_details .back() .sub_details .push_back( + operation_details .push_back( OperationDetails( "", OperationDetails::NONE ) ) ; if ( partition_new .sector_start < partition_old .sector_start ) //move to the left @@ -1226,17 +1231,15 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, if ( t % (blocksize * 100) == 0 ) { - operation_details .back() .sub_details .back() .progress_text = + operation_details .back() .progress_text = String::ucompose( _("%1 of %2 moved"), Utils::format_size( t +1 ), Utils::format_size( partition_old .get_length() ) ) ; - operation_details .back() .sub_details .back() .description = - "" + - operation_details .back() .sub_details .back() .progress_text + - "" ; + operation_details .back() .description = + "" + operation_details .back() .progress_text + "" ; - operation_details .back() .sub_details .back() .fraction = + operation_details .back() .fraction = t / static_cast( partition_old .get_length() ) ; } } @@ -1274,17 +1277,15 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, if ( t % (blocksize * 100) == 0 ) { - operation_details .back() .sub_details .back() .progress_text = + operation_details .back() .progress_text = String::ucompose( _("%1 of %2 moved"), Utils::format_size( t +1 ), Utils::format_size( partition_old .get_length() ) ) ; - operation_details .back() .sub_details .back() .description = - "" + - operation_details .back() .sub_details .back() .progress_text + - "" ; + operation_details .back() .description = + "" + operation_details .back() .progress_text + "" ; - operation_details .back() .sub_details .back() .fraction = + operation_details .back() .fraction = t / static_cast( partition_old .get_length() ) ; } } @@ -1303,7 +1304,9 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, } //final description - operation_details .back() .sub_details .back() .description = + //FIXME: this description doesn't have to be correct, in case of an error we should display how + //much data really has been moved... + operation_details .back() .description = "" + String::ucompose( _("%1 of %2 moved"), Utils::format_size( partition_old .get_length() ), @@ -1311,16 +1314,16 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, "" ; //reset fraction to -1 to make room for a new one (or a pulsebar) - operation_details .back() .sub_details .back() .fraction = -1 ; + operation_details .back() .fraction = -1 ; if ( ! succes ) { if ( ! error_message .empty() ) - operation_details .back() .sub_details .push_back( + operation_details .push_back( OperationDetails( error_message, OperationDetails::NONE ) ) ; if ( ! ped_error .empty() ) - operation_details .back() .sub_details .push_back( + operation_details .push_back( OperationDetails( "" + ped_error + "", OperationDetails::NONE ) ) ; } } @@ -1328,55 +1331,73 @@ bool GParted_Core::move_filesystem( const Partition & partition_old, close_device_and_disk() ; } - operation_details .back() .status = succes ? OperationDetails::SUCCES : OperationDetails::ERROR ; return succes ; } +bool GParted_Core::resize_move_filesystem_using_libparted( const Partition & partition_old, + const Partition & partition_new, + std::vector & operation_details ) +{ + operation_details .push_back( OperationDetails( _("using libparted"), OperationDetails::NONE ) ) ; + + bool return_value = false ; + if ( open_device_and_disk( partition_old .device_path ) ) + { + PedPartition * lp_partition = NULL ; + PedFileSystem * fs = NULL ; + PedGeometry * lp_geom = NULL ; + + lp_partition = ped_disk_get_partition_by_sector( + lp_disk, + (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( lp_partition ) + { + fs = ped_file_system_open( & lp_partition ->geom ); + if ( fs ) + { + lp_geom = ped_geometry_new( lp_device, + partition_new .sector_start, + partition_new .get_length() ) ; + if ( lp_geom ) + return_value = ped_file_system_resize( fs, lp_geom, NULL ) && commit() ; + + ped_file_system_close( fs ); + } + } + + close_device_and_disk() ; + } + + if ( ! return_value && ! ped_error .empty() ) + operation_details .push_back( OperationDetails( "" + ped_error + "", OperationDetails::NONE ) ) ; + + return return_value ; +} + bool GParted_Core::resize( const Device & device, const Partition & partition_old, Partition & partition_new, - std::vector & operation_details ) + std::vector & operation_details, + bool strict ) { - //extended partition - if ( partition_old .type == GParted::TYPE_EXTENDED ) - return resize_move_partition( partition_old, partition_new, false, operation_details ) ; - bool succes = false ; -//FIXME, i don't think this is valid anymore now we have filesystems (hfs and hfs+ e.g.) which do a move through GPARTED -//and a shrink through LIBPARTED... -//how about (fake)decoupling partition and resize through libparted by simply doing it twice? -//it would hardly do anything to performance and it would greatly improve consitency in the core. - //resize using libparted.. - if ( get_fs( partition_old .filesystem ) .grow == GParted::FS::LIBPARTED || - get_fs( partition_old .filesystem ) .shrink == GParted::FS::LIBPARTED || - get_fs( partition_old .filesystem ) .move == GParted::FS::LIBPARTED ) - { - if ( check_repair( partition_new, operation_details ) ) - { - succes = LP_resize_move_partition_and_filesystem( partition_old, partition_new, operation_details ) ; - - //always check after a resize, but if it failes the whole operation failes - if ( ! check_repair( partition_new, operation_details ) ) - succes = false ; - } - - return succes ; - } - - //use custom resize tools.. if ( check_repair( partition_new, operation_details ) ) { succes = true ; + + if ( ! strict ) + succes = calculate_exact_geom( partition_old, partition_new, operation_details, true ) ; + //FIXME, find another way to resolve this cylsize problem... - if ( partition_new .get_length() < partition_old .get_length() ) + //i think we don't need cylsize here anymore.. now partition_new is _exact_ we don't have to buffer + //for security. + if ( succes && partition_new .get_length() < partition_old .get_length() ) succes = resize_filesystem( partition_old, partition_new, operation_details, device .cylsize ) ; if ( succes ) succes = resize_move_partition( partition_old, partition_new, - get_fs( partition_new .filesystem ) .move,//FIXME, still not sure about this one - //see other FIXME's in this function. operation_details ) ; //these 3 are always executed, however, if 1 of them fails the whole operation fails @@ -1397,10 +1418,8 @@ bool GParted_Core::resize( const Device & device, } bool GParted_Core::resize_move_partition( const Partition & partition_old, - Partition & partition_new, - bool fixed_start, - std::vector & operation_details, - Sector min_size ) + const Partition & partition_new, + std::vector & operation_details ) { //i'm not too happy with this, but i think it is the correct way from a i18n POV enum Action @@ -1504,25 +1523,10 @@ bool GParted_Core::resize_move_partition( const Partition & partition_old, if ( lp_partition ) { - constraint = ped_constraint_any( lp_device ); - - if ( fixed_start && constraint ) - { - //create a constraint which keeps de startpoint intact and rounds the end to a cylinder - ped_disk_set_partition_geom( lp_disk, - lp_partition, - constraint, - partition_new .sector_start, - partition_new .sector_end ) ; - ped_constraint_destroy( constraint ); - constraint = NULL ; - - ped_geometry_set_start( & lp_partition ->geom, partition_new .sector_start ) ; - constraint = ped_constraint_exact( & lp_partition ->geom ) ; - } - else if ( min_size > 0 ) - constraint ->min_size = min_size ;//at this moment min_size and fixed start are mut. excl. - //this might change in the (near) future. + PedGeometry *geom = ped_geometry_new( lp_device, + partition_new .sector_start, + partition_new .get_length() ) ; + constraint = ped_constraint_exact( geom ) ; if ( constraint ) { @@ -1542,15 +1546,12 @@ bool GParted_Core::resize_move_partition( const Partition & partition_old, if ( return_value ) { - partition_new .sector_start = lp_partition ->geom .start ; - partition_new .sector_end = lp_partition ->geom .end ; - operation_details .back() .sub_details .push_back( OperationDetails( "" + - String::ucompose( _("new start: %1"), partition_new .sector_start ) + "\n" + - String::ucompose( _("new end: %1"), partition_new .sector_end ) + "\n" + - String::ucompose( _("new size: %1"), Utils::format_size( partition_new .get_length() ) ) + + String::ucompose( _("new start: %1"), lp_partition ->geom .start ) + "\n" + + String::ucompose( _("new end: %1"), lp_partition ->geom .end ) + "\n" + + String::ucompose( _("new size: %1"), Utils::format_size( lp_partition ->geom .length ) ) + "", OperationDetails::NONE ) ) ; } @@ -1578,10 +1579,16 @@ bool GParted_Core::resize_filesystem( const Partition & partition_old, Sector cylinder_size, bool fill_partition ) { + //by default 'grow' to accomodate expand_filesystem() + GParted::FS::Support action = get_fs( partition_old .filesystem ) .grow ; + if ( ! fill_partition ) { if ( partition_new .get_length() < partition_old .get_length() ) + { operation_details .push_back( OperationDetails( _("shrink filesystem") ) ) ; + action = get_fs( partition_old .filesystem ) .shrink ; + } else if ( partition_new .get_length() > partition_old .get_length() ) operation_details .push_back( OperationDetails( _("grow filesystem") ) ) ; else @@ -1596,17 +1603,29 @@ bool GParted_Core::resize_filesystem( const Partition & partition_old, } } - set_proper_filesystem( partition_new .filesystem, cylinder_size ) ; - if ( p_filesystem && p_filesystem ->Resize( partition_new, operation_details .back() .sub_details, fill_partition ) ) + bool succes = false ; + switch ( action ) { - operation_details .back() .status = OperationDetails::SUCCES ; - return true ; - } - else - { - operation_details .back() .status = OperationDetails::ERROR ; - return false ; + case GParted::FS::NONE: + break ; + case GParted::FS::GPARTED: + break ; + case GParted::FS::LIBPARTED: + succes = resize_move_filesystem_using_libparted( partition_old, + partition_new, + operation_details .back() .sub_details ) ; + break ; + case GParted::FS::EXTERNAL: + set_proper_filesystem( partition_new .filesystem, cylinder_size ) ; + succes = ( p_filesystem && + p_filesystem ->Resize( partition_new, + operation_details .back() .sub_details, + fill_partition ) ) ; + break ; } + + operation_details .back() .status = succes ? OperationDetails::SUCCES : OperationDetails::ERROR ; + return succes ; } bool GParted_Core::maximize_filesystem( const Partition & partition, @@ -1630,169 +1649,6 @@ bool GParted_Core::maximize_filesystem( const Partition & partition, return resize_filesystem( partition, partition, operation_details, 0, true ) ; } -bool GParted_Core::LP_resize_move_partition_and_filesystem( const Partition & partition_old, - Partition & partition_new, - std::vector & operation_details ) -{ -//FIXME: i really should focus on decoupling partition and fs resize when using libparted. -//that would make things a LOT more clear and consistent. - //i'm not too happy with this, but i think it is the correct way from a i18n POV - enum Action - { - NONE = 0, - MOVE_RIGHT = 1, - MOVE_LEFT = 2, - GROW = 3, - SHRINK = 4, - MOVE_RIGHT_GROW = 5, - MOVE_RIGHT_SHRINK = 6, - MOVE_LEFT_GROW = 7, - MOVE_LEFT_SHRINK = 8 - } ; - Action action = NONE ; - - if ( partition_new .get_length() > partition_old .get_length() ) - action = GROW ; - else if ( partition_new .get_length() < partition_old .get_length() ) - action = SHRINK ; - - if ( partition_new .sector_start > partition_old .sector_start && - partition_new .sector_end > partition_old .sector_end ) - action = action == GROW ? MOVE_RIGHT_GROW : action == SHRINK ? MOVE_RIGHT_SHRINK : MOVE_RIGHT ; - else if ( partition_new .sector_start < partition_old .sector_start && - partition_new .sector_end < partition_old .sector_end ) - action = action == GROW ? MOVE_LEFT_GROW : action == SHRINK ? MOVE_LEFT_SHRINK : MOVE_LEFT ; - - Glib::ustring description ; - switch ( action ) - { - case NONE : - description = _("resize/move partition and filesytem using libparted") ; - break ; - case MOVE_RIGHT : - description = _("move partition and filesytem to the right using libparted") ; - break ; - case MOVE_LEFT : - description = _("move partition and filesytem to the left using libparted") ; - break ; - case GROW : - description = _("grow partition and filesytem from %1 to %2 using libparted") ; - break ; - case SHRINK : - description = _("shrink partition and filesytem from %1 to %2 using libparted") ; - break ; - case MOVE_RIGHT_GROW : - description = _("move partition and filesytem to the right and grow it from %1 to %2 using libparted") ; - break ; - case MOVE_RIGHT_SHRINK : - description = _("move partition and filesytem to the right and shrink it from %1 to %2 using libparted") ; - break ; - case MOVE_LEFT_GROW : - description = _("move partition and filesytem to the left and grow it from %1 to %2 using libparted") ; - break ; - case MOVE_LEFT_SHRINK : - description = _("move partition and filesytem to the left and shrink it from %1 to %2 using libparted") ; - break ; - } - - if ( ! description .empty() && action != NONE && action != MOVE_LEFT && action != MOVE_RIGHT ) - description = String::ucompose( description, - Utils::format_size( partition_old .get_length() ), - Utils::format_size( partition_new .get_length() ) ) ; - - operation_details .push_back( OperationDetails( description ) ) ; - - - if ( action == NONE ) - operation_details .back() .sub_details .push_back( - OperationDetails( - Glib::ustring( "" ) + - _("new and old partition have the same size and positition. continuing anyway") + - Glib::ustring( "" ), - OperationDetails::NONE ) ) ; - - operation_details .back() .sub_details .push_back( - OperationDetails( - "" + - String::ucompose( _("old start: %1"), partition_old .sector_start ) + "\n" + - String::ucompose( _("old end: %1"), partition_old .sector_end ) + "\n" + - String::ucompose( _("old size: %1"), Utils::format_size( partition_old .get_length() ) ) + - "", - OperationDetails::NONE ) ) ; - - //finally the actual resize/move - bool return_value = false ; - - PedFileSystem *fs = NULL ; - PedConstraint *constraint = NULL ; - lp_partition = NULL ; - ped_error .clear() ; - - if ( open_device_and_disk( partition_old .device_path ) ) - { - lp_partition = ped_disk_get_partition_by_sector( - lp_disk, - (partition_old .sector_end + partition_old .sector_start) / 2 ) ; - if ( lp_partition ) - { - fs = ped_file_system_open( & lp_partition ->geom ); - if ( fs ) - { - constraint = ped_file_system_get_resize_constraint( fs ); - if ( constraint ) - { - if ( ped_disk_set_partition_geom( lp_disk, - lp_partition, - constraint, - partition_new .sector_start, - partition_new .sector_end ) - && - ped_file_system_resize( fs, & lp_partition ->geom, NULL ) - ) - { - return_value = commit() ; - - if ( return_value ) - { - partition_new .sector_start = lp_partition ->geom .start ; - partition_new .sector_end = lp_partition ->geom .end ; - - operation_details .back() .sub_details .push_back( - OperationDetails( - "" + - String::ucompose( _("new start: %1"), - partition_new .sector_start ) + - "\n" + - String::ucompose( _("new end: %1"), - partition_new .sector_end ) + - "\n" + - String::ucompose( - _("new size: %1"), - Utils::format_size( partition_new .get_length() ) ) + - "", - OperationDetails::NONE ) ) ; - } - } - - ped_constraint_destroy( constraint ); - } - - ped_file_system_close( fs ); - } - } - - close_device_and_disk() ; - } - - operation_details .back() .status = return_value ? OperationDetails::SUCCES : OperationDetails::ERROR ; - - if ( ! return_value && ! ped_error .empty() ) - operation_details .back() .sub_details .push_back( - OperationDetails( "" + ped_error + "", OperationDetails::NONE ) ) ; - - return return_value ; -} - bool GParted_Core::copy( const Partition & partition_src, Partition & partition_dest, Sector min_size, @@ -2060,6 +1916,106 @@ bool GParted_Core::copy_block( PedDevice * lp_device_src, return true ; } +//FIXME: after all it might be a good idea to pass a min_size here.. +//when moving we don't want the calculated geom to be smaller then the actual fs.. +bool GParted_Core::calculate_exact_geom( const Partition & partition_old, + Partition & partition_new, + std::vector & operation_details, + bool fixed_start ) +{ + operation_details .push_back( OperationDetails( + String::ucompose( _("calculate new size and position of %1"), partition_new .get_path() ) ) ) ; + + if ( fixed_start ) + operation_details .back() .sub_details .push_back( + OperationDetails( _("fixed start"), OperationDetails::NONE ) ) ; + + operation_details .back() .sub_details .push_back( + OperationDetails( + "" + + String::ucompose( _("requested start: %1"), partition_new .sector_start ) + "\n" + + String::ucompose( _("requested end: %1"), partition_new .sector_end ) + "\n" + + String::ucompose( _("requested size: %1"), Utils::format_size( partition_new .get_length() ) ) + + "", + OperationDetails::NONE ) ) ; + + ped_error .clear() ; + bool succes = false ; + if ( open_device_and_disk( partition_old .device_path ) ) + { + lp_partition = NULL ; + + if ( partition_old .type == GParted::TYPE_EXTENDED ) + lp_partition = ped_disk_extended_partition( lp_disk ) ; + else + lp_partition = ped_disk_get_partition_by_sector( + lp_disk, + (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + + if ( lp_partition ) + { + PedConstraint *constraint = NULL ; + constraint = ped_constraint_any( lp_device ) ; + + if ( constraint && fixed_start ) + { + //create a constraint which keeps de startpoint intact and rounds the end to a cylinder + ped_disk_set_partition_geom( lp_disk, + lp_partition, + constraint, + partition_new .sector_start, + partition_new .sector_end ) ; + ped_constraint_destroy( constraint ); + constraint = NULL ; + + ped_geometry_set_start( & lp_partition ->geom, partition_new .sector_start ) ; + constraint = ped_constraint_exact( & lp_partition ->geom ) ; + } + + if ( constraint ) + { + constraint ->min_size = partition_new .sectors_used ; + + //FIXME: if we insert a weird partitionnew geom here (e.g. start > end) + //ped_disk_set_partition_geom() will still return true (althoug an lp exception is written + //to stdout.. see if this also affect create_partition and resize_move_partition + if ( ped_disk_set_partition_geom( lp_disk, + lp_partition, + constraint, + partition_new .sector_start, + partition_new .sector_end ) ) + { + partition_new .sector_start = lp_partition ->geom .start ; + partition_new .sector_end = lp_partition ->geom .end ; + succes = true ; + } + + ped_constraint_destroy( constraint ); + } + } + + close_device_and_disk() ; + } + + if ( succes ) + { + operation_details .back() .sub_details .push_back( + OperationDetails( + "" + + String::ucompose( _("new start: %1"), partition_new .sector_start ) + "\n" + + String::ucompose( _("new end: %1"), partition_new .sector_end ) + "\n" + + String::ucompose( _("new size: %1"), Utils::format_size( partition_new .get_length() ) ) + + "", + OperationDetails::NONE ) ) ; + } + else if ( ! ped_error .empty() ) + operation_details .back() .sub_details .push_back( + OperationDetails( "" + ped_error + "", OperationDetails::NONE ) ) ; + + operation_details .back() .status = succes ? OperationDetails::SUCCES : OperationDetails::ERROR ; + return succes ; +} + void GParted_Core::set_proper_filesystem( const FILESYSTEM & filesystem, Sector cylinder_size ) { if ( p_filesystem ) diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 02d02526..9302539d 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -108,6 +108,8 @@ Win_GParted::Win_GParted( const std::vector & user_devices ) void Win_GParted::init_menubar() { + //FIXME: store menuindex in variables, so we don't have to use these numbers everywhere + //see my local version of the installerpatch for details. //fill menubar_main and connect callbacks //gparted menu = manage( new Gtk::Menu() ) ; diff --git a/src/fat32.cc b/src/fat32.cc index 85f330ea..d73fa072 100644 --- a/src/fat32.cc +++ b/src/fat32.cc @@ -41,8 +41,6 @@ FS fat32::get_filesystem_support() fs .shrink = GParted::FS::LIBPARTED ; fs .move = GParted::FS::LIBPARTED ; -//FIXME: find a way to decouple FS and partitionresizing when using libparted.. -//this is especially important while copying fat* FS's fs .copy = GParted::FS::GPARTED ; fs .MIN = 32 * MEBIBYTE ; //smaller fs'es will cause windows scandisk to fail..