28

Why is cp --reflink=auto not the default behaviour? Could it cause any harm to enable it?

Is it possible to enable it at compile time, so it is used all across the system, not just in interactive shells?

  • 4
    Yes, good question. IMHO it will, as only BTRFS starts to be a default Linux file system. – Adam Ryczkowski Jun 22 '13 at 18:38
33

It's not the default since for robustness reasons one may want a copy to take place to protect against data corruption. Also for performance reasons you may want the writes to happen at copy time rather than some latency sensitive process working on a CoW file and being delayed by the writes possibly to a different part of a mechanical disk. Note that from coreutils v8.24 mv will reflink by default, since it doesn't have the above constraints.

  • 8
    (that could be considered as an authoritative answer since Pádraig is a maintainer of GNU coreutils). – Stéphane Chazelas May 20 '15 at 14:54
  • 7
    I doubt this answer is correct, at least on btrfs. If the file is later written to, the new data will be written to a different disk sector anyway due to btrfs CoW, so there is no latency advantage to not doing reflinks. Files that have NoDataCoW set can't be reflinked anyway. And if you want to protect against data corruption you'll need to copy to a different partition and reflinks also won't work. – JanKanis Sep 8 '15 at 19:04
  • 2
    There are latency issues as BTRFS needs to find and allocate space at write time. This might not even be available thus throwing ENOSPC errors at write time – Pádraig Brady Sep 9 '15 at 11:38
  • 1
    What use does mv have for reflink? – Macil Feb 18 '16 at 19:21
  • 1
    cross subvolume renames on btrfs – Pádraig Brady Feb 19 '16 at 3:54
17

Don't know why it's not the default, maybe so that it behaves the same as other copying utilities (rsync, cpio, pax, tar...) which have no support for it (or when files are copied across an interface that doesn't allow that (like NFS, samba, fuse file systems layers...).

I was in the same situation a few years ago, and looking at GNU cp code quickly, it's still the same, you have to patch the code to get a different default behavior:

--- coreutils-8.21/src/cp.c~    2013-06-22 21:50:26.265639114 +0100
+++ coreutils-8.21/src/cp.c     2013-06-22 21:51:06.880513924 +0100
@@ -775,7 +775,7 @@ cp_option_init (struct cp_options *x)
   x->interactive = I_UNSPECIFIED;
   x->move_mode = false;
   x->one_file_system = false;
-  x->reflink_mode = REFLINK_NEVER;
+  x->reflink_mode = REFLINK_AUTO;

   x->preserve_ownership = false;
   x->preserve_links = false;
4

One big issue is the potential to run out of space to do the copy when you write.

With a normal copy, then as soon as the copy completes, you never have to worry about a write to existing parts of the file failing: the space is entirely allocated and won't go away until you delete the file. But with a reflink copy, there's always a risk that at some point weeks or months down the road, a write to an existing part of the file will fail because there wasn't enough space to make a copy.

Discovering that your system had been doing reflink copies behind your back when an operation like that failed would be a pretty nasty surprise.

  • At least on btrfs even write to already allocated part of the file can fail with ENOSPC... – graywolf Jul 21 '18 at 14:30
2
alias cp='cp --reflink=auto --sparse=always'

makes better sense than patching the code

  • 5
    Looks like you overlooked the Is it possible to enable it at compile time, so it is used all across the system, not just in interactive shells in the OP's question. – Stéphane Chazelas Sep 26 '13 at 9:54
  • 4
    @StephaneChazelas One could always rename /bin/cp and replace it with a similar shell script – goncalopp Jan 16 '14 at 16:30
0
  1. Robustness reasons one may want a copy to take place to protect against data "loss".

    We don't know that's the reason, but the bad things that can happen are limited to destruction of media. Most all block devices will have some form of corruption identification(crc), if not forward error correction(parity).

  2. Not for performance reasons.

    CoW happens when only part of the ?erase? block is written to. With modern !disk! device the hardware block size is a multiple of 4k. Changing part of the 4k causes the drive to read the whole 4k and write it out again, but on top of that the kernel is going to do the same thing so there won't be any partial writes reaching the block device, SSD or otherwise. The kernel needs to perform the CoW for the same reasons, unless we've a cached copy we can't make up the data that exists in the other parts of the device, save for the tale end of a file but then the point is moot. But caching a copy of a file and copying a file are vary different operations, the former is much cheaper.

    The address of the writing is immaterial, but make it be know that "some un-used part of device" is cheaper to discover than "where the file's blocks currently reside."

The fact is any CoW method is either cheaper or equal to simply updating a block device. Now if we were not talking block devices, then it'd be another story... Written on tape somewhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.