0

I have a lot of files in various directories on a btrfs filesystem. They are all identical, and some may have been created using a "old-style" full copy, some are clones (cp --reflink). I want to find out whether there are any non-clones.

In some cases, there might be clones of old-style copies, see the cp example below. In such a case, the output of btrfs fi du is unhelpful: all the files have 0.00B in the Exclusive column, and something in the Set shared column. But it's not necessarily one shared set. So I cannot use btrfs fi du to tell them apart. How can I?


I assume this is not detailed enough to be understood (but I wanted to put the question first), so here's a more elaborate example. Suppose I have two pairs of files; each pair's members are clones. In other words, I did this:

dd if=/dev/urandom of=a1 count=1 bs=1M
cp --reflink=always a1 a2
cp --reflink=never a1 b1
cp --reflink=always b1 b2

Of course, the files will take up 2MB on disk (each x2 shares its extents with x1).

I can see this using btrfs fi du . (last line)

     Total   Exclusive  Set shared  Filename
   1.00MiB       0.00B           -  ./a1
   1.00MiB       0.00B           -  ./b1
   1.00MiB       0.00B           -  ./a2
   1.00MiB       0.00B           -  ./b2
   4.00MiB       0.00B     2.00MiB  .

However, I cannot see it via btrfs fi du *:

     Total   Exclusive  Set shared  Filename
   1.00MiB       0.00B     1.00MiB  a1
   1.00MiB       0.00B     1.00MiB  a2
   1.00MiB       0.00B     1.00MiB  b1
   1.00MiB       0.00B     1.00MiB  b2

Here, I don't have the last line. I cannot distinguish this case (two pairs) from the case that all four files are in one single shared set (in other words, cp a1 a2; cp a1 b1; cp a1 b2 all with --reflink=always); the output would be exactly the same.

Obviously, if all those files are in the same directory, I would just use fi du .. But if they are in different directories, I cannot do this. How can I get that "last line" that tells me if it's a single shared set or multiple separate ones?

1 Answer 1

2

Obviously, if all those files are in the same directory, I would just use fi du .. But if they are in different directories, I cannot do this. How can I get that "last line" that tells me if it's a single shared set or multiple separate ones?

Make it so they are in the same directory.

  1. Create a temporary directory.
  2. ln all the relevant files to the directory (i.e. create hardlinks). There may be name collisions, you may need to link some files to modified names.
  3. Run btrfs fi du . in the directory.
  4. Remove all the files inside the directory and the directory itself.
1
  • Thanks. I've thought of this, too, already (and it's a good trick that might help others having the same problem). However I'd prefer an easier solution, as I'm dealing with quite a lot of files and it's tedious to to all this linking...
    – Marian
    Commented Mar 27, 2023 at 22:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .