[hatari-devel] Re: GemDOS_DFree

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

On 9.6.2025 15.29, Christian Zietz via Emutos-devel wrote:
...
The results on macOS are ... interesting:

sizeof(struct statvfs) = 64
sizeof(f_bfree) = 4
sizeof(f_bavail) = 4
statfs() = 0
f_blocks = 83758080
f_frsize = 4096
f_bfree = 11770043
f_bavail = 11770043
f_bsize = 4161536

First the members are just 4 bytes (32 bits) long! Then, the total file system size is specified by POSIX to be "f_blocks*f_frsize". But it is not clearly specified, whether the free blocks are given in units of "f_frsize" or "f_bsize". Hatari uses different units for total and free space: "Total = buf.f_blocks/1024 * buf.f_frsize" and "Free = Free/1024 * buf.f_bsize". But with the values above, this calculation gives more free space than total space on macOS!

If we look into how Apple fills these fields:
https://github.com/apple-oss-distributions/Libc/ blob/63976b830a836a22649b806fe62e8614fe3e5555/emulated/statvfs.c#L35 ... "f_bsize" corresponds to "f_iosize", which is the "optimal transfer block size". Thus, I'm not sure if it correct to use "f_bsize" here.

Very confusing. I guess the original post will just have to accept that the values on macOS are rubbish.

Maybe attached patch would be OK for it?


	- Eero
From 8ad864ca1b7d526916ba3d3350034352bef43a3d Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Fri, 13 Jun 2025 00:51:33 +0300
Subject: [PATCH] Workaround for Mac Dfree() issue

Report + test program by Christian Zietz.
---
 src/gemdos.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/gemdos.c b/src/gemdos.c
index 224b6671..e1591146 100644
--- a/src/gemdos.c
+++ b/src/gemdos.c
@@ -1645,12 +1645,21 @@ static bool GemDOS_DFree(uint32_t Params)
 	memset(&buf, 0, sizeof(buf));
 	if (statvfs(emudrives[Drive-2]->hd_emulation_dir, &buf) == 0)
 	{
-		Total = buf.f_blocks/1024 * buf.f_frsize;
+		Total = buf.f_blocks * buf.f_frsize;
 		if (buf.f_bavail > 0)
 			Free = buf.f_bavail;	/* free for unprivileged user */
 		else
 			Free = buf.f_bfree;
-		Free = Free/1024 * buf.f_bsize;
+
+		/* f_bsize may be too large/invalid on Mac */
+		if (Free * buf.f_bsize <= Total)
+			Free *= buf.f_bsize;
+		else
+			Free *= buf.f_frsize;
+
+		/* as 1KB cluster counts */
+		Total /= 1024;
+		Free /= 1024;
 
 		/* TOS version limits based on:
 		 *   http://hddriver.seimet.de/en/faq.html
-- 
2.39.5



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/