If I have a large file, I can use ln to make make copies of it that don't use up extra disk space. But what if I don't want an exact copy of the file? Is there a way to create a new version of a file with some modifications without needing to copy the whole file and use twice the disk space?My motivation is editing id3 tags on mp3 files from a torrent download. I don't want to edit the downloaded files directly because that messes up the seeding but I also don't want to copy the files and use twice the disk space just to edit some id3 tags their headers.
Is it possible to create an edited copy of a file without using up extra disk space?
files;file sharing
If there is no built-in capability in the program that you use, to overlay new information in some way over a base file, you have to resolve this on the filesystem level, transparently to the application using the file. Because of your space requirement a revision control system would not suffice, although it provides you with multiple versions.One thing you can investigate is to store the files on a Btrfs filesystem and have the originals in one originals snapshot and the updated versions in a view based on this snapshot. This should work well for ID3v1 tags (as they are the end of a file) and also for those files that have ID3v2 tags, as long as they have enough reserved space for the changes and do not require rewriting of the MP3 file. Thus only the actual blocks changed for a file are taking extra disk space.If you add additional file in the originals you have to make an explicit cp --reflink src dst for all the files added at a later stage. Your downloads would then work with the originals and  your id3 editor ( e.g. picard) and your music player on the derived view. Unchanged (or not yet changed) files in that view will look exactly the same as under the originals.Example (starting with an Btrfs volume on /data0 and a test.mp3 file in /tmp):/data0$ btrfs subvolume create /data0/mp3orgCreate subvolume '/data0/mp3org'/data0$ cp /tmp/test.mp3 mp3org//data0$ btrfs subvolume snapshot /data0/mp3org/ /data0/id3updateCreate a snapshot of '/data0/mp3org/' in '/data0/id3update'The file test.mp3 is now available in both directories (mp3org and id3update):/data0$ ls -l /data0/mp3orgtotal 7600-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3/data0$ ls -l /data0/id3update/total 7600-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3Change the one in the snapshot:/data0$ id3v2 -c This is a change id3update/test.mp3/data0$ ls -l /data0/mp3orgtotal 7600-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3/data0$ ls -l /data0/id3update/total 7608-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3The file size has not changed, but the contents of the second one did. This is because the comment did fit in the reserved space for the id3v2 in the original file./data0$  grep -F is a change mp3org/* id3update/*Binary file id3update/test.mp3 matchesCopy another file in the original subvolume, it doesn't show up in id3update:/data0$ cp /tmp/test.mp3 mp3org/abc.mp3/data0$ ls -l mp3org/ id3update/id3update/:total 7600-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3mp3org/:total 15200-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3Make an explicit reflink copy:/data0$ cp --reflink mp3org/abc.mp3 id3update//data0$ ls -l mp3org/ id3update/id3update/:total 15200-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:29 abc.mp3-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:24 test.mp3mp3org/:total 15200-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:28 abc.mp3-rw-rw-r-- 1 avanderneut users 7781043 Oct 25 15:21 test.mp3And change the new file:/data0$ id3v2 -c another file change id3update/abc.mp3/data0$ grep -F change mp3org/* id3update/*Binary file id3update/abc.mp3 matchesBinary file id3update/test.mp3 matchesIf mp3org gets filled automatically you can keep id3update up to date by running a script on a regular basis that does the cp --reflink src dst if the destination doesn't yet exists.which are most often at the beginning of a file