summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gui/action.cpp27
-rw-r--r--gui/devices/landscape/res/landscape.xml19
-rw-r--r--gui/devices/portrait/res/portrait.xml19
-rw-r--r--gui/devices/watch/res/watch.xml19
-rw-r--r--gui/objects.hpp1
-rw-r--r--partition.cpp77
-rw-r--r--partitionmanager.cpp28
-rw-r--r--partitions.hpp5
-rw-r--r--prebuilt/Android.mk1
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