Freeing up local disk space

It turns out that iCloud does not necessarily free up disk space, even when you ask it to.

I wanted to add a virtual machine, which required a lot of free disk space, so I started freeing up space by removing local downloads.

I cleared a bunch of videos and large pdf files I had used for presentations and quickly freed up 100GiB which should be plenty for the virtual machine I was going to need.

Annoyingly, freeing up disk space does not actually free up disk space. Even though Disk Utility reported that I had more than a 100GiB free, Parallels insisted that I didn't.

Investigating

Starting to wonder what was going on, I went to df to try to figure out what was going on, and found out that there is a discrepancy between what Disk Utility says and what df says:

It appears that despite my cleaning up, the files still claimed the space they originally used. To get around this, I needed to force the file system to release the resources.

What happens is that iCloud optimizes storage on demand when the disk starts to fill up, but if I need a lot of storage available to even start a process then I am stuck with a situation where I cannot use the disk space because it is only going to get freed up on demand, even if it is available.

Workaround

To work around this, I created a large file with a utility that does not care about free disk space before it starts writing. I created a file with 30GB-ish of all zeroes using dd and then promptly deleted it once it was created:

Lo and behold: Suddenly, free disk space balooned from 17GiB to 67GiB!

Results

A generalized utility to release claimed disk space could look like this:

#!/usr/bin/env bash

spin()
{
  spinner="/|\\-/|\\-"
  while :
  do
    for i in `seq 0 7`
    do
      echo -n "${spinner:$i:1}"
      echo -en "\010"
      sleep 0.2
    done
  done
}

avail()
{
  df -h | sed -n 2p | awk '{print $4}'
}

echo "Space available before reclaiming disk space: $(avail)"

spin &
spin_pid=$!

cd $TMPDIR
filename=zeroes.$$

dd if=/dev/zero \
    of=$filename \
    count=524288000 \
    bs=1024 >/dev/null 2>&1
rm -f $filename

kill $spin_pid
wait $spin_pid

echo -en "\010"
echo -n "Space available after reclaiming disk space:  $(avail)"
echo ""

Now you too can reclaim disk space used by iCloud files.