]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/cephfs: replace deprecated IF with C preprocessor macro
authorKefu Chai <k.chai@proxmox.com>
Fri, 30 Jan 2026 08:43:03 +0000 (16:43 +0800)
committerKefu Chai <k.chai@proxmox.com>
Mon, 2 Feb 2026 03:14:44 +0000 (11:14 +0800)
Complete the migration started in 719b74984605 by replacing
deprecated Cython IF statements with C preprocessor conditionals.

The cephfs binding used deprecated IF/ELSE statements in types.pxd
for platform-specific dirent struct definitions. The challenge was that
dirent has a d_off field on Linux but not on FreeBSD/Darwin.

Solution:
- Remove dirent declaration from types.pxd (had deprecated IF)
- Declare dirent with common fields in c_cephfs.pxd
- Define DIRENT_D_OFF(d) C macro using C preprocessor conditionals:
  - Returns d->d_off on Linux
  - Returns 0UL on FreeBSD/Darwin
- Use DIRENT_D_OFF macro in cephfs.pyx instead of conditional field access
- No Tempita preprocessing or UNAME_SYSNAME needed
- Revert setup.py to original (no changes needed)

Why C preprocessor instead of Tempita:
Tempita requires preprocessing files with setup.py, which works for .pyx
files but is problematic for .pxd files since setup.py runs in the source
directory and could overwrite sources. The C preprocessor approach is
cleaner, requires no setup.py changes, and follows the pattern used in
rados.pxd for BUILD_DOC conditionals.

This eliminates all deprecated Cython IF statements and prepares
for Cython 3.0+ compatibility. The C preprocessor approach allows
portable access to platform-specific struct fields without Cython IF.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
src/pybind/cephfs/c_cephfs.pxd
src/pybind/cephfs/cephfs.pyx
src/pybind/cephfs/mock_cephfs.pxi
src/pybind/cephfs/types.pxd

index 8245f12f69f62ce0db9510f003c5172a94c8689e..88fd6abb4f8b7f306ee0cba2a256c5272669cc19 100644 (file)
@@ -4,6 +4,27 @@
 from libc.stdint cimport *
 from types cimport *
 
+# dirent struct with common fields and platform-specific d_off handling
+cdef extern from *:
+    """
+    #include <dirent.h>
+    #if defined(__FreeBSD__) || defined(__APPLE__)
+    #define DIRENT_D_OFF(d) 0UL
+    #else
+    #define DIRENT_D_OFF(d) ((d)->d_off)
+    #endif
+    """
+    # Declare struct with common fields
+    cdef struct dirent:
+        long int d_ino
+        unsigned short int d_reclen
+        unsigned char d_type
+        char d_name[256]
+        # Note: d_off only on Linux - use DIRENT_D_OFF macro to access
+
+    # Macro to get d_off portably
+    unsigned long DIRENT_D_OFF(dirent *d)
+
 cdef extern from "../include/platform_errno.h":
     ctypedef signed int int32_t;
     int32_t ceph_to_hostos_errno(int32_t e)
index 1d8fc2282ea69faad024e39f2dc29f4d48000c76..7a3b4668d7e84de9402b6ab1a10a842de8c86a67 100644 (file)
@@ -300,6 +300,8 @@ cdef class DirResult(object):
         return False
 
     def readdir(self):
+        cdef dirent *dirent
+
         self.lib.require_state("mounted")
 
         with nogil:
@@ -307,20 +309,12 @@ cdef class DirResult(object):
         if not dirent:
             return None
 
-        IF UNAME_SYSNAME == "FreeBSD" or UNAME_SYSNAME == "Darwin":
-            return DirEntry(d_ino=dirent.d_ino,
-                            d_off=0,
-                            d_reclen=dirent.d_reclen,
-                            d_type=dirent.d_type,
-                            d_name=dirent.d_name,
-                            d_snapid=CEPH_NOSNAP)
-        ELSE:
-            return DirEntry(d_ino=dirent.d_ino,
-                            d_off=dirent.d_off,
-                            d_reclen=dirent.d_reclen,
-                            d_type=dirent.d_type,
-                            d_name=dirent.d_name,
-                            d_snapid=CEPH_NOSNAP)
+        return DirEntry(d_ino=dirent.d_ino,
+                        d_off=DIRENT_D_OFF(dirent),
+                        d_reclen=dirent.d_reclen,
+                        d_type=dirent.d_type,
+                        d_name=dirent.d_name,
+                        d_snapid=CEPH_NOSNAP)
 
     def close(self):
         if self.handle:
@@ -383,20 +377,12 @@ cdef class SnapDiffHandle(object):
         if ret == 0:
             return None
 
-        IF UNAME_SYSNAME == "FreeBSD" or UNAME_SYSNAME == "Darwin":
-            return DirEntry(d_ino=difent.dir_entry.d_ino,
-                            d_off=0,
-                            d_reclen=difent.dir_entry.d_reclen,
-                            d_type=difent.dir_entry.d_type,
-                            d_name=difent.dir_entry.d_name,
-                            d_snapid=difent.snapid)
-        ELSE:
-            return DirEntry(d_ino=difent.dir_entry.d_ino,
-                            d_off=difent.dir_entry.d_off,
-                            d_reclen=difent.dir_entry.d_reclen,
-                            d_type=difent.dir_entry.d_type,
-                            d_name=difent.dir_entry.d_name,
-                            d_snapid=difent.snapid)
+        return DirEntry(d_ino=difent.dir_entry.d_ino,
+                        d_off=DIRENT_D_OFF(&difent.dir_entry),
+                        d_reclen=difent.dir_entry.d_reclen,
+                        d_type=difent.dir_entry.d_type,
+                        d_name=difent.dir_entry.d_name,
+                        d_snapid=difent.snapid)
 
     def close(self):
         if (not self.opened):
index 717d6e468bb67bea65e757a3d158059d0c45f709..006575c9a8579be03924b838c11cade1a4f7bf50 100644 (file)
@@ -9,6 +9,28 @@ cdef:
         pass
 
 
+cdef extern from *:
+    """
+    // Mock dirent struct and DIRENT_D_OFF macro for BUILD_DOC
+    struct dirent {
+        long int d_ino;
+        unsigned short int d_reclen;
+        unsigned char d_type;
+        char d_name[256];
+    };
+    #define DIRENT_D_OFF(d) 0UL
+    """
+    # dirent struct for mock (matches declaration in c_cephfs.pxd)
+    cdef struct dirent:
+        long int d_ino
+        unsigned short int d_reclen
+        unsigned char d_type
+        char d_name[256]
+
+    # Macro to get d_off portably (always returns 0 in mock)
+    unsigned long DIRENT_D_OFF(dirent *d)
+
+
 cdef:
     cdef struct statx "ceph_statx":
         uint32_t    stx_mask
@@ -48,7 +70,8 @@ cdef nogil:
         int dummy
 
     cdef struct ceph_snapdiff_entry_t:
-        int dummy
+        dirent dir_entry
+        uint64_t snapid
 
     ctypedef void* rados_t
 
index cbe31cbf4ba8031b7a17b23edbf06badfb9987d9..d4f3db9202aa9a42f5945402c5c79fe1c5bc9515 100644 (file)
@@ -40,18 +40,3 @@ cdef extern from "<sys/uio.h>":
         void *iov_base
         size_t iov_len
 
-IF UNAME_SYSNAME == "FreeBSD" or UNAME_SYSNAME == "Darwin":
-    cdef extern from "dirent.h":
-        cdef struct dirent:
-            long int d_ino
-            unsigned short int d_reclen
-            unsigned char d_type
-            char d_name[256]
-ELSE:
-    cdef extern from "dirent.h":
-        cdef struct dirent:
-            long int d_ino
-            unsigned long int d_off
-            unsigned short int d_reclen
-            unsigned char d_type
-            char d_name[256]