Wie finde ich heraus, ob eine Datei auf btrfs beim Schreiben kopiert wird?

7

Ich weiß, dass cpes eine --reflinkOption gibt, um vollständige Kopien im Vergleich zu "Kopien" beim Schreiben zu steuern.

Kann ich unter btrfs ls(oder einen anderen Befehl) herausfinden, ob eine Datei (im Sinne eines Copy-on-Write) einen Speicher mit einer anderen Datei teilt?

EDIT: @ StéphaneChazelas weist mich darauf hin filefrag, aber das scheitert für mich:

root@void:/tmp/mount# mount | tail -1
/tmp/back on /tmp/mount type btrfs (rw,relatime,space_cache)
root@void:/tmp/mount# df -h | tail -1
/dev/loop0       32M   13M   20M  38% /tmp/mount
root@void:/tmp/mount# ls -lh
total 8.0M
-rw-r--r-- 1 root root 8.0M Jan 19 08:43 one
root@void:/tmp/mount# cp --reflink=always one two
root@void:/tmp/mount# sync
root@void:/tmp/mount# ls -lh
total 16M
-rw-r--r-- 1 root root 8.0M Jan 19 08:43 one
-rw-r--r-- 1 root root 8.0M Jan 19 08:45 two
root@void:/tmp/mount# df -h | tail -1
/dev/loop0       32M   13M   20M  38% /tmp/mount
root@void:/tmp/mount# filefrag -kvx one 
Filesystem type is: 9123683e
File size of one is 8388608 (8192 blocks of 1024 bytes)
FIEMAP failed with unknown flags 2
one: FIBMAP unsupported
root@void:/tmp/mount# uname -a
Linux void 4.1.7+ #817 PREEMPT Sat Sep 19 15:25:36 BST 2015 armv6l GNU/Linux
kein Benutzer
quelle
2
Mit filefrag -vkönnen Sie überprüfen, ob zwei Dateien gemeinsame Daten haben.
Stéphane Chazelas
1
@ StéphaneChazelas: Schlägt für mich fehl, siehe meine Bearbeitung.
Nicht-Benutzer

Antworten:

5

Ich weiß nicht, wie ich es über den lsBefehl finden kann. Aber wenn Sie es wirklich wollen, können Sie den btrfs-progs / btrfs-debug-Baum verwenden .

Mit reflink = always teilen sich die Dateien einen gemeinsamen Datenblock. Dieser allgemeine Datenblock (auch bekannt als Extents) hat Refs von mehr als 1.

  1. Zuerst müssen Sie die Objekt-ID für die Dateien eins und zwei finden

    #./btrfs-debug-tree  /dev/xvdc
    (Check under FS_TREE)
      <snip>
        item 8 key (256 DIR_INDEX 4) itemoff 15842 itemsize 33
            location key (259 INODE_ITEM 0) type FILE
            namelen 3 datalen 0 name: one
        item 9 key (256 DIR_INDEX 5) itemoff 15809 itemsize 33
            location key (260 INODE_ITEM 0) type FILE
            namelen 3 datalen 0 name: two
      </snip>
    

Von oben sehen wir seine 259 (eins) und 260 (zwei) .

  1. Finden Sie jetzt seine Refs. vom Umfang Baum. Der folgende Befehl findet den Datenblock, der von zwei Dateien gemeinsam genutzt wird.

    # ./btrfs-debug-tree  /dev/xvdc | grep -A2 "refs 2"
            extent refs 2 gen 9 flags DATA
            extent data backref root 5 objectid 260 offset 0 count 1
            extent data backref root 5 objectid 259 offset 0 count 1
    

Bonus: Erstellen Sie eine weitere Referenz:

# cp --reflink=always one three

Überprüfen Sie, ob die Nachzählung um 1 erhöht wurde.

# ./btrfs-debug-tree   /dev/xvdc | grep -A3 "refs 3"
        extent refs 3 gen 9 flags DATA
        extent data backref root 5 objectid 260 offset 0 count 1
        extent data backref root 5 objectid 261 offset 0 count 1
        extent data backref root 5 objectid 259 offset 0 count 1

Hier wird der Datenblock von drei Dateien geteilt, auf die die Objekt- ID 259,260,261 zeigt .

webminal.org
quelle
Danke, gut zu wissen btrfs-debug-tree.
Nicht-Benutzer
1

Ich habe gerade ein Programm namens fienode(← Link) veröffentlicht, das einen SHA1-Hash der physischen Ausmaße einer Datei berechnet. Identische CoW-Kopien haben denselben Hash.

Hier finden Sie auch eine ausführlichere Antwort, in der erläutert wird, warum dies erforderlich ist.

Beachten Sie jedoch, dass es BTRFS frei steht, die physischen Ausmaße zu ändern. Ich habe beobachtet, dass eine große reflinked Datei ihre physischen Ausdehnungen ohne Provokation ändert, wodurch sich die fienodeAusgabe unterscheidet, obwohl die Mehrheit der physischen Ausdehnungen noch gemeinsam genutzt wurde.

pwaller
quelle