Bug 15602 - wrong fs space information at mounted cifs share with subpath
Summary: wrong fs space information at mounted cifs share with subpath
Status: NEW
Alias: None
Product: CifsVFS
Classification: Unclassified
Component: kernel fs (show other bugs)
Version: 5.x
Hardware: All Linux
: P5 normal
Target Milestone: ---
Assignee: Steve French
QA Contact: cifs QA contact
Depends on:
Reported: 2024-03-07 06:24 UTC by Bastian Urschel
Modified: 2024-03-07 06:24 UTC (History)
0 users

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Bastian Urschel 2024-03-07 06:24:02 UTC

we've a netapp storage system with a volume (root volume with 1GB) exported as a cifs share. This cifs share is called "nas2". Below this volume, there are subvolumes mounted, for example vol1 (3TB), vol2 (15TB).
nas2     ( 1GB volume size)
 |- vol1 ( 3TB volume size)
 |- vol2 (15TB volume size)
You can alternatively use zfs to build such a structure and share "nas2" with samba.

I observe different behaviors on Windows and Linux-systems if mounting this cifs share with subpath like "//":
 - Windows systems shows the correct filesystem space of "\\\nas2\vol1"
 - a df on Linux systems with mounted cifs "//" returns wrong space information and shows only 1GB which is space of root volume. Linux systems can ran into problem if copying a file which is bigger than 1GB because of missing space.
The cli tool "smbclient" behaves like Windows clients and shows correct block information of "vol1" if doing an ls with smbclient at path "nas2/vol1".

I've done some research on two possibilities and sniffed with wireshark:
 - smbclient: navigate to "nas2/vol1", started capture and make an ls (correct space info is shown as blocks and blocksize)
 - fs kernel client: doing a mount.cifs for share with subpath "nas2/vol1". Call "df -h" which shows 1GB but should show 3TB
I've saved those two captures if it is usefull for bugfix. We compared these two captures and it seems that there is a difference in the way these two possibilities ask for FileFsSizeInformation/FileFsFullSizeInformation. smbclient asks for a specific file which is the subpath. The fs kernel client asks for empty file which seems to be the root of share.

After that we had a look at client kernel module sources (v6.7.1) and we've found in file "smb2ops.c" functions "smb2_queryfs" and "smb311_queryfs". In "smb2_queryfs" there is a call of smb2_query_info_compound which has a path-parameter. This path-parameter is set to an empty string. In function "smb311_queryfs" there is struct "oparms" which has struct member "path", also set to an empty string.
If you fill these two places with string "/vol1" instead of "", build the cifs client kernel module, load it and mount the share with subpath ("//") you will get the correct filesystem size if doing an "df -h". Because this is a static solution, I've started an approach to get it more dynamic and used the content of string cifs_sb->ctx->prepath to feed those two path variables in both functions. Possibly this approach is ugly but it works if your source is a storage system. If a bugfix can be implemented it will also be interesting to make this bugfix dfs compatible as my approach will not work with dfs because paths on dfs can be different than on storage backends (prepath is empty if using a dfs).
I don't have any deep diving knowledge in this kernel module and because this approach was (possibly) an ugly fix, I wanted to make this bugreport and share my efforts in hope that this bug can be fixed in the future.

Best regards/Viele Grüße
Bastian Urschel