@@ -742,7 +742,58 @@ class c_flock_t(ctypes.Structure): # type: ignore
742742# - 3.14.1 -> 3.16.2: no change
743743_fuse_int32 = ctypes .c_int32 if (fuse_version_major , fuse_version_minor ) >= (3 , 17 ) else ctypes .c_int
744744_fuse_uint32 = ctypes .c_uint32 if (fuse_version_major , fuse_version_minor ) >= (3 , 17 ) else ctypes .c_uint
745- if fuse_version_major == 2 :
745+ if _system == 'NetBSD' :
746+ # NetBSD has its own FUSE library reimplementation with mismatching struct layouts!
747+ # writepage is a bitfield (as in libFUSE 3.x), but the fh_old member still exists and the reported version is 2.9!
748+ # https://www.netbsd.org/docs/puffs/
749+ # https://github.com/NetBSD/src/blob/netbsd-11/lib/librefuse/fuse.h#L100-L129
750+ # https://github.com/NetBSD/src/blob/netbsd-10/lib/librefuse/fuse.h#L100-L129
751+ # - fuse_file_info is unchanged between 10 and 11
752+ # - FUSE_USE_VERSION is not set, but is set to _REFUSE_VERSION_ (3.10) with a warning if not set!
753+ # - However, the CI prints FUSE version 2.9?!
754+ # - Seems there is no sane way to get the correct compiled version! This is again an absolute shit show!
755+ # https://github.com/NetBSD/src/blob/netbsd-9/lib/librefuse/fuse.h#L51-L61
756+ # - fuse_file_info looks quite different and version is specified as 2.6!
757+ # - #define FUSE_USE_VERSION 26
758+ fuse_version = (fuse_version_major , fuse_version_minor )
759+ _fuse_file_info_fields_ : list [FieldsEntry ] = [
760+ ('flags' , ctypes .c_int32 ),
761+ ('fh_old' , ctypes .c_uint32 ),
762+ ]
763+
764+ _fuse_file_info_fields_bitfield : list [FieldsEntry ] = []
765+
766+ if fuse_version >= (2 , 9 ):
767+ _fuse_file_info_fields_bitfield += [('writepage' , ctypes .c_int32 , 1 )]
768+ else :
769+ _fuse_file_info_fields_ += [('writepage' , ctypes .c_int32 )]
770+
771+ _fuse_file_info_fields_bitfield += [
772+ ('direct_io' , ctypes .c_uint32 , 1 ), # Introduced in FUSE 2.4
773+ ('keep_cache' , ctypes .c_uint32 , 1 ), # Introduced in FUSE 2.4
774+ ('flush' , ctypes .c_uint32 , 1 ), # Introduced in FUSE 2.6
775+ ]
776+ if fuse_version >= (2 , 9 ):
777+ _fuse_file_info_fields_bitfield += [
778+ ('nonseekable' , ctypes .c_uint , 1 ), # Introduced in FUSE 2.8
779+ ('flock_release' , ctypes .c_uint , 1 ), # Introduced in FUSE 2.9
780+ ('cache_readdir' , ctypes .c_uint , 1 ), # Introduced in FUSE 3.5
781+ ]
782+
783+ _fuse_file_info_flag_count = sum (x [2 ] for x in _fuse_file_info_fields_bitfield )
784+ assert _fuse_file_info_flag_count < ctypes .sizeof (_fuse_uint32 ) * 8
785+
786+ _fuse_file_info_fields_ += _fuse_file_info_fields_bitfield
787+ _fuse_file_info_fields_ += [
788+ ('padding' , _fuse_uint32 , ctypes .sizeof (_fuse_uint32 ) * 8 - _fuse_file_info_flag_count ),
789+ ('fh' , ctypes .c_uint64 ),
790+ ('lock_owner' , ctypes .c_uint64 ),
791+ ]
792+
793+ if fuse_version >= (2 , 9 ):
794+ _fuse_file_info_fields_ += [('poll_events' , ctypes .c_uint32 )]
795+
796+ elif fuse_version_major == 2 :
746797 _fh_old_type = ctypes .c_uint if _system == 'OpenBSD' else ctypes .c_ulong
747798 _fuse_file_info_fields_ : list [FieldsEntry ] = [
748799 ('flags' , ctypes .c_int ),
0 commit comments