|
34 | 34 | from typing import TYPE_CHECKING, Any, Optional, Union, get_type_hints |
35 | 35 |
|
36 | 36 | FieldsEntry = Union[tuple[str, type], tuple[str, type, int]] |
| 37 | +BitFieldsEntry = tuple[str, type, int] |
37 | 38 | ReadDirResult = Iterable[Union[str, tuple[str, dict[str, int], int], tuple[str, int, int]]] |
38 | 39 |
|
39 | 40 | if TYPE_CHECKING: |
@@ -742,9 +743,60 @@ class c_flock_t(ctypes.Structure): # type: ignore |
742 | 743 | # - 3.14.1 -> 3.16.2: no change |
743 | 744 | _fuse_int32 = ctypes.c_int32 if (fuse_version_major, fuse_version_minor) >= (3, 17) else ctypes.c_int |
744 | 745 | _fuse_uint32 = ctypes.c_uint32 if (fuse_version_major, fuse_version_minor) >= (3, 17) else ctypes.c_uint |
745 | | -if fuse_version_major == 2: |
| 746 | +_fuse_file_info_fields_: list[FieldsEntry] = [] |
| 747 | +_fuse_file_info_fields_bitfield: list[BitFieldsEntry] = [] |
| 748 | +if _system == 'NetBSD': |
| 749 | + # NetBSD has its own FUSE library reimplementation with mismatching struct layouts! |
| 750 | + # writepage is a bitfield (as in libFUSE 3.x), but the fh_old member still exists and the reported version is 2.9! |
| 751 | + # https://www.netbsd.org/docs/puffs/ |
| 752 | + # https://github.com/NetBSD/src/blob/netbsd-11/lib/librefuse/fuse.h#L100-L129 |
| 753 | + # https://github.com/NetBSD/src/blob/netbsd-10/lib/librefuse/fuse.h#L100-L129 |
| 754 | + # - fuse_file_info is unchanged between 10 and 11 |
| 755 | + # - FUSE_USE_VERSION is not set, but is set to _REFUSE_VERSION_ (3.10) with a warning if not set! |
| 756 | + # - However, the CI prints FUSE version 2.9?! |
| 757 | + # - Seems there is no sane way to get the correct compiled version! This is again an absolute shit show! |
| 758 | + # https://github.com/NetBSD/src/blob/netbsd-9/lib/librefuse/fuse.h#L51-L61 |
| 759 | + # - fuse_file_info looks quite different and version is specified as 2.6! |
| 760 | + # - #define FUSE_USE_VERSION 26 |
| 761 | + fuse_version = (fuse_version_major, fuse_version_minor) |
| 762 | + _fuse_file_info_fields_ = [ |
| 763 | + ('flags', ctypes.c_int32), |
| 764 | + ('fh_old', ctypes.c_uint32), |
| 765 | + ] |
| 766 | + |
| 767 | + if fuse_version >= (2, 9): |
| 768 | + _fuse_file_info_fields_bitfield += [('writepage', ctypes.c_int32, 1)] |
| 769 | + else: |
| 770 | + _fuse_file_info_fields_ += [('writepage', ctypes.c_int32)] |
| 771 | + |
| 772 | + _fuse_file_info_fields_bitfield += [ |
| 773 | + ('direct_io', ctypes.c_uint32, 1), # Introduced in FUSE 2.4 |
| 774 | + ('keep_cache', ctypes.c_uint32, 1), # Introduced in FUSE 2.4 |
| 775 | + ('flush', ctypes.c_uint32, 1), # Introduced in FUSE 2.6 |
| 776 | + ] |
| 777 | + if fuse_version >= (2, 9): |
| 778 | + _fuse_file_info_fields_bitfield += [ |
| 779 | + ('nonseekable', ctypes.c_uint, 1), # Introduced in FUSE 2.8 |
| 780 | + ('flock_release', ctypes.c_uint, 1), # Introduced in FUSE 2.9 |
| 781 | + ('cache_readdir', ctypes.c_uint, 1), # Introduced in FUSE 3.5 |
| 782 | + ] |
| 783 | + |
| 784 | + _fuse_file_info_flag_count = sum(x[2] for x in _fuse_file_info_fields_bitfield) |
| 785 | + assert _fuse_file_info_flag_count < ctypes.sizeof(_fuse_uint32) * 8 |
| 786 | + |
| 787 | + _fuse_file_info_fields_ += _fuse_file_info_fields_bitfield |
| 788 | + _fuse_file_info_fields_ += [ |
| 789 | + ('padding', _fuse_uint32, ctypes.sizeof(_fuse_uint32) * 8 - _fuse_file_info_flag_count), |
| 790 | + ('fh', ctypes.c_uint64), |
| 791 | + ('lock_owner', ctypes.c_uint64), |
| 792 | + ] |
| 793 | + |
| 794 | + if fuse_version >= (2, 9): |
| 795 | + _fuse_file_info_fields_ += [('poll_events', ctypes.c_uint32)] |
| 796 | + |
| 797 | +elif fuse_version_major == 2: |
746 | 798 | _fh_old_type = ctypes.c_uint if _system == 'OpenBSD' else ctypes.c_ulong |
747 | | - _fuse_file_info_fields_: list[FieldsEntry] = [ |
| 799 | + _fuse_file_info_fields_ = [ |
748 | 800 | ('flags', ctypes.c_int), |
749 | 801 | ('fh_old', _fh_old_type), |
750 | 802 | ('writepage', ctypes.c_int), |
@@ -972,7 +1024,8 @@ class fuse_conn_info(ctypes.Structure): # Added in 2.6 (ABI break of "init" fro |
972 | 1024 | # Another ABI break as discussed here: https://lists.debian.org/debian-devel/2024/03/msg00278.html |
973 | 1025 | # The break was in 3.14.1 NOT in 3.14.0, but I cannot query the bugfix version. |
974 | 1026 | # I'd hope that all 3.14.0 installations have been replaced by updates to 3.14.1. |
975 | | - if fuse_version_minor >= 14 and fuse_version_minor < 17: |
| 1027 | + # ... they have not. My own system, Ubuntu 24.04 uses fuse 3.14.0. Check for >= 3.15. |
| 1028 | + if fuse_version_minor >= 15 and fuse_version_minor < 17: |
976 | 1029 | _fuse_config_fields_ += [('parallel_direct_writes', ctypes.c_int)] |
977 | 1030 |
|
978 | 1031 | _fuse_config_fields_ += [ |
|
0 commit comments