// reflink -- copy a file by sharing its blocks instead of duplicating them. // // reflink // // The copy is instant and free whatever the file's size: only metadata is // written. Both files are ordinary and writable afterwards; the first write to // either copies just the run it touches. `df` before and after is the check // that it really shared rather than quietly copying. // // Uses FICLONE, which is Linux's ioctl for exactly this, so the same call works // against any filesystem that supports cloning. #include "core/types.h" #include "uapi/user.h" #include "uapi/fcntl.h" #define FICLONE 0x40049409 static void puts_(const char *s) { int n = 0; while (s[n]) n++; write(2, (void *)s, n); } int main(int argc, char *argv[]) { if (argc != 3) { puts_("usage: reflink \n"); exit(); } int src = open(argv[1], O_RDONLY); if (src < 0) { puts_("reflink: cannot open "); puts_(argv[1]); puts_("\n"); exit(); } // O_TRUNC matters: FICLONE replaces the destination's contents entirely, // and creating it non-empty would leave blocks to release mid-clone. int dst = open(argv[2], O_CREATE | O_WRONLY | O_TRUNC); if (dst < 0) { puts_("reflink: cannot create "); puts_(argv[2]); puts_("\n"); close(src); exit(); } if (ioctl(dst, FICLONE, (void *)(long)src) < 0) { puts_("reflink: FICLONE failed\n"); close(src); close(dst); exit(); } close(src); close(dst); exit(); }