0

I have a Samba server running ZFS in Linux.

  • It is a standard by-the-book install with no special configuration.
  • Each share is mapped to their own ZFS dataset, but not all datasets have their own share.

Oracle Linux 9.2 ZFS 2.1.12 Samba 4.17.5

I used this dfree script to get windows to report the proper used and free space remaining in File Explorer:

#!/bin/bash
USED=$((`zfs get -o value -Hp used $1` / 1024)) > /dev/null
AVAIL=$((`zfs get -o value -Hp available $1` / 1024)) > /dev/null
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

This works as intended.

However this is creating confusion to end users: they see the reported capacities for the different shares are slightly different, assume this means they must be different servers, and call me asking why that is.

So I want Windows to report the used space and capacity of the entire ZFS pool regardless of the share, rather than the reported used and available space of the individual datasets their shares are mapped to.

In theory I should simply replace $1 with the name of the pool ("tank" in this case), however the reported disk space does not change in windows:

#!/bin/bash
USED=$((`zfs get -o value -Hp used tank` / 1024)) > /dev/null
AVAIL=$((`zfs get -o value -Hp available tank` / 1024)) > /dev/null
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

enter image description here

Various tinkering causes Windows to either report strange values or nothing at all.

The only way I found to make this work so far is to hardcode USED and AVAIL to be what the zfs get commands are supposed to return:

#!/bin/bash
USED=11258621113
AVAIL=28766985099
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

enter image description here

Am I missing something silly? Has anyone got this to work?

Thanks!

1
  • Depending on what metrics you want to show users, you may want to use the referenced property of the filesystem (to show actual disk space used), or even logicalreferenced (to show the total amount of user data that has been compressed down) in place of the used property.
    – Jim L.
    Commented Oct 2, 2023 at 21:25

2 Answers 2

0

First off, I regret I do not have a solution for you, because I can't reproduce your problem. I have never used a dfree command directive in smb.conf in over a dozen Samba instances on FreeBSD machines, and have never had the problem you describe. Samba seems to know how to query the disk space stats, and Windows reports reasonable disk utilization metrics. For a filesystem with:

$ zfs list -Hpo used,avail tank/r2d2
2209625051136   1605933772800

Windows shows: 1.45TB free out of 3.32TB

I am not qualified to say for sure, but the root problem of Samba not being able to determine sane numbers may lie in a defect somewhere in the upstream integration of ZFS and Samba. At the very least, Samba ought to be able to find the ZFS filesystem's used and avail properties, as you are trying to do by hand. All my systems figure this out just fine on their own.

But at a more fundamental level, your post suggests that you realize, though your users may not, that ZFS is something of a paradigm shift in disk storage. One telling hint is that you're having to calculate the "Total" capacity of the filesystem. ZFS itself doesn't have this concept (at the filesystem level), and indeed, there is no size property that can be accessed by the zfs list utility.

At the filesystem level, the used vs. available numbers will always be squishy, because the data itself is squishy. ZFS filesystems can be (and often are) configured to compress data on-the-fly, without the user being aware of that. So a user might see a volume with 100G available, save a compressible 10G file, and then be baffled when instead of dropping to 90G free, the volume still has 95G free. They'll wonder how the server's disk array seemingly stored a 10G file, but the "available" space decreased by only 5GB. It's because the compression is transparent to the user.

Another way to put it: take a generic 4TB drive. What is its "capacity"? The subset of your users who call you asking about disk space will probably say "four terabytes." But in ZFS, that's the physical capacity, the amount of hard disk space, a minimum number, and is true only in the case where the data is incompressible. If your data is compressible, then the total logical capacity of the drive (which may be what your users think of when they ask "How much more storage do we have?") is likely higher than 4 TB. Even using the old lz4 compression algorithm, I have filesystems that exceed 3x compression, one reaching almost 6x. At that rate the "4 TB" drive's capacity would be between 12 and 24 terabytes. With zstd compression, the compression ratios can go to double digits.

The difficulty is that, while ZFS knows what the compression ratio of the stored data is (used vs. logicalused), there is no way to determine how compressible the "available" space is until data is actually written to it. In other words, total=used+avail breaks because although used is known, avail is only a minimum. total could actually be more than used+avail, depending on what your future data storage patterns are.

In ZFS filesystems, there is no such thing as "disk capacity" except in the context of the actual data that is going to be stored. When a filesystem with a known available value stores additional data, say a file 10G in size, it could compress at 2:1 to consume only 5G of the actual disk. So saving a compressible 10G file could cause the logical capacity to go up by 5GB. Storing that 10G of data caused your apparent "capacity" to go up by 5 GB. This is why your users are confused. They don't understand that a drive with a nominal physical capacity of 4TB could increase to a logical capacity of 8TB of actual user data, if the user data is 2:1 compressible. Tracking the amount of available or total space in a compressible filesystem is always going to be a shifting target.

IMO you're on the right track when you say that you want to shift to reporting disk space metrics at the pool level. That is what I do in my uptime monitoring system, because regardless of the compression level, the output from zpool always reflects the actual numbers of bytes that are used (allocated) or not used (size-allocated) on the drive. Indeed, at the pool level is where we finally find a "Size" property, something ZFS filesystems don't have. The amount used and amount available are slightly less meaningful, notably because they reflect RAID-Z parity, but the ratio of used/size is generally accurate:

$ zpool list -po cap,alloc,size
  CAP          ALLOC           SIZE
   56  2256319561728  3985729650688
$ bc <<< 'scale=4; 2256319561728/3985729650688'
.5660

Most people can understand that the disk is "56% full" or "92% full." But when they ask, "how much more data can we store?" the answer can only be "It depends."

Please update your post as you arrive closer to your preferred solution. I realize all I've posted here doesn't address your question directly, but I wanted to illustrate the fact that the difficulty you're facing is rooted as much or more in user education as it is in technical methods.

0
-1

In Samba, the disk space reporting for shares is typically done at the share level, not at the pool level. This is why you are seeing slightly different reported capacities for each share, as they correspond to the properties of the individual datasets.

If you want Windows to report the used space and capacity of the entire ZFS pool, you may need to consider an alternative approach, as modifying the behavior of Samba's disk space reporting for individual shares can be complex and might not yield the desired results.

One possible approach is to create a separate share that points to the root of the ZFS pool (e.g., /tank) and then use that share for reporting the pool-level disk space. Here's how you could do it:

  1. Create a share that points to the ZFS pool's root directory in your Samba configuration file (usually /etc/samba/smb.conf). You can do this by adding a new section like this:

    [pool-root]
    path = /tank
    read only = yes
    browseable = no
    

    Adjust the path (/tank) to match your ZFS pool's mount point.

  2. Restart the Samba service to apply the configuration changes:

    sudo systemctl restart smbd
    
  3. Access the pool-root share from Windows, and it should report the disk space for the entire ZFS pool.

Please note that by creating this special share, users will be able to access the root of the ZFS pool, so make sure to set appropriate permissions and restrictions to limit access if necessary.

Keep in mind that this approach does not modify how individual share-level reporting works in Samba. It simply provides an additional share that points to the pool's root for reporting purposes.

You must log in to answer this question.

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