How about separating the judgement and the defrag part into two separate binaries? That way the judgement part would only spill out one filename per line which would be passed into the defrag binary on standard input. In the end, some filesystems require special handling of defragmentation and you probably don't want to put all this logic and heavy lifting into shake. The judgement part of shake itself becomes thus only a clever disk layout analyzer and file sorter. Also, the file system handling code could become a lot cleaner.
Both binaries could then be optimized on their own, shake could spawn multiple defrag binaries per spindle or per filesystem. It could also supply some stub binaries like defrag.xfs, defrag.btrfs to call out for the native tools of those filesystems as an option.
I want to throw in the following idea:
How about separating the judgement and the defrag part into two separate binaries? That way the judgement part would only spill out one filename per line which would be passed into the defrag binary on standard input. In the end, some filesystems require special handling of defragmentation and you probably don't want to put all this logic and heavy lifting into shake. The judgement part of shake itself becomes thus only a clever disk layout analyzer and file sorter. Also, the file system handling code could become a lot cleaner.
Both binaries could then be optimized on their own, shake could spawn multiple defrag binaries per spindle or per filesystem. It could also supply some stub binaries like defrag.xfs, defrag.btrfs to call out for the native tools of those filesystems as an option.