Trimming Unused Space
Every generation of flash drive comes with a more complex controller. One of the most useful things that an operating system can do, rather than try to optimize flash access itself, is give the controller enough information to do this optimization.
Flash drives, like hard disks, don't know anything about the contents of the filesystem. They support two commands: write this data to this block, and read the contents of this block. Aside from some management commands, this is all that's exposed by an operating system's block device layer.
Most modern drives also support the TRIM command. This lets the filesystem layer notify the block layer that some space is unused. This sounds fairly trivial, but is actually quite important when it comes to wear levelling.
Each flash cell has a finite number of rewrite cycles before it gets stuck. A modern flash controller dynamically modifies the mapping between blocks and cells to attempt to spread writes evenly across all cells. If you write constantly to the same cell, you can wear it out in a few hours, but if you spread writes perfectly across a flash disk, then a modern drive can sustain its maximum write speed for more than 1,000 years before hitting the write limitlong enough for the system to fail completely for reasons unrelated to the durability of flash. Wear levelling isn't perfect and it depends a lot on the information that the controller has.
One of the things that wear levelling algorithms do is try to copy data that is not frequently modified to cells with high erase counts. For example, most systems contain a set of standard libraries that are only modified by major upgrades every six months or more. If a cell is near its reliable erase cycle limit, the controller may try to put some blocks from one of these files onto it. If the access pattern is reliable, then the cell will last for years, while more frequent writes all go to cells that have not been used as much.
If you have just erased a file in a cell with a high rewrite count, then the controller doesn't know that the operating system doesn't care about the data in the cell, and will need to copy it if it wants to remap that cell. With the TRIM command, the controller knows that it can erase the cell without having to first copy its contents. This makes it much cheaper to remap blocks and reduces the number of erase operations required, which makes wear levelling and defragmentation much more reliable.
There's still a lot more that operating systems can do, but quite often they're limited by the block device interface. The remapping logic in a typical controller could trivially implement copy-on-write semantics, for example. If you copied a file, the block map would just be updated so that two blocks referenced the same address in the cell. You'd only need to erase and rewrite blocks when you actually modified one copy. Unfortunately, the block device interface doesn't support this kind of high-level command.
It's also worth noting that many of these restrictions are only relevant to flash, and not to some of the other SSD technologies that we looked at in the previous article. Technological progress being what it is, it's quite likely that we will see very efficient flash filesystems widely deployed just in time for flash to be obsolete.