diff options
Diffstat (limited to '')
-rw-r--r-- | gui/action.cpp | 27 | ||||
-rw-r--r-- | gui/devices/landscape/res/landscape.xml | 19 | ||||
-rw-r--r-- | gui/devices/portrait/res/portrait.xml | 19 | ||||
-rw-r--r-- | gui/devices/watch/res/watch.xml | 19 | ||||
-rw-r--r-- | gui/objects.hpp | 1 | ||||
-rw-r--r-- | partition.cpp | 77 | ||||
-rw-r--r-- | partitionmanager.cpp | 28 | ||||
-rw-r--r-- | partitions.hpp | 5 | ||||
-rw-r--r-- | prebuilt/Android.mk | 1 |
9 files changed, 193 insertions, 3 deletions
diff --git a/gui/action.cpp b/gui/action.cpp index 7ecd0b46a..fc3973738 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -223,6 +223,7 @@ GUIAction::GUIAction(xml_node<>* node) ADD_ACTION(installsu); ADD_ACTION(decrypt_backup); ADD_ACTION(repair); + ADD_ACTION(resize); ADD_ACTION(changefilesystem); ADD_ACTION(flashimage); } @@ -872,6 +873,10 @@ int GUIAction::getpartitiondetails(std::string arg) DataManager::SetValue("tw_partition_can_repair", 1); else DataManager::SetValue("tw_partition_can_repair", 0); + if (Part->Can_Resize()) + DataManager::SetValue("tw_partition_can_resize", 1); + else + DataManager::SetValue("tw_partition_can_resize", 0); if (TWFunc::Path_Exists("/sbin/mkdosfs")) DataManager::SetValue("tw_partition_vfat", 1); else @@ -1651,6 +1656,28 @@ int GUIAction::repair(std::string arg) return 0; } +int GUIAction::resize(std::string arg) +{ + int op_status = 0; + + operation_start("Resize Partition"); + if (simulate) { + simulate_progress_bar(); + } else { + string part_path; + DataManager::GetValue("tw_partition_mount_point", part_path); + if (PartitionManager.Resize_By_Path(part_path, true)) { + op_status = 0; // success + } else { + LOGERR("Error resizing file system.\n"); + op_status = 1; // fail + } + } + + operation_end(op_status); + return 0; +} + int GUIAction::changefilesystem(std::string arg) { int op_status = 0; diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml index 12c66290b..529aef79c 100644 --- a/gui/devices/landscape/res/landscape.xml +++ b/gui/devices/landscape/res/landscape.xml @@ -1381,6 +1381,25 @@ </object> <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> <condition var1="tw_partition_can_repair" op="=" var2="1" /> <placement x="%col2_x%" y="%row2_y%" /> <text>Repair</text> diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml index 997da9d23..9ffd6e44e 100644 --- a/gui/devices/portrait/res/portrait.xml +++ b/gui/devices/portrait/res/portrait.xml @@ -1118,6 +1118,25 @@ </object> <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> <condition var1="tw_partition_can_repair" op="=" var2="1" /> <placement x="%col1_x%" y="%row4_y%" /> <text>Repair</text> diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml index f0f383dcb..a8535c659 100644 --- a/gui/devices/watch/res/watch.xml +++ b/gui/devices/watch/res/watch.xml @@ -1096,6 +1096,25 @@ </object> <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> <condition var1="tw_partition_can_repair" op="=" var2="1" /> <placement x="%col1_x%" y="%row4_y%" /> <text>Repair</text> diff --git a/gui/objects.hpp b/gui/objects.hpp index ee0f08b8f..1991877ee 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -354,6 +354,7 @@ protected: int fixsu(std::string arg); int decrypt_backup(std::string arg); int repair(std::string arg); + int resize(std::string arg); int changefilesystem(std::string arg); int startmtp(std::string arg); int stopmtp(std::string arg); diff --git a/partition.cpp b/partition.cpp index 2f9f41a69..9c5462d3e 100644 --- a/partition.cpp +++ b/partition.cpp @@ -534,7 +534,7 @@ bool TWPartition::Process_Flags(string Flags, bool Display_Error) { } } else if (ptr_len > 10 && strncmp(ptr, "blocksize=", 10) == 0) { ptr += 10; - Format_Block_Size = atoi(ptr); + Format_Block_Size = (unsigned long)(atol(ptr)); } else if (ptr_len > 7 && strncmp(ptr, "length=", 7) == 0) { ptr += 7; Length = atoi(ptr); @@ -1184,6 +1184,8 @@ bool TWPartition::Wipe_AndSec(void) { } bool TWPartition::Can_Repair() { + if (Mount_Read_Only) + return false; if (Current_File_System == "vfat" && TWFunc::Path_Exists("/sbin/dosfsck")) return true; else if ((Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") && TWFunc::Path_Exists("/sbin/e2fsck")) @@ -1226,7 +1228,7 @@ bool TWPartition::Repair() { return false; gui_print("Repairing %s using e2fsck...\n", Display_Name.c_str()); Find_Actual_Block_Device(); - command = "/sbin/e2fsck -p " + Actual_Block_Device; + command = "/sbin/e2fsck -fp " + Actual_Block_Device; LOGINFO("Repair command: %s\n", command.c_str()); if (TWFunc::Exec_Cmd(command) == 0) { gui_print("Done.\n"); @@ -1277,6 +1279,77 @@ bool TWPartition::Repair() { return false; } +bool TWPartition::Can_Resize() { + if (Mount_Read_Only) + return false; + if ((Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") && TWFunc::Path_Exists("/sbin/resize2fs")) + return true; + return false; +} + +bool TWPartition::Resize() { + string command; + + if (Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") { + if (!Can_Repair()) { + LOGERR("Cannot resize %s because %s cannot be repaired before resizing.\n", Display_Name.c_str(), Display_Name.c_str()); + return false; + } + if (!TWFunc::Path_Exists("/sbin/resize2fs")) { + gui_print("resize2fs does not exist! Cannot resize!\n"); + return false; + } + // Repair will unmount so no need to do it twice + gui_print("Repairing %s before resizing.\n", Display_Name.c_str()); + if (!Repair()) + return false; + gui_print("Resizing %s using resize2fs...\n", Display_Name.c_str()); + Find_Actual_Block_Device(); + command = "/sbin/resize2fs " + Actual_Block_Device; + if (Length != 0) { + unsigned int block_device_size; + int fd, ret; + + fd = open(Actual_Block_Device.c_str(), O_RDONLY); + if (fd < 0) { + LOGERR("Resize: Failed to open '%s'\n", Actual_Block_Device.c_str()); + return false; + } + ret = ioctl(fd, BLKGETSIZE, &block_device_size); + close(fd); + if (ret) { + LOGERR("Resize: ioctl error\n"); + return false; + } + unsigned long long Actual_Size = (unsigned long long)(block_device_size) * 512LLU; + unsigned long long Block_Count; + if (Length < 0) { + // Reduce overall size by this length + Block_Count = (Actual_Size / 1024LLU) - ((unsigned long long)(Length * -1) / 1024LLU); + } else { + // This is the size, not a size reduction + Block_Count = ((unsigned long long)(Length) / 1024LLU); + } + char temp[256]; + sprintf(temp, "%llu", Block_Count); + command += " "; + command += temp; + command += "K"; + } + LOGINFO("Resize command: %s\n", command.c_str()); + if (TWFunc::Exec_Cmd(command) == 0) { + Update_Size(true); + gui_print("Done.\n"); + return true; + } else { + Update_Size(true); + LOGERR("Unable to resize '%s'.\n", Mount_Point.c_str()); + return false; + } + } + return false; +} + bool TWPartition::Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid) { if (Backup_Method == FILES) { return Backup_Tar(backup_folder, overall_size, other_backups_size, tar_fork_pid); diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 055f73697..572cd7c93 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -1259,6 +1259,34 @@ int TWPartitionManager::Repair_By_Path(string Path, bool Display_Error) { return false; } +int TWPartitionManager::Resize_By_Path(string Path, bool Display_Error) { + std::vector<TWPartition*>::iterator iter; + int ret = false; + bool found = false; + string Local_Path = TWFunc::Get_Root_Path(Path); + + if (Local_Path == "/tmp" || Local_Path == "/") + return true; + + // Iterate through all partitions + for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { + if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) { + ret = (*iter)->Resize(); + found = true; + } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) { + (*iter)->Resize(); + } + } + if (found) { + return ret; + } else if (Display_Error) { + LOGERR("Resize: Unable to find partition for path '%s'\n", Local_Path.c_str()); + } else { + LOGINFO("Resize: Unable to find partition for path '%s'\n", Local_Path.c_str()); + } + return false; +} + void TWPartitionManager::Update_System_Details(void) { std::vector<TWPartition*>::iterator iter; int data_size = 0; diff --git a/partitions.hpp b/partitions.hpp index 1489a8ec2..63c01af8d 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -59,6 +59,8 @@ public: bool Can_Repair(); // Checks to see if we have everything needed to be able to repair the current file system uint64_t Get_Max_FileSize(); //get partition maxFileSie bool Repair(); // Repairs the current file system + bool Can_Resize(); // Checks to see if we have everything needed to be able to resize the current file system + bool Resize(); // Resizes the current file system bool Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid); // Backs up the partition to the folder specified bool Check_MD5(string restore_folder); // Checks MD5 of a backup bool Restore(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // Restores the partition using the backup folder provided @@ -165,7 +167,7 @@ private: string Fstab_File_System; // File system from the recovery.fstab int Mount_Flags; // File system flags from recovery.fstab string Mount_Options; // File system options from recovery.fstab - int Format_Block_Size; // Block size for formatting + unsigned long Format_Block_Size; // Block size for formatting bool Ignore_Blkid; // Ignore blkid results due to superblocks lying to us on certain devices / partitions bool Retain_Layout_Version; // Retains the .layout_version file during a wipe (needed on devices like Sony Xperia T where /data and /data/media are separate partitions) bool Can_Flash_Img; // Indicates if this partition can have images flashed to it via the GUI @@ -207,6 +209,7 @@ public: int Format_Data(); // Really formats data on /data/media devices -- also removes encryption int Wipe_Media_From_Data(); // Removes and recreates the media folder on /data/media devices int Repair_By_Path(string Path, bool Display_Error); // Repairs a partition based on path + int Resize_By_Path(string Path, bool Display_Error); // Resizes a partition based on path void Update_System_Details(); // Updates fstab, file systems, sizes, etc. int Decrypt_Device(string Password); // Attempt to decrypt any encrypted partitions int usb_storage_enable(void); // Enable USB storage mode diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk index 1449dc8af..3ecf02fbf 100644 --- a/prebuilt/Android.mk +++ b/prebuilt/Android.mk @@ -26,6 +26,7 @@ RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/mkdosfs RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/e2fsck RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/mke2fs RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/tune2fs +RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/resize2fs ifneq ($(TARGET_ARCH), x86_64) RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/linker endif |