-
-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
QDirStat doesn't scan Btrfs subvolumes #39
Comments
One approach would be to check if the current filesystem is Btrfs and list its subvolumes, but the Btrfs developers in their infinite wisdom decided that This is broken by design. (but then, so are many things about Btrfs). |
The |
Question to the world: How do I find out without root privileges what subvolumes a Btrfs filesystem has? |
It looks like a Btrfs subvolume always has i-node ID 256: http://stackoverflow.com/questions/25908149/how-to-test-if-location-is-a-btrfs-subvolume Tested on a sample Btrfs. Need to verify that this is reliable - and preferably documented. |
The content of
Now the question is how to tell the difference between a subvolume mount point and the mount point of a full-fledged Btrfs into another Btrfs: /home on a separate partition might be a Btrfs as well, so we couldn't tell the difference between /home and any subvolume of /. This output shows /dev/vda6 as the device for all of those Btrfs subvolumes, but the output of the stat() syscall or the |
Once I know that I am on one of those Btrfs partitions, I can do string comparisons: Am I still on /dev/vda6, or is another (Btrfs?) partition mounted there, too (say, /dev/vda7)? But how do I find out in the beginning that I am on /dev/vda6? The minor/major device ID returned from lstat() is not the one from /dev/vda6, but from some Btrfs device that does not show up below /dev (or does it? I couldn't find it). |
Btrfs:
I.e. stat() returns major/minor device 0x0026, but the underlying partition /dev/vda6 has major/minor device 0xFD06. XFS:
stat() returns 0x0803, and this is the underlying partition's (/dev/sda3) major/minor device ID. |
There is some more (but not much more) information in /proc/self/mountinfo:
See also https://www.kernel.org/doc/Documentation/filesystems/proc.txt :
|
Now working on a promising approach in branch huha-subvols: Reading and storing /proc/mounts (or fallback /etc/mtab) and comparing the device names when a mount point is found. The initial mount point of QDirStat's tree is found by canonicalizing the path (removing symlinks and and ".." parts) and comparing that path to any of the known mount points from /proc/mounts. If there is no corresponding mount point, the last path component is removed for the next lookup etc. up to /. If no device name can be obtained for either the tree root or for a mount point that was found, the simple major/minor device number comparison has priority, i.e. it is considered a filesystem boundary when they are different. That's what QDirStat (and KDirStat) always did. But for Btrfs, even though major/minor are different when a subvolume mount point is detected, if the device name is still the same (both directories on, say, /dev/sda2), it is considered the same filesystem, and QDirStat keeps reading. A nice side effect is that this is not limited to Btrfs: Other filesystem types that have a similar behaviour will benefit from that, too. Right now the toplevel .snapshots directory is still excluded, but that is by sheer accident: There is a very old exclude rule for that name because some backup tools use it, too. |
Tested on an openSUSE Tumbleweed VM with a root Btrfs and a /home Btrfs, and it appears to work great: When started to read /, it doesn't stop at all the subvolumes on that filesystem, but it does stop at all the other mount points, including /home (which is also a Btrfs, so this might have been problematic). From the log:
Subvolumes on both Btrfs partitions:
Finally, all the mount points:
|
This concludes the C++ part of this issue. The Perl part in qdirstat-cache-writer still remains to be done; it's equally important there. |
Also tested successfully on a setup with Btrfs on LVM:
|
The Btrfs snapshots are conveniently filtered out, but that seems more like a byproduct of a Btrfs bug to me:
They don't show up in /proc/mounts or /etc/mtab or in the output of
And forcing a
This is convenient right now because adding snapshots to the directory sums would count every file that is also in a snapshot several times. If a user still wants to scan a snapshot, he can simply use the normal "Continue reading at mount point" function from the context menu, just like with a normal mount point. |
The qdirstat-cache-writer script now also checks the device names of a mount point and its parent directory, not only their major/minor device numbers; so now it will not stop at Btrfs subvolumes while scanning. That script uses a more simplistic approach than QDirStat itself: It invokes the df command with that path and parses its output. If the path contains very weird special characters, this may fail, in which case that directory (which at that point is already known to have a different device major/minor number than its parent) is considered a filesystem boundary, and that branch is not scanned. |
If you use QDirStat to scan a Btrfs partition, any subvolumes of that partition are not scanned: Btrfs subvolumes are treated just like ordinary mount points (which, to all intents and purposes, they are). So you might wonder why the df command shows your 40 GB root filesystem as 97% full, yet QDirStat shows only about 7 GB. The rest might be hidden in subvolumes.
QDirStat stops reading at mount points - which only makes sense because normally you want to know what eats up the disk space on that one partition that is filling up, not on any others like /home that are mounted there. Unfortunately, a Btrfs subvolume is also just another mount point, and QDirStat will start reading there, too - at /var/log, at /var/spool, at /var/lib/libvirt etc.; a typical Btrfs root filesystem has about a dozen subvolumes, and all files in them are currently disregarded by QDirStat.
You can of course click on "Continue reading at mount point" individually in
QDirStat's directory tree for each one of them, but that's tedious.
The text was updated successfully, but these errors were encountered: