Skip to content

Add fallback implementation to blockio used when platform isn't Linux, MacOS and FreeBSD - #886

Open
mwihoti wants to merge 2 commits into
IntersectMBO:mainfrom
mwihoti:feature/872-posix-fallback
Open

mwihoti wants to merge 2 commits into
IntersectMBO:mainfrom
mwihoti:feature/872-posix-fallback

Conversation

@mwihoti

@mwihoti mwihoti commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Description

Resolves #872.

I added a generic portable fallback: serial HasBlockIO in src-unix, which gets picked when the platform isn't Linux, MacOS, Windows or FreeBSD. I also introduced a posixblockio cabal flag that forces this fallback on any platform, allowing CI to build and test it on Linux without needing extra runners.

Instead of reusing the macOS backend (as #847 did, which assumes F_NOCACHE), I chose the dedicated fallback route for Unix. The generic POSIX layer cannot assume that O_DIRECT, F_NOCACHE or posix_fallocate exist, and unix's fileAllocate and fileSetCaching throw where they're missing. Therefore I guarded those features using the HAVE_* macros from HsUnix.h (the same include used by the FreeBSD backend) so they gracefully degrade to no-ops, similar to how the macOS backend already handles hAllocate. Both modules are .hsc rather than .hs because GHC's cpp can't process HsUnix.h (it pulls in glibc headers) while hsc2hs can the same reason the FreeBSD backend's Fcntl is .hsc.

Finally, I added a +posixblockio entry to the CI matrix alongside +serialblockio, and updated the platform notes in IO.hs, the README and the changelog.

Tested locally: the default Linux build is unchanged, cabal build blockio --flag=+posixblockio compiles the fallback, and cabal test blockio:test --flag=+posixblockio passes all 11 tests against it. One limitation: on Linux all the HAVE_* macros are true, so CI only compiles the "supported" branches; the #else no-ops are only compiled on a platform that actually lacks the syscalls. Running --flag=+posixblockio on FreeBSD would be a useful second data point.

Checklist

  • Read our contribution guidelines at CONTRIBUTING.md, and make sure that this PR complies with the guidelines.
image image image

@jorisdral jorisdral left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the plan you outline in the PR description is sensible! But something may have gone wrong with your commits, because I'm missing code changes.

P.S.: no need to post screenshots of your console with test output. CI will verify that the tests succeed.

Comment thread blockio/blockio.cabal Outdated
Comment thread blockio/blockio.cabal Outdated
Comment thread blockio/CHANGELOG.md Outdated
Comment on lines +11 to +17
* Add a portable serial `HasBlockIO` implementation for POSIX systems that do
not have a dedicated one, so `blockio` builds on more than Linux, MacOS,
Windows, and FreeBSD. Operations the platform does not support
(`posix_fallocate`, `O_DIRECT`/`F_NOCACHE`) degrade to no-ops. See [issue
#872][issue-872] and [PR #NNN][pr-NNN].
* Add the `posixblockio` cabal flag, which forces the portable implementation
on any platform, for testing it. See [PR #NNN][pr-NNN].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fill in the [PR #NNN][pr-NNN] links

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the changes yet

@mwihoti
mwihoti force-pushed the feature/872-posix-fallback branch from 59e4238 to e9b447d Compare September 23, 2026 05:45
Comment thread blockio/CHANGELOG.md Outdated
Comment on lines +11 to +17
* Add a portable serial `HasBlockIO` implementation for POSIX systems that do
not have a dedicated one, so `blockio` builds on more than Linux, MacOS,
Windows, and FreeBSD. Operations the platform does not support
(`posix_fallocate`, `O_DIRECT`/`F_NOCACHE`) degrade to no-ops. See [issue
#872][issue-872] and [PR #NNN][pr-NNN].
* Add the `posixblockio` cabal flag, which forces the portable implementation
on any platform, for testing it. See [PR #NNN][pr-NNN].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the changes yet

Comment thread blockio/CHANGELOG.md Outdated
Comment on lines +11 to +17
* Add a portable serial `HasBlockIO` implementation for POSIX systems that do
not have a dedicated one, so `blockio` builds on more than Linux, MacOS,
Windows, and FreeBSD. Operations the platform does not support
(`posix_fallocate`, `O_DIRECT`/`F_NOCACHE`) degrade to no-ops. See [issue
#872][issue-872] and [PR #NNN][pr-NNN].
* Add the `posixblockio` cabal flag, which forces the portable implementation
on any platform, for testing it. See [PR #NNN][pr-NNN].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure about using the name "POSIX" to describe the fallback implementation. Posix is a standard, not an operating system. I think we should call it something like "unix-like", or maybe even "fallback". Do you have thoughts on this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unix-like fits

Comment thread blockio/README.md Outdated
Comment on lines +25 to +28
as well. On other POSIX systems a portable serial implementation is used that
relies only on the parts of the `unix` package available on the platform; it
can be selected explicitly on any platform with the `posixblockio` cabal flag.
The simulated implementation also performs each I/O operation sequentially.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
as well. On other POSIX systems a portable serial implementation is used that
relies only on the parts of the `unix` package available on the platform; it
can be selected explicitly on any platform with the `posixblockio` cabal flag.
The simulated implementation also performs each I/O operation sequentially.
as well. If the operating system is none of the above, then the system is assumed to be Unix-like, in which case the library uses a fallback implementation that performs I/O operations sequentially.
The simulated implementation also performs each I/O operation sequentially.

Comment thread blockio/CHANGELOG.md Outdated
Comment on lines +11 to +15
* Add a portable serial `HasBlockIO` implementation for POSIX systems that do
not have a dedicated one, so `blockio` builds on more than Linux, MacOS,
Windows, and FreeBSD. Operations the platform does not support
(`posix_fallocate`, `O_DIRECT`/`F_NOCACHE`) degrade to no-ops. See [issue
#872][issue-872] and [PR #NNN][pr-NNN].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also emphasize that the OS is now assumed to be Unix-like in case the OS is not one of the explicitly supported OS's (Linux, MacOS, Windows, FreeBSD). This is different from the previous behaviour, where the library would simply be unbuildable on unsupported OS's.

Comment thread blockio/blockio.cabal Outdated
Comment on lines +74 to +81
flag posixblockio
description:
Use the portable POSIX HasBlockIO implementation regardless of the
operating system. Intended for testing that implementation on platforms
that have a dedicated one. Not supported on Windows.

default: False
manual: True

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
flag posixblockio
description:
Use the portable POSIX HasBlockIO implementation regardless of the
operating system. Intended for testing that implementation on platforms
that have a dedicated one. Not supported on Windows.
default: False
manual: True
flag unixlikeblockio
description:
Use the Unix-like HasBlockIO implementation regardless of the
operating system. Intended for testing that implementation on platforms
that have a dedicated one. No-op on Windows.
default: False
manual: True

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably copied this module from another System.FS.BlockIO.Internal.Fcntl, but it's no longer necessary. This type of module is only necessary to support unix versions <unix-2.8.7, but we support >=unix-2.8.7.

Comment thread blockio/src/System/FS/BlockIO/IO.hs Outdated
Comment on lines +42 to +43
'submitIO', just like the MacOS, Windows, FreeBSD, and portable POSIX
implementations do.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'submitIO', just like the MacOS, Windows, FreeBSD, and portable POSIX
implementations do.
'submitIO', just like the MacOS, Windows, FreeBSD, and Unix-like
implementations do.

Comment thread blockio/src/System/FS/BlockIO/IO.hs Outdated
* MacOS: a mocked context using an @MVar@
* Windows: a mocked context using an @MVar@
* FreeBSD: a mocked context using an @MVar@
* Other POSIX systems: a mocked context using an @MVar@

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update this everywhere:

Suggested change
* Other POSIX systems: a mocked context using an @MVar@
* Unix-like systems: a mocked context using an @MVar@

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I have done updates

Comment on lines +24 to +27
-- | A portable, serial implementation of 'HasBlockIO' for POSIX systems that
-- do not have a dedicated implementation (Linux, MacOS, and FreeBSD do). It
-- uses only the parts of the @unix@ package that are available on the
-- platform, and degrades to no-ops where an operation is not supported.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
-- | A portable, serial implementation of 'HasBlockIO' for POSIX systems that
-- do not have a dedicated implementation (Linux, MacOS, and FreeBSD do). It
-- uses only the parts of the @unix@ package that are available on the
-- platform, and degrades to no-ops where an operation is not supported.
-- | A portable, serial implementation of 'HasBlockIO' for Unix-like systems that
-- do not have a dedicated implementation (Linux, MacOS, and FreeBSD do).

Comment on lines +70 to +72
hSynchronise :: Handle HandleIO -> IO ()
hSynchronise h = FS.withOpenHandle "hSynchronise" (handleRaw h) $ \fd ->
Unix.fileSynchronise fd

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks to me like fileSynchronise can also throw an error if the system does not HAVE_FSYNC. We should also make it a no-op in that case, like we do with hAllocate. We should also update the docs accordingly.

Linux, MacOS, Windows, and FreeBSD each have a dedicated HasBlockIO
implementation, but every other platform couldn't build blockio at all.

This adds a serial fallback in src-unix, used when the platform isn't one
of those four. It relies only on the parts of the unix package that are
actually available, and degrades to no-ops where the platform doesn't
support an operation (O_DIRECT/F_NOCACHE, posix_fallocate, fsync).

Also adds the unixlikeblockio cabal flag, which forces the fallback on any
platform, so CI can build and test it on Linux without needing dedicated
runners for the other platforms.

Resolves IntersectMBO#872.
@mwihoti
mwihoti force-pushed the feature/872-posix-fallback branch from e9b447d to 03b89f0 Compare September 30, 2026 05:49
@mwihoti
mwihoti requested a review from jorisdral September 30, 2026 05:59
@mwihoti mwihoti changed the title Added fallback implementation to blockio used when platform isn't Linux, MacOS and FreeBSD Add fallback implementation to blockio used when platform isn't Linux, MacOS and FreeBSD Oct 6, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support platforms other than Linux, OSX, and Windows

2 participants