Camlistore and TahoeLAFS are both designed this way. But they are more of a content store than a file system.
In fact, BTRFS is implemented this way. The content and the metadata can be separately treated with mirrors vs raid. You can balance just the metadata or both data and metadata. When you convert an ext2/3/4 file system to BTRFS, it just sets up it's own metadata pointing to the same blocks that the ext used. You get a free snapshot of your data pre-conversion and it's all COW from then on. I believe the B-Tree of BTRFS is the metadata and the content never changes on disk until no more pointers exist. If you decide to go back, it just restores the superblock and the old data is still in the same spot. You would only regain that space after you delete the snapshot and the last pointers to the data are gone.
Btrfs is not content-addressable, although everything else you say about it is correct.
This does make rolling things back trivial.
It doesn't give you dedupe for free, though. Think about what would have to happen: every modification would mean rehashing the modified block (not a problem, that should happen anyway to verify integrity). Let's say we dedupe at the block level rather than the file level to avoid the need for more expensive hashing operations, and to increase the likelihood of actually sharing stuff. Now, to determine whether we can deallocate the new block, we need to look up the hash. So we need an index of every block on the file system by hash. That necessarily involves either a big chunk of memory or a bunch of random I/O. Both are at a premium for a filesystem - the former for cache, the latter for throughput.
If you just want file dedupe, it's a smaller problem, but is less likely to create gains - most people don't store many copies of the same file, unless they're in the third party file storage business. So it isn't really suited to a general file system. If this is something you want, you could periodically go through your file system, hash all files with only one link count in the inode, and hard link them using the hash as a file name, into an set of directories fanning out by hash prefix. There may be some wrinkles with permissions; I believe btrfs has a different kind of copy with copy-on-write semantics that might be useful here.
But I don't think you'd have this problem. Just like we have an inode telling every block of a file, a filesystem like that would need a similar structure telling every hash of the file. When you delete a block, you look at this structure, the same way you look at an inode.
The only thing missing is that you'll need a counter at the blocks. And this counter will create some synchronization problems that may turn out more important than saving disk space.
It's also worth noting that ZFS has been available as a root file system long before FreeBSD added ZFS to RELEASE. I remember running OpenSolaris (and some of it's forks, eg Nexenta) with ZFS root about 6 years ago. Possibly longer actually.
The issue with ZFS as root was more of a problem with the boot menu than the OS. OpenSolaris used GRUB where as FreeBSD obviously doesn't, so FreeBSD needs to either port their ZFS drivers to their bootloader, or employ a hacky method of having a UFS boot volume that then points to a ZFS root partition (which, sadly, is how FreeBSD currently works).
Interestingly, since GRUB is GPL, it meant that technically there were GPL ZFS drivers even before Btrfs started life (never mind the various Linux ports of CDDL-licenced ZFS drivers that have appeared since). Albeit those GPL ZFS drivers were read only
A ZFS-aware loader hit CURRENT in late 2008, and a dedicated zfsloader for use from (gpt)zfsboot hit the stable branches in late 2009.
Anyhow, thank you for the correction :)
The above video is an explanation of a bunch of the barriers to implementing block pointer rewrites. The conclusion is that it would make the code a lot more complicated and break a lot of the layering, and probably make addition of other new features a lot harder. Even a standalone offline rewriting tool wouldn't necessarily be accepted into the OpenZFS codebase because of the maintenance burden. Their advice is that if you think you need that feature to solve a particular problem, you should be looking for a workaround to solve that problem without requiring the huge block pointer rewrite project (which nobody's working on), even if the workarounds have a significant and permanent performance impact.
When you take into account how long the feature's been in demand and been on the roadmaps under "eventually", it's clearly not going to happen anytime soon and won't happen without a major change to how ZFS development is being done. It's not definitely impossible, but it's perpetually several years away from happening. With btrfs already having it's equivalent to that feature and stealing an ever-growing slice of the users who need that feature, it's probably never going to happen for ZFS.
http://open-zfs.org/w/images/7/71/Fast_File_Cloning-Pavel_Za...
> the filesystem could offer an abstraction over a patch and pointer to the original file
I've implemented a delta-based patching system before: the idea is that, given two binary buffers (ostensibly files), encode the differences between them. I have no idea how Xdelta (VCDIFF-based) and bsdiff manage to do this at reasonable speeds (their code is too much for me to understand), but the best I could manage for this was O(n^2). It's a very complicated and difficult thing to do efficiently. But indeed it can result in massive file space savings. You could cheat a bit by intercepting fwrite commands, but that won't catch insertions or deletions. Nor programs that overwrite files instead of updating them in-place (eg most of them.) As you can guess, to really make something like this efficient would require program authors to rethink how they write to files, which is unlikely to ever gain traction.
What I'd really like to see, but know that we'll never get thanks to xkcd.com/927, is a metadata system for files that is portable. Instead of relying on file extensions or unreliable magic byte header detection, you'd have the MIME type included in this metadata. Along with the displayed file name that can have any characters in them (sans maybe the path separator), the file attributes (read/write/exec/user/group/owner/hidden), creation+modification+access times, etc. And then when you'd send a file through your e-mail client or FTP it up to some web server, it'd copy over the metadata along with it. So when you moved your file from extfs over to NTFS, and then copied that over to ZFS, you wouldn't lose all of that metadata.
But good luck getting all file system authors and browser vendors to agree to a common format to transparently wrap files with.
It's not as seamless as one might wish; you do have to use zip. do the transfer and then unzip on the target, and of course remember to use -V in the first place.
FTP implementations also exist in the VMS world for transferring the file metadata, but I haven't used these myself so can't comment on their usability in practice.
The downside to ZIP is that the information is cast away once you decompress it. If your file system doesn't maintain that metadata (eg Windows and file permissions), then it's just gone.
You also can't really just keep your files in ZIP because operating systems don't really natively integrate transparent ZIP support into files, and you probably don't want the file compressed in most cases (your app may want to read it often, and not want to pay the cost of decompressing the whole thing.)
But that is very close to what I am seeking, yes.
However full deduplication could never be free simply because of the overhead of keeping a table of all the duplicated data and scanning new content for duplications.
ZFS has deduplication as an optional feature, which is implemented as a content-addressable store of filesystem blocks. In contrast to e.g. git the content-addressable aspect is an implementation detail that is not exposed to users.
I know that. But CoW does cover a few points raised by the previous poster.
> ZFS has deduplication as an optional feature, which is implemented as a content-addressable store of filesystem blocks. In contrast to e.g. git the content-addressable aspect is an implementation detail that is not exposed to users.
I know what dedup is and how ZFS utilises it (I've been running ZFS for about 8 years now - I'm quite familiar with it).
If you read my post again, you'll see I was discussing two separate points: 1) that CoW file systems do provide the pointer-like methods the former commenter raised. And 2) deduping isn't free.
What you're arguing with me is semantics and if you read the former post again, you'll understand why I chose the language I chose.
Why aren't modern filesystems based on a content-addressable-store where the content is 100% separated from the organization of the filesystem itself? It seems to me like it would make more sense to have only one copy of a file ever saved and when modifications are made you get a new pointer to the changed file. Obviously it wouldn't make sense to do full copy on modifications for files over a certain size, but in this situation the filesystem could offer an abstraction over a patch and pointer to the original file until the system is idling and a full copy could be made.
The reason I ask about this is because it would make updating anything and rolling things back trivial since it would simply be a pointer change in the file hierarchy hash map from the new file to the old file and back again. Furthermore, such a system would give you dedupe for free and files could be marked for deletion only once the last pointer to the file in the CAS has been deleted.