TL;DR? Scroll to the “Summary” below.
I noticed recently that my old trusty ASUS Zenfone 2 was running out of free space. Only a few gigs free out of 64GB internal storage. The thing is – I could not understand where the storage went. The total file size between apps, media and documents, as reported by all file managers, as well as manually tallying the sizes when connected to the PC – amounted to barely half of the 54GB data partition (the remaining ~10GB are various system/cache partitions and are normally invisible to Android apps).
Following a recommendation, I downloaded the DiskUsage app, which painted the following gloomy picture:
27 GB in System data?! I am used to this part (which includes not just core system stuff, but anything not visible to the users such as individual app data and cache) to be several gigs, but this has got to be some bug. In fact, Android marks any storage that is not accounted in a specific category as “system data”, which meant this could be anything. Just to be safe, I went through all the 100-some installed apps in Settings and checked their used storage, and found nothing to explain this.
With no satisfactory answers online, I turned to USB debugging, opened adb shell, then used the trusty Linux df and du commands to analyze the storage. A similar picture emerged: /data showed ~4GB free out of 54GB, while the total size of /sdcard (the user-visible storage partition) totaled only ~16GB. Doing a deeper analysis on /data proved impossible, since most of the contents there is invisible without root access. I was able to determine that the issue was not the infamous logs/modemcrash bug.
At this point I realized that I will not get further without “rooting” the phone, which I proceeded to do, cautiously, following this guide, involving TWRP and Magisk. I am pleased to say that it worked without a hitch. The only issue I hit was that the “Root” script failed to push and install Magisk. This turned out to be due to an incorrect Android USB driver installed on my PC, which could not detect the phone in recovery mode. I booted the phone to system, copied magisk.zip manually, rebooted to recovery, and used TWRP’s built-in ‘Install’ feature. After that it was a matter of installing the Magisk Manager from the APK, and Root Checker announced that root access was properly configured.
Back to the original issue – now I could run su in adb shell to get root access, and finally examine /data in full. To my dismay – I still found nothing. Well, there was about 1.2GB of precompiled .DEX files under /data/dalvik-cache, which was reduced to <400MB after wiping and letting Android re-optimize all the apps at next boot, but du on /data still showed only ~23GB, while df claimed that 50GB was in use!
With no visible culprits, I suspected corruption of the file system itself. Finally, this turned out to be the root-cause, and the steps outlined here paved the road to victory.
I ran adb shell su in recovery mode (for this I had to install the correct driver, as mentioned above), unmounted /data and /sdcard (both of which point to the data partition, just different folders), then used e2fsck. To use it, you need to first find the actual physical partition behind those mount points. df shows this information from the recovery shell, but not from the system shell. In my case, it turned out to be /dev/block/mmcblk0p19.
Note: Never attempt to do any manipulations with fsck/e2fsck outside of recovery mode (when the system is running). File system checks should only run on an unmounted file system (or else wrong results / corruption can ensue), and you cannot unmount /data while it’s being used by a live Android system.
Anyhow, running e2fsck with the -n switch (read-only mode) immediately showed TONS of file system errors: orphaned Inodes, wrong file/directory/free space counts, and what not. Running e2fsck -p (automatic repair) failed with the reply “UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY“. Well, using e2fsck -y is basically a manual run which assumes you answer ‘yes’ to every question, which is what I did. It fixed all the errors, and the next e2fsck -n run showed a clean file system. Finally! But did we reclaim the free space that was deemed lost? The post-fix DiskUsage screenshot below answers it affirmatively and convincingly:
If your Android phone has substantial unaccounted-for “used” space, which shows as huge “System data” in DiskUsage or significant discrepancies between df and du output in adb shell, then it is possible that the data partition file system has become corrupted.
Before following the advice below – it is strongly advised you back up all the contents of your phone.
After installing a custom recovery image and “rooting” your phone (instructions are phone-specific), you can run adb shell su in recovery mode, and from there you can use fsck (e2fsck) to examine, and if necessary, fix the file system.
I suggest to first run the file system checker in read only mode (-n) and look at the errors it finds. Some errors may indicate deeper problems, which cannot be easily/automatically fixed without the risk of worse corruption. Such deep analysis is beyond the scope of this write-up. Use the advice herein at your own risk.
It is possible the excess storage use is not due to corruption, but just some forgotten junk residing in the data partition (maybe due to some rogue app). As “root”, you will be able to see all the contents of /data and, if df and du outputs do not differ greatly, locate the biggest space wasters and remove them if possible.
Words of caution
When I first installed Magisk Manager, it offered me to upgrade the app, and the Magisk system itself. After upgrading both to the latest versions, I found that my phone would no longer boot past the recovery. I had to manually reinstall (in TWRP) the magisk version recommended in the Zenfone 2 unlock+root guide. Conclusion: it is best to stick to the versions that were tried and tested on the specific phone at the time the guide was written.
The same thing happened when I tried to “unroot” by doing a “Complete uninstall” from the Magisk Manager app. I understood from the discussion that it is a known issue, and the full solution may require flashing the stock recovery, followed by stock firmware. For now, I just uninstalled the app (which seems enough to block “root” access), but kept the rest of the stuff, in case I want to quickly enable “root” again at a future point.