kdave / btrfs-progs

Development of userspace BTRFS tools
GNU General Public License v2.0
540 stars 240 forks source link

Add option to btrfs filesystem defragment to not defragment shared extents #519

Open crass opened 1 year ago

crass commented 1 year ago

Its a well known issue that running defragment will break up reflink clones. One can google and see this is the source of a lot of headaches for users and I bet will continue to be. I'm hoping that this could be the start of remedying that.

This big idea here is to allow for a sub-optimal defragmentation that does not break up reflinks or shared extents in general. I noticed that the defragment command can take a starting byte offset and a length in bytes arguments. So it seems defragment should be able to (easily?) look at the extents of a given file and only defragment sequential extents that do not contain shared extents. Currently a script could be written to do this by getting the FIEMAP and running a series of defragment operations specifying start and length. It would be better to have this be done internally as an option for defragment. There should be a note in the documentation for this option that its a sub-optimal defragmentation.

kdave commented 1 year ago

The defrag ioctl needs an update to pass the 'none' option and to pass the level. Adding a flag to skip shared extents can also be added, but yes this can be emulated by userspace now. The snapshot-aware defrag has been disabled and removed some time ago, the performance was bad and it had large memory requirements. IIRC we've discussed whether the reflink breaking should be optional and it seems there are users who want that too.