[Mono-dev] [PATCH] DriveInfo implementation - volume space

Javier Martín lordhabbit at gmail.com
Sun Dec 9 14:29:07 EST 2007


I'm back from the no-internet land! Hi again!


Robert Jordan wrote:
>In volumes.c:
>
>+	if (NULL != availFree)
>+		availFree->QuadPart = buf.f_bavail * buf.f_frsize;
>+	if (NULL != totalSize)
>+		totalSize->QuadPart = buf.f_blocks * buf.f_frsize;
>+	if (NULL != totalFree)
>+		totalFree->QuadPart = buf.f_bfree * buf.f_frsize;
>
>On systems w/out LARGE_FILE support (_FILE_OFFSET_BITS != 64),
>the computations are not performed at 64-bit precision, so
>you better cast the result to guint64.

You are partially right: indeed the result could be performed with
<64b precision on systems with _FILE_OFFSET_BITS < 64 (very few, I
believe, since FUSE requires 64-bit off_t and friends), but you are
wrong on where to apply the fix: casting the (already truncated)
result will just fill the upper 32 bits with zeros. Instead, the cast
should be performed on the arguments, so the computation is performed
with >= 64 bits precision and no data is lost.

In fact, I'm thinking of writing a small macro checking if
_FILE_OFFSET_BITS is less than 64 and then applying the cast. I don't
want the code to break with a 128-bit off_t (though it WILL break
because ULARGE_INTEGER is only 64bits xD). Maybe it could be like
this:

#define WIDEN(x,t) ( (sizeof(x) < sizeof(t)) ? (t)x : x );
So the result could be like this:
availSpace->QuadPart = WIDEN(buf.f_bavail,guint64) * buf.f_frsize;

This way, the code will always use 64-bits precision (the right
argument for * is automatically casted to the wider type), and when
_FOT > 64 it will fail to compile reminding the 2030 Mono developers
(we should already be looking for newborns and start training them in
the ways of the Force) that the result type needs to be changed. I
consider that better than just random "oh my, I lost ten exbibytes"
errors.

* Disclaimer: this last part was not entirely serious, but it has
induced a reflection in me. Still don't know if I used
System.Reflection or CECIL, though. Seriously now, do I need to resend
the fixed patch or will you insert the three casts required?

>I don't think your patch will make into 1.2.6, but feel free
>to ask the team (Dick, Miguel).
>To avoid stability issues, you can always work with a stable
>branch (e.g. branches/mono-1-2-6/ in SVN) and apply the patch
>to this version.

That way I discovered a bit after I posted my last message. I was even
able to build .deb packages for my Ubuntu server based on 1.2.4 (last
version "apt-get source" retrieved) with incredible ease. Just had to
re-invoke the autotools so that Makefiles would be regenerated. Thanks
for the advice!

By the way, I'm already thinking about a new patch for this class.
This time, volume names are the target. Beware!

Habbit



More information about the Mono-devel-list mailing list